· 6 years ago · Feb 04, 2020, 03:54 AM
1
2
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru">
5<head>
6 <meta charset="UTF-8">
7</head>
8<head>
9
10 <title>Портал обучения и развития ГК "Белуга Групп"</title>
11 <link rel="apple-touch-icon" sizes="180x180" href="download_file.html?file_id=6580249293358135002">
12 <link rel="icon" type="image/png" sizes="32x32" href="download_file.html?file_id=6580249740371323075">
13 <link rel="icon" type="image/png" sizes="16x16" href="download_file.html?file_id=6580249635751793539">
14 <!-- <link rel="manifest" href="/site.webmanifest"> -->
15 <link rel="SHORTCUT ICON" type="image/x-icon" href="download_file.html?file_id=6580249487043410683"/>
16 <link rel="mask-icon" href="download_file.html?file_id=6580250129698875782" color="#5bbad5">
17 <meta name="msapplication-TileColor" content="#da532c">
18 <meta name="theme-color" content="#ffffff">
19 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
20 <script type="text/javascript" src="scripts/jquery.js" language="javascript"></script>
21 <script type="text/javascript" src="scripts/main_functions.js" language="javascript"></script>
22 <script type="text/javascript" src="scripts/wt-common.js" language="javascript"></script>
23 <script type="text/javascript" src="scripts/wt-game.js" language="javascript"></script>
24 <!-- <script type="text/javascript" src="scripts/jquery.ui.totop.js" language="javascript"></script> -->
25 <script type="text/javascript" src="scripts/jquery.easing.1.3.js" language="javascript"></script>
26 <script type="text/javascript" src="scripts/jqplugins/qtip/jquery.qtip.min.js" language="javascript"></script>
27 <link href="wt-game.css" rel="stylesheet" type="text/css"/>
28
29 <meta name="viewport" content="width=device-width">
30
31 <link href="scripts/jqplugins/qtip/jquery.qtip.min.css" rel="stylesheet" type="text/css"/>
32 <link rel="stylesheet" href="fonts/fontico/style.css" type="text/css">
33
34
35 <link href="custom_web_template.html?object_id=6034009707764127317" rel="stylesheet" type="text/css"/>
36
37 <link rel="stylesheet" href="scripts/extjs-5/build/packages/ext-theme-crisp/build/resources/ext-theme-crisp-all.css" type="text/css">
38 <link rel="stylesheet" href="pp/Ext5/player.css" type="text/css">
39
40 <link href="custom_web_template.html?object_id=6015134018786367009" rel="stylesheet" type="text/css"/>
41
42 <!-- IE9 uses the same CSS rules as W3C. Older versions may need some CSS fixes. Files below are here to apply these fixes. IE6 is not supported anymore -->
43 <!--[if lte IE 8]><link rel="stylesheet" type="text/css" href="/ie8-lte.css" /><![endif]-->
44 <!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="/ie7-lte.css" /><![endif]-->
45</head>
46<link rel="stylesheet" href="fonts/fontico/style.css" type="text/css">
47
48
49
50 <link href="/custom_web_template.html?object_id=5725320134341301769" rel="stylesheet" type="text/css"/>
51
52 <link href="custom_web_template.html?object_id=6034009707764127317" rel="stylesheet" type="text/css"/>
53 <link href="/custom_web_template.html?object_id=6039881813288121903" rel="stylesheet" type="text/css"/>
54
55
56
57
58
59
60<link href="/custom_web_template.html?object_code=beluga_assessment_style" rel="stylesheet" type="text/css"/>
61
62
63<body id="wt-body" onload="OnLoad()" onresize="OnResize()">
64 <script>
65 var s = location.href;
66 if (s.indexOf("logout:true@") > 0)
67 {
68 location.href = window.location.protocol+"//" +window.location.host + window.location.pathname + window.location.search;
69 }
70 </script>
71<script>
72/**
73 * Intro.js v0.9.0
74 * https://github.com/usablica/intro.js
75 * MIT licensed
76 *
77 * Copyright (C) 2013 usabli.ca - A weekend project by Afshin Mehrabani (@afshinmeh)
78 */
79
80(function (root, factory) {
81 if (typeof exports === 'object') {
82 // CommonJS
83 factory(exports);
84 } else if (typeof define === 'function' && define.amd) {
85 // AMD. Register as an anonymous module.
86 define(['exports'], factory);
87 } else {
88 // Browser globals
89 factory(root);
90 }
91} (this, function (exports) {
92 //Default config/variables
93 var VERSION = '0.9.0';
94
95 /**
96 * IntroJs main class
97 *
98 * @class IntroJs
99 */
100 function IntroJs(obj) {
101 this._targetElement = obj;
102
103 this._options = {
104 /* Next button label in tooltip box */
105 /*nextLabel: 'Next →',*/
106 nextLabel: 'Далее →',
107 /* Previous button label in tooltip box */
108 /* prevLabel: '← Back',*/
109 prevLabel: '← Назад',
110 /* Skip button label in tooltip box */
111 /* skipLabel: 'Skip', */
112 skipLabel: 'Пропустить',
113 /* Done button label in tooltip box */
114 /* doneLabel: 'Done',*/
115 doneLabel: 'Готово',
116 /* Default tooltip box position */
117 tooltipPosition: 'bottom',
118 /* Next CSS class for tooltip boxes */
119 tooltipClass: '',
120 /* Close introduction when pressing Escape button? */
121 exitOnEsc: true,
122 /* Close introduction when clicking on overlay layer? */
123 exitOnOverlayClick: true,
124 /* Show step numbers in introduction? */
125 showStepNumbers: true,
126 /* Let user use keyboard to navigate the tour? */
127 keyboardNavigation: true,
128 /* Show tour control buttons? */
129 showButtons: true,
130 /* Show tour bullets? */
131 showBullets: true,
132 /* Scroll to highlighted element? */
133 scrollToElement: true,
134 /* Set the overlay opacity */
135 overlayOpacity: 0.8
136 };
137 }
138
139 /**
140 * Initiate a new introduction/guide from an element in the page
141 *
142 * @api private
143 * @method _introForElement
144 * @param {Object} targetElm
145 * @returns {Boolean} Success or not?
146 */
147 function _introForElement(targetElm) {
148 var introItems = [],
149 self = this;
150
151 if (this._options.steps) {
152 //use steps passed programmatically
153 var allIntroSteps = [];
154
155 for (var i = 0, stepsLength = this._options.steps.length; i < stepsLength; i++) {
156 var currentItem = _cloneObject(this._options.steps[i]);
157 //set the step
158 currentItem.step = introItems.length + 1;
159 //use querySelector function only when developer used CSS selector
160 if (typeof(currentItem.element) === 'string') {
161 //grab the element with given selector from the page
162 currentItem.element = document.querySelector(currentItem.element);
163 }
164
165 //intro without element
166 if (typeof(currentItem.element) === 'undefined' || currentItem.element == null) {
167 var floatingElementQuery = document.querySelector(".introjsFloatingElement");
168
169 if (floatingElementQuery == null) {
170 floatingElementQuery = document.createElement('div');
171 floatingElementQuery.className = 'introjsFloatingElement';
172
173 document.body.appendChild(floatingElementQuery);
174 }
175
176 currentItem.element = floatingElementQuery;
177 currentItem.position = 'floating';
178 }
179
180 if (currentItem.element != null) {
181 introItems.push(currentItem);
182 }
183 }
184
185 } else {
186 //use steps from data-* annotations
187 var allIntroSteps = targetElm.querySelectorAll('*[data-intro]');
188 //if there's no element to intro
189 if (allIntroSteps.length < 1) {
190 return false;
191 }
192
193 //first add intro items with data-step
194 for (var i = 0, elmsLength = allIntroSteps.length; i < elmsLength; i++) {
195 var currentElement = allIntroSteps[i];
196 var step = parseInt(currentElement.getAttribute('data-step'), 10);
197
198 if (step > 0) {
199 introItems[step - 1] = {
200 element: currentElement,
201 intro: currentElement.getAttribute('data-intro'),
202 step: parseInt(currentElement.getAttribute('data-step'), 10),
203 tooltipClass: currentElement.getAttribute('data-tooltipClass'),
204 position: currentElement.getAttribute('data-position') || this._options.tooltipPosition
205 };
206 }
207 }
208
209 //next add intro items without data-step
210 //todo: we need a cleanup here, two loops are redundant
211 var nextStep = 0;
212 for (var i = 0, elmsLength = allIntroSteps.length; i < elmsLength; i++) {
213 var currentElement = allIntroSteps[i];
214
215 if (currentElement.getAttribute('data-step') == null) {
216
217 while (true) {
218 if (typeof introItems[nextStep] == 'undefined') {
219 break;
220 } else {
221 nextStep++;
222 }
223 }
224
225 introItems[nextStep] = {
226 element: currentElement,
227 intro: currentElement.getAttribute('data-intro'),
228 step: nextStep + 1,
229 tooltipClass: currentElement.getAttribute('data-tooltipClass'),
230 position: currentElement.getAttribute('data-position') || this._options.tooltipPosition
231 };
232 }
233 }
234 }
235
236 //removing undefined/null elements
237 var tempIntroItems = [];
238 for (var z = 0; z < introItems.length; z++) {
239 introItems[z] && tempIntroItems.push(introItems[z]); // copy non-empty values to the end of the array
240 }
241
242 introItems = tempIntroItems;
243
244 //Ok, sort all items with given steps
245 introItems.sort(function (a, b) {
246 return a.step - b.step;
247 });
248
249 //set it to the introJs object
250 self._introItems = introItems;
251
252 //add overlay layer to the page
253 if(_addOverlayLayer.call(self, targetElm)) {
254 //then, start the show
255 _nextStep.call(self);
256
257 var skipButton = targetElm.querySelector('.introjs-skipbutton'),
258 nextStepButton = targetElm.querySelector('.introjs-nextbutton');
259
260 self._onKeyDown = function(e) {
261 if (e.keyCode === 27 && self._options.exitOnEsc == true) {
262 //escape key pressed, exit the intro
263 _exitIntro.call(self, targetElm);
264 //check if any callback is defined
265 if (self._introExitCallback != undefined) {
266 self._introExitCallback.call(self);
267 }
268 } else if(e.keyCode === 37) {
269 //left arrow
270 _previousStep.call(self);
271 } else if (e.keyCode === 39 || e.keyCode === 13) {
272 //right arrow or enter
273 _nextStep.call(self);
274 //prevent default behaviour on hitting Enter, to prevent steps being skipped in some browsers
275 if(e.preventDefault) {
276 e.preventDefault();
277 } else {
278 e.returnValue = false;
279 }
280 }
281 };
282
283 self._onResize = function(e) {
284 _setHelperLayerPosition.call(self, document.querySelector('.introjs-helperLayer'));
285 };
286
287 if (window.addEventListener) {
288 if (this._options.keyboardNavigation) {
289 window.addEventListener('keydown', self._onKeyDown, true);
290 }
291 //for window resize
292 window.addEventListener("resize", self._onResize, true);
293 } else if (document.attachEvent) { //IE
294 if (this._options.keyboardNavigation) {
295 document.attachEvent('onkeydown', self._onKeyDown);
296 }
297 //for window resize
298 document.attachEvent("onresize", self._onResize);
299 }
300 }
301 return false;
302 }
303
304 /*
305 * makes a copy of the object
306 * @api private
307 * @method _cloneObject
308 */
309 function _cloneObject(object) {
310 if (object == null || typeof (object) != 'object' || typeof (object.nodeType) != 'undefined') {
311 return object;
312 }
313 var temp = {};
314 for (var key in object) {
315 temp[key] = _cloneObject(object[key]);
316 }
317 return temp;
318 }
319 /**
320 * Go to specific step of introduction
321 *
322 * @api private
323 * @method _goToStep
324 */
325 function _goToStep(step) {
326 //because steps starts with zero
327 this._currentStep = step - 2;
328 if (typeof (this._introItems) !== 'undefined') {
329 _nextStep.call(this);
330 }
331 }
332
333 /**
334 * Go to next step on intro
335 *
336 * @api private
337 * @method _nextStep
338 */
339 function _nextStep() {
340 this._direction = 'forward';
341
342 if (typeof (this._currentStep) === 'undefined') {
343 this._currentStep = 0;
344 } else {
345 ++this._currentStep;
346 }
347
348 if ((this._introItems.length) <= this._currentStep) {
349 //end of the intro
350 //check if any callback is defined
351 if (typeof (this._introCompleteCallback) === 'function') {
352 this._introCompleteCallback.call(this);
353 }
354 _exitIntro.call(this, this._targetElement);
355 return;
356 }
357
358 var nextStep = this._introItems[this._currentStep];
359 if (typeof (this._introBeforeChangeCallback) !== 'undefined') {
360 this._introBeforeChangeCallback.call(this, nextStep.element);
361 }
362
363 _showElement.call(this, nextStep);
364 }
365
366 /**
367 * Go to previous step on intro
368 *
369 * @api private
370 * @method _nextStep
371 */
372 function _previousStep() {
373 this._direction = 'backward';
374
375 if (this._currentStep === 0) {
376 return false;
377 }
378
379 var nextStep = this._introItems[--this._currentStep];
380 if (typeof (this._introBeforeChangeCallback) !== 'undefined') {
381 this._introBeforeChangeCallback.call(this, nextStep.element);
382 }
383
384 _showElement.call(this, nextStep);
385 }
386
387 /**
388 * Exit from intro
389 *
390 * @api private
391 * @method _exitIntro
392 * @param {Object} targetElement
393 */
394 function _exitIntro(targetElement) {
395 //remove overlay layer from the page
396 var overlayLayer = targetElement.querySelector('.introjs-overlay');
397
398 //return if intro already completed or skipped
399 if (overlayLayer == null) {
400 return;
401 }
402
403 //for fade-out animation
404 overlayLayer.style.opacity = 0;
405 setTimeout(function () {
406 if (overlayLayer.parentNode) {
407 overlayLayer.parentNode.removeChild(overlayLayer);
408 }
409 }, 500);
410
411 //remove all helper layers
412 var helperLayer = targetElement.querySelector('.introjs-helperLayer');
413 if (helperLayer) {
414 helperLayer.parentNode.removeChild(helperLayer);
415 }
416
417 //remove intro floating element
418 var floatingElement = document.querySelector('.introjsFloatingElement');
419 if (floatingElement) {
420 floatingElement.parentNode.removeChild(floatingElement);
421 }
422
423 //remove `introjs-showElement` class from the element
424 var showElement = document.querySelector('.introjs-showElement');
425 if (showElement) {
426 showElement.className = showElement.className.replace(/introjs-[a-zA-Z]+/g, '').replace(/^\s+|\s+$/g, ''); // This is a manual trim.
427 }
428
429 //remove `introjs-fixParent` class from the elements
430 var fixParents = document.querySelectorAll('.introjs-fixParent');
431 if (fixParents && fixParents.length > 0) {
432 for (var i = fixParents.length - 1; i >= 0; i--) {
433 fixParents[i].className = fixParents[i].className.replace(/introjs-fixParent/g, '').replace(/^\s+|\s+$/g, '');
434 };
435 }
436
437 //clean listeners
438 if (window.removeEventListener) {
439 window.removeEventListener('keydown', this._onKeyDown, true);
440 } else if (document.detachEvent) { //IE
441 document.detachEvent('onkeydown', this._onKeyDown);
442 }
443
444 //set the step to zero
445 this._currentStep = undefined;
446 }
447
448 /**
449 * Render tooltip box in the page
450 *
451 * @api private
452 * @method _placeTooltip
453 * @param {Object} targetElement
454 * @param {Object} tooltipLayer
455 * @param {Object} arrowLayer
456 */
457 function _placeTooltip(targetElement, tooltipLayer, arrowLayer, helperNumberLayer) {
458 var tooltipCssClass = '',
459 currentStepObj,
460 tooltipOffset,
461 targetElementOffset;
462
463 //reset the old style
464 tooltipLayer.style.top = null;
465 tooltipLayer.style.right = null;
466 tooltipLayer.style.bottom = null;
467 tooltipLayer.style.left = null;
468 tooltipLayer.style.marginLeft = null;
469 tooltipLayer.style.marginTop = null;
470
471 arrowLayer.style.display = 'inherit';
472
473 if (typeof(helperNumberLayer) != 'undefined' && helperNumberLayer != null) {
474 helperNumberLayer.style.top = null;
475 helperNumberLayer.style.left = null;
476 }
477
478 //prevent error when `this._currentStep` is undefined
479 if (!this._introItems[this._currentStep]) return;
480
481 //if we have a custom css class for each step
482 currentStepObj = this._introItems[this._currentStep];
483 if (typeof (currentStepObj.tooltipClass) === 'string') {
484 tooltipCssClass = currentStepObj.tooltipClass;
485 } else {
486 tooltipCssClass = this._options.tooltipClass;
487 }
488
489 tooltipLayer.className = ('introjs-tooltip ' + tooltipCssClass).replace(/^\s+|\s+$/g, '');
490
491 //custom css class for tooltip boxes
492 var tooltipCssClass = this._options.tooltipClass;
493
494 currentTooltipPosition = this._introItems[this._currentStep].position;
495 switch (currentTooltipPosition) {
496 case 'top':
497 tooltipLayer.style.left = '15px';
498 tooltipLayer.style.top = '-' + (_getOffset(tooltipLayer).height + 10) + 'px';
499 arrowLayer.className = 'introjs-arrow bottom';
500 break;
501 case 'right':
502 tooltipLayer.style.left = (_getOffset(targetElement).width + 20) + 'px';
503 arrowLayer.className = 'introjs-arrow left';
504 break;
505 case 'left':
506 if (this._options.showStepNumbers == true) {
507 tooltipLayer.style.top = '15px';
508 }
509 tooltipLayer.style.right = (_getOffset(targetElement).width + 20) + 'px';
510 arrowLayer.className = 'introjs-arrow right';
511 break;
512 case 'floating':
513 arrowLayer.style.display = 'none';
514
515 //we have to adjust the top and left of layer manually for intro items without element
516 tooltipOffset = _getOffset(tooltipLayer);
517
518 tooltipLayer.style.left = '50%';
519 tooltipLayer.style.top = '50%';
520 tooltipLayer.style.marginLeft = '-' + (tooltipOffset.width / 2) + 'px';
521 tooltipLayer.style.marginTop = '-' + (tooltipOffset.height / 2) + 'px';
522
523 if (typeof(helperNumberLayer) != 'undefined' && helperNumberLayer != null) {
524 helperNumberLayer.style.left = '-' + ((tooltipOffset.width / 2) + 18) + 'px';
525 helperNumberLayer.style.top = '-' + ((tooltipOffset.height / 2) + 18) + 'px';
526 }
527
528 break;
529 case 'bottom-right-aligned':
530 arrowLayer.className = 'introjs-arrow top-right';
531 tooltipLayer.style.right = '0px';
532 tooltipLayer.style.bottom = '-' + (_getOffset(tooltipLayer).height + 10) + 'px';
533 break;
534 case 'bottom-middle-aligned':
535 targetElementOffset = _getOffset(targetElement);
536 tooltipOffset = _getOffset(tooltipLayer);
537
538 arrowLayer.className = 'introjs-arrow top-middle';
539 tooltipLayer.style.left = (targetElementOffset.width / 2 - tooltipOffset.width / 2) + 'px';
540 tooltipLayer.style.bottom = '-' + (tooltipOffset.height + 10) + 'px';
541 break;
542 case 'bottom-left-aligned':
543 // Bottom-left-aligned is the same as the default bottom
544 case 'bottom':
545 // Bottom going to follow the default behavior
546 default:
547 tooltipLayer.style.bottom = '-' + (_getOffset(tooltipLayer).height + 10) + 'px';
548 arrowLayer.className = 'introjs-arrow top';
549 break;
550 }
551 }
552
553 /**
554 * Update the position of the helper layer on the screen
555 *
556 * @api private
557 * @method _setHelperLayerPosition
558 * @param {Object} helperLayer
559 */
560 function _setHelperLayerPosition(helperLayer) {
561 if (helperLayer) {
562 //prevent error when `this._currentStep` in undefined
563 if (!this._introItems[this._currentStep]) return;
564
565 var currentElement = this._introItems[this._currentStep],
566 elementPosition = _getOffset(currentElement.element),
567 widthHeightPadding = 10;
568
569 if (currentElement.position == 'floating') {
570 widthHeightPadding = 0;
571 }
572
573 //set new position to helper layer
574 helperLayer.setAttribute('style', 'width: ' + (elementPosition.width + widthHeightPadding) + 'px; ' +
575 'height:' + (elementPosition.height + widthHeightPadding) + 'px; ' +
576 'top:' + (elementPosition.top - 5) + 'px;' +
577 'left: ' + (elementPosition.left - 5) + 'px;');
578 }
579 }
580
581 /**
582 * Show an element on the page
583 *
584 * @api private
585 * @method _showElement
586 * @param {Object} targetElement
587 */
588 function _showElement(targetElement) {
589
590 if (typeof (this._introChangeCallback) !== 'undefined') {
591 this._introChangeCallback.call(this, targetElement.element);
592 }
593
594 var self = this,
595 oldHelperLayer = document.querySelector('.introjs-helperLayer'),
596 elementPosition = _getOffset(targetElement.element);
597
598 if (oldHelperLayer != null) {
599 var oldHelperNumberLayer = oldHelperLayer.querySelector('.introjs-helperNumberLayer'),
600 oldtooltipLayer = oldHelperLayer.querySelector('.introjs-tooltiptext'),
601 oldArrowLayer = oldHelperLayer.querySelector('.introjs-arrow'),
602 oldtooltipContainer = oldHelperLayer.querySelector('.introjs-tooltip'),
603 skipTooltipButton = oldHelperLayer.querySelector('.introjs-skipbutton'),
604 prevTooltipButton = oldHelperLayer.querySelector('.introjs-prevbutton'),
605 nextTooltipButton = oldHelperLayer.querySelector('.introjs-nextbutton');
606
607 //hide the tooltip
608 oldtooltipContainer.style.opacity = 0;
609
610 if (oldHelperNumberLayer != null) {
611 var lastIntroItem = this._introItems[(targetElement.step - 2 >= 0 ? targetElement.step - 2 : 0)];
612
613 if (lastIntroItem != null && (this._direction == 'forward' && lastIntroItem.position == 'floating') || (this._direction == 'backward' && targetElement.position == 'floating')) {
614 oldHelperNumberLayer.style.opacity = 0;
615 }
616 }
617
618 //set new position to helper layer
619 _setHelperLayerPosition.call(self, oldHelperLayer);
620
621 //remove `introjs-fixParent` class from the elements
622 var fixParents = document.querySelectorAll('.introjs-fixParent');
623 if (fixParents && fixParents.length > 0) {
624 for (var i = fixParents.length - 1; i >= 0; i--) {
625 fixParents[i].className = fixParents[i].className.replace(/introjs-fixParent/g, '').replace(/^\s+|\s+$/g, '');
626 };
627 }
628
629 //remove old classes
630 var oldShowElement = document.querySelector('.introjs-showElement');
631 oldShowElement.className = oldShowElement.className.replace(/introjs-[a-zA-Z]+/g, '').replace(/^\s+|\s+$/g, '');
632 //we should wait until the CSS3 transition is competed (it's 0.3 sec) to prevent incorrect `height` and `width` calculation
633 if (self._lastShowElementTimer) {
634 clearTimeout(self._lastShowElementTimer);
635 }
636 self._lastShowElementTimer = setTimeout(function() {
637 //set current step to the label
638 if (oldHelperNumberLayer != null) {
639 oldHelperNumberLayer.innerHTML = targetElement.step;
640 }
641 //set current tooltip text
642 oldtooltipLayer.innerHTML = targetElement.intro;
643 //set the tooltip position
644 _placeTooltip.call(self, targetElement.element, oldtooltipContainer, oldArrowLayer, oldHelperNumberLayer);
645
646 //change active bullet
647 oldHelperLayer.querySelector('.introjs-bullets li > a.active').className = '';
648 oldHelperLayer.querySelector('.introjs-bullets li > a[data-stepnumber="' + targetElement.step + '"]').className = 'active';
649
650 //show the tooltip
651 oldtooltipContainer.style.opacity = 1;
652 if (oldHelperNumberLayer) oldHelperNumberLayer.style.opacity = 1;
653 }, 350);
654
655 } else {
656 var helperLayer = document.createElement('div'),
657 arrowLayer = document.createElement('div'),
658 tooltipLayer = document.createElement('div'),
659 tooltipTextLayer = document.createElement('div'),
660 bulletsLayer = document.createElement('div'),
661 buttonsLayer = document.createElement('div');
662
663 helperLayer.className = 'introjs-helperLayer';
664
665 //set new position to helper layer
666 _setHelperLayerPosition.call(self, helperLayer);
667
668 //add helper layer to target element
669 this._targetElement.appendChild(helperLayer);
670
671 arrowLayer.className = 'introjs-arrow';
672
673 tooltipTextLayer.className = 'introjs-tooltiptext';
674 tooltipTextLayer.innerHTML = targetElement.intro;
675
676 bulletsLayer.className = 'introjs-bullets';
677
678 if (this._options.showBullets === false) {
679 bulletsLayer.style.display = 'none';
680 }
681
682 var ulContainer = document.createElement('ul');
683
684 for (var i = 0, stepsLength = this._introItems.length; i < stepsLength; i++) {
685 var innerLi = document.createElement('li');
686 var anchorLink = document.createElement('a');
687
688 anchorLink.onclick = function() {
689 self.goToStep(this.getAttribute('data-stepnumber'));
690 };
691
692 if (i === 0) anchorLink.className = "active";
693
694 anchorLink.href = 'javascript:void(0);';
695 anchorLink.innerHTML = " ";
696 anchorLink.setAttribute('data-stepnumber', this._introItems[i].step);
697
698 innerLi.appendChild(anchorLink);
699 ulContainer.appendChild(innerLi);
700 }
701
702 bulletsLayer.appendChild(ulContainer);
703
704 buttonsLayer.className = 'introjs-tooltipbuttons';
705 if (this._options.showButtons === false) {
706 buttonsLayer.style.display = 'none';
707 }
708
709 tooltipLayer.className = 'introjs-tooltip';
710 tooltipLayer.appendChild(tooltipTextLayer);
711 tooltipLayer.appendChild(bulletsLayer);
712
713 //add helper layer number
714 if (this._options.showStepNumbers == true) {
715 var helperNumberLayer = document.createElement('span');
716 helperNumberLayer.className = 'introjs-helperNumberLayer';
717 helperNumberLayer.innerHTML = targetElement.step;
718 helperLayer.appendChild(helperNumberLayer);
719 }
720 tooltipLayer.appendChild(arrowLayer);
721 helperLayer.appendChild(tooltipLayer);
722
723 //next button
724 var nextTooltipButton = document.createElement('a');
725
726 nextTooltipButton.onclick = function() {
727 if (self._introItems.length - 1 != self._currentStep) {
728 _nextStep.call(self);
729 }
730 };
731
732 nextTooltipButton.href = 'javascript:void(0);';
733 nextTooltipButton.innerHTML = this._options.nextLabel;
734
735 //previous button
736 var prevTooltipButton = document.createElement('a');
737
738 prevTooltipButton.onclick = function() {
739 if (self._currentStep != 0) {
740 _previousStep.call(self);
741 }
742 };
743
744 prevTooltipButton.href = 'javascript:void(0);';
745 prevTooltipButton.innerHTML = this._options.prevLabel;
746
747 //skip button
748 var skipTooltipButton = document.createElement('a');
749 skipTooltipButton.className = 'introjs-button introjs-skipbutton';
750 skipTooltipButton.href = 'javascript:void(0);';
751 skipTooltipButton.innerHTML = this._options.skipLabel;
752
753 skipTooltipButton.onclick = function() {
754 if (self._introItems.length - 1 == self._currentStep && typeof (self._introCompleteCallback) === 'function') {
755 self._introCompleteCallback.call(self);
756 }
757
758 if (self._introItems.length - 1 != self._currentStep && typeof (self._introExitCallback) === 'function') {
759 self._introExitCallback.call(self);
760 }
761
762 _exitIntro.call(self, self._targetElement);
763 };
764
765 buttonsLayer.appendChild(skipTooltipButton);
766
767 //in order to prevent displaying next/previous button always
768 if (this._introItems.length > 1) {
769 buttonsLayer.appendChild(prevTooltipButton);
770 buttonsLayer.appendChild(nextTooltipButton);
771 }
772
773 tooltipLayer.appendChild(buttonsLayer);
774
775 //set proper position
776 _placeTooltip.call(self, targetElement.element, tooltipLayer, arrowLayer, helperNumberLayer);
777 }
778
779 if (this._currentStep == 0 && this._introItems.length > 1) {
780 prevTooltipButton.className = 'introjs-button introjs-prevbutton introjs-disabled';
781 nextTooltipButton.className = 'introjs-button introjs-nextbutton';
782 skipTooltipButton.innerHTML = this._options.skipLabel;
783 } else if (this._introItems.length - 1 == this._currentStep || this._introItems.length == 1) {
784 skipTooltipButton.innerHTML = this._options.doneLabel;
785 prevTooltipButton.className = 'introjs-button introjs-prevbutton';
786 nextTooltipButton.className = 'introjs-button introjs-nextbutton introjs-disabled';
787 } else {
788 prevTooltipButton.className = 'introjs-button introjs-prevbutton';
789 nextTooltipButton.className = 'introjs-button introjs-nextbutton';
790 skipTooltipButton.innerHTML = this._options.skipLabel;
791 }
792
793 //Set focus on "next" button, so that hitting Enter always moves you onto the next step
794 nextTooltipButton.focus();
795
796 //add target element position style
797 targetElement.element.className += ' introjs-showElement';
798
799 var currentElementPosition = _getPropValue(targetElement.element, 'position');
800 if (currentElementPosition !== 'absolute' &&
801 currentElementPosition !== 'relative') {
802 //change to new intro item
803 targetElement.element.className += ' introjs-relativePosition';
804 }
805
806 var parentElm = targetElement.element.parentNode;
807 while (parentElm != null) {
808 if (parentElm.tagName.toLowerCase() === 'body') break;
809
810 //fix The Stacking Contenxt problem.
811 //More detail: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context
812 var zIndex = _getPropValue(parentElm, 'z-index');
813 var opacity = parseFloat(_getPropValue(parentElm, 'opacity'));
814 if (/[0-9]+/.test(zIndex) || opacity < 1) {
815 parentElm.className += ' introjs-fixParent';
816 }
817
818 parentElm = parentElm.parentNode;
819 }
820
821 if (!_elementInViewport(targetElement.element) && this._options.scrollToElement === true) {
822 var rect = targetElement.element.getBoundingClientRect(),
823 winHeight=_getWinSize().height,
824 top = rect.bottom - (rect.bottom - rect.top),
825 bottom = rect.bottom - winHeight;
826
827 //Scroll up
828 if (top < 0 || targetElement.element.clientHeight > winHeight) {
829 window.scrollBy(0, top - 30); // 30px padding from edge to look nice
830
831 //Scroll down
832 } else {
833 window.scrollBy(0, bottom + 100); // 70px + 30px padding from edge to look nice
834 }
835 }
836
837 if (typeof (this._introAfterChangeCallback) !== 'undefined') {
838 this._introAfterChangeCallback.call(this, targetElement.element);
839 }
840 }
841
842 /**
843 * Get an element CSS property on the page
844 * Thanks to JavaScript Kit: http://www.javascriptkit.com/dhtmltutors/dhtmlcascade4.shtml
845 *
846 * @api private
847 * @method _getPropValue
848 * @param {Object} element
849 * @param {String} propName
850 * @returns Element's property value
851 */
852 function _getPropValue (element, propName) {
853 var propValue = '';
854 if (element.currentStyle) { //IE
855 propValue = element.currentStyle[propName];
856 } else if (document.defaultView && document.defaultView.getComputedStyle) { //Others
857 propValue = document.defaultView.getComputedStyle(element, null).getPropertyValue(propName);
858 }
859
860 //Prevent exception in IE
861 if (propValue && propValue.toLowerCase) {
862 return propValue.toLowerCase();
863 } else {
864 return propValue;
865 }
866 }
867
868 /**
869 * Provides a cross-browser way to get the screen dimensions
870 * via: http://stackoverflow.com/questions/5864467/internet-explorer-innerheight
871 *
872 * @api private
873 * @method _getWinSize
874 * @returns {Object} width and height attributes
875 */
876 function _getWinSize() {
877 if (window.innerWidth != undefined) {
878 return { width: window.innerWidth, height: window.innerHeight };
879 } else {
880 var D = document.documentElement;
881 return { width: D.clientWidth, height: D.clientHeight };
882 }
883 }
884
885 /**
886 * Add overlay layer to the page
887 * http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
888 *
889 * @api private
890 * @method _elementInViewport
891 * @param {Object} el
892 */
893 function _elementInViewport(el) {
894 var rect = el.getBoundingClientRect();
895
896 return (
897 rect.top >= 0 &&
898 rect.left >= 0 &&
899 (rect.bottom+80) <= window.innerHeight && // add 80 to get the text right
900 rect.right <= window.innerWidth
901 );
902 }
903
904 /**
905 * Add overlay layer to the page
906 *
907 * @api private
908 * @method _addOverlayLayer
909 * @param {Object} targetElm
910 */
911 function _addOverlayLayer(targetElm) {
912 var overlayLayer = document.createElement('div'),
913 styleText = '',
914 self = this;
915
916 //set css class name
917 overlayLayer.className = 'introjs-overlay';
918
919 //check if the target element is body, we should calculate the size of overlay layer in a better way
920 if (targetElm.tagName.toLowerCase() === 'body') {
921 styleText += 'top: 0;bottom: 0; left: 0;right: 0;position: fixed;';
922 overlayLayer.setAttribute('style', styleText);
923 } else {
924 //set overlay layer position
925 var elementPosition = _getOffset(targetElm);
926 if (elementPosition) {
927 styleText += 'width: ' + elementPosition.width + 'px; height:' + elementPosition.height + 'px; top:' + elementPosition.top + 'px;left: ' + elementPosition.left + 'px;';
928 overlayLayer.setAttribute('style', styleText);
929 }
930 }
931
932 targetElm.appendChild(overlayLayer);
933
934 overlayLayer.onclick = function() {
935 if (self._options.exitOnOverlayClick == true) {
936 _exitIntro.call(self, targetElm);
937
938 //check if any callback is defined
939 if (self._introExitCallback != undefined) {
940 self._introExitCallback.call(self);
941 }
942 }
943 };
944
945 setTimeout(function() {
946 styleText += 'opacity: ' + self._options.overlayOpacity.toString() + ';';
947 overlayLayer.setAttribute('style', styleText);
948 }, 10);
949
950 return true;
951 }
952
953 /**
954 * Get an element position on the page
955 * Thanks to `meouw`: http://stackoverflow.com/a/442474/375966
956 *
957 * @api private
958 * @method _getOffset
959 * @param {Object} element
960 * @returns Element's position info
961 */
962 function _getOffset(element) {
963 var elementPosition = {};
964
965 //set width
966 elementPosition.width = element.offsetWidth;
967
968 //set height
969 elementPosition.height = element.offsetHeight;
970
971 //calculate element top and left
972 var _x = 0;
973 var _y = 0;
974 while (element && !isNaN(element.offsetLeft) && !isNaN(element.offsetTop)) {
975 _x += element.offsetLeft;
976 _y += element.offsetTop;
977 element = element.offsetParent;
978 }
979 //set top
980 elementPosition.top = _y;
981 //set left
982 elementPosition.left = _x;
983
984 return elementPosition;
985 }
986
987 /**
988 * Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
989 * via: http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically
990 *
991 * @param obj1
992 * @param obj2
993 * @returns obj3 a new object based on obj1 and obj2
994 */
995 function _mergeOptions(obj1,obj2) {
996 var obj3 = {};
997 for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
998 for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
999 return obj3;
1000 }
1001
1002 var introJs = function (targetElm) {
1003 if (typeof (targetElm) === 'object') {
1004 //Ok, create a new instance
1005 return new IntroJs(targetElm);
1006
1007 } else if (typeof (targetElm) === 'string') {
1008 //select the target element with query selector
1009 var targetElement = document.querySelector(targetElm);
1010
1011 if (targetElement) {
1012 return new IntroJs(targetElement);
1013 } else {
1014 throw new Error('There is no element with given selector.');
1015 }
1016 } else {
1017 return new IntroJs(document.body);
1018 }
1019 };
1020
1021 /**
1022 * Current IntroJs version
1023 *
1024 * @property version
1025 * @type String
1026 */
1027 introJs.version = VERSION;
1028
1029 //Prototype
1030 introJs.fn = IntroJs.prototype = {
1031 clone: function () {
1032 return new IntroJs(this);
1033 },
1034 setOption: function(option, value) {
1035 this._options[option] = value;
1036 return this;
1037 },
1038 setOptions: function(options) {
1039 this._options = _mergeOptions(this._options, options);
1040 return this;
1041 },
1042 start: function () {
1043 _introForElement.call(this, this._targetElement);
1044 return this;
1045 },
1046 goToStep: function(step) {
1047 _goToStep.call(this, step);
1048 return this;
1049 },
1050 nextStep: function() {
1051 _nextStep.call(this);
1052 return this;
1053 },
1054 previousStep: function() {
1055 _previousStep.call(this);
1056 return this;
1057 },
1058 exit: function() {
1059 _exitIntro.call(this, this._targetElement);
1060 },
1061 refresh: function() {
1062 _setHelperLayerPosition.call(this, document.querySelector('.introjs-helperLayer'));
1063 return this;
1064 },
1065 onbeforechange: function(providedCallback) {
1066 if (typeof (providedCallback) === 'function') {
1067 this._introBeforeChangeCallback = providedCallback;
1068 } else {
1069 throw new Error('Provided callback for onbeforechange was not a function');
1070 }
1071 return this;
1072 },
1073 onchange: function(providedCallback) {
1074 if (typeof (providedCallback) === 'function') {
1075 this._introChangeCallback = providedCallback;
1076 } else {
1077 throw new Error('Provided callback for onchange was not a function.');
1078 }
1079 return this;
1080 },
1081 onafterchange: function(providedCallback) {
1082 if (typeof (providedCallback) === 'function') {
1083 this._introAfterChangeCallback = providedCallback;
1084 } else {
1085 throw new Error('Provided callback for onafterchange was not a function');
1086 }
1087 return this;
1088 },
1089 oncomplete: function(providedCallback) {
1090 if (typeof (providedCallback) === 'function') {
1091 this._introCompleteCallback = providedCallback;
1092 } else {
1093 throw new Error('Provided callback for oncomplete was not a function.');
1094 }
1095 return this;
1096 },
1097 onexit: function(providedCallback) {
1098 if (typeof (providedCallback) === 'function') {
1099 this._introExitCallback = providedCallback;
1100 } else {
1101 throw new Error('Provided callback for onexit was not a function.');
1102 }
1103 return this;
1104 }
1105 };
1106
1107 exports.introJs = introJs;
1108 return introJs;
1109}));
1110</script><script>
1111/*смена позиционирования у класса slide-wrap1 для плавной прокрутки верхнего слайдера-меню*/
1112
1113var SLIDER_ANIMATION_DELAY = 400;
1114
1115$(document).ready(function(){
1116 if (window.navigator.appName == "Microsoft Internet Explorer")
1117 {
1118 // This is an IE browser. What mode is the engine in?
1119 if (document.documentMode == 7) //
1120 {
1121 $("img.icon_of_task").css("margin-top", "0");
1122 $(".task_spis_list").css("width", "266px");
1123 $("p.day").css("margin-top", "0");
1124 }
1125 }
1126
1127 var slideWrap = $(".slide-wrap1");
1128
1129 $(".slide-item1").mouseover(function() {
1130 if (!slideWrap.is(":animated"))
1131 {
1132 $(this).addClass("slide-item1-hover");
1133 css_heigth = $("body").height() - $(".header_top").eq(0).height() + parseInt($(".top_slider").eq(0).css("padding-top").split("px")[0] )+200;
1134 $(".slide-list1").css("height", css_heigth);
1135 if ($(this).index() == 3)
1136 {
1137 $(this).find(".dropmenu .dropdown_list").css("left", -238);
1138 }
1139 else
1140 {
1141 $(this).find(".dropmenu .dropdown_list").css("left", 226);
1142 }
1143 // вертикальное центрирование текста:
1144 $(this).find(".item_name_many").each(function() {
1145 $(this).css("padding-top", ($(this).parent().outerHeight() - $(this).height()) / 2 - 3);
1146 });
1147 }
1148 });
1149 $(".slide-item1").mouseout(function() {
1150 if (!slideWrap.is(":animated"))
1151 {
1152 $(this).removeClass("slide-item1-hover");
1153 $(".slide-list1").css("height", "");
1154 }
1155 });
1156
1157 // выравнивание текста главного меню:
1158 $(".slide-item1-text").each(function() {
1159 $(this).css({
1160 top: ($(this).parent().outerHeight() - $(this).outerHeight()) / 2 - 3
1161 });
1162 });
1163});
1164
1165
1166/*нижний слайдер с брендами*/
1167
1168function htmSlider(){
1169 /* Зададим следующие параметры */
1170 /* обертка слайдера */
1171 var slideWrap = jQuery('.slide-wrap');
1172 /* кнопки вперед/назад */
1173 var nextLink = jQuery('.next-slide');
1174 var prevLink = jQuery('.prev-slide');
1175 /* ширина слайда с отступами */
1176 var slideWidth = jQuery('.slide-item').outerWidth(true);
1177 /* смещение слайдера */
1178 var scrollSlider = -slideWidth;
1179
1180 w = slideWrap.children().length *(slideWidth);
1181 if (w < slideWrap.parent().innerWidth())
1182 {
1183 nextLink.hide(); prevLink.hide();
1184 }
1185 else
1186 {
1187 nextLink.show(); prevLink.show();
1188 }
1189 /* Клик по ссылке на следующий слайд */
1190 nextLink.click(function(){
1191 if(!slideWrap.is(':animated')) {
1192 slideWrap.find('.slide-item:first').clone().appendTo(slideWrap);
1193 slideWrap.animate({left: scrollSlider}, SLIDER_ANIMATION_DELAY, function(){
1194 slideWrap.find('.slide-item:first').remove();
1195 slideWrap.css({'left': 0});
1196 });
1197 }
1198 });
1199
1200 /* Клик по ссылке на предыдующий слайд */
1201 prevLink.click(function(){
1202 if(!slideWrap.is(':animated')) {
1203 slideWrap.css({'left': scrollSlider}).find('.slide-item:last').clone().prependTo(slideWrap);
1204 slideWrap.animate({left: 0}, SLIDER_ANIMATION_DELAY, function(){
1205 slideWrap.find('.slide-item:last').remove();
1206 });
1207 }
1208 });
1209}
1210
1211jQuery(document).ready(function(){
1212 /* иницилизируем функцию слайдера */
1213 htmSlider();
1214});
1215
1216
1217/*верхний слайдер-меню*/
1218
1219function htmSlider_m(){
1220 /* Зададим следующие параметры */
1221 /* обертка слайдера */
1222 var slideWrap = jQuery('.slide-wrap1');
1223 /* кнопки вперед/назад */
1224 var nextLink = jQuery('.next-slide1');
1225 var prevLink = jQuery('.prev-slide1');
1226 /* ширина слайда с отступами */
1227 var slideWidth = jQuery('.slide-item1').outerWidth(true);
1228 /* смещение слайдера */
1229 var scrollSlider = -slideWidth;
1230
1231 //
1232 w = slideWrap.children().length *(slideWidth);
1233 if (w <= slideWrap.parent().innerWidth())
1234 {
1235 nextLink.hide(); prevLink.hide();
1236 }
1237 else
1238 {
1239 nextLink.show(); prevLink.show();
1240 }
1241 /* Клик по ссылке на следующий слайд */
1242 nextLink.click(function(){
1243 if(!slideWrap.is(':animated')) {
1244 slideWrap.animate({left: scrollSlider}, SLIDER_ANIMATION_DELAY, function(){
1245 slideWrap
1246 .find('.slide-item1:first')
1247 .appendTo(slideWrap)
1248 .parent()
1249 .css({'left': 0});
1250 slideWrap.find("div[num]").each(function(){
1251 if ($(this).attr("rel") != undefined)
1252 {
1253 //$(this).attr("onclick", "window.location ='" + $(this).attr("rel") + "&slider=" + slideWrap.children().eq(0).attr("num") + "'; if (event.stopPropagation){ event.stopPropagation();event.cancelBubble = true;}else{ event.cancelBubble = true;};");
1254 $(this).attr("slide", slideWrap.children().eq(0).attr("num"));
1255 }
1256 })
1257 $(".crumbs").eq(0).children().each(function(){
1258 if ($(this).attr("rel") != undefined)
1259 {
1260 //$(this).attr("onclick", "window.location ='" + $(this).attr("rel") + "&slider=" + slideWrap.children().eq(0).attr("num") + "'");
1261 $(this).attr("slide", slideWrap.children().eq(0).attr("num"));
1262 }
1263 });
1264 });
1265
1266 }
1267 });
1268
1269 /* Клик по ссылке на предыдующий слайд */
1270 prevLink.click(function(){
1271 if(!slideWrap.is(':animated')) {
1272 slideWrap
1273 .css({'left': scrollSlider})
1274 .find('.slide-item1:last')
1275 .prependTo(slideWrap)
1276 .parent()
1277 .animate({left: 0}, SLIDER_ANIMATION_DELAY, function(){
1278 slideWrap.find("div[num]").each(function(){
1279 //$(this).attr("onclick", "window.location ='" + $(this).attr("rel") + "&slider=" + slideWrap.children().eq(0).attr("num") + "'; if (event.stopPropagation){ event.stopPropagation();event.cancelBubble = true;} else{ event.cancelBubble = true;};");
1280 $(this).attr("slide", slideWrap.children().eq(0).attr("num"));
1281 })
1282 $(".crumbs").eq(0).children().each(function(){
1283 if ($(this).attr("rel") != undefined)
1284 {
1285 //$(this).attr("onclick", "window.location ='" + $(this).attr("rel") + "&slider=" + slideWrap.children().eq(0).attr("num") + "'");
1286 $(this).attr("slide", slideWrap.children().eq(0).attr("num"));
1287 }
1288 });
1289 });
1290
1291 }
1292 });
1293}
1294
1295jQuery(document).ready(function(){
1296 /* иницилизируем функцию слайдера */
1297 htmSlider_m();
1298});
1299
1300// Кастомизация элементов ввода:
1301
1302var synergyGetSelectElementText = function(selectElement) {
1303 try {
1304 return selectElement.options[selectElement.selectedIndex].text;
1305 } catch(_err) {
1306 console.log("synergyGetSelectElementText ERROR : " + _err);
1307 return "";
1308 }
1309};
1310
1311function HtmlEscapeString(str)
1312 {
1313 str = str.replace(/&/g, "&");
1314 str = str.replace(/"/g, """);
1315 str = str.replace(/'/g, "'");
1316 str = str.replace(/</g, "<");
1317 str = str.replace(/>/g, ">");
1318 return str;
1319 }
1320
1321function synergyCustomizeElements() {
1322 // Выпадающие списки:
1323 $("select.synergy_select_element").each(function() {
1324 $(this).removeClass("synergy_select_element");
1325 $(this).hide();
1326 if ($(this).hasClass("select-disabled")){
1327 $(this).wrap("<div class=\"synergy_select_box select-disabled\"></div>");
1328 }
1329 else{
1330 $(this).wrap("<div class=\"synergy_select_box\"></div>");
1331 }
1332 $(this).after("<p class=\"synergy_select_box_text\">" + synergyGetSelectElementText(this) + "</p><div class=\"synergy_select_box_button\"></div>");
1333 var selectBoxDropdown = "<div class=\"synergy_select_box_dropdown\">";
1334 for (var i = 0; i < this.options.length; i++)
1335 {
1336 selectBoxDropdown += "<a index=\"" + i + "\" title=\"" + HtmlEscapeString(this.options[i].text) + "\">" + this.options[i].text + "</a>";
1337 }
1338 selectBoxDropdown += "</div>";
1339 $(this).parent().append(selectBoxDropdown);
1340 });
1341}
1342
1343$(document).ready(function(){
1344 synergyCustomizeElements();
1345
1346 $("body").click(function(event) {
1347 var target = event.target;
1348 if($(target).closest(".synergy_select_box.select-disabled").length){return};
1349
1350 var dropdownVisible = $("div.synergy_select_box_dropdown:visible").get(0);
1351 if (dropdownVisible)
1352 {
1353 $(dropdownVisible).hide();
1354 }
1355 var targetSelectBox = $(target).hasClass("synergy_select_box") ? target : $(target).parents("div.synergy_select_box").get(0);
1356 if (targetSelectBox)
1357 {
1358 if ($(target).parent().hasClass("synergy_select_box_dropdown"))
1359 {
1360 var selectElement = $(targetSelectBox).children("select").get(0);
1361 selectElement.selectedIndex = parseInt($(target).attr("index"));
1362 $(selectElement).trigger("change");
1363 $(targetSelectBox).children("p").get(0).innerHTML = synergyGetSelectElementText(selectElement);
1364 }
1365 if (!dropdownVisible || dropdownVisible && $(dropdownVisible).parent().get(0) != targetSelectBox)
1366 {
1367 $(targetSelectBox).children("div.synergy_select_box_dropdown").show();
1368 }
1369 }
1370 });
1371});
1372</script>
1373<div class="main-wrapper">
1374
1375
1376
1377<script>
1378 $('head').append('<meta name="viewport" content="width=device-width">');
1379</script>
1380 <div id="b-shade" class="b-view-preloader" style="display: block;">
1381 <div class="b-ball-1"></div>
1382 <div class="b-ball-2"></div>
1383 </div>
1384 <!--HEADER-->
1385
1386<script>
1387 function getInitials (string) {
1388 var names = (string != "" && string != " ") ? string.split(' ') : [];
1389 var initials = "";
1390
1391 if (names.length > 1) {
1392 initials = names[1].substring(0, 1).toUpperCase();
1393 initials += (names[1] != "") ? "." : "";
1394 initials += names[0].substring(0, 1).toUpperCase();
1395 initials += (names[0] != "") ? "." : "";
1396 } else {
1397 if (names.length != 0) {
1398 initials = string.substring(0, 1).toUpperCase();
1399 initials += ".";
1400 }
1401 }
1402 return initials;
1403 }
1404
1405 function closeMenu() {
1406 $("#work_cabinet_icon").removeClass("active");
1407 $("#wk_list").removeClass("active");
1408
1409 $("#mob_work_cabinet").toggleClass("active");
1410 $("#mob_work_cabinet_content").toggleClass("active");
1411 }
1412
1413 $(document).ready(function () {
1414 var options = {"userID":"6017678077230275438","is_admin":false,"dropdown_menu_items":[{"name":"Мои оцениваемые сотрудники","link_href":"view_doc.html?mode=my_employees_evaluation&doc_id=6631859965698670224"},{"name":"Панель руководителя","link_href":"view_doc.html?mode=boss_panel&doc_id=6335652978792405855"},{"name":"Адаптация сотрудника","link_href":"view_doc.html?mode=adaptation&doc_id=6335653159623287534"},{"name":"Отчет по адаптации","link_href":"view_doc.html?mode=doc_type&object_id=6039881813288121911&doc_id=6335653748949613493"}],"user_roles":["func_manager_menu"],"menuItems":[{"name":"Каталог курсов","link_href":"view_doc.html?mode=edu_catalog&doc_id=6628161676399233617"},{"name":"Документы","link_href":"view_doc.html?mode=lib&doc_id=6628162092753246374"},{"name":"Обучение","link_href":"view_doc.html?mode=doc&doc_id=5800376573543914533"},{"name":"МИРР","link_href":"view_doc.html?mode=self_assessment&doc_id=6631857937049990730"},{"name":"Библиотека","link_href":"view_doc.html?mode=doc&doc_id=6522717384966615904"},{"name":"Заявки","link_href":"view_doc.html?mode=doc&doc_id=6148914691236517176"},{"name":"Вакансии компании","link_href":"view_doc.html?mode=company_vacancys&doc_id=6711191531803911194"}],"avatar":"/download_file.html?file_id=6631996913705945604","fullname":"Лебедев Дмитрий Олегович","scores":0,"scoresText":"баллов","mode":"learning_stat","eventsCount":0,"learnCount":3,"auth_type":"outside","breadcrumbs":[]},
1415 mainMenuContainer,
1416 mainMobMenuContainer,
1417 workCabinetContainer,
1418 mobWorkCabinetContainer,
1419 roleNamesContainer,
1420 mobRoleNamesContainer;
1421
1422 //отключаем прелоадер
1423 setTimeout(function () {
1424 $("#b-shade").hide();
1425 }, 2000);
1426
1427 //мероприятия
1428 $('#header_events, #header_mob_events').text(options.eventsCount);
1429
1430 //аватар
1431 if (options.avatar.length > 0) {
1432 $('#userpic').append(
1433 $('<div/>')
1434 .addClass("b-header__userpic")
1435 .css("background-image", "url("+options.avatar+")")
1436 );
1437 } else {
1438 $('#userpic').append(
1439 $('<div/>')
1440 .addClass("b-user__avatar no-photo header active")
1441 .text(getInitials(options.fullname))
1442 );
1443 }
1444
1445 //меню
1446 mainMenuContainer = $('#header_menu_main');
1447 mainMobMenuContainer = $('#header_mob_menu_main');
1448 options.menuItems.forEach(function (item) {
1449 var a = $('<a href="' + item.link_href + '"></a>');
1450 a.text(item.name);
1451 mainMenuContainer.append(a);
1452
1453 var li = $('<li><a href="' + item.link_href + '"></a></li>');
1454 $("a", li).text(item.name);
1455 mainMobMenuContainer.append(li);
1456 });
1457
1458 //курсы тесты
1459 $('#header_learnings, #header_mob_learnings').text(options.learnCount);
1460
1461 //меню рабочего кабинета
1462 roleNamesContainer = $('#role_names');
1463 mobRoleNamesContainer = $('#mob_role_names');
1464 if (options.is_admin) {
1465 roleNamesContainer.append(
1466 $("<span/>")
1467 .addClass("b-text__grey")
1468 .text("Администратор")
1469 );
1470
1471 mobRoleNamesContainer.append(
1472 $("<li/>")
1473 .append(
1474 $("<a/>")
1475 .attr("href", "javascript:void(0);")
1476 .text("Администратор")
1477 )
1478 );
1479 } else {
1480 options.user_roles.forEach(function (item) {
1481 var span = $('<span class="b-text__grey"></span>'),
1482 li = $('<li><a href="javascript:void(0);"></a></li>'),
1483 a = $('a', li);
1484 if (item == "sub_manager_menu") {
1485 span.text("Руководитель подразделения");
1486 a.text("Руководитель подразделения");
1487 } else if (item == "hr_menu") {
1488 span.text("HR");
1489 a.text("HR");
1490 } else if (item == "trainer_menu") {
1491 span.text("Тренер");
1492 a.text("Тренер");
1493 } else if (item == "sv_menu") {
1494 span.text("Супервайзер");
1495 a.text("Супервайзер");
1496 } else if (item == "field_manager_menu") {
1497 span.text("Полевой руководитель");
1498 a.text("Полевой руководитель");
1499 } else if (item == "func_manager_menu") {
1500 span.text("Функциональный руководитель");
1501 a.text("Функциональный руководитель");
1502 } else if (item == "ks_menu") {
1503 span.text("КС");
1504 a.text("КС");
1505 } else if (item == "edu_manager_menu") {
1506 span.text("Ответственный по обучению");
1507 a.text("Ответственный по обучению");
1508 }
1509
1510 roleNamesContainer.append(span);
1511 mobRoleNamesContainer.append(li);
1512 });
1513 }
1514
1515 workCabinetContainer = $('#wk_list');
1516 mobWorkCabinetContainer = $('#mob_wk_list');
1517 if (options.dropdown_menu_items.length > 0) {
1518 options.dropdown_menu_items.forEach(function (item) {
1519 var li = $('<li class="b-header__user-account-item"><a href="' + item.link_href + '" class="b-header__user-account-links">' + item.name + '</a></li>');
1520 workCabinetContainer.append(li);
1521
1522 var mob_li = $('<li/>')
1523 .append(
1524 $('<a href="' + item.link_href + '"></a>')
1525 .text(item.name)
1526 );
1527 mobWorkCabinetContainer.append(mob_li);
1528 });
1529 } else {
1530 $("#work_cabinet")
1531 .removeClass("b-header__user-link-item")
1532 .text("Личный кабинет")
1533 .css("font-size", "12px")
1534 .css("line-height", "16px");
1535
1536 $("#mob_work_cabinet span").text("Личный кабинет");
1537 $("#mob_work_cabinet i").remove();
1538 }
1539 //Хлебные крошки
1540 if(options.breadcrumbs.length > 0){
1541 options.breadcrumbs.forEach(function(el){
1542 $(".b-breadcrumbs-ul").prepend(
1543 $('<li/>')
1544 .addClass('b-breadcrumbs-item')
1545 .append(
1546 (function(){
1547 var link = 'javascript:void(0);';
1548 if (el.template != '') {
1549 link = el.template;
1550 } else {
1551 link = 'view_doc.html?mode=doc&doc_id='+el.id;
1552 }
1553
1554 return '<a href="' + link + '" class="b-breadcrumbs-link">' + el.name + '</a>';
1555 })()
1556 )
1557 )
1558 });
1559 } else {
1560 $(".b-breadcrumbs").remove();
1561 }
1562
1563 // скрытие рабочего кабинета
1564 $(document).on("click", function(event) {
1565 var target_id = event.target.id;
1566
1567 if (target_id === "wk_list" || target_id === "work_cabinet_icon" || target_id === "work_cabinet") {
1568 return false;
1569 } work_cabinet
1570
1571 closeMenu();
1572 });
1573
1574 //кнопка "рабочий кабинет"
1575 $("#work_cabinet_icon, #mob_work_cabinet span").on('click', function () {
1576 if (options.dropdown_menu_items.length > 0) {
1577 if ( $("#work_cabinet_icon").hasClass("active")) {
1578 $("#work_cabinet_icon").removeClass("active");
1579 $("#wk_list").removeClass("active");
1580 } else {
1581 $("#work_cabinet_icon").addClass("active");
1582 $("#wk_list").addClass("active");
1583 }
1584
1585 $("#mob_work_cabinet").toggleClass("active");
1586 $("#mob_work_cabinet_content").toggleClass("active");
1587 } else {
1588 location.href = "/view_doc.html?mode=profile";
1589 }
1590 });
1591
1592 //кнопка выход
1593 $('#header_exit, #mob_exit').on('click', function (event) {
1594 if (options.auth_type === 'cookie') {
1595 var sDate = new Date(0).toUTCString();
1596 document.cookie = "user_login=null; path=/; expires=" + sDate + ";";
1597 document.cookie = "user_password=null; path=/; expires=" + sDate + ";";
1598 document.location.href = window.location.protocol + "//" + window.location.host + "/view_doc.html?mode=default&logout=1";
1599 } else if (options.auth_type === 'basic') {
1600 var xhr = new XMLHttpRequest();
1601 xhr.open('GET', document.location.origin + '/view_doc.html?mode=home', true);
1602 xhr.setRequestHeader('Authorization', '');
1603 xhr.send();
1604 document.location.href = document.location.origin + '/view_doc.html?mode=default';
1605 } else {
1606 try {
1607 if (document.all || !!navigator.userAgent.match(/Trident\/7\./)) {
1608 document.execCommand("ClearAuthenticationCache");
1609 window.history.back();
1610 window.location.href = window.location.protocol + "//" + window.location.host + "/view_doc.html?mode=default&logout=1";
1611 } else {
1612 window.history.back();
1613 window.location.href = window.location.protocol + "//logout:true@" + window.location.host + "/view_doc.html?mode=default&logout=1";
1614 }
1615 }
1616 catch(e)
1617 {}
1618 }
1619 });
1620
1621 //ссылка на my_account
1622 $('#header_course_test_link, #header_event_link').on('click', function () {
1623 window.open('/view_doc.html?mode=my_account');
1624 });
1625
1626 $('#mob_work_cabinet, #mob_work_cabinet span').on('click', function () {
1627 $('#mob_work_cabinet').toggleClass('active');
1628 $('.b-header__icon-open').toggleClass('active');
1629 $('.b-header__cabinet-content').toggleClass('active');
1630 });
1631
1632 //клик по бургеру
1633 $(".b-header__toggle-menu").on('click', function(){
1634 $('.b-header__mob-menu-container').toggleClass('active');
1635 $('.b-header__fixed').toggleClass('active');
1636 $('#show-xs').toggleClass('is-close')
1637 });
1638 });
1639</script>
1640<script>
1641 function preloaderOn(){
1642 $("#b-shade").show();
1643 }
1644 function preloaderOff(){
1645 $("#b-shade").hide();
1646 }
1647</script>
1648<header class="b-header">
1649 <div class="b-header__mob-menu-container">
1650 <div class="b-container">
1651 <div class="b-header__mob-menu-but-wrap">
1652 <a href="/view_doc.html?mode=my_account" class="b-header__mob-menu-but">
1653 <div class="b-header__mob-menu-but-container">
1654 <div class="float-left b-header__icon-course b-header__mob-icon-course"></div>
1655 <div class="float-left b-header__icon-test b-header__mob-icon-test"></div>
1656 <div id="header_mob_learnings" class="b-header__user-account-courses-num float-left b-header__mob-text"></div>
1657 </div>
1658 </a>
1659 <a href="/view_doc.html?mode=my_account" class="b-header__mob-menu-but">
1660 <div class="b-header__mob-menu-but-container two">
1661 <div class="float-left b-header__icon-union b-header__mob-icon-union"></div>
1662 <div id="header_mob_events" class="b-header__user-account-star-text float-left b-header__mob-text"></div>
1663 </div>
1664 </a>
1665 </div>
1666 <div id="mob_work_cabinet" class="b-header__cabinet"><span>Рабочий кабинет</span> <i class="b-icon__open little b-header__icon-open"></i></div>
1667 <div id="mob_work_cabinet_content" class="b-header__cabinet-content">
1668 <ul id="mob_role_names" class="b-header__cabinet-breadcrumbs">
1669 </ul>
1670 <div class="b-header__cabinet-nav">
1671 <ul id="mob_wk_list">
1672 </ul>
1673 </div>
1674 </div>
1675 <div class="b-header__mob-nav">
1676 <ul id="header_mob_menu_main">
1677 </ul>
1678 </div>
1679 <div class="b-header__mob-points clearfix">
1680 <div class="b-header__mob-points-num">
1681 <span id="header_mob_scores"></span>
1682 <span id="header_mob_scores_text"></span>
1683 </div>
1684 <div class="b-header__mob-exit"><a id="mob_exit" href="javascript:void(0);">Выход <span class="b-icon__exit-white"></span></a></div>
1685 </div>
1686 </div>
1687 </div>
1688 <div class="b-container b-header__fixed">
1689 <div class="b-header__wrap clearfix">
1690 <div class="b-header__mob-menu float-left">
1691 <div id="show-xs" class="b-header__toggle-menu hidden-lg show-xs">
1692 <span class="b-header__toggle-wrapper-elements">
1693 <span class="b-header__toggle-element-first"></span>
1694 <span class="b-header__toggle-element-second"></span>
1695 <span class="b-header__toggle-element-third"></span>
1696 </span>
1697 </div>
1698 </div>
1699 <div class="b-header__logo clearfix float-left">
1700 <a href="/view_doc.html?mode=home" class="float-left"><img src="download_file.html?file_id=6621495142608807619" alt="logo"></a>
1701 <div class="b-header__logo-text float-left"><span>Портал обучения и развития</span></div>
1702 </div>
1703 <div class="b-header__user-account-wrap clearfix float-right">
1704 <div class="b-header__user-exit float-right">
1705 <div class="t-icon-exit">
1706 <div class="t-icon-exit__wrap-arrow">
1707 <div class="t-icon-exit__arrow"></div>
1708 </div>
1709 <div class="t-icon-exit__wrap-footer">
1710 <div id="header_exit" class="t-icon-exit__footer"></div>
1711 </div>
1712 </div>
1713 </div>
1714 <div class="b-header__user-account clearfix float-right">
1715 <div class="b-header__user-account-icons clearfix float-left">
1716 <div id="header_course_test_link" class="b-header__user-account-courses clearfix float-left">
1717 <a href="javascript:void(0);" class="b-header__user-courses-link">
1718 <div class="b-icon-course float-left b-header__icon-course"></div>
1719 <div class="b-icon-test float-left b-header__icon-test"></div>
1720 <div id="header_learnings" class="b-header__user-account-courses-num float-left"></div>
1721 </a>
1722 </div>
1723 <div id="header_event_link" class="b-header__user-account-star clearfix float-left">
1724 <a href="javascript:void(0);" class="b-header__user-star-link">
1725 <div class="b-icon-union float-left b-header__icon-union"></div>
1726 <div id="header_events" class="b-header__user-account-star-text float-left"></div>
1727 </a>
1728 </div>
1729 </div>
1730 <div id="work_cabinet_icon" class="b-header__user-account-link float-left" style="cursor: pointer">
1731 <a id="work_cabinet" href="javascript:void(0);" class="b-header__user-link-item">Рабочий кабинет</a>
1732 <ul id="wk_list" class="b-header__user-account-wrapper">
1733 <li id="role_names" class="b-header__user-account-item first"></li>
1734 </ul>
1735 </div>
1736
1737 <div class="b-header__user-account-image-wrap float-left">
1738 <a id="userpic" href="/view_doc.html?mode=profile"></a>
1739 </div>
1740 </div>
1741 </div>
1742 </div>
1743 <div class="b-header__nav">
1744 <nav id="header_menu_main">
1745 </nav>
1746 </div>
1747 </div>
1748</header>
1749<!-- Global site tag (gtag.js) - Google Analytics -->
1750<script async src="https://www.googletagmanager.com/gtag/js?id=UA-146633021-1"></script>
1751<script>
1752 window.dataLayer = window.dataLayer || [];
1753 function gtag(){dataLayer.push(arguments);}
1754 gtag('js', new Date());
1755
1756 gtag('config', 'UA-146633021-1');
1757</script>
1758<div class="b-breadcrumbs">
1759 <div class="b-container">
1760 <ul class="b-breadcrumbs-ul">
1761 </ul>
1762 </div>
1763</div>
1764 <div class="content">
1765 <!--MAIN -->
1766 <script>
1767/*!
1768 * jQuery UI Core 1.9.2
1769 * http://jqueryui.com
1770 *
1771 * Copyright 2012 jQuery Foundation and other contributors
1772 * Released under the MIT license.
1773 * http://jquery.org/license
1774 *
1775 * http://api.jqueryui.com/category/ui-core/
1776 */
1777(function( $, undefined ) {
1778
1779var uuid = 0,
1780 runiqueId = /^ui-id-\d+$/;
1781
1782// prevent duplicate loading
1783// this is only a problem because we proxy existing functions
1784// and we don't want to double proxy them
1785$.ui = $.ui || {};
1786if ( $.ui.version ) {
1787 return;
1788}
1789
1790$.extend( $.ui, {
1791 version: "1.9.2",
1792
1793 keyCode: {
1794 BACKSPACE: 8,
1795 COMMA: 188,
1796 DELETE: 46,
1797 DOWN: 40,
1798 END: 35,
1799 ENTER: 13,
1800 ESCAPE: 27,
1801 HOME: 36,
1802 LEFT: 37,
1803 NUMPAD_ADD: 107,
1804 NUMPAD_DECIMAL: 110,
1805 NUMPAD_DIVIDE: 111,
1806 NUMPAD_ENTER: 108,
1807 NUMPAD_MULTIPLY: 106,
1808 NUMPAD_SUBTRACT: 109,
1809 PAGE_DOWN: 34,
1810 PAGE_UP: 33,
1811 PERIOD: 190,
1812 RIGHT: 39,
1813 SPACE: 32,
1814 TAB: 9,
1815 UP: 38
1816 }
1817});
1818
1819// plugins
1820$.fn.extend({
1821 _focus: $.fn.focus,
1822 focus: function( delay, fn ) {
1823 return typeof delay === "number" ?
1824 this.each(function() {
1825 var elem = this;
1826 setTimeout(function() {
1827 $( elem ).focus();
1828 if ( fn ) {
1829 fn.call( elem );
1830 }
1831 }, delay );
1832 }) :
1833 this._focus.apply( this, arguments );
1834 },
1835
1836 scrollParent: function() {
1837 var scrollParent;
1838 if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
1839 scrollParent = this.parents().filter(function() {
1840 return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
1841 }).eq(0);
1842 } else {
1843 scrollParent = this.parents().filter(function() {
1844 return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
1845 }).eq(0);
1846 }
1847
1848 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
1849 },
1850
1851 zIndex: function( zIndex ) {
1852 if ( zIndex !== undefined ) {
1853 return this.css( "zIndex", zIndex );
1854 }
1855
1856 if ( this.length ) {
1857 var elem = $( this[ 0 ] ), position, value;
1858 while ( elem.length && elem[ 0 ] !== document ) {
1859 // Ignore z-index if position is set to a value where z-index is ignored by the browser
1860 // This makes behavior of this function consistent across browsers
1861 // WebKit always returns auto if the element is positioned
1862 position = elem.css( "position" );
1863 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
1864 // IE returns 0 when zIndex is not specified
1865 // other browsers return a string
1866 // we ignore the case of nested elements with an explicit value of 0
1867 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
1868 value = parseInt( elem.css( "zIndex" ), 10 );
1869 if ( !isNaN( value ) && value !== 0 ) {
1870 return value;
1871 }
1872 }
1873 elem = elem.parent();
1874 }
1875 }
1876
1877 return 0;
1878 },
1879
1880 uniqueId: function() {
1881 return this.each(function() {
1882 if ( !this.id ) {
1883 this.id = "ui-id-" + (++uuid);
1884 }
1885 });
1886 },
1887
1888 removeUniqueId: function() {
1889 return this.each(function() {
1890 if ( runiqueId.test( this.id ) ) {
1891 $( this ).removeAttr( "id" );
1892 }
1893 });
1894 }
1895});
1896
1897// selectors
1898function focusable( element, isTabIndexNotNaN ) {
1899 var map, mapName, img,
1900 nodeName = element.nodeName.toLowerCase();
1901 if ( "area" === nodeName ) {
1902 map = element.parentNode;
1903 mapName = map.name;
1904 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
1905 return false;
1906 }
1907 img = $( "img[usemap=#" + mapName + "]" )[0];
1908 return !!img && visible( img );
1909 }
1910 return ( /input|select|textarea|button|object/.test( nodeName ) ?
1911 !element.disabled :
1912 "a" === nodeName ?
1913 element.href || isTabIndexNotNaN :
1914 isTabIndexNotNaN) &&
1915 // the element and all of its ancestors must be visible
1916 visible( element );
1917}
1918
1919function visible( element ) {
1920 return $.expr.filters.visible( element ) &&
1921 !$( element ).parents().andSelf().filter(function() {
1922 return $.css( this, "visibility" ) === "hidden";
1923 }).length;
1924}
1925
1926$.extend( $.expr[ ":" ], {
1927 data: $.expr.createPseudo ?
1928 $.expr.createPseudo(function( dataName ) {
1929 return function( elem ) {
1930 return !!$.data( elem, dataName );
1931 };
1932 }) :
1933 // support: jQuery <1.8
1934 function( elem, i, match ) {
1935 return !!$.data( elem, match[ 3 ] );
1936 },
1937
1938 focusable: function( element ) {
1939 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
1940 },
1941
1942 tabbable: function( element ) {
1943 var tabIndex = $.attr( element, "tabindex" ),
1944 isTabIndexNaN = isNaN( tabIndex );
1945 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
1946 }
1947});
1948
1949// support
1950$(function() {
1951 var body = document.body,
1952 div = body.appendChild( div = document.createElement( "div" ) );
1953
1954 // access offsetHeight before setting the style to prevent a layout bug
1955 // in IE 9 which causes the element to continue to take up space even
1956 // after it is removed from the DOM (#8026)
1957 div.offsetHeight;
1958
1959 $.extend( div.style, {
1960 minHeight: "100px",
1961 height: "auto",
1962 padding: 0,
1963 borderWidth: 0
1964 });
1965
1966 $.support.minHeight = div.offsetHeight === 100;
1967 $.support.selectstart = "onselectstart" in div;
1968
1969 // set display to none to avoid a layout bug in IE
1970 // http://dev.jquery.com/ticket/4014
1971 body.removeChild( div ).style.display = "none";
1972});
1973
1974// support: jQuery <1.8
1975if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
1976 $.each( [ "Width", "Height" ], function( i, name ) {
1977 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
1978 type = name.toLowerCase(),
1979 orig = {
1980 innerWidth: $.fn.innerWidth,
1981 innerHeight: $.fn.innerHeight,
1982 outerWidth: $.fn.outerWidth,
1983 outerHeight: $.fn.outerHeight
1984 };
1985
1986 function reduce( elem, size, border, margin ) {
1987 $.each( side, function() {
1988 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
1989 if ( border ) {
1990 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
1991 }
1992 if ( margin ) {
1993 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
1994 }
1995 });
1996 return size;
1997 }
1998
1999 $.fn[ "inner" + name ] = function( size ) {
2000 if ( size === undefined ) {
2001 return orig[ "inner" + name ].call( this );
2002 }
2003
2004 return this.each(function() {
2005 $( this ).css( type, reduce( this, size ) + "px" );
2006 });
2007 };
2008
2009 $.fn[ "outer" + name] = function( size, margin ) {
2010 if ( typeof size !== "number" ) {
2011 return orig[ "outer" + name ].call( this, size );
2012 }
2013
2014 return this.each(function() {
2015 $( this).css( type, reduce( this, size, true, margin ) + "px" );
2016 });
2017 };
2018 });
2019}
2020
2021// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
2022if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
2023 $.fn.removeData = (function( removeData ) {
2024 return function( key ) {
2025 if ( arguments.length ) {
2026 return removeData.call( this, $.camelCase( key ) );
2027 } else {
2028 return removeData.call( this );
2029 }
2030 };
2031 })( $.fn.removeData );
2032}
2033
2034
2035
2036
2037
2038// deprecated
2039
2040(function() {
2041 var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || [];
2042 $.ui.ie = uaMatch.length ? true : false;
2043 $.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6;
2044})();
2045
2046$.fn.extend({
2047 disableSelection: function() {
2048 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
2049 ".ui-disableSelection", function( event ) {
2050 event.preventDefault();
2051 });
2052 },
2053
2054 enableSelection: function() {
2055 return this.unbind( ".ui-disableSelection" );
2056 }
2057});
2058
2059$.extend( $.ui, {
2060 // $.ui.plugin is deprecated. Use the proxy pattern instead.
2061 plugin: {
2062 add: function( module, option, set ) {
2063 var i,
2064 proto = $.ui[ module ].prototype;
2065 for ( i in set ) {
2066 proto.plugins[ i ] = proto.plugins[ i ] || [];
2067 proto.plugins[ i ].push( [ option, set[ i ] ] );
2068 }
2069 },
2070 call: function( instance, name, args ) {
2071 var i,
2072 set = instance.plugins[ name ];
2073 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
2074 return;
2075 }
2076
2077 for ( i = 0; i < set.length; i++ ) {
2078 if ( instance.options[ set[ i ][ 0 ] ] ) {
2079 set[ i ][ 1 ].apply( instance.element, args );
2080 }
2081 }
2082 }
2083 },
2084
2085 contains: $.contains,
2086
2087 // only used by resizable
2088 hasScroll: function( el, a ) {
2089
2090 //If overflow is hidden, the element might have extra content, but the user wants to hide it
2091 if ( $( el ).css( "overflow" ) === "hidden") {
2092 return false;
2093 }
2094
2095 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
2096 has = false;
2097
2098 if ( el[ scroll ] > 0 ) {
2099 return true;
2100 }
2101
2102 // TODO: determine which cases actually cause this to happen
2103 // if the element doesn't have the scroll set, see if it's possible to
2104 // set the scroll
2105 el[ scroll ] = 1;
2106 has = ( el[ scroll ] > 0 );
2107 el[ scroll ] = 0;
2108 return has;
2109 },
2110
2111 // these are odd functions, fix the API or move into individual plugins
2112 isOverAxis: function( x, reference, size ) {
2113 //Determines when x coordinate is over "b" element axis
2114 return ( x > reference ) && ( x < ( reference + size ) );
2115 },
2116 isOver: function( y, x, top, left, height, width ) {
2117 //Determines when x, y coordinates is over "b" element
2118 return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
2119 }
2120});
2121
2122})( jQuery );
2123
2124//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlcyI6WyJqcXVlcnl1aS9qcXVlcnkudWkuY29yZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIGpRdWVyeSBVSSBDb3JlIDEuOS4yXG4gKiBodHRwOi8vanF1ZXJ5dWkuY29tXG4gKlxuICogQ29weXJpZ2h0IDIwMTIgalF1ZXJ5IEZvdW5kYXRpb24gYW5kIG90aGVyIGNvbnRyaWJ1dG9yc1xuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxuICogaHR0cDovL2pxdWVyeS5vcmcvbGljZW5zZVxuICpcbiAqIGh0dHA6Ly9hcGkuanF1ZXJ5dWkuY29tL2NhdGVnb3J5L3VpLWNvcmUvXG4gKi9cbihmdW5jdGlvbiggJCwgdW5kZWZpbmVkICkge1xuXG52YXIgdXVpZCA9IDAsXG5cdHJ1bmlxdWVJZCA9IC9edWktaWQtXFxkKyQvO1xuXG4vLyBwcmV2ZW50IGR1cGxpY2F0ZSBsb2FkaW5nXG4vLyB0aGlzIGlzIG9ubHkgYSBwcm9ibGVtIGJlY2F1c2Ugd2UgcHJveHkgZXhpc3RpbmcgZnVuY3Rpb25zXG4vLyBhbmQgd2UgZG9uJ3Qgd2FudCB0byBkb3VibGUgcHJveHkgdGhlbVxuJC51aSA9ICQudWkgfHwge307XG5pZiAoICQudWkudmVyc2lvbiApIHtcblx0cmV0dXJuO1xufVxuXG4kLmV4dGVuZCggJC51aSwge1xuXHR2ZXJzaW9uOiBcIjEuOS4yXCIsXG5cblx0a2V5Q29kZToge1xuXHRcdEJBQ0tTUEFDRTogOCxcblx0XHRDT01NQTogMTg4LFxuXHRcdERFTEVURTogNDYsXG5cdFx0RE9XTjogNDAsXG5cdFx0RU5EOiAzNSxcblx0XHRFTlRFUjogMTMsXG5cdFx0RVNDQVBFOiAyNyxcblx0XHRIT01FOiAzNixcblx0XHRMRUZUOiAzNyxcblx0XHROVU1QQURfQUREOiAxMDcsXG5cdFx0TlVNUEFEX0RFQ0lNQUw6IDExMCxcblx0XHROVU1QQURfRElWSURFOiAxMTEsXG5cdFx0TlVNUEFEX0VOVEVSOiAxMDgsXG5cdFx0TlVNUEFEX01VTFRJUExZOiAxMDYsXG5cdFx0TlVNUEFEX1NVQlRSQUNUOiAxMDksXG5cdFx0UEFHRV9ET1dOOiAzNCxcblx0XHRQQUdFX1VQOiAzMyxcblx0XHRQRVJJT0Q6IDE5MCxcblx0XHRSSUdIVDogMzksXG5cdFx0U1BBQ0U6IDMyLFxuXHRcdFRBQjogOSxcblx0XHRVUDogMzhcblx0fVxufSk7XG5cbi8vIHBsdWdpbnNcbiQuZm4uZXh0ZW5kKHtcblx0X2ZvY3VzOiAkLmZuLmZvY3VzLFxuXHRmb2N1czogZnVuY3Rpb24oIGRlbGF5LCBmbiApIHtcblx0XHRyZXR1cm4gdHlwZW9mIGRlbGF5ID09PSBcIm51bWJlclwiID9cblx0XHRcdHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIGVsZW0gPSB0aGlzO1xuXHRcdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdCQoIGVsZW0gKS5mb2N1cygpO1xuXHRcdFx0XHRcdGlmICggZm4gKSB7XG5cdFx0XHRcdFx0XHRmbi5jYWxsKCBlbGVtICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9LCBkZWxheSApO1xuXHRcdFx0fSkgOlxuXHRcdFx0dGhpcy5fZm9jdXMuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHR9LFxuXG5cdHNjcm9sbFBhcmVudDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIHNjcm9sbFBhcmVudDtcblx0XHRpZiAoKCQudWkuaWUgJiYgKC8oc3RhdGljfHJlbGF0aXZlKS8pLnRlc3QodGhpcy5jc3MoJ3Bvc2l0aW9uJykpKSB8fCAoL2Fic29sdXRlLykudGVzdCh0aGlzLmNzcygncG9zaXRpb24nKSkpIHtcblx0XHRcdHNjcm9sbFBhcmVudCA9IHRoaXMucGFyZW50cygpLmZpbHRlcihmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuICgvKHJlbGF0aXZlfGFic29sdXRlfGZpeGVkKS8pLnRlc3QoJC5jc3ModGhpcywncG9zaXRpb24nKSkgJiYgKC8oYXV0b3xzY3JvbGwpLykudGVzdCgkLmNzcyh0aGlzLCdvdmVyZmxvdycpKyQuY3NzKHRoaXMsJ292ZXJmbG93LXknKSskLmNzcyh0aGlzLCdvdmVyZmxvdy14JykpO1xuXHRcdFx0fSkuZXEoMCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHNjcm9sbFBhcmVudCA9IHRoaXMucGFyZW50cygpLmZpbHRlcihmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuICgvKGF1dG98c2Nyb2xsKS8pLnRlc3QoJC5jc3ModGhpcywnb3ZlcmZsb3cnKSskLmNzcyh0aGlzLCdvdmVyZmxvdy15JykrJC5jc3ModGhpcywnb3ZlcmZsb3cteCcpKTtcblx0XHRcdH0pLmVxKDApO1xuXHRcdH1cblxuXHRcdHJldHVybiAoL2ZpeGVkLykudGVzdCh0aGlzLmNzcygncG9zaXRpb24nKSkgfHwgIXNjcm9sbFBhcmVudC5sZW5ndGggPyAkKGRvY3VtZW50KSA6IHNjcm9sbFBhcmVudDtcblx0fSxcblxuXHR6SW5kZXg6IGZ1bmN0aW9uKCB6SW5kZXggKSB7XG5cdFx0aWYgKCB6SW5kZXggIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHJldHVybiB0aGlzLmNzcyggXCJ6SW5kZXhcIiwgekluZGV4ICk7XG5cdFx0fVxuXG5cdFx0aWYgKCB0aGlzLmxlbmd0aCApIHtcblx0XHRcdHZhciBlbGVtID0gJCggdGhpc1sgMCBdICksIHBvc2l0aW9uLCB2YWx1ZTtcblx0XHRcdHdoaWxlICggZWxlbS5sZW5ndGggJiYgZWxlbVsgMCBdICE9PSBkb2N1bWVudCApIHtcblx0XHRcdFx0Ly8gSWdub3JlIHotaW5kZXggaWYgcG9zaXRpb24gaXMgc2V0IHRvIGEgdmFsdWUgd2hlcmUgei1pbmRleCBpcyBpZ25vcmVkIGJ5IHRoZSBicm93c2VyXG5cdFx0XHRcdC8vIFRoaXMgbWFrZXMgYmVoYXZpb3Igb2YgdGhpcyBmdW5jdGlvbiBjb25zaXN0ZW50IGFjcm9zcyBicm93c2Vyc1xuXHRcdFx0XHQvLyBXZWJLaXQgYWx3YXlzIHJldHVybnMgYXV0byBpZiB0aGUgZWxlbWVudCBpcyBwb3NpdGlvbmVkXG5cdFx0XHRcdHBvc2l0aW9uID0gZWxlbS5jc3MoIFwicG9zaXRpb25cIiApO1xuXHRcdFx0XHRpZiAoIHBvc2l0aW9uID09PSBcImFic29sdXRlXCIgfHwgcG9zaXRpb24gPT09IFwicmVsYXRpdmVcIiB8fCBwb3NpdGlvbiA9PT0gXCJmaXhlZFwiICkge1xuXHRcdFx0XHRcdC8vIElFIHJldHVybnMgMCB3aGVuIHpJbmRleCBpcyBub3Qgc3BlY2lmaWVkXG5cdFx0XHRcdFx0Ly8gb3RoZXIgYnJvd3NlcnMgcmV0dXJuIGEgc3RyaW5nXG5cdFx0XHRcdFx0Ly8gd2UgaWdub3JlIHRoZSBjYXNlIG9mIG5lc3RlZCBlbGVtZW50cyB3aXRoIGFuIGV4cGxpY2l0IHZhbHVlIG9mIDBcblx0XHRcdFx0XHQvLyA8ZGl2IHN0eWxlPVwiei1pbmRleDogLTEwO1wiPjxkaXYgc3R5bGU9XCJ6LWluZGV4OiAwO1wiPjwvZGl2PjwvZGl2PlxuXHRcdFx0XHRcdHZhbHVlID0gcGFyc2VJbnQoIGVsZW0uY3NzKCBcInpJbmRleFwiICksIDEwICk7XG5cdFx0XHRcdFx0aWYgKCAhaXNOYU4oIHZhbHVlICkgJiYgdmFsdWUgIT09IDAgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdGVsZW0gPSBlbGVtLnBhcmVudCgpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiAwO1xuXHR9LFxuXG5cdHVuaXF1ZUlkOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCAhdGhpcy5pZCApIHtcblx0XHRcdFx0dGhpcy5pZCA9IFwidWktaWQtXCIgKyAoKyt1dWlkKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHRyZW1vdmVVbmlxdWVJZDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGlmICggcnVuaXF1ZUlkLnRlc3QoIHRoaXMuaWQgKSApIHtcblx0XHRcdFx0JCggdGhpcyApLnJlbW92ZUF0dHIoIFwiaWRcIiApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG59KTtcblxuLy8gc2VsZWN0b3JzXG5mdW5jdGlvbiBmb2N1c2FibGUoIGVsZW1lbnQsIGlzVGFiSW5kZXhOb3ROYU4gKSB7XG5cdHZhciBtYXAsIG1hcE5hbWUsIGltZyxcblx0XHRub2RlTmFtZSA9IGVsZW1lbnQubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0aWYgKCBcImFyZWFcIiA9PT0gbm9kZU5hbWUgKSB7XG5cdFx0bWFwID0gZWxlbWVudC5wYXJlbnROb2RlO1xuXHRcdG1hcE5hbWUgPSBtYXAubmFtZTtcblx0XHRpZiAoICFlbGVtZW50LmhyZWYgfHwgIW1hcE5hbWUgfHwgbWFwLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgIT09IFwibWFwXCIgKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGltZyA9ICQoIFwiaW1nW3VzZW1hcD0jXCIgKyBtYXBOYW1lICsgXCJdXCIgKVswXTtcblx0XHRyZXR1cm4gISFpbWcgJiYgdmlzaWJsZSggaW1nICk7XG5cdH1cblx0cmV0dXJuICggL2lucHV0fHNlbGVjdHx0ZXh0YXJlYXxidXR0b258b2JqZWN0Ly50ZXN0KCBub2RlTmFtZSApID9cblx0XHQhZWxlbWVudC5kaXNhYmxlZCA6XG5cdFx0XCJhXCIgPT09IG5vZGVOYW1lID9cblx0XHRcdGVsZW1lbnQuaHJlZiB8fCBpc1RhYkluZGV4Tm90TmFOIDpcblx0XHRcdGlzVGFiSW5kZXhOb3ROYU4pICYmXG5cdFx0Ly8gdGhlIGVsZW1lbnQgYW5kIGFsbCBvZiBpdHMgYW5jZXN0b3JzIG11c3QgYmUgdmlzaWJsZVxuXHRcdHZpc2libGUoIGVsZW1lbnQgKTtcbn1cblxuZnVuY3Rpb24gdmlzaWJsZSggZWxlbWVudCApIHtcblx0cmV0dXJuICQuZXhwci5maWx0ZXJzLnZpc2libGUoIGVsZW1lbnQgKSAmJlxuXHRcdCEkKCBlbGVtZW50ICkucGFyZW50cygpLmFuZFNlbGYoKS5maWx0ZXIoZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gJC5jc3MoIHRoaXMsIFwidmlzaWJpbGl0eVwiICkgPT09IFwiaGlkZGVuXCI7XG5cdFx0fSkubGVuZ3RoO1xufVxuXG4kLmV4dGVuZCggJC5leHByWyBcIjpcIiBdLCB7XG5cdGRhdGE6ICQuZXhwci5jcmVhdGVQc2V1ZG8gP1xuXHRcdCQuZXhwci5jcmVhdGVQc2V1ZG8oZnVuY3Rpb24oIGRhdGFOYW1lICkge1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gISEkLmRhdGEoIGVsZW0sIGRhdGFOYW1lICk7XG5cdFx0XHR9O1xuXHRcdH0pIDpcblx0XHQvLyBzdXBwb3J0OiBqUXVlcnkgPDEuOFxuXHRcdGZ1bmN0aW9uKCBlbGVtLCBpLCBtYXRjaCApIHtcblx0XHRcdHJldHVybiAhISQuZGF0YSggZWxlbSwgbWF0Y2hbIDMgXSApO1xuXHRcdH0sXG5cblx0Zm9jdXNhYmxlOiBmdW5jdGlvbiggZWxlbWVudCApIHtcblx0XHRyZXR1cm4gZm9jdXNhYmxlKCBlbGVtZW50LCAhaXNOYU4oICQuYXR0ciggZWxlbWVudCwgXCJ0YWJpbmRleFwiICkgKSApO1xuXHR9LFxuXG5cdHRhYmJhYmxlOiBmdW5jdGlvbiggZWxlbWVudCApIHtcblx0XHR2YXIgdGFiSW5kZXggPSAkLmF0dHIoIGVsZW1lbnQsIFwidGFiaW5kZXhcIiApLFxuXHRcdFx0aXNUYWJJbmRleE5hTiA9IGlzTmFOKCB0YWJJbmRleCApO1xuXHRcdHJldHVybiAoIGlzVGFiSW5kZXhOYU4gfHwgdGFiSW5kZXggPj0gMCApICYmIGZvY3VzYWJsZSggZWxlbWVudCwgIWlzVGFiSW5kZXhOYU4gKTtcblx0fVxufSk7XG5cbi8vIHN1cHBvcnRcbiQoZnVuY3Rpb24oKSB7XG5cdHZhciBib2R5ID0gZG9jdW1lbnQuYm9keSxcblx0XHRkaXYgPSBib2R5LmFwcGVuZENoaWxkKCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICkgKTtcblxuXHQvLyBhY2Nlc3Mgb2Zmc2V0SGVpZ2h0IGJlZm9yZSBzZXR0aW5nIHRoZSBzdHlsZSB0byBwcmV2ZW50IGEgbGF5b3V0IGJ1Z1xuXHQvLyBpbiBJRSA5IHdoaWNoIGNhdXNlcyB0aGUgZWxlbWVudCB0byBjb250aW51ZSB0byB0YWtlIHVwIHNwYWNlIGV2ZW5cblx0Ly8gYWZ0ZXIgaXQgaXMgcmVtb3ZlZCBmcm9tIHRoZSBET00gKCM4MDI2KVxuXHRkaXYub2Zmc2V0SGVpZ2h0O1xuXG5cdCQuZXh0ZW5kKCBkaXYuc3R5bGUsIHtcblx0XHRtaW5IZWlnaHQ6IFwiMTAwcHhcIixcblx0XHRoZWlnaHQ6IFwiYXV0b1wiLFxuXHRcdHBhZGRpbmc6IDAsXG5cdFx0Ym9yZGVyV2lkdGg6IDBcblx0fSk7XG5cblx0JC5zdXBwb3J0Lm1pbkhlaWdodCA9IGRpdi5vZmZzZXRIZWlnaHQgPT09IDEwMDtcblx0JC5zdXBwb3J0LnNlbGVjdHN0YXJ0ID0gXCJvbnNlbGVjdHN0YXJ0XCIgaW4gZGl2O1xuXG5cdC8vIHNldCBkaXNwbGF5IHRvIG5vbmUgdG8gYXZvaWQgYSBsYXlvdXQgYnVnIGluIElFXG5cdC8vIGh0dHA6Ly9kZXYuanF1ZXJ5LmNvbS90aWNrZXQvNDAxNFxuXHRib2R5LnJlbW92ZUNoaWxkKCBkaXYgKS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XG59KTtcblxuLy8gc3VwcG9ydDogalF1ZXJ5IDwxLjhcbmlmICggISQoIFwiPGE+XCIgKS5vdXRlcldpZHRoKCAxICkuanF1ZXJ5ICkge1xuXHQkLmVhY2goIFsgXCJXaWR0aFwiLCBcIkhlaWdodFwiIF0sIGZ1bmN0aW9uKCBpLCBuYW1lICkge1xuXHRcdHZhciBzaWRlID0gbmFtZSA9PT0gXCJXaWR0aFwiID8gWyBcIkxlZnRcIiwgXCJSaWdodFwiIF0gOiBbIFwiVG9wXCIsIFwiQm90dG9tXCIgXSxcblx0XHRcdHR5cGUgPSBuYW1lLnRvTG93ZXJDYXNlKCksXG5cdFx0XHRvcmlnID0ge1xuXHRcdFx0XHRpbm5lcldpZHRoOiAkLmZuLmlubmVyV2lkdGgsXG5cdFx0XHRcdGlubmVySGVpZ2h0OiAkLmZuLmlubmVySGVpZ2h0LFxuXHRcdFx0XHRvdXRlcldpZHRoOiAkLmZuLm91dGVyV2lkdGgsXG5cdFx0XHRcdG91dGVySGVpZ2h0OiAkLmZuLm91dGVySGVpZ2h0XG5cdFx0XHR9O1xuXG5cdFx0ZnVuY3Rpb24gcmVkdWNlKCBlbGVtLCBzaXplLCBib3JkZXIsIG1hcmdpbiApIHtcblx0XHRcdCQuZWFjaCggc2lkZSwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHNpemUgLT0gcGFyc2VGbG9hdCggJC5jc3MoIGVsZW0sIFwicGFkZGluZ1wiICsgdGhpcyApICkgfHwgMDtcblx0XHRcdFx0aWYgKCBib3JkZXIgKSB7XG5cdFx0XHRcdFx0c2l6ZSAtPSBwYXJzZUZsb2F0KCAkLmNzcyggZWxlbSwgXCJib3JkZXJcIiArIHRoaXMgKyBcIldpZHRoXCIgKSApIHx8IDA7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCBtYXJnaW4gKSB7XG5cdFx0XHRcdFx0c2l6ZSAtPSBwYXJzZUZsb2F0KCAkLmNzcyggZWxlbSwgXCJtYXJnaW5cIiArIHRoaXMgKSApIHx8IDA7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0cmV0dXJuIHNpemU7XG5cdFx0fVxuXG5cdFx0JC5mblsgXCJpbm5lclwiICsgbmFtZSBdID0gZnVuY3Rpb24oIHNpemUgKSB7XG5cdFx0XHRpZiAoIHNpemUgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIG9yaWdbIFwiaW5uZXJcIiArIG5hbWUgXS5jYWxsKCB0aGlzICk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdCQoIHRoaXMgKS5jc3MoIHR5cGUsIHJlZHVjZSggdGhpcywgc2l6ZSApICsgXCJweFwiICk7XG5cdFx0XHR9KTtcblx0XHR9O1xuXG5cdFx0JC5mblsgXCJvdXRlclwiICsgbmFtZV0gPSBmdW5jdGlvbiggc2l6ZSwgbWFyZ2luICkge1xuXHRcdFx0aWYgKCB0eXBlb2Ygc2l6ZSAhPT0gXCJudW1iZXJcIiApIHtcblx0XHRcdFx0cmV0dXJuIG9yaWdbIFwib3V0ZXJcIiArIG5hbWUgXS5jYWxsKCB0aGlzLCBzaXplICk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdCQoIHRoaXMpLmNzcyggdHlwZSwgcmVkdWNlKCB0aGlzLCBzaXplLCB0cnVlLCBtYXJnaW4gKSArIFwicHhcIiApO1xuXHRcdFx0fSk7XG5cdFx0fTtcblx0fSk7XG59XG5cbi8vIHN1cHBvcnQ6IGpRdWVyeSAxLjYuMSwgMS42LjIgKGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0Lzk0MTMpXG5pZiAoICQoIFwiPGE+XCIgKS5kYXRhKCBcImEtYlwiLCBcImFcIiApLnJlbW92ZURhdGEoIFwiYS1iXCIgKS5kYXRhKCBcImEtYlwiICkgKSB7XG5cdCQuZm4ucmVtb3ZlRGF0YSA9IChmdW5jdGlvbiggcmVtb3ZlRGF0YSApIHtcblx0XHRyZXR1cm4gZnVuY3Rpb24oIGtleSApIHtcblx0XHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCApIHtcblx0XHRcdFx0cmV0dXJuIHJlbW92ZURhdGEuY2FsbCggdGhpcywgJC5jYW1lbENhc2UoIGtleSApICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gcmVtb3ZlRGF0YS5jYWxsKCB0aGlzICk7XG5cdFx0XHR9XG5cdFx0fTtcblx0fSkoICQuZm4ucmVtb3ZlRGF0YSApO1xufVxuXG5cblxuXG5cbi8vIGRlcHJlY2F0ZWRcblxuKGZ1bmN0aW9uKCkge1xuXHR2YXIgdWFNYXRjaCA9IC9tc2llIChbXFx3Ll0rKS8uZXhlYyggbmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpICkgfHwgW107XG5cdCQudWkuaWUgPSB1YU1hdGNoLmxlbmd0aCA/IHRydWUgOiBmYWxzZTtcblx0JC51aS5pZTYgPSBwYXJzZUZsb2F0KCB1YU1hdGNoWyAxIF0sIDEwICkgPT09IDY7XG59KSgpO1xuXG4kLmZuLmV4dGVuZCh7XG5cdGRpc2FibGVTZWxlY3Rpb246IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmJpbmQoICggJC5zdXBwb3J0LnNlbGVjdHN0YXJ0ID8gXCJzZWxlY3RzdGFydFwiIDogXCJtb3VzZWRvd25cIiApICtcblx0XHRcdFwiLnVpLWRpc2FibGVTZWxlY3Rpb25cIiwgZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0fSk7XG5cdH0sXG5cblx0ZW5hYmxlU2VsZWN0aW9uOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy51bmJpbmQoIFwiLnVpLWRpc2FibGVTZWxlY3Rpb25cIiApO1xuXHR9XG59KTtcblxuJC5leHRlbmQoICQudWksIHtcblx0Ly8gJC51aS5wbHVnaW4gaXMgZGVwcmVjYXRlZC4gIFVzZSB0aGUgcHJveHkgcGF0dGVybiBpbnN0ZWFkLlxuXHRwbHVnaW46IHtcblx0XHRhZGQ6IGZ1bmN0aW9uKCBtb2R1bGUsIG9wdGlvbiwgc2V0ICkge1xuXHRcdFx0dmFyIGksXG5cdFx0XHRcdHByb3RvID0gJC51aVsgbW9kdWxlIF0ucHJvdG90eXBlO1xuXHRcdFx0Zm9yICggaSBpbiBzZXQgKSB7XG5cdFx0XHRcdHByb3RvLnBsdWdpbnNbIGkgXSA9IHByb3RvLnBsdWdpbnNbIGkgXSB8fCBbXTtcblx0XHRcdFx0cHJvdG8ucGx1Z2luc1sgaSBdLnB1c2goIFsgb3B0aW9uLCBzZXRbIGkgXSBdICk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRjYWxsOiBmdW5jdGlvbiggaW5zdGFuY2UsIG5hbWUsIGFyZ3MgKSB7XG5cdFx0XHR2YXIgaSxcblx0XHRcdFx0c2V0ID0gaW5zdGFuY2UucGx1Z2luc1sgbmFtZSBdO1xuXHRcdFx0aWYgKCAhc2V0IHx8ICFpbnN0YW5jZS5lbGVtZW50WyAwIF0ucGFyZW50Tm9kZSB8fCBpbnN0YW5jZS5lbGVtZW50WyAwIF0ucGFyZW50Tm9kZS5ub2RlVHlwZSA9PT0gMTEgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Zm9yICggaSA9IDA7IGkgPCBzZXQubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdGlmICggaW5zdGFuY2Uub3B0aW9uc1sgc2V0WyBpIF1bIDAgXSBdICkge1xuXHRcdFx0XHRcdHNldFsgaSBdWyAxIF0uYXBwbHkoIGluc3RhbmNlLmVsZW1lbnQsIGFyZ3MgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHRjb250YWluczogJC5jb250YWlucyxcblxuXHQvLyBvbmx5IHVzZWQgYnkgcmVzaXphYmxlXG5cdGhhc1Njcm9sbDogZnVuY3Rpb24oIGVsLCBhICkge1xuXG5cdFx0Ly9JZiBvdmVyZmxvdyBpcyBoaWRkZW4sIHRoZSBlbGVtZW50IG1pZ2h0IGhhdmUgZXh0cmEgY29udGVudCwgYnV0IHRoZSB1c2VyIHdhbnRzIHRvIGhpZGUgaXRcblx0XHRpZiAoICQoIGVsICkuY3NzKCBcIm92ZXJmbG93XCIgKSA9PT0gXCJoaWRkZW5cIikge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHZhciBzY3JvbGwgPSAoIGEgJiYgYSA9PT0gXCJsZWZ0XCIgKSA/IFwic2Nyb2xsTGVmdFwiIDogXCJzY3JvbGxUb3BcIixcblx0XHRcdGhhcyA9IGZhbHNlO1xuXG5cdFx0aWYgKCBlbFsgc2Nyb2xsIF0gPiAwICkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0Ly8gVE9ETzogZGV0ZXJtaW5lIHdoaWNoIGNhc2VzIGFjdHVhbGx5IGNhdXNlIHRoaXMgdG8gaGFwcGVuXG5cdFx0Ly8gaWYgdGhlIGVsZW1lbnQgZG9lc24ndCBoYXZlIHRoZSBzY3JvbGwgc2V0LCBzZWUgaWYgaXQncyBwb3NzaWJsZSB0b1xuXHRcdC8vIHNldCB0aGUgc2Nyb2xsXG5cdFx0ZWxbIHNjcm9sbCBdID0gMTtcblx0XHRoYXMgPSAoIGVsWyBzY3JvbGwgXSA+IDAgKTtcblx0XHRlbFsgc2Nyb2xsIF0gPSAwO1xuXHRcdHJldHVybiBoYXM7XG5cdH0sXG5cblx0Ly8gdGhlc2UgYXJlIG9kZCBmdW5jdGlvbnMsIGZpeCB0aGUgQVBJIG9yIG1vdmUgaW50byBpbmRpdmlkdWFsIHBsdWdpbnNcblx0aXNPdmVyQXhpczogZnVuY3Rpb24oIHgsIHJlZmVyZW5jZSwgc2l6ZSApIHtcblx0XHQvL0RldGVybWluZXMgd2hlbiB4IGNvb3JkaW5hdGUgaXMgb3ZlciBcImJcIiBlbGVtZW50IGF4aXNcblx0XHRyZXR1cm4gKCB4ID4gcmVmZXJlbmNlICkgJiYgKCB4IDwgKCByZWZlcmVuY2UgKyBzaXplICkgKTtcblx0fSxcblx0aXNPdmVyOiBmdW5jdGlvbiggeSwgeCwgdG9wLCBsZWZ0LCBoZWlnaHQsIHdpZHRoICkge1xuXHRcdC8vRGV0ZXJtaW5lcyB3aGVuIHgsIHkgY29vcmRpbmF0ZXMgaXMgb3ZlciBcImJcIiBlbGVtZW50XG5cdFx0cmV0dXJuICQudWkuaXNPdmVyQXhpcyggeSwgdG9wLCBoZWlnaHQgKSAmJiAkLnVpLmlzT3ZlckF4aXMoIHgsIGxlZnQsIHdpZHRoICk7XG5cdH1cbn0pO1xuXG59KSggalF1ZXJ5ICk7XG4iXSwiZmlsZSI6ImpxdWVyeXVpL2pxdWVyeS51aS5jb3JlLmpzIn0=
2125
2126/*!
2127 * jQuery UI Datepicker 1.9.2
2128 * http://jqueryui.com
2129 *
2130 * Copyright 2012 jQuery Foundation and other contributors
2131 * Released under the MIT license.
2132 * http://jquery.org/license
2133 *
2134 * http://api.jqueryui.com/datepicker/
2135 *
2136 * Depends:
2137 * jquery.ui.core.js
2138 */
2139(function( $, undefined ) {
2140
2141$.extend($.ui, { datepicker: { version: "1.9.2" } });
2142
2143var PROP_NAME = 'datepicker';
2144var dpuuid = new Date().getTime();
2145var instActive;
2146
2147/* Date picker manager.
2148 Use the singleton instance of this class, $.datepicker, to interact with the date picker.
2149 Settings for (groups of) date pickers are maintained in an instance object,
2150 allowing multiple different settings on the same page. */
2151
2152function Datepicker() {
2153 this.debug = false; // Change this to true to start debugging
2154 this._curInst = null; // The current instance in use
2155 this._keyEvent = false; // If the last event was a key event
2156 this._disabledInputs = []; // List of date picker inputs that have been disabled
2157 this._datepickerShowing = false; // True if the popup picker is showing , false if not
2158 this._inDialog = false; // True if showing within a "dialog", false if not
2159 this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
2160 this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
2161 this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
2162 this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
2163 this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
2164 this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
2165 this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
2166 this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
2167 this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
2168 this.regional = []; // Available regional settings, indexed by language code
2169 this.regional[''] = { // Default regional settings
2170 closeText: 'Done', // Display text for close link
2171 prevText: 'Prev', // Display text for previous month link
2172 nextText: 'Next', // Display text for next month link
2173 currentText: 'Today', // Display text for current month link
2174 monthNames: ['January','February','March','April','May','June',
2175 'July','August','September','October','November','December'], // Names of months for drop-down and formatting
2176 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
2177 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
2178 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
2179 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
2180 weekHeader: 'Wk', // Column header for week of the year
2181 dateFormat: 'mm/dd/yy', // See format options on parseDate
2182 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
2183 isRTL: false, // True if right-to-left language, false if left-to-right
2184 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
2185 yearSuffix: '' // Additional text to append to the year in the month headers
2186 };
2187 this._defaults = { // Global defaults for all the date picker instances
2188 showOn: 'focus', // 'focus' for popup on focus,
2189 // 'button' for trigger button, or 'both' for either
2190 showAnim: 'fadeIn', // Name of jQuery animation for popup
2191 showOptions: {}, // Options for enhanced animations
2192 defaultDate: null, // Used when field is blank: actual date,
2193 // +/-number for offset from today, null for today
2194 appendText: '', // Display text following the input box, e.g. showing the format
2195 buttonText: '...', // Text for trigger button
2196 buttonImage: '', // URL for trigger button image
2197 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
2198 hideIfNoPrevNext: false, // True to hide next/previous month links
2199 // if not applicable, false to just disable them
2200 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
2201 gotoCurrent: false, // True if today link goes back to current selection instead
2202 changeMonth: false, // True if month can be selected directly, false if only prev/next
2203 changeYear: false, // True if year can be selected directly, false if only prev/next
2204 yearRange: 'c-10:c+10', // Range of years to display in drop-down,
2205 // either relative to today's year (-nn:+nn), relative to currently displayed year
2206 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
2207 showOtherMonths: false, // True to show dates in other months, false to leave blank
2208 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
2209 showWeek: false, // True to show week of the year, false to not show it
2210 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
2211 // takes a Date and returns the number of the week for it
2212 shortYearCutoff: '+10', // Short year values < this are in the current century,
2213 // > this are in the previous century,
2214 // string value starting with '+' for current year + value
2215 minDate: null, // The earliest selectable date, or null for no limit
2216 maxDate: null, // The latest selectable date, or null for no limit
2217 duration: 'fast', // Duration of display/closure
2218 beforeShowDay: null, // Function that takes a date and returns an array with
2219 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
2220 // [2] = cell title (optional), e.g. $.datepicker.noWeekends
2221 beforeShow: null, // Function that takes an input field and
2222 // returns a set of custom settings for the date picker
2223 onSelect: null, // Define a callback function when a date is selected
2224 onChangeMonthYear: null, // Define a callback function when the month or year is changed
2225 onClose: null, // Define a callback function when the datepicker is closed
2226 numberOfMonths: 1, // Number of months to show at a time
2227 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
2228 stepMonths: 1, // Number of months to step back/forward
2229 stepBigMonths: 12, // Number of months to step back/forward for the big links
2230 altField: '', // Selector for an alternate field to store selected dates into
2231 altFormat: '', // The date format to use for the alternate field
2232 constrainInput: true, // The input is constrained by the current date format
2233 showButtonPanel: false, // True to show button panel, false to not show it
2234 autoSize: false, // True to size the input for the date format, false to leave as is
2235 disabled: false // The initial disabled state
2236 };
2237 $.extend(this._defaults, this.regional['']);
2238 this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
2239}
2240
2241$.extend(Datepicker.prototype, {
2242 /* Class name added to elements to indicate already configured with a date picker. */
2243 markerClassName: 'hasDatepicker',
2244
2245 //Keep track of the maximum number of rows displayed (see #7043)
2246 maxRows: 4,
2247
2248 /* Debug logging (if enabled). */
2249 log: function () {
2250 if (this.debug)
2251 console.log.apply('', arguments);
2252 },
2253
2254 // TODO rename to "widget" when switching to widget factory
2255 _widgetDatepicker: function() {
2256 return this.dpDiv;
2257 },
2258
2259 /* Override the default settings for all instances of the date picker.
2260 @param settings object - the new settings to use as defaults (anonymous object)
2261 @return the manager object */
2262 setDefaults: function(settings) {
2263 extendRemove(this._defaults, settings || {});
2264 return this;
2265 },
2266
2267 /* Attach the date picker to a jQuery selection.
2268 @param target element - the target input field or division or span
2269 @param settings object - the new settings to use for this date picker instance (anonymous) */
2270 _attachDatepicker: function(target, settings) {
2271 // check for settings on the control itself - in namespace 'date:'
2272 var inlineSettings = null;
2273 for (var attrName in this._defaults) {
2274 var attrValue = target.getAttribute('date:' + attrName);
2275 if (attrValue) {
2276 inlineSettings = inlineSettings || {};
2277 try {
2278 inlineSettings[attrName] = eval(attrValue);
2279 } catch (err) {
2280 inlineSettings[attrName] = attrValue;
2281 }
2282 }
2283 }
2284 var nodeName = target.nodeName.toLowerCase();
2285 var inline = (nodeName == 'div' || nodeName == 'span');
2286 if (!target.id) {
2287 this.uuid += 1;
2288 target.id = 'dp' + this.uuid;
2289 }
2290 var inst = this._newInst($(target), inline);
2291 inst.settings = $.extend({}, settings || {}, inlineSettings || {});
2292 if (nodeName == 'input') {
2293 this._connectDatepicker(target, inst);
2294 } else if (inline) {
2295 this._inlineDatepicker(target, inst);
2296 }
2297 },
2298
2299 /* Create a new instance object. */
2300 _newInst: function(target, inline) {
2301 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
2302 return {id: id, input: target, // associated target
2303 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
2304 drawMonth: 0, drawYear: 0, // month being drawn
2305 inline: inline, // is datepicker inline or not
2306 dpDiv: (!inline ? this.dpDiv : // presentation div
2307 bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
2308 },
2309
2310 /* Attach the date picker to an input field. */
2311 _connectDatepicker: function(target, inst) {
2312 var input = $(target);
2313 inst.append = $([]);
2314 inst.trigger = $([]);
2315 if (input.hasClass(this.markerClassName))
2316 return;
2317 this._attachments(input, inst);
2318 input.addClass(this.markerClassName).keydown(this._doKeyDown).
2319 keypress(this._doKeyPress).keyup(this._doKeyUp).
2320 bind("setData.datepicker", function(event, key, value) {
2321 inst.settings[key] = value;
2322 }).bind("getData.datepicker", function(event, key) {
2323 return this._get(inst, key);
2324 });
2325 this._autoSize(inst);
2326 $.data(target, PROP_NAME, inst);
2327 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
2328 if( inst.settings.disabled ) {
2329 this._disableDatepicker( target );
2330 }
2331 },
2332
2333 /* Make attachments based on settings. */
2334 _attachments: function(input, inst) {
2335 var appendText = this._get(inst, 'appendText');
2336 var isRTL = this._get(inst, 'isRTL');
2337 if (inst.append)
2338 inst.append.remove();
2339 if (appendText) {
2340 inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
2341 input[isRTL ? 'before' : 'after'](inst.append);
2342 }
2343 input.unbind('focus', this._showDatepicker);
2344 if (inst.trigger)
2345 inst.trigger.remove();
2346 var showOn = this._get(inst, 'showOn');
2347 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
2348 input.focus(this._showDatepicker);
2349 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
2350 var buttonText = this._get(inst, 'buttonText');
2351 var buttonImage = this._get(inst, 'buttonImage');
2352 inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
2353 $('<img/>').addClass(this._triggerClass).
2354 attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
2355 $('<button type="button"></button>').addClass(this._triggerClass).
2356 html(buttonImage == '' ? buttonText : $('<img/>').attr(
2357 { src:buttonImage, alt:buttonText, title:buttonText })));
2358 input[isRTL ? 'before' : 'after'](inst.trigger);
2359 inst.trigger.click(function() {
2360 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
2361 $.datepicker._hideDatepicker();
2362 else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
2363 $.datepicker._hideDatepicker();
2364 $.datepicker._showDatepicker(input[0]);
2365 } else
2366 $.datepicker._showDatepicker(input[0]);
2367 return false;
2368 });
2369 }
2370 },
2371
2372 /* Apply the maximum length for the date format. */
2373 _autoSize: function(inst) {
2374 if (this._get(inst, 'autoSize') && !inst.inline) {
2375 var date = new Date(2009, 12 - 1, 20); // Ensure double digits
2376 var dateFormat = this._get(inst, 'dateFormat');
2377 if (dateFormat.match(/[DM]/)) {
2378 var findMax = function(names) {
2379 var max = 0;
2380 var maxI = 0;
2381 for (var i = 0; i < names.length; i++) {
2382 if (names[i].length > max) {
2383 max = names[i].length;
2384 maxI = i;
2385 }
2386 }
2387 return maxI;
2388 };
2389 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
2390 'monthNames' : 'monthNamesShort'))));
2391 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
2392 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
2393 }
2394 inst.input.attr('size', this._formatDate(inst, date).length);
2395 }
2396 },
2397
2398 /* Attach an inline date picker to a div. */
2399 _inlineDatepicker: function(target, inst) {
2400 var divSpan = $(target);
2401 if (divSpan.hasClass(this.markerClassName))
2402 return;
2403 divSpan.addClass(this.markerClassName).append(inst.dpDiv).
2404 bind("setData.datepicker", function(event, key, value){
2405 inst.settings[key] = value;
2406 }).bind("getData.datepicker", function(event, key){
2407 return this._get(inst, key);
2408 });
2409 $.data(target, PROP_NAME, inst);
2410 this._setDate(inst, this._getDefaultDate(inst), true);
2411 this._updateDatepicker(inst);
2412 this._updateAlternate(inst);
2413 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
2414 if( inst.settings.disabled ) {
2415 this._disableDatepicker( target );
2416 }
2417 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
2418 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
2419 inst.dpDiv.css( "display", "block" );
2420 },
2421
2422 /* Pop-up the date picker in a "dialog" box.
2423 @param input element - ignored
2424 @param date string or Date - the initial date to display
2425 @param onSelect function - the function to call when a date is selected
2426 @param settings object - update the dialog date picker instance's settings (anonymous object)
2427 @param pos int[2] - coordinates for the dialog's position within the screen or
2428 event - with x/y coordinates or
2429 leave empty for default (screen centre)
2430 @return the manager object */
2431 _dialogDatepicker: function(input, date, onSelect, settings, pos) {
2432 var inst = this._dialogInst; // internal instance
2433 if (!inst) {
2434 this.uuid += 1;
2435 var id = 'dp' + this.uuid;
2436 this._dialogInput = $('<input type="text" id="' + id +
2437 '" style="position: absolute; top: -100px; width: 0px;"/>');
2438 this._dialogInput.keydown(this._doKeyDown);
2439 $('body').append(this._dialogInput);
2440 inst = this._dialogInst = this._newInst(this._dialogInput, false);
2441 inst.settings = {};
2442 $.data(this._dialogInput[0], PROP_NAME, inst);
2443 }
2444 extendRemove(inst.settings, settings || {});
2445 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
2446 this._dialogInput.val(date);
2447
2448 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
2449 if (!this._pos) {
2450 var browserWidth = document.documentElement.clientWidth;
2451 var browserHeight = document.documentElement.clientHeight;
2452 var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
2453 var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
2454 this._pos = // should use actual width/height below
2455 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
2456 }
2457
2458 // move input on screen for focus, but hidden behind dialog
2459 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
2460 inst.settings.onSelect = onSelect;
2461 this._inDialog = true;
2462 this.dpDiv.addClass(this._dialogClass);
2463 this._showDatepicker(this._dialogInput[0]);
2464 if ($.blockUI)
2465 $.blockUI(this.dpDiv);
2466 $.data(this._dialogInput[0], PROP_NAME, inst);
2467 return this;
2468 },
2469
2470 /* Detach a datepicker from its control.
2471 @param target element - the target input field or division or span */
2472 _destroyDatepicker: function(target) {
2473 var $target = $(target);
2474 var inst = $.data(target, PROP_NAME);
2475 if (!$target.hasClass(this.markerClassName)) {
2476 return;
2477 }
2478 var nodeName = target.nodeName.toLowerCase();
2479 $.removeData(target, PROP_NAME);
2480 if (nodeName == 'input') {
2481 inst.append.remove();
2482 inst.trigger.remove();
2483 $target.removeClass(this.markerClassName).
2484 unbind('focus', this._showDatepicker).
2485 unbind('keydown', this._doKeyDown).
2486 unbind('keypress', this._doKeyPress).
2487 unbind('keyup', this._doKeyUp);
2488 } else if (nodeName == 'div' || nodeName == 'span')
2489 $target.removeClass(this.markerClassName).empty();
2490 },
2491
2492 /* Enable the date picker to a jQuery selection.
2493 @param target element - the target input field or division or span */
2494 _enableDatepicker: function(target) {
2495 var $target = $(target);
2496 var inst = $.data(target, PROP_NAME);
2497 if (!$target.hasClass(this.markerClassName)) {
2498 return;
2499 }
2500 var nodeName = target.nodeName.toLowerCase();
2501 if (nodeName == 'input') {
2502 target.disabled = false;
2503 inst.trigger.filter('button').
2504 each(function() { this.disabled = false; }).end().
2505 filter('img').css({opacity: '1.0', cursor: ''});
2506 }
2507 else if (nodeName == 'div' || nodeName == 'span') {
2508 var inline = $target.children('.' + this._inlineClass);
2509 inline.children().removeClass('ui-state-disabled');
2510 inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
2511 prop("disabled", false);
2512 }
2513 this._disabledInputs = $.map(this._disabledInputs,
2514 function(value) { return (value == target ? null : value); }); // delete entry
2515 },
2516
2517 /* Disable the date picker to a jQuery selection.
2518 @param target element - the target input field or division or span */
2519 _disableDatepicker: function(target) {
2520 var $target = $(target);
2521 var inst = $.data(target, PROP_NAME);
2522 if (!$target.hasClass(this.markerClassName)) {
2523 return;
2524 }
2525 var nodeName = target.nodeName.toLowerCase();
2526 if (nodeName == 'input') {
2527 target.disabled = true;
2528 inst.trigger.filter('button').
2529 each(function() { this.disabled = true; }).end().
2530 filter('img').css({opacity: '0.5', cursor: 'default'});
2531 }
2532 else if (nodeName == 'div' || nodeName == 'span') {
2533 var inline = $target.children('.' + this._inlineClass);
2534 inline.children().addClass('ui-state-disabled');
2535 inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
2536 prop("disabled", true);
2537 }
2538 this._disabledInputs = $.map(this._disabledInputs,
2539 function(value) { return (value == target ? null : value); }); // delete entry
2540 this._disabledInputs[this._disabledInputs.length] = target;
2541 },
2542
2543 /* Is the first field in a jQuery collection disabled as a datepicker?
2544 @param target element - the target input field or division or span
2545 @return boolean - true if disabled, false if enabled */
2546 _isDisabledDatepicker: function(target) {
2547 if (!target) {
2548 return false;
2549 }
2550 for (var i = 0; i < this._disabledInputs.length; i++) {
2551 if (this._disabledInputs[i] == target)
2552 return true;
2553 }
2554 return false;
2555 },
2556
2557 /* Retrieve the instance data for the target control.
2558 @param target element - the target input field or division or span
2559 @return object - the associated instance data
2560 @throws error if a jQuery problem getting data */
2561 _getInst: function(target) {
2562 try {
2563 return $.data(target, PROP_NAME);
2564 }
2565 catch (err) {
2566 throw 'Missing instance data for this datepicker';
2567 }
2568 },
2569
2570 /* Update or retrieve the settings for a date picker attached to an input field or division.
2571 @param target element - the target input field or division or span
2572 @param name object - the new settings to update or
2573 string - the name of the setting to change or retrieve,
2574 when retrieving also 'all' for all instance settings or
2575 'defaults' for all global defaults
2576 @param value any - the new value for the setting
2577 (omit if above is an object or to retrieve a value) */
2578 _optionDatepicker: function(target, name, value) {
2579 var inst = this._getInst(target);
2580 if (arguments.length == 2 && typeof name == 'string') {
2581 return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
2582 (inst ? (name == 'all' ? $.extend({}, inst.settings) :
2583 this._get(inst, name)) : null));
2584 }
2585 var settings = name || {};
2586 if (typeof name == 'string') {
2587 settings = {};
2588 settings[name] = value;
2589 }
2590 if (inst) {
2591 if (this._curInst == inst) {
2592 this._hideDatepicker();
2593 }
2594 var date = this._getDateDatepicker(target, true);
2595 var minDate = this._getMinMaxDate(inst, 'min');
2596 var maxDate = this._getMinMaxDate(inst, 'max');
2597 extendRemove(inst.settings, settings);
2598 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
2599 if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
2600 inst.settings.minDate = this._formatDate(inst, minDate);
2601 if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
2602 inst.settings.maxDate = this._formatDate(inst, maxDate);
2603 this._attachments($(target), inst);
2604 this._autoSize(inst);
2605 this._setDate(inst, date);
2606 this._updateAlternate(inst);
2607 this._updateDatepicker(inst);
2608 }
2609 },
2610
2611 // change method deprecated
2612 _changeDatepicker: function(target, name, value) {
2613 this._optionDatepicker(target, name, value);
2614 },
2615
2616 /* Redraw the date picker attached to an input field or division.
2617 @param target element - the target input field or division or span */
2618 _refreshDatepicker: function(target) {
2619 var inst = this._getInst(target);
2620 if (inst) {
2621 this._updateDatepicker(inst);
2622 }
2623 },
2624
2625 /* Set the dates for a jQuery selection.
2626 @param target element - the target input field or division or span
2627 @param date Date - the new date */
2628 _setDateDatepicker: function(target, date) {
2629 var inst = this._getInst(target);
2630 if (inst) {
2631 this._setDate(inst, date);
2632 this._updateDatepicker(inst);
2633 this._updateAlternate(inst);
2634 }
2635 },
2636
2637 /* Get the date(s) for the first entry in a jQuery selection.
2638 @param target element - the target input field or division or span
2639 @param noDefault boolean - true if no default date is to be used
2640 @return Date - the current date */
2641 _getDateDatepicker: function(target, noDefault) {
2642 var inst = this._getInst(target);
2643 if (inst && !inst.inline)
2644 this._setDateFromField(inst, noDefault);
2645 return (inst ? this._getDate(inst) : null);
2646 },
2647
2648 /* Handle keystrokes. */
2649 _doKeyDown: function(event) {
2650 var inst = $.datepicker._getInst(event.target);
2651 var handled = true;
2652 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
2653 inst._keyEvent = true;
2654 if ($.datepicker._datepickerShowing)
2655 switch (event.keyCode) {
2656 case 9: $.datepicker._hideDatepicker();
2657 handled = false;
2658 break; // hide on tab out
2659 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
2660 $.datepicker._currentClass + ')', inst.dpDiv);
2661 if (sel[0])
2662 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
2663 var onSelect = $.datepicker._get(inst, 'onSelect');
2664 if (onSelect) {
2665 var dateStr = $.datepicker._formatDate(inst);
2666
2667 // trigger custom callback
2668 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
2669 }
2670 else
2671 $.datepicker._hideDatepicker();
2672 return false; // don't submit the form
2673 break; // select the value on enter
2674 case 27: $.datepicker._hideDatepicker();
2675 break; // hide on escape
2676 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
2677 -$.datepicker._get(inst, 'stepBigMonths') :
2678 -$.datepicker._get(inst, 'stepMonths')), 'M');
2679 break; // previous month/year on page up/+ ctrl
2680 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
2681 +$.datepicker._get(inst, 'stepBigMonths') :
2682 +$.datepicker._get(inst, 'stepMonths')), 'M');
2683 break; // next month/year on page down/+ ctrl
2684 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
2685 handled = event.ctrlKey || event.metaKey;
2686 break; // clear on ctrl or command +end
2687 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
2688 handled = event.ctrlKey || event.metaKey;
2689 break; // current on ctrl or command +home
2690 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
2691 handled = event.ctrlKey || event.metaKey;
2692 // -1 day on ctrl or command +left
2693 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
2694 -$.datepicker._get(inst, 'stepBigMonths') :
2695 -$.datepicker._get(inst, 'stepMonths')), 'M');
2696 // next month/year on alt +left on Mac
2697 break;
2698 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
2699 handled = event.ctrlKey || event.metaKey;
2700 break; // -1 week on ctrl or command +up
2701 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
2702 handled = event.ctrlKey || event.metaKey;
2703 // +1 day on ctrl or command +right
2704 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
2705 +$.datepicker._get(inst, 'stepBigMonths') :
2706 +$.datepicker._get(inst, 'stepMonths')), 'M');
2707 // next month/year on alt +right
2708 break;
2709 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
2710 handled = event.ctrlKey || event.metaKey;
2711 break; // +1 week on ctrl or command +down
2712 default: handled = false;
2713 }
2714 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
2715 $.datepicker._showDatepicker(this);
2716 else {
2717 handled = false;
2718 }
2719 if (handled) {
2720 event.preventDefault();
2721 event.stopPropagation();
2722 }
2723 },
2724
2725 /* Filter entered characters - based on date format. */
2726 _doKeyPress: function(event) {
2727 var inst = $.datepicker._getInst(event.target);
2728 if ($.datepicker._get(inst, 'constrainInput')) {
2729 var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
2730 var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
2731 return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
2732 }
2733 },
2734
2735 /* Synchronise manual entry and field/alternate field. */
2736 _doKeyUp: function(event) {
2737 var inst = $.datepicker._getInst(event.target);
2738 if (inst.input.val() != inst.lastVal) {
2739 try {
2740 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
2741 (inst.input ? inst.input.val() : null),
2742 $.datepicker._getFormatConfig(inst));
2743 if (date) { // only if valid
2744 $.datepicker._setDateFromField(inst);
2745 $.datepicker._updateAlternate(inst);
2746 $.datepicker._updateDatepicker(inst);
2747 }
2748 }
2749 catch (err) {
2750 $.datepicker.log(err);
2751 }
2752 }
2753 return true;
2754 },
2755
2756 /* Pop-up the date picker for a given input field.
2757 If false returned from beforeShow event handler do not show.
2758 @param input element - the input field attached to the date picker or
2759 event - if triggered by focus */
2760 _showDatepicker: function(input) {
2761 input = input.target || input;
2762 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
2763 input = $('input', input.parentNode)[0];
2764 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
2765 return;
2766 var inst = $.datepicker._getInst(input);
2767 if ($.datepicker._curInst && $.datepicker._curInst != inst) {
2768 $.datepicker._curInst.dpDiv.stop(true, true);
2769 if ( inst && $.datepicker._datepickerShowing ) {
2770 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
2771 }
2772 }
2773 var beforeShow = $.datepicker._get(inst, 'beforeShow');
2774 var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
2775 if(beforeShowSettings === false){
2776 //false
2777 return;
2778 }
2779 extendRemove(inst.settings, beforeShowSettings);
2780 inst.lastVal = null;
2781 $.datepicker._lastInput = input;
2782 $.datepicker._setDateFromField(inst);
2783 if ($.datepicker._inDialog) // hide cursor
2784 input.value = '';
2785 if (!$.datepicker._pos) { // position below input
2786 $.datepicker._pos = $.datepicker._findPos(input);
2787 $.datepicker._pos[1] += input.offsetHeight; // add the height
2788 }
2789 var isFixed = false;
2790 $(input).parents().each(function() {
2791 isFixed |= $(this).css('position') == 'fixed';
2792 return !isFixed;
2793 });
2794 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
2795 $.datepicker._pos = null;
2796 //to avoid flashes on Firefox
2797 inst.dpDiv.empty();
2798 // determine sizing offscreen
2799 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
2800 $.datepicker._updateDatepicker(inst);
2801 // fix width for dynamic number of date pickers
2802 // and adjust position before showing
2803 offset = $.datepicker._checkOffset(inst, offset, isFixed);
2804 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
2805 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
2806 left: offset.left + 'px', top: offset.top + 'px'});
2807 if (!inst.inline) {
2808 var showAnim = $.datepicker._get(inst, 'showAnim');
2809 var duration = $.datepicker._get(inst, 'duration');
2810 var postProcess = function() {
2811 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
2812 if( !! cover.length ){
2813 var borders = $.datepicker._getBorders(inst.dpDiv);
2814 cover.css({left: -borders[0], top: -borders[1],
2815 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
2816 }
2817 };
2818 inst.dpDiv.zIndex($(input).zIndex()+1);
2819 $.datepicker._datepickerShowing = true;
2820
2821 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
2822 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
2823 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
2824 else
2825 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
2826 if (!showAnim || !duration)
2827 postProcess();
2828 if (inst.input.is(':visible') && !inst.input.is(':disabled'))
2829 inst.input.focus();
2830 $.datepicker._curInst = inst;
2831 }
2832 },
2833
2834 /* Generate the date picker content. */
2835 _updateDatepicker: function(inst) {
2836 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
2837 var borders = $.datepicker._getBorders(inst.dpDiv);
2838 instActive = inst; // for delegate hover events
2839 inst.dpDiv.empty().append(this._generateHTML(inst));
2840 this._attachHandlers(inst);
2841 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
2842 if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
2843 cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
2844 }
2845 inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
2846 var numMonths = this._getNumberOfMonths(inst);
2847 var cols = numMonths[1];
2848 var width = 17;
2849 inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
2850 if (cols > 1)
2851 inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
2852 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
2853 'Class']('ui-datepicker-multi');
2854 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
2855 'Class']('ui-datepicker-rtl');
2856 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
2857 // #6694 - don't focus the input if it's already focused
2858 // this breaks the change event in IE
2859 inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
2860 inst.input.focus();
2861 // deffered render of the years select (to avoid flashes on Firefox)
2862 if( inst.yearshtml ){
2863 var origyearshtml = inst.yearshtml;
2864 setTimeout(function(){
2865 //assure that inst.yearshtml didn't change.
2866 if( origyearshtml === inst.yearshtml && inst.yearshtml ){
2867 inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
2868 }
2869 origyearshtml = inst.yearshtml = null;
2870 }, 0);
2871 }
2872 },
2873
2874 /* Retrieve the size of left and top borders for an element.
2875 @param elem (jQuery object) the element of interest
2876 @return (number[2]) the left and top borders */
2877 _getBorders: function(elem) {
2878 var convert = function(value) {
2879 return {thin: 1, medium: 2, thick: 3}[value] || value;
2880 };
2881 return [parseFloat(convert(elem.css('border-left-width'))),
2882 parseFloat(convert(elem.css('border-top-width')))];
2883 },
2884
2885 /* Check positioning to remain on screen. */
2886 _checkOffset: function(inst, offset, isFixed) {
2887 var dpWidth = inst.dpDiv.outerWidth();
2888 var dpHeight = inst.dpDiv.outerHeight();
2889 var inputWidth = inst.input ? inst.input.outerWidth() : 0;
2890 var inputHeight = inst.input ? inst.input.outerHeight() : 0;
2891 var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft());
2892 var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
2893
2894 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
2895 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
2896 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
2897
2898 // now check if datepicker is showing outside window viewport - move to a better place if so.
2899 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
2900 Math.abs(offset.left + dpWidth - viewWidth) : 0);
2901 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
2902 Math.abs(dpHeight + inputHeight) : 0);
2903
2904 return offset;
2905 },
2906
2907 /* Find an object's position on the screen. */
2908 _findPos: function(obj) {
2909 var inst = this._getInst(obj);
2910 var isRTL = this._get(inst, 'isRTL');
2911 while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
2912 obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
2913 }
2914 var position = $(obj).offset();
2915 return [position.left, position.top];
2916 },
2917
2918 /* Hide the date picker from view.
2919 @param input element - the input field attached to the date picker */
2920 _hideDatepicker: function(input) {
2921 var inst = this._curInst;
2922 if (!inst || (input && inst != $.data(input, PROP_NAME)))
2923 return;
2924 if (this._datepickerShowing) {
2925 var showAnim = this._get(inst, 'showAnim');
2926 var duration = this._get(inst, 'duration');
2927 var postProcess = function() {
2928 $.datepicker._tidyDialog(inst);
2929 };
2930
2931 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
2932 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
2933 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
2934 else
2935 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
2936 (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
2937 if (!showAnim)
2938 postProcess();
2939 this._datepickerShowing = false;
2940 var onClose = this._get(inst, 'onClose');
2941 if (onClose)
2942 onClose.apply((inst.input ? inst.input[0] : null),
2943 [(inst.input ? inst.input.val() : ''), inst]);
2944 this._lastInput = null;
2945 if (this._inDialog) {
2946 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
2947 if ($.blockUI) {
2948 $.unblockUI();
2949 $('body').append(this.dpDiv);
2950 }
2951 }
2952 this._inDialog = false;
2953 }
2954 },
2955
2956 /* Tidy up after a dialog display. */
2957 _tidyDialog: function(inst) {
2958 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
2959 },
2960
2961 /* Close date picker if clicked elsewhere. */
2962 _checkExternalClick: function(event) {
2963 if (!$.datepicker._curInst)
2964 return;
2965
2966 var $target = $(event.target),
2967 inst = $.datepicker._getInst($target[0]);
2968
2969 if ( ( ( $target[0].id != $.datepicker._mainDivId &&
2970 $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
2971 !$target.hasClass($.datepicker.markerClassName) &&
2972 !$target.closest("." + $.datepicker._triggerClass).length &&
2973 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
2974 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
2975 $.datepicker._hideDatepicker();
2976 },
2977
2978 /* Adjust one of the date sub-fields. */
2979 _adjustDate: function(id, offset, period) {
2980 var target = $(id);
2981 var inst = this._getInst(target[0]);
2982 if (this._isDisabledDatepicker(target[0])) {
2983 return;
2984 }
2985 this._adjustInstDate(inst, offset +
2986 (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
2987 period);
2988 this._updateDatepicker(inst);
2989 },
2990
2991 /* Action for current link. */
2992 _gotoToday: function(id) {
2993 var target = $(id);
2994 var inst = this._getInst(target[0]);
2995 if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
2996 inst.selectedDay = inst.currentDay;
2997 inst.drawMonth = inst.selectedMonth = inst.currentMonth;
2998 inst.drawYear = inst.selectedYear = inst.currentYear;
2999 }
3000 else {
3001 var date = new Date();
3002 inst.selectedDay = date.getDate();
3003 inst.drawMonth = inst.selectedMonth = date.getMonth();
3004 inst.drawYear = inst.selectedYear = date.getFullYear();
3005 }
3006 this._notifyChange(inst);
3007 this._adjustDate(target);
3008 },
3009
3010 /* Action for selecting a new month/year. */
3011 _selectMonthYear: function(id, select, period) {
3012 var target = $(id);
3013 var inst = this._getInst(target[0]);
3014 inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
3015 inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
3016 parseInt(select.options[select.selectedIndex].value,10);
3017 this._notifyChange(inst);
3018 this._adjustDate(target);
3019 },
3020
3021 /* Action for selecting a day. */
3022 _selectDay: function(id, month, year, td) {
3023 var target = $(id);
3024 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
3025 return;
3026 }
3027 var inst = this._getInst(target[0]);
3028 inst.selectedDay = inst.currentDay = $('a', td).html();
3029 inst.selectedMonth = inst.currentMonth = month;
3030 inst.selectedYear = inst.currentYear = year;
3031 this._selectDate(id, this._formatDate(inst,
3032 inst.currentDay, inst.currentMonth, inst.currentYear));
3033 },
3034
3035 /* Erase the input field and hide the date picker. */
3036 _clearDate: function(id) {
3037 var target = $(id);
3038 var inst = this._getInst(target[0]);
3039 this._selectDate(target, '');
3040 },
3041
3042 /* Update the input field with the selected date. */
3043 _selectDate: function(id, dateStr) {
3044 var target = $(id);
3045 var inst = this._getInst(target[0]);
3046 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
3047 if (inst.input)
3048 inst.input.val(dateStr);
3049 this._updateAlternate(inst);
3050 var onSelect = this._get(inst, 'onSelect');
3051 if (onSelect)
3052 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
3053 else if (inst.input)
3054 inst.input.trigger('change'); // fire the change event
3055 if (inst.inline)
3056 this._updateDatepicker(inst);
3057 else {
3058 this._hideDatepicker();
3059 this._lastInput = inst.input[0];
3060 if (typeof(inst.input[0]) != 'object')
3061 inst.input.focus(); // restore focus
3062 this._lastInput = null;
3063 }
3064 },
3065
3066 /* Update any alternate field to synchronise with the main field. */
3067 _updateAlternate: function(inst) {
3068 var altField = this._get(inst, 'altField');
3069 if (altField) { // update alternate field too
3070 var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
3071 var date = this._getDate(inst);
3072 var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
3073 $(altField).each(function() { $(this).val(dateStr); });
3074 }
3075 },
3076
3077 /* Set as beforeShowDay function to prevent selection of weekends.
3078 @param date Date - the date to customise
3079 @return [boolean, string] - is this date selectable?, what is its CSS class? */
3080 noWeekends: function(date) {
3081 var day = date.getDay();
3082 return [(day > 0 && day < 6), ''];
3083 },
3084
3085 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
3086 @param date Date - the date to get the week for
3087 @return number - the number of the week within the year that contains this date */
3088 iso8601Week: function(date) {
3089 var checkDate = new Date(date.getTime());
3090 // Find Thursday of this week starting on Monday
3091 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
3092 var time = checkDate.getTime();
3093 checkDate.setMonth(0); // Compare with Jan 1
3094 checkDate.setDate(1);
3095 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
3096 },
3097
3098 /* Parse a string value into a date object.
3099 See formatDate below for the possible formats.
3100
3101 @param format string - the expected format of the date
3102 @param value string - the date in the above format
3103 @param settings Object - attributes include:
3104 shortYearCutoff number - the cutoff year for determining the century (optional)
3105 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
3106 dayNames string[7] - names of the days from Sunday (optional)
3107 monthNamesShort string[12] - abbreviated names of the months (optional)
3108 monthNames string[12] - names of the months (optional)
3109 @return Date - the extracted date value or null if value is blank */
3110 parseDate: function (format, value, settings) {
3111 if (format == null || value == null)
3112 throw 'Invalid arguments';
3113 value = (typeof value == 'object' ? value.toString() : value + '');
3114 if (value == '')
3115 return null;
3116 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
3117 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
3118 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
3119 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
3120 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
3121 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
3122 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
3123 var year = -1;
3124 var month = -1;
3125 var day = -1;
3126 var doy = -1;
3127 var literal = false;
3128 // Check whether a format character is doubled
3129 var lookAhead = function(match) {
3130 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
3131 if (matches)
3132 iFormat++;
3133 return matches;
3134 };
3135 // Extract a number from the string value
3136 var getNumber = function(match) {
3137 var isDoubled = lookAhead(match);
3138 var size = (match == '@' ? 14 : (match == '!' ? 20 :
3139 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
3140 var digits = new RegExp('^\\d{1,' + size + '}');
3141 var num = value.substring(iValue).match(digits);
3142 if (!num)
3143 throw 'Missing number at position ' + iValue;
3144 iValue += num[0].length;
3145 return parseInt(num[0], 10);
3146 };
3147 // Extract a name from the string value and convert to an index
3148 var getName = function(match, shortNames, longNames) {
3149 var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
3150 return [ [k, v] ];
3151 }).sort(function (a, b) {
3152 return -(a[1].length - b[1].length);
3153 });
3154 var index = -1;
3155 $.each(names, function (i, pair) {
3156 var name = pair[1];
3157 if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
3158 index = pair[0];
3159 iValue += name.length;
3160 return false;
3161 }
3162 });
3163 if (index != -1)
3164 return index + 1;
3165 else
3166 throw 'Unknown name at position ' + iValue;
3167 };
3168 // Confirm that a literal character matches the string value
3169 var checkLiteral = function() {
3170 if (value.charAt(iValue) != format.charAt(iFormat))
3171 throw 'Unexpected literal at position ' + iValue;
3172 iValue++;
3173 };
3174 var iValue = 0;
3175 for (var iFormat = 0; iFormat < format.length; iFormat++) {
3176 if (literal)
3177 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
3178 literal = false;
3179 else
3180 checkLiteral();
3181 else
3182 switch (format.charAt(iFormat)) {
3183 case 'd':
3184 day = getNumber('d');
3185 break;
3186 case 'D':
3187 getName('D', dayNamesShort, dayNames);
3188 break;
3189 case 'o':
3190 doy = getNumber('o');
3191 break;
3192 case 'm':
3193 month = getNumber('m');
3194 break;
3195 case 'M':
3196 month = getName('M', monthNamesShort, monthNames);
3197 break;
3198 case 'y':
3199 year = getNumber('y');
3200 break;
3201 case '@':
3202 var date = new Date(getNumber('@'));
3203 year = date.getFullYear();
3204 month = date.getMonth() + 1;
3205 day = date.getDate();
3206 break;
3207 case '!':
3208 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
3209 year = date.getFullYear();
3210 month = date.getMonth() + 1;
3211 day = date.getDate();
3212 break;
3213 case "'":
3214 if (lookAhead("'"))
3215 checkLiteral();
3216 else
3217 literal = true;
3218 break;
3219 default:
3220 checkLiteral();
3221 }
3222 }
3223 if (iValue < value.length){
3224 var extra = value.substr(iValue);
3225 if (!/^\s+/.test(extra)) {
3226 throw "Extra/unparsed characters found in date: " + extra;
3227 }
3228 }
3229 if (year == -1)
3230 year = new Date().getFullYear();
3231 else if (year < 100)
3232 year += new Date().getFullYear() - new Date().getFullYear() % 100 +
3233 (year <= shortYearCutoff ? 0 : -100);
3234 if (doy > -1) {
3235 month = 1;
3236 day = doy;
3237 do {
3238 var dim = this._getDaysInMonth(year, month - 1);
3239 if (day <= dim)
3240 break;
3241 month++;
3242 day -= dim;
3243 } while (true);
3244 }
3245 var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
3246 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
3247 throw 'Invalid date'; // E.g. 31/02/00
3248 return date;
3249 },
3250
3251 /* Standard date formats. */
3252 ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
3253 COOKIE: 'D, dd M yy',
3254 ISO_8601: 'yy-mm-dd',
3255 RFC_822: 'D, d M y',
3256 RFC_850: 'DD, dd-M-y',
3257 RFC_1036: 'D, d M y',
3258 RFC_1123: 'D, d M yy',
3259 RFC_2822: 'D, d M yy',
3260 RSS: 'D, d M y', // RFC 822
3261 TICKS: '!',
3262 TIMESTAMP: '@',
3263 W3C: 'yy-mm-dd', // ISO 8601
3264
3265 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
3266 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
3267
3268 /* Format a date object into a string value.
3269 The format can be combinations of the following:
3270 d - day of month (no leading zero)
3271 dd - day of month (two digit)
3272 o - day of year (no leading zeros)
3273 oo - day of year (three digit)
3274 D - day name short
3275 DD - day name long
3276 m - month of year (no leading zero)
3277 mm - month of year (two digit)
3278 M - month name short
3279 MM - month name long
3280 y - year (two digit)
3281 yy - year (four digit)
3282 @ - Unix timestamp (ms since 01/01/1970)
3283 ! - Windows ticks (100ns since 01/01/0001)
3284 '...' - literal text
3285 '' - single quote
3286
3287 @param format string - the desired format of the date
3288 @param date Date - the date value to format
3289 @param settings Object - attributes include:
3290 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
3291 dayNames string[7] - names of the days from Sunday (optional)
3292 monthNamesShort string[12] - abbreviated names of the months (optional)
3293 monthNames string[12] - names of the months (optional)
3294 @return string - the date in the above format */
3295 formatDate: function (format, date, settings) {
3296 if (!date)
3297 return '';
3298 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
3299 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
3300 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
3301 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
3302 // Check whether a format character is doubled
3303 var lookAhead = function(match) {
3304 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
3305 if (matches)
3306 iFormat++;
3307 return matches;
3308 };
3309 // Format a number, with leading zero if necessary
3310 var formatNumber = function(match, value, len) {
3311 var num = '' + value;
3312 if (lookAhead(match))
3313 while (num.length < len)
3314 num = '0' + num;
3315 return num;
3316 };
3317 // Format a name, short or long as requested
3318 var formatName = function(match, value, shortNames, longNames) {
3319 return (lookAhead(match) ? longNames[value] : shortNames[value]);
3320 };
3321 var output = '';
3322 var literal = false;
3323 if (date)
3324 for (var iFormat = 0; iFormat < format.length; iFormat++) {
3325 if (literal)
3326 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
3327 literal = false;
3328 else
3329 output += format.charAt(iFormat);
3330 else
3331 switch (format.charAt(iFormat)) {
3332 case 'd':
3333 output += formatNumber('d', date.getDate(), 2);
3334 break;
3335 case 'D':
3336 output += formatName('D', date.getDay(), dayNamesShort, dayNames);
3337 break;
3338 case 'o':
3339 output += formatNumber('o',
3340 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
3341 break;
3342 case 'm':
3343 output += formatNumber('m', date.getMonth() + 1, 2);
3344 break;
3345 case 'M':
3346 output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
3347 break;
3348 case 'y':
3349 output += (lookAhead('y') ? date.getFullYear() :
3350 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
3351 break;
3352 case '@':
3353 output += date.getTime();
3354 break;
3355 case '!':
3356 output += date.getTime() * 10000 + this._ticksTo1970;
3357 break;
3358 case "'":
3359 if (lookAhead("'"))
3360 output += "'";
3361 else
3362 literal = true;
3363 break;
3364 default:
3365 output += format.charAt(iFormat);
3366 }
3367 }
3368 return output;
3369 },
3370
3371 /* Extract all possible characters from the date format. */
3372 _possibleChars: function (format) {
3373 var chars = '';
3374 var literal = false;
3375 // Check whether a format character is doubled
3376 var lookAhead = function(match) {
3377 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
3378 if (matches)
3379 iFormat++;
3380 return matches;
3381 };
3382 for (var iFormat = 0; iFormat < format.length; iFormat++)
3383 if (literal)
3384 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
3385 literal = false;
3386 else
3387 chars += format.charAt(iFormat);
3388 else
3389 switch (format.charAt(iFormat)) {
3390 case 'd': case 'm': case 'y': case '@':
3391 chars += '0123456789';
3392 break;
3393 case 'D': case 'M':
3394 return null; // Accept anything
3395 case "'":
3396 if (lookAhead("'"))
3397 chars += "'";
3398 else
3399 literal = true;
3400 break;
3401 default:
3402 chars += format.charAt(iFormat);
3403 }
3404 return chars;
3405 },
3406
3407 /* Get a setting value, defaulting if necessary. */
3408 _get: function(inst, name) {
3409 return inst.settings[name] !== undefined ?
3410 inst.settings[name] : this._defaults[name];
3411 },
3412
3413 /* Parse existing date and initialise date picker. */
3414 _setDateFromField: function(inst, noDefault) {
3415 if (inst.input.val() == inst.lastVal) {
3416 return;
3417 }
3418 var dateFormat = this._get(inst, 'dateFormat');
3419 var dates = inst.lastVal = inst.input ? inst.input.val() : null;
3420 var date, defaultDate;
3421 date = defaultDate = this._getDefaultDate(inst);
3422 var settings = this._getFormatConfig(inst);
3423 try {
3424 date = this.parseDate(dateFormat, dates, settings) || defaultDate;
3425 } catch (event) {
3426 this.log(event);
3427 dates = (noDefault ? '' : dates);
3428 }
3429 inst.selectedDay = date.getDate();
3430 inst.drawMonth = inst.selectedMonth = date.getMonth();
3431 inst.drawYear = inst.selectedYear = date.getFullYear();
3432 inst.currentDay = (dates ? date.getDate() : 0);
3433 inst.currentMonth = (dates ? date.getMonth() : 0);
3434 inst.currentYear = (dates ? date.getFullYear() : 0);
3435 this._adjustInstDate(inst);
3436 },
3437
3438 /* Retrieve the default date shown on opening. */
3439 _getDefaultDate: function(inst) {
3440 return this._restrictMinMax(inst,
3441 this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
3442 },
3443
3444 /* A date may be specified as an exact value or a relative one. */
3445 _determineDate: function(inst, date, defaultDate) {
3446 var offsetNumeric = function(offset) {
3447 var date = new Date();
3448 date.setDate(date.getDate() + offset);
3449 return date;
3450 };
3451 var offsetString = function(offset) {
3452 try {
3453 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
3454 offset, $.datepicker._getFormatConfig(inst));
3455 }
3456 catch (e) {
3457 // Ignore
3458 }
3459 var date = (offset.toLowerCase().match(/^c/) ?
3460 $.datepicker._getDate(inst) : null) || new Date();
3461 var year = date.getFullYear();
3462 var month = date.getMonth();
3463 var day = date.getDate();
3464 var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
3465 var matches = pattern.exec(offset);
3466 while (matches) {
3467 switch (matches[2] || 'd') {
3468 case 'd' : case 'D' :
3469 day += parseInt(matches[1],10); break;
3470 case 'w' : case 'W' :
3471 day += parseInt(matches[1],10) * 7; break;
3472 case 'm' : case 'M' :
3473 month += parseInt(matches[1],10);
3474 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
3475 break;
3476 case 'y': case 'Y' :
3477 year += parseInt(matches[1],10);
3478 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
3479 break;
3480 }
3481 matches = pattern.exec(offset);
3482 }
3483 return new Date(year, month, day);
3484 };
3485 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
3486 (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
3487 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
3488 if (newDate) {
3489 newDate.setHours(0);
3490 newDate.setMinutes(0);
3491 newDate.setSeconds(0);
3492 newDate.setMilliseconds(0);
3493 }
3494 return this._daylightSavingAdjust(newDate);
3495 },
3496
3497 /* Handle switch to/from daylight saving.
3498 Hours may be non-zero on daylight saving cut-over:
3499 > 12 when midnight changeover, but then cannot generate
3500 midnight datetime, so jump to 1AM, otherwise reset.
3501 @param date (Date) the date to check
3502 @return (Date) the corrected date */
3503 _daylightSavingAdjust: function(date) {
3504 if (!date) return null;
3505 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
3506 return date;
3507 },
3508
3509 /* Set the date(s) directly. */
3510 _setDate: function(inst, date, noChange) {
3511 var clear = !date;
3512 var origMonth = inst.selectedMonth;
3513 var origYear = inst.selectedYear;
3514 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
3515 inst.selectedDay = inst.currentDay = newDate.getDate();
3516 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
3517 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
3518 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
3519 this._notifyChange(inst);
3520 this._adjustInstDate(inst);
3521 if (inst.input) {
3522 inst.input.val(clear ? '' : this._formatDate(inst));
3523 }
3524 },
3525
3526 /* Retrieve the date(s) directly. */
3527 _getDate: function(inst) {
3528 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
3529 this._daylightSavingAdjust(new Date(
3530 inst.currentYear, inst.currentMonth, inst.currentDay)));
3531 return startDate;
3532 },
3533
3534 /* Attach the onxxx handlers. These are declared statically so
3535 * they work with static code transformers like Caja.
3536 */
3537 _attachHandlers: function(inst) {
3538 var stepMonths = this._get(inst, 'stepMonths');
3539 var id = '#' + inst.id.replace( /\\\\/g, "\\" );
3540 inst.dpDiv.find('[data-handler]').map(function () {
3541 var handler = {
3542 prev: function () {
3543 window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M');
3544 },
3545 next: function () {
3546 window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M');
3547 },
3548 hide: function () {
3549 window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker();
3550 },
3551 today: function () {
3552 window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id);
3553 },
3554 selectDay: function () {
3555 window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this);
3556 return false;
3557 },
3558 selectMonth: function () {
3559 window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M');
3560 return false;
3561 },
3562 selectYear: function () {
3563 window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y');
3564 return false;
3565 }
3566 };
3567 $(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]);
3568 });
3569 },
3570
3571 /* Generate the HTML for the current state of the date picker. */
3572 _generateHTML: function(inst) {
3573 var today = new Date();
3574 today = this._daylightSavingAdjust(
3575 new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
3576 var isRTL = this._get(inst, 'isRTL');
3577 var showButtonPanel = this._get(inst, 'showButtonPanel');
3578 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
3579 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
3580 var numMonths = this._getNumberOfMonths(inst);
3581 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
3582 var stepMonths = this._get(inst, 'stepMonths');
3583 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
3584 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
3585 new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
3586 var minDate = this._getMinMaxDate(inst, 'min');
3587 var maxDate = this._getMinMaxDate(inst, 'max');
3588 var drawMonth = inst.drawMonth - showCurrentAtPos;
3589 var drawYear = inst.drawYear;
3590 if (drawMonth < 0) {
3591 drawMonth += 12;
3592 drawYear--;
3593 }
3594 if (maxDate) {
3595 var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
3596 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
3597 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
3598 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
3599 drawMonth--;
3600 if (drawMonth < 0) {
3601 drawMonth = 11;
3602 drawYear--;
3603 }
3604 }
3605 }
3606 inst.drawMonth = drawMonth;
3607 inst.drawYear = drawYear;
3608 var prevText = this._get(inst, 'prevText');
3609 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
3610 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
3611 this._getFormatConfig(inst)));
3612 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
3613 '<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' +
3614 ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
3615 (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
3616 var nextText = this._get(inst, 'nextText');
3617 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
3618 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
3619 this._getFormatConfig(inst)));
3620 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
3621 '<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' +
3622 ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
3623 (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
3624 var currentText = this._get(inst, 'currentText');
3625 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
3626 currentText = (!navigationAsDateFormat ? currentText :
3627 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
3628 var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" data-handler="hide" data-event="click">' +
3629 this._get(inst, 'closeText') + '</button>' : '');
3630 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
3631 (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" data-handler="today" data-event="click"' +
3632 '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
3633 var firstDay = parseInt(this._get(inst, 'firstDay'),10);
3634 firstDay = (isNaN(firstDay) ? 0 : firstDay);
3635 var showWeek = this._get(inst, 'showWeek');
3636 var dayNames = this._get(inst, 'dayNames');
3637 var dayNamesShort = this._get(inst, 'dayNamesShort');
3638 var dayNamesMin = this._get(inst, 'dayNamesMin');
3639 var monthNames = this._get(inst, 'monthNames');
3640 var monthNamesShort = this._get(inst, 'monthNamesShort');
3641 var beforeShowDay = this._get(inst, 'beforeShowDay');
3642 var showOtherMonths = this._get(inst, 'showOtherMonths');
3643 var selectOtherMonths = this._get(inst, 'selectOtherMonths');
3644 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
3645 var defaultDate = this._getDefaultDate(inst);
3646 var html = '';
3647 for (var row = 0; row < numMonths[0]; row++) {
3648 var group = '';
3649 this.maxRows = 4;
3650 for (var col = 0; col < numMonths[1]; col++) {
3651 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
3652 var cornerClass = ' ui-corner-all';
3653 var calender = '';
3654 if (isMultiMonth) {
3655 calender += '<div class="ui-datepicker-group';
3656 if (numMonths[1] > 1)
3657 switch (col) {
3658 case 0: calender += ' ui-datepicker-group-first';
3659 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
3660 case numMonths[1]-1: calender += ' ui-datepicker-group-last';
3661 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
3662 default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
3663 }
3664 calender += '">';
3665 }
3666 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
3667 (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
3668 (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
3669 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
3670 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
3671 '</div><table class="ui-datepicker-calendar"><thead>' +
3672 '<tr>';
3673 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
3674 for (var dow = 0; dow < 7; dow++) { // days of the week
3675 var day = (dow + firstDay) % 7;
3676 thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
3677 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
3678 }
3679 calender += thead + '</tr></thead><tbody>';
3680 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
3681 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
3682 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
3683 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
3684 var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
3685 var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
3686 this.maxRows = numRows;
3687 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
3688 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
3689 calender += '<tr>';
3690 var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
3691 this._get(inst, 'calculateWeek')(printDate) + '</td>');
3692 for (var dow = 0; dow < 7; dow++) { // create date picker days
3693 var daySettings = (beforeShowDay ?
3694 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
3695 var otherMonth = (printDate.getMonth() != drawMonth);
3696 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
3697 (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
3698 tbody += '<td class="' +
3699 ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
3700 (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
3701 ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
3702 (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
3703 // or defaultDate is current printedDate and defaultDate is selectedDate
3704 ' ' + this._dayOverClass : '') + // highlight selected day
3705 (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days
3706 (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
3707 (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
3708 (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
3709 ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
3710 (unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions
3711 (otherMonth && !showOtherMonths ? ' ' : // display for other months
3712 (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
3713 (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
3714 (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
3715 (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
3716 '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
3717 printDate.setDate(printDate.getDate() + 1);
3718 printDate = this._daylightSavingAdjust(printDate);
3719 }
3720 calender += tbody + '</tr>';
3721 }
3722 drawMonth++;
3723 if (drawMonth > 11) {
3724 drawMonth = 0;
3725 drawYear++;
3726 }
3727 calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
3728 ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
3729 group += calender;
3730 }
3731 html += group;
3732 }
3733 html += buttonPanel + ($.ui.ie6 && !inst.inline ?
3734 '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
3735 inst._keyEvent = false;
3736 return html;
3737 },
3738
3739 /* Generate the month and year header. */
3740 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
3741 secondary, monthNames, monthNamesShort) {
3742 var changeMonth = this._get(inst, 'changeMonth');
3743 var changeYear = this._get(inst, 'changeYear');
3744 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
3745 var html = '<div class="ui-datepicker-title">';
3746 var monthHtml = '';
3747 // month selection
3748 if (secondary || !changeMonth)
3749 monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
3750 else {
3751 var inMinYear = (minDate && minDate.getFullYear() == drawYear);
3752 var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
3753 monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
3754 for (var month = 0; month < 12; month++) {
3755 if ((!inMinYear || month >= minDate.getMonth()) &&
3756 (!inMaxYear || month <= maxDate.getMonth()))
3757 monthHtml += '<option value="' + month + '"' +
3758 (month == drawMonth ? ' selected="selected"' : '') +
3759 '>' + monthNamesShort[month] + '</option>';
3760 }
3761 monthHtml += '</select>';
3762 }
3763 if (!showMonthAfterYear)
3764 html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : '');
3765 // year selection
3766 if ( !inst.yearshtml ) {
3767 inst.yearshtml = '';
3768 if (secondary || !changeYear)
3769 html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
3770 else {
3771 // determine range of years to display
3772 var years = this._get(inst, 'yearRange').split(':');
3773 var thisYear = new Date().getFullYear();
3774 var determineYear = function(value) {
3775 var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
3776 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
3777 parseInt(value, 10)));
3778 return (isNaN(year) ? thisYear : year);
3779 };
3780 var year = determineYear(years[0]);
3781 var endYear = Math.max(year, determineYear(years[1] || ''));
3782 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
3783 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
3784 inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';
3785 for (; year <= endYear; year++) {
3786 inst.yearshtml += '<option value="' + year + '"' +
3787 (year == drawYear ? ' selected="selected"' : '') +
3788 '>' + year + '</option>';
3789 }
3790 inst.yearshtml += '</select>';
3791
3792 html += inst.yearshtml;
3793 inst.yearshtml = null;
3794 }
3795 }
3796 html += this._get(inst, 'yearSuffix');
3797 if (showMonthAfterYear)
3798 html += (secondary || !(changeMonth && changeYear) ? ' ' : '') + monthHtml;
3799 html += '</div>'; // Close datepicker_header
3800 return html;
3801 },
3802
3803 /* Adjust one of the date sub-fields. */
3804 _adjustInstDate: function(inst, offset, period) {
3805 var year = inst.drawYear + (period == 'Y' ? offset : 0);
3806 var month = inst.drawMonth + (period == 'M' ? offset : 0);
3807 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
3808 (period == 'D' ? offset : 0);
3809 var date = this._restrictMinMax(inst,
3810 this._daylightSavingAdjust(new Date(year, month, day)));
3811 inst.selectedDay = date.getDate();
3812 inst.drawMonth = inst.selectedMonth = date.getMonth();
3813 inst.drawYear = inst.selectedYear = date.getFullYear();
3814 if (period == 'M' || period == 'Y')
3815 this._notifyChange(inst);
3816 },
3817
3818 /* Ensure a date is within any min/max bounds. */
3819 _restrictMinMax: function(inst, date) {
3820 var minDate = this._getMinMaxDate(inst, 'min');
3821 var maxDate = this._getMinMaxDate(inst, 'max');
3822 var newDate = (minDate && date < minDate ? minDate : date);
3823 newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
3824 return newDate;
3825 },
3826
3827 /* Notify change of month/year. */
3828 _notifyChange: function(inst) {
3829 var onChange = this._get(inst, 'onChangeMonthYear');
3830 if (onChange)
3831 onChange.apply((inst.input ? inst.input[0] : null),
3832 [inst.selectedYear, inst.selectedMonth + 1, inst]);
3833 },
3834
3835 /* Determine the number of months to show. */
3836 _getNumberOfMonths: function(inst) {
3837 var numMonths = this._get(inst, 'numberOfMonths');
3838 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
3839 },
3840
3841 /* Determine the current maximum date - ensure no time components are set. */
3842 _getMinMaxDate: function(inst, minMax) {
3843 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
3844 },
3845
3846 /* Find the number of days in a given month. */
3847 _getDaysInMonth: function(year, month) {
3848 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
3849 },
3850
3851 /* Find the day of the week of the first of a month. */
3852 _getFirstDayOfMonth: function(year, month) {
3853 return new Date(year, month, 1).getDay();
3854 },
3855
3856 /* Determines if we should allow a "next/prev" month display change. */
3857 _canAdjustMonth: function(inst, offset, curYear, curMonth) {
3858 var numMonths = this._getNumberOfMonths(inst);
3859 var date = this._daylightSavingAdjust(new Date(curYear,
3860 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
3861 if (offset < 0)
3862 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
3863 return this._isInRange(inst, date);
3864 },
3865
3866 /* Is the given date in the accepted range? */
3867 _isInRange: function(inst, date) {
3868 var minDate = this._getMinMaxDate(inst, 'min');
3869 var maxDate = this._getMinMaxDate(inst, 'max');
3870 return ((!minDate || date.getTime() >= minDate.getTime()) &&
3871 (!maxDate || date.getTime() <= maxDate.getTime()));
3872 },
3873
3874 /* Provide the configuration settings for formatting/parsing. */
3875 _getFormatConfig: function(inst) {
3876 var shortYearCutoff = this._get(inst, 'shortYearCutoff');
3877 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
3878 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
3879 return {shortYearCutoff: shortYearCutoff,
3880 dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
3881 monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
3882 },
3883
3884 /* Format the given date for display. */
3885 _formatDate: function(inst, day, month, year) {
3886 if (!day) {
3887 inst.currentDay = inst.selectedDay;
3888 inst.currentMonth = inst.selectedMonth;
3889 inst.currentYear = inst.selectedYear;
3890 }
3891 var date = (day ? (typeof day == 'object' ? day :
3892 this._daylightSavingAdjust(new Date(year, month, day))) :
3893 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
3894 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
3895 }
3896});
3897
3898/*
3899 * Bind hover events for datepicker elements.
3900 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
3901 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
3902 */
3903function bindHover(dpDiv) {
3904 var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
3905 return dpDiv.delegate(selector, 'mouseout', function() {
3906 $(this).removeClass('ui-state-hover');
3907 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
3908 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
3909 })
3910 .delegate(selector, 'mouseover', function(){
3911 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
3912 $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
3913 $(this).addClass('ui-state-hover');
3914 if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
3915 if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
3916 }
3917 });
3918}
3919
3920/* jQuery extend now ignores nulls! */
3921function extendRemove(target, props) {
3922 $.extend(target, props);
3923 for (var name in props)
3924 if (props[name] == null || props[name] == undefined)
3925 target[name] = props[name];
3926 return target;
3927};
3928
3929/* Invoke the datepicker functionality.
3930 @param options string - a command, optionally followed by additional parameters or
3931 Object - settings for attaching new datepicker functionality
3932 @return jQuery object */
3933$.fn.datepicker = function(options){
3934
3935 /* Verify an empty collection wasn't passed - Fixes #6976 */
3936 if ( !this.length ) {
3937 return this;
3938 }
3939
3940 /* Initialise the date picker. */
3941 if (!$.datepicker.initialized) {
3942 $(document).mousedown($.datepicker._checkExternalClick).
3943 find(document.body).append($.datepicker.dpDiv);
3944 $.datepicker.initialized = true;
3945 }
3946
3947 var otherArgs = Array.prototype.slice.call(arguments, 1);
3948 if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
3949 return $.datepicker['_' + options + 'Datepicker'].
3950 apply($.datepicker, [this[0]].concat(otherArgs));
3951 if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
3952 return $.datepicker['_' + options + 'Datepicker'].
3953 apply($.datepicker, [this[0]].concat(otherArgs));
3954 return this.each(function() {
3955 typeof options == 'string' ?
3956 $.datepicker['_' + options + 'Datepicker'].
3957 apply($.datepicker, [this].concat(otherArgs)) :
3958 $.datepicker._attachDatepicker(this, options);
3959 });
3960};
3961
3962$.datepicker = new Datepicker(); // singleton instance
3963$.datepicker.initialized = false;
3964$.datepicker.uuid = new Date().getTime();
3965$.datepicker.version = "1.9.2";
3966
3967// Workaround for #4055
3968// Add another global to avoid noConflict issues with inline event handlers
3969window['DP_jQuery_' + dpuuid] = $;
3970
3971})(jQuery);
3972
3973//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlcyI6WyJqcXVlcnl1aS9qcXVlcnkudWkuZGF0ZXBpY2tlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIGpRdWVyeSBVSSBEYXRlcGlja2VyIDEuOS4yXG4gKiBodHRwOi8vanF1ZXJ5dWkuY29tXG4gKlxuICogQ29weXJpZ2h0IDIwMTIgalF1ZXJ5IEZvdW5kYXRpb24gYW5kIG90aGVyIGNvbnRyaWJ1dG9yc1xuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxuICogaHR0cDovL2pxdWVyeS5vcmcvbGljZW5zZVxuICpcbiAqIGh0dHA6Ly9hcGkuanF1ZXJ5dWkuY29tL2RhdGVwaWNrZXIvXG4gKlxuICogRGVwZW5kczpcbiAqXHRqcXVlcnkudWkuY29yZS5qc1xuICovXG4oZnVuY3Rpb24oICQsIHVuZGVmaW5lZCApIHtcblxuJC5leHRlbmQoJC51aSwgeyBkYXRlcGlja2VyOiB7IHZlcnNpb246IFwiMS45LjJcIiB9IH0pO1xuXG52YXIgUFJPUF9OQU1FID0gJ2RhdGVwaWNrZXInO1xudmFyIGRwdXVpZCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xudmFyIGluc3RBY3RpdmU7XG5cbi8qIERhdGUgcGlja2VyIG1hbmFnZXIuXG4gICBVc2UgdGhlIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLCAkLmRhdGVwaWNrZXIsIHRvIGludGVyYWN0IHdpdGggdGhlIGRhdGUgcGlja2VyLlxuICAgU2V0dGluZ3MgZm9yIChncm91cHMgb2YpIGRhdGUgcGlja2VycyBhcmUgbWFpbnRhaW5lZCBpbiBhbiBpbnN0YW5jZSBvYmplY3QsXG4gICBhbGxvd2luZyBtdWx0aXBsZSBkaWZmZXJlbnQgc2V0dGluZ3Mgb24gdGhlIHNhbWUgcGFnZS4gKi9cblxuZnVuY3Rpb24gRGF0ZXBpY2tlcigpIHtcblx0dGhpcy5kZWJ1ZyA9IGZhbHNlOyAvLyBDaGFuZ2UgdGhpcyB0byB0cnVlIHRvIHN0YXJ0IGRlYnVnZ2luZ1xuXHR0aGlzLl9jdXJJbnN0ID0gbnVsbDsgLy8gVGhlIGN1cnJlbnQgaW5zdGFuY2UgaW4gdXNlXG5cdHRoaXMuX2tleUV2ZW50ID0gZmFsc2U7IC8vIElmIHRoZSBsYXN0IGV2ZW50IHdhcyBhIGtleSBldmVudFxuXHR0aGlzLl9kaXNhYmxlZElucHV0cyA9IFtdOyAvLyBMaXN0IG9mIGRhdGUgcGlja2VyIGlucHV0cyB0aGF0IGhhdmUgYmVlbiBkaXNhYmxlZFxuXHR0aGlzLl9kYXRlcGlja2VyU2hvd2luZyA9IGZhbHNlOyAvLyBUcnVlIGlmIHRoZSBwb3B1cCBwaWNrZXIgaXMgc2hvd2luZyAsIGZhbHNlIGlmIG5vdFxuXHR0aGlzLl9pbkRpYWxvZyA9IGZhbHNlOyAvLyBUcnVlIGlmIHNob3dpbmcgd2l0aGluIGEgXCJkaWFsb2dcIiwgZmFsc2UgaWYgbm90XG5cdHRoaXMuX21haW5EaXZJZCA9ICd1aS1kYXRlcGlja2VyLWRpdic7IC8vIFRoZSBJRCBvZiB0aGUgbWFpbiBkYXRlcGlja2VyIGRpdmlzaW9uXG5cdHRoaXMuX2lubGluZUNsYXNzID0gJ3VpLWRhdGVwaWNrZXItaW5saW5lJzsgLy8gVGhlIG5hbWUgb2YgdGhlIGlubGluZSBtYXJrZXIgY2xhc3Ncblx0dGhpcy5fYXBwZW5kQ2xhc3MgPSAndWktZGF0ZXBpY2tlci1hcHBlbmQnOyAvLyBUaGUgbmFtZSBvZiB0aGUgYXBwZW5kIG1hcmtlciBjbGFzc1xuXHR0aGlzLl90cmlnZ2VyQ2xhc3MgPSAndWktZGF0ZXBpY2tlci10cmlnZ2VyJzsgLy8gVGhlIG5hbWUgb2YgdGhlIHRyaWdnZXIgbWFya2VyIGNsYXNzXG5cdHRoaXMuX2RpYWxvZ0NsYXNzID0gJ3VpLWRhdGVwaWNrZXItZGlhbG9nJzsgLy8gVGhlIG5hbWUgb2YgdGhlIGRpYWxvZyBtYXJrZXIgY2xhc3Ncblx0dGhpcy5fZGlzYWJsZUNsYXNzID0gJ3VpLWRhdGVwaWNrZXItZGlzYWJsZWQnOyAvLyBUaGUgbmFtZSBvZiB0aGUgZGlzYWJsZWQgY292ZXJpbmcgbWFya2VyIGNsYXNzXG5cdHRoaXMuX3Vuc2VsZWN0YWJsZUNsYXNzID0gJ3VpLWRhdGVwaWNrZXItdW5zZWxlY3RhYmxlJzsgLy8gVGhlIG5hbWUgb2YgdGhlIHVuc2VsZWN0YWJsZSBjZWxsIG1hcmtlciBjbGFzc1xuXHR0aGlzLl9jdXJyZW50Q2xhc3MgPSAndWktZGF0ZXBpY2tlci1jdXJyZW50LWRheSc7IC8vIFRoZSBuYW1lIG9mIHRoZSBjdXJyZW50IGRheSBtYXJrZXIgY2xhc3Ncblx0dGhpcy5fZGF5T3ZlckNsYXNzID0gJ3VpLWRhdGVwaWNrZXItZGF5cy1jZWxsLW92ZXInOyAvLyBUaGUgbmFtZSBvZiB0aGUgZGF5IGhvdmVyIG1hcmtlciBjbGFzc1xuXHR0aGlzLnJlZ2lvbmFsID0gW107IC8vIEF2YWlsYWJsZSByZWdpb25hbCBzZXR0aW5ncywgaW5kZXhlZCBieSBsYW5ndWFnZSBjb2RlXG5cdHRoaXMucmVnaW9uYWxbJyddID0geyAvLyBEZWZhdWx0IHJlZ2lvbmFsIHNldHRpbmdzXG5cdFx0Y2xvc2VUZXh0OiAnRG9uZScsIC8vIERpc3BsYXkgdGV4dCBmb3IgY2xvc2UgbGlua1xuXHRcdHByZXZUZXh0OiAnUHJldicsIC8vIERpc3BsYXkgdGV4dCBmb3IgcHJldmlvdXMgbW9udGggbGlua1xuXHRcdG5leHRUZXh0OiAnTmV4dCcsIC8vIERpc3BsYXkgdGV4dCBmb3IgbmV4dCBtb250aCBsaW5rXG5cdFx0Y3VycmVudFRleHQ6ICdUb2RheScsIC8vIERpc3BsYXkgdGV4dCBmb3IgY3VycmVudCBtb250aCBsaW5rXG5cdFx0bW9udGhOYW1lczogWydKYW51YXJ5JywnRmVicnVhcnknLCdNYXJjaCcsJ0FwcmlsJywnTWF5JywnSnVuZScsXG5cdFx0XHQnSnVseScsJ0F1Z3VzdCcsJ1NlcHRlbWJlcicsJ09jdG9iZXInLCdOb3ZlbWJlcicsJ0RlY2VtYmVyJ10sIC8vIE5hbWVzIG9mIG1vbnRocyBmb3IgZHJvcC1kb3duIGFuZCBmb3JtYXR0aW5nXG5cdFx0bW9udGhOYW1lc1Nob3J0OiBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJywgJ09jdCcsICdOb3YnLCAnRGVjJ10sIC8vIEZvciBmb3JtYXR0aW5nXG5cdFx0ZGF5TmFtZXM6IFsnU3VuZGF5JywgJ01vbmRheScsICdUdWVzZGF5JywgJ1dlZG5lc2RheScsICdUaHVyc2RheScsICdGcmlkYXknLCAnU2F0dXJkYXknXSwgLy8gRm9yIGZvcm1hdHRpbmdcblx0XHRkYXlOYW1lc1Nob3J0OiBbJ1N1bicsICdNb24nLCAnVHVlJywgJ1dlZCcsICdUaHUnLCAnRnJpJywgJ1NhdCddLCAvLyBGb3IgZm9ybWF0dGluZ1xuXHRcdGRheU5hbWVzTWluOiBbJ1N1JywnTW8nLCdUdScsJ1dlJywnVGgnLCdGcicsJ1NhJ10sIC8vIENvbHVtbiBoZWFkaW5ncyBmb3IgZGF5cyBzdGFydGluZyBhdCBTdW5kYXlcblx0XHR3ZWVrSGVhZGVyOiAnV2snLCAvLyBDb2x1bW4gaGVhZGVyIGZvciB3ZWVrIG9mIHRoZSB5ZWFyXG5cdFx0ZGF0ZUZvcm1hdDogJ21tL2RkL3l5JywgLy8gU2VlIGZvcm1hdCBvcHRpb25zIG9uIHBhcnNlRGF0ZVxuXHRcdGZpcnN0RGF5OiAwLCAvLyBUaGUgZmlyc3QgZGF5IG9mIHRoZSB3ZWVrLCBTdW4gPSAwLCBNb24gPSAxLCAuLi5cblx0XHRpc1JUTDogZmFsc2UsIC8vIFRydWUgaWYgcmlnaHQtdG8tbGVmdCBsYW5ndWFnZSwgZmFsc2UgaWYgbGVmdC10by1yaWdodFxuXHRcdHNob3dNb250aEFmdGVyWWVhcjogZmFsc2UsIC8vIFRydWUgaWYgdGhlIHllYXIgc2VsZWN0IHByZWNlZGVzIG1vbnRoLCBmYWxzZSBmb3IgbW9udGggdGhlbiB5ZWFyXG5cdFx0eWVhclN1ZmZpeDogJycgLy8gQWRkaXRpb25hbCB0ZXh0IHRvIGFwcGVuZCB0byB0aGUgeWVhciBpbiB0aGUgbW9udGggaGVhZGVyc1xuXHR9O1xuXHR0aGlzLl9kZWZhdWx0cyA9IHsgLy8gR2xvYmFsIGRlZmF1bHRzIGZvciBhbGwgdGhlIGRhdGUgcGlja2VyIGluc3RhbmNlc1xuXHRcdHNob3dPbjogJ2ZvY3VzJywgLy8gJ2ZvY3VzJyBmb3IgcG9wdXAgb24gZm9jdXMsXG5cdFx0XHQvLyAnYnV0dG9uJyBmb3IgdHJpZ2dlciBidXR0b24sIG9yICdib3RoJyBmb3IgZWl0aGVyXG5cdFx0c2hvd0FuaW06ICdmYWRlSW4nLCAvLyBOYW1lIG9mIGpRdWVyeSBhbmltYXRpb24gZm9yIHBvcHVwXG5cdFx0c2hvd09wdGlvbnM6IHt9LCAvLyBPcHRpb25zIGZvciBlbmhhbmNlZCBhbmltYXRpb25zXG5cdFx0ZGVmYXVsdERhdGU6IG51bGwsIC8vIFVzZWQgd2hlbiBmaWVsZCBpcyBibGFuazogYWN0dWFsIGRhdGUsXG5cdFx0XHQvLyArLy1udW1iZXIgZm9yIG9mZnNldCBmcm9tIHRvZGF5LCBudWxsIGZvciB0b2RheVxuXHRcdGFwcGVuZFRleHQ6ICcnLCAvLyBEaXNwbGF5IHRleHQgZm9sbG93aW5nIHRoZSBpbnB1dCBib3gsIGUuZy4gc2hvd2luZyB0aGUgZm9ybWF0XG5cdFx0YnV0dG9uVGV4dDogJy4uLicsIC8vIFRleHQgZm9yIHRyaWdnZXIgYnV0dG9uXG5cdFx0YnV0dG9uSW1hZ2U6ICcnLCAvLyBVUkwgZm9yIHRyaWdnZXIgYnV0dG9uIGltYWdlXG5cdFx0YnV0dG9uSW1hZ2VPbmx5OiBmYWxzZSwgLy8gVHJ1ZSBpZiB0aGUgaW1hZ2UgYXBwZWFycyBhbG9uZSwgZmFsc2UgaWYgaXQgYXBwZWFycyBvbiBhIGJ1dHRvblxuXHRcdGhpZGVJZk5vUHJldk5leHQ6IGZhbHNlLCAvLyBUcnVlIHRvIGhpZGUgbmV4dC9wcmV2aW91cyBtb250aCBsaW5rc1xuXHRcdFx0Ly8gaWYgbm90IGFwcGxpY2FibGUsIGZhbHNlIHRvIGp1c3QgZGlzYWJsZSB0aGVtXG5cdFx0bmF2aWdhdGlvbkFzRGF0ZUZvcm1hdDogZmFsc2UsIC8vIFRydWUgaWYgZGF0ZSBmb3JtYXR0aW5nIGFwcGxpZWQgdG8gcHJldi90b2RheS9uZXh0IGxpbmtzXG5cdFx0Z290b0N1cnJlbnQ6IGZhbHNlLCAvLyBUcnVlIGlmIHRvZGF5IGxpbmsgZ29lcyBiYWNrIHRvIGN1cnJlbnQgc2VsZWN0aW9uIGluc3RlYWRcblx0XHRjaGFuZ2VNb250aDogZmFsc2UsIC8vIFRydWUgaWYgbW9udGggY2FuIGJlIHNlbGVjdGVkIGRpcmVjdGx5LCBmYWxzZSBpZiBvbmx5IHByZXYvbmV4dFxuXHRcdGNoYW5nZVllYXI6IGZhbHNlLCAvLyBUcnVlIGlmIHllYXIgY2FuIGJlIHNlbGVjdGVkIGRpcmVjdGx5LCBmYWxzZSBpZiBvbmx5IHByZXYvbmV4dFxuXHRcdHllYXJSYW5nZTogJ2MtMTA6YysxMCcsIC8vIFJhbmdlIG9mIHllYXJzIHRvIGRpc3BsYXkgaW4gZHJvcC1kb3duLFxuXHRcdFx0Ly8gZWl0aGVyIHJlbGF0aXZlIHRvIHRvZGF5J3MgeWVhciAoLW5uOitubiksIHJlbGF0aXZlIHRvIGN1cnJlbnRseSBkaXNwbGF5ZWQgeWVhclxuXHRcdFx0Ly8gKGMtbm46YytubiksIGFic29sdXRlIChubm5uOm5ubm4pLCBvciBhIGNvbWJpbmF0aW9uIG9mIHRoZSBhYm92ZSAobm5ubjotbilcblx0XHRzaG93T3RoZXJNb250aHM6IGZhbHNlLCAvLyBUcnVlIHRvIHNob3cgZGF0ZXMgaW4gb3RoZXIgbW9udGhzLCBmYWxzZSB0byBsZWF2ZSBibGFua1xuXHRcdHNlbGVjdE90aGVyTW9udGhzOiBmYWxzZSwgLy8gVHJ1ZSB0byBhbGxvdyBzZWxlY3Rpb24gb2YgZGF0ZXMgaW4gb3RoZXIgbW9udGhzLCBmYWxzZSBmb3IgdW5zZWxlY3RhYmxlXG5cdFx0c2hvd1dlZWs6IGZhbHNlLCAvLyBUcnVlIHRvIHNob3cgd2VlayBvZiB0aGUgeWVhciwgZmFsc2UgdG8gbm90IHNob3cgaXRcblx0XHRjYWxjdWxhdGVXZWVrOiB0aGlzLmlzbzg2MDFXZWVrLCAvLyBIb3cgdG8gY2FsY3VsYXRlIHRoZSB3ZWVrIG9mIHRoZSB5ZWFyLFxuXHRcdFx0Ly8gdGFrZXMgYSBEYXRlIGFuZCByZXR1cm5zIHRoZSBudW1iZXIgb2YgdGhlIHdlZWsgZm9yIGl0XG5cdFx0c2hvcnRZZWFyQ3V0b2ZmOiAnKzEwJywgLy8gU2hvcnQgeWVhciB2YWx1ZXMgPCB0aGlzIGFyZSBpbiB0aGUgY3VycmVudCBjZW50dXJ5LFxuXHRcdFx0Ly8gPiB0aGlzIGFyZSBpbiB0aGUgcHJldmlvdXMgY2VudHVyeSxcblx0XHRcdC8vIHN0cmluZyB2YWx1ZSBzdGFydGluZyB3aXRoICcrJyBmb3IgY3VycmVudCB5ZWFyICsgdmFsdWVcblx0XHRtaW5EYXRlOiBudWxsLCAvLyBUaGUgZWFybGllc3Qgc2VsZWN0YWJsZSBkYXRlLCBvciBudWxsIGZvciBubyBsaW1pdFxuXHRcdG1heERhdGU6IG51bGwsIC8vIFRoZSBsYXRlc3Qgc2VsZWN0YWJsZSBkYXRlLCBvciBudWxsIGZvciBubyBsaW1pdFxuXHRcdGR1cmF0aW9uOiAnZmFzdCcsIC8vIER1cmF0aW9uIG9mIGRpc3BsYXkvY2xvc3VyZVxuXHRcdGJlZm9yZVNob3dEYXk6IG51bGwsIC8vIEZ1bmN0aW9uIHRoYXQgdGFrZXMgYSBkYXRlIGFuZCByZXR1cm5zIGFuIGFycmF5IHdpdGhcblx0XHRcdC8vIFswXSA9IHRydWUgaWYgc2VsZWN0YWJsZSwgZmFsc2UgaWYgbm90LCBbMV0gPSBjdXN0b20gQ1NTIGNsYXNzIG5hbWUocykgb3IgJycsXG5cdFx0XHQvLyBbMl0gPSBjZWxsIHRpdGxlIChvcHRpb25hbCksIGUuZy4gJC5kYXRlcGlja2VyLm5vV2Vla2VuZHNcblx0XHRiZWZvcmVTaG93OiBudWxsLCAvLyBGdW5jdGlvbiB0aGF0IHRha2VzIGFuIGlucHV0IGZpZWxkIGFuZFxuXHRcdFx0Ly8gcmV0dXJucyBhIHNldCBvZiBjdXN0b20gc2V0dGluZ3MgZm9yIHRoZSBkYXRlIHBpY2tlclxuXHRcdG9uU2VsZWN0OiBudWxsLCAvLyBEZWZpbmUgYSBjYWxsYmFjayBmdW5jdGlvbiB3aGVuIGEgZGF0ZSBpcyBzZWxlY3RlZFxuXHRcdG9uQ2hhbmdlTW9udGhZZWFyOiBudWxsLCAvLyBEZWZpbmUgYSBjYWxsYmFjayBmdW5jdGlvbiB3aGVuIHRoZSBtb250aCBvciB5ZWFyIGlzIGNoYW5nZWRcblx0XHRvbkNsb3NlOiBudWxsLCAvLyBEZWZpbmUgYSBjYWxsYmFjayBmdW5jdGlvbiB3aGVuIHRoZSBkYXRlcGlja2VyIGlzIGNsb3NlZFxuXHRcdG51bWJlck9mTW9udGhzOiAxLCAvLyBOdW1iZXIgb2YgbW9udGhzIHRvIHNob3cgYXQgYSB0aW1lXG5cdFx0c2hvd0N1cnJlbnRBdFBvczogMCwgLy8gVGhlIHBvc2l0aW9uIGluIG11bHRpcGUgbW9udGhzIGF0IHdoaWNoIHRvIHNob3cgdGhlIGN1cnJlbnQgbW9udGggKHN0YXJ0aW5nIGF0IDApXG5cdFx0c3RlcE1vbnRoczogMSwgLy8gTnVtYmVyIG9mIG1vbnRocyB0byBzdGVwIGJhY2svZm9yd2FyZFxuXHRcdHN0ZXBCaWdNb250aHM6IDEyLCAvLyBOdW1iZXIgb2YgbW9udGhzIHRvIHN0ZXAgYmFjay9mb3J3YXJkIGZvciB0aGUgYmlnIGxpbmtzXG5cdFx0YWx0RmllbGQ6ICcnLCAvLyBTZWxlY3RvciBmb3IgYW4gYWx0ZXJuYXRlIGZpZWxkIHRvIHN0b3JlIHNlbGVjdGVkIGRhdGVzIGludG9cblx0XHRhbHRGb3JtYXQ6ICcnLCAvLyBUaGUgZGF0ZSBmb3JtYXQgdG8gdXNlIGZvciB0aGUgYWx0ZXJuYXRlIGZpZWxkXG5cdFx0Y29uc3RyYWluSW5wdXQ6IHRydWUsIC8vIFRoZSBpbnB1dCBpcyBjb25zdHJhaW5lZCBieSB0aGUgY3VycmVudCBkYXRlIGZvcm1hdFxuXHRcdHNob3dCdXR0b25QYW5lbDogZmFsc2UsIC8vIFRydWUgdG8gc2hvdyBidXR0b24gcGFuZWwsIGZhbHNlIHRvIG5vdCBzaG93IGl0XG5cdFx0YXV0b1NpemU6IGZhbHNlLCAvLyBUcnVlIHRvIHNpemUgdGhlIGlucHV0IGZvciB0aGUgZGF0ZSBmb3JtYXQsIGZhbHNlIHRvIGxlYXZlIGFzIGlzXG5cdFx0ZGlzYWJsZWQ6IGZhbHNlIC8vIFRoZSBpbml0aWFsIGRpc2FibGVkIHN0YXRlXG5cdH07XG5cdCQuZXh0ZW5kKHRoaXMuX2RlZmF1bHRzLCB0aGlzLnJlZ2lvbmFsWycnXSk7XG5cdHRoaXMuZHBEaXYgPSBiaW5kSG92ZXIoJCgnPGRpdiBpZD1cIicgKyB0aGlzLl9tYWluRGl2SWQgKyAnXCIgY2xhc3M9XCJ1aS1kYXRlcGlja2VyIHVpLXdpZGdldCB1aS13aWRnZXQtY29udGVudCB1aS1oZWxwZXItY2xlYXJmaXggdWktY29ybmVyLWFsbFwiPjwvZGl2PicpKTtcbn1cblxuJC5leHRlbmQoRGF0ZXBpY2tlci5wcm90b3R5cGUsIHtcblx0LyogQ2xhc3MgbmFtZSBhZGRlZCB0byBlbGVtZW50cyB0byBpbmRpY2F0ZSBhbHJlYWR5IGNvbmZpZ3VyZWQgd2l0aCBhIGRhdGUgcGlja2VyLiAqL1xuXHRtYXJrZXJDbGFzc05hbWU6ICdoYXNEYXRlcGlja2VyJyxcblxuXHQvL0tlZXAgdHJhY2sgb2YgdGhlIG1heGltdW0gbnVtYmVyIG9mIHJvd3MgZGlzcGxheWVkIChzZWUgIzcwNDMpXG5cdG1heFJvd3M6IDQsXG5cblx0LyogRGVidWcgbG9nZ2luZyAoaWYgZW5hYmxlZCkuICovXG5cdGxvZzogZnVuY3Rpb24gKCkge1xuXHRcdGlmICh0aGlzLmRlYnVnKVxuXHRcdFx0Y29uc29sZS5sb2cuYXBwbHkoJycsIGFyZ3VtZW50cyk7XG5cdH0sXG5cblx0Ly8gVE9ETyByZW5hbWUgdG8gXCJ3aWRnZXRcIiB3aGVuIHN3aXRjaGluZyB0byB3aWRnZXQgZmFjdG9yeVxuXHRfd2lkZ2V0RGF0ZXBpY2tlcjogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZHBEaXY7XG5cdH0sXG5cblx0LyogT3ZlcnJpZGUgdGhlIGRlZmF1bHQgc2V0dGluZ3MgZm9yIGFsbCBpbnN0YW5jZXMgb2YgdGhlIGRhdGUgcGlja2VyLlxuXHQgICBAcGFyYW0gIHNldHRpbmdzICBvYmplY3QgLSB0aGUgbmV3IHNldHRpbmdzIHRvIHVzZSBhcyBkZWZhdWx0cyAoYW5vbnltb3VzIG9iamVjdClcblx0ICAgQHJldHVybiB0aGUgbWFuYWdlciBvYmplY3QgKi9cblx0c2V0RGVmYXVsdHM6IGZ1bmN0aW9uKHNldHRpbmdzKSB7XG5cdFx0ZXh0ZW5kUmVtb3ZlKHRoaXMuX2RlZmF1bHRzLCBzZXR0aW5ncyB8fCB7fSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0LyogQXR0YWNoIHRoZSBkYXRlIHBpY2tlciB0byBhIGpRdWVyeSBzZWxlY3Rpb24uXG5cdCAgIEBwYXJhbSAgdGFyZ2V0ICAgIGVsZW1lbnQgLSB0aGUgdGFyZ2V0IGlucHV0IGZpZWxkIG9yIGRpdmlzaW9uIG9yIHNwYW5cblx0ICAgQHBhcmFtICBzZXR0aW5ncyAgb2JqZWN0IC0gdGhlIG5ldyBzZXR0aW5ncyB0byB1c2UgZm9yIHRoaXMgZGF0ZSBwaWNrZXIgaW5zdGFuY2UgKGFub255bW91cykgKi9cblx0X2F0dGFjaERhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCwgc2V0dGluZ3MpIHtcblx0XHQvLyBjaGVjayBmb3Igc2V0dGluZ3Mgb24gdGhlIGNvbnRyb2wgaXRzZWxmIC0gaW4gbmFtZXNwYWNlICdkYXRlOidcblx0XHR2YXIgaW5saW5lU2V0dGluZ3MgPSBudWxsO1xuXHRcdGZvciAodmFyIGF0dHJOYW1lIGluIHRoaXMuX2RlZmF1bHRzKSB7XG5cdFx0XHR2YXIgYXR0clZhbHVlID0gdGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0ZTonICsgYXR0ck5hbWUpO1xuXHRcdFx0aWYgKGF0dHJWYWx1ZSkge1xuXHRcdFx0XHRpbmxpbmVTZXR0aW5ncyA9IGlubGluZVNldHRpbmdzIHx8IHt9O1xuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdGlubGluZVNldHRpbmdzW2F0dHJOYW1lXSA9IGV2YWwoYXR0clZhbHVlKTtcblx0XHRcdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHRcdFx0aW5saW5lU2V0dGluZ3NbYXR0ck5hbWVdID0gYXR0clZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHZhciBub2RlTmFtZSA9IHRhcmdldC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdHZhciBpbmxpbmUgPSAobm9kZU5hbWUgPT0gJ2RpdicgfHwgbm9kZU5hbWUgPT0gJ3NwYW4nKTtcblx0XHRpZiAoIXRhcmdldC5pZCkge1xuXHRcdFx0dGhpcy51dWlkICs9IDE7XG5cdFx0XHR0YXJnZXQuaWQgPSAnZHAnICsgdGhpcy51dWlkO1xuXHRcdH1cblx0XHR2YXIgaW5zdCA9IHRoaXMuX25ld0luc3QoJCh0YXJnZXQpLCBpbmxpbmUpO1xuXHRcdGluc3Quc2V0dGluZ3MgPSAkLmV4dGVuZCh7fSwgc2V0dGluZ3MgfHwge30sIGlubGluZVNldHRpbmdzIHx8IHt9KTtcblx0XHRpZiAobm9kZU5hbWUgPT0gJ2lucHV0Jykge1xuXHRcdFx0dGhpcy5fY29ubmVjdERhdGVwaWNrZXIodGFyZ2V0LCBpbnN0KTtcblx0XHR9IGVsc2UgaWYgKGlubGluZSkge1xuXHRcdFx0dGhpcy5faW5saW5lRGF0ZXBpY2tlcih0YXJnZXQsIGluc3QpO1xuXHRcdH1cblx0fSxcblxuXHQvKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2JqZWN0LiAqL1xuXHRfbmV3SW5zdDogZnVuY3Rpb24odGFyZ2V0LCBpbmxpbmUpIHtcblx0XHR2YXIgaWQgPSB0YXJnZXRbMF0uaWQucmVwbGFjZSgvKFteQS1aYS16MC05Xy1dKS9nLCAnXFxcXFxcXFwkMScpOyAvLyBlc2NhcGUgalF1ZXJ5IG1ldGEgY2hhcnNcblx0XHRyZXR1cm4ge2lkOiBpZCwgaW5wdXQ6IHRhcmdldCwgLy8gYXNzb2NpYXRlZCB0YXJnZXRcblx0XHRcdHNlbGVjdGVkRGF5OiAwLCBzZWxlY3RlZE1vbnRoOiAwLCBzZWxlY3RlZFllYXI6IDAsIC8vIGN1cnJlbnQgc2VsZWN0aW9uXG5cdFx0XHRkcmF3TW9udGg6IDAsIGRyYXdZZWFyOiAwLCAvLyBtb250aCBiZWluZyBkcmF3blxuXHRcdFx0aW5saW5lOiBpbmxpbmUsIC8vIGlzIGRhdGVwaWNrZXIgaW5saW5lIG9yIG5vdFxuXHRcdFx0ZHBEaXY6ICghaW5saW5lID8gdGhpcy5kcERpdiA6IC8vIHByZXNlbnRhdGlvbiBkaXZcblx0XHRcdGJpbmRIb3ZlcigkKCc8ZGl2IGNsYXNzPVwiJyArIHRoaXMuX2lubGluZUNsYXNzICsgJyB1aS1kYXRlcGlja2VyIHVpLXdpZGdldCB1aS13aWRnZXQtY29udGVudCB1aS1oZWxwZXItY2xlYXJmaXggdWktY29ybmVyLWFsbFwiPjwvZGl2PicpKSl9O1xuXHR9LFxuXG5cdC8qIEF0dGFjaCB0aGUgZGF0ZSBwaWNrZXIgdG8gYW4gaW5wdXQgZmllbGQuICovXG5cdF9jb25uZWN0RGF0ZXBpY2tlcjogZnVuY3Rpb24odGFyZ2V0LCBpbnN0KSB7XG5cdFx0dmFyIGlucHV0ID0gJCh0YXJnZXQpO1xuXHRcdGluc3QuYXBwZW5kID0gJChbXSk7XG5cdFx0aW5zdC50cmlnZ2VyID0gJChbXSk7XG5cdFx0aWYgKGlucHV0Lmhhc0NsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKSlcblx0XHRcdHJldHVybjtcblx0XHR0aGlzLl9hdHRhY2htZW50cyhpbnB1dCwgaW5zdCk7XG5cdFx0aW5wdXQuYWRkQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpLmtleWRvd24odGhpcy5fZG9LZXlEb3duKS5cblx0XHRcdGtleXByZXNzKHRoaXMuX2RvS2V5UHJlc3MpLmtleXVwKHRoaXMuX2RvS2V5VXApLlxuXHRcdFx0YmluZChcInNldERhdGEuZGF0ZXBpY2tlclwiLCBmdW5jdGlvbihldmVudCwga2V5LCB2YWx1ZSkge1xuXHRcdFx0XHRpbnN0LnNldHRpbmdzW2tleV0gPSB2YWx1ZTtcblx0XHRcdH0pLmJpbmQoXCJnZXREYXRhLmRhdGVwaWNrZXJcIiwgZnVuY3Rpb24oZXZlbnQsIGtleSkge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5fZ2V0KGluc3QsIGtleSk7XG5cdFx0XHR9KTtcblx0XHR0aGlzLl9hdXRvU2l6ZShpbnN0KTtcblx0XHQkLmRhdGEodGFyZ2V0LCBQUk9QX05BTUUsIGluc3QpO1xuXHRcdC8vSWYgZGlzYWJsZWQgb3B0aW9uIGlzIHRydWUsIGRpc2FibGUgdGhlIGRhdGVwaWNrZXIgb25jZSBpdCBoYXMgYmVlbiBhdHRhY2hlZCB0byB0aGUgaW5wdXQgKHNlZSB0aWNrZXQgIzU2NjUpXG5cdFx0aWYoIGluc3Quc2V0dGluZ3MuZGlzYWJsZWQgKSB7XG5cdFx0XHR0aGlzLl9kaXNhYmxlRGF0ZXBpY2tlciggdGFyZ2V0ICk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIE1ha2UgYXR0YWNobWVudHMgYmFzZWQgb24gc2V0dGluZ3MuICovXG5cdF9hdHRhY2htZW50czogZnVuY3Rpb24oaW5wdXQsIGluc3QpIHtcblx0XHR2YXIgYXBwZW5kVGV4dCA9IHRoaXMuX2dldChpbnN0LCAnYXBwZW5kVGV4dCcpO1xuXHRcdHZhciBpc1JUTCA9IHRoaXMuX2dldChpbnN0LCAnaXNSVEwnKTtcblx0XHRpZiAoaW5zdC5hcHBlbmQpXG5cdFx0XHRpbnN0LmFwcGVuZC5yZW1vdmUoKTtcblx0XHRpZiAoYXBwZW5kVGV4dCkge1xuXHRcdFx0aW5zdC5hcHBlbmQgPSAkKCc8c3BhbiBjbGFzcz1cIicgKyB0aGlzLl9hcHBlbmRDbGFzcyArICdcIj4nICsgYXBwZW5kVGV4dCArICc8L3NwYW4+Jyk7XG5cdFx0XHRpbnB1dFtpc1JUTCA/ICdiZWZvcmUnIDogJ2FmdGVyJ10oaW5zdC5hcHBlbmQpO1xuXHRcdH1cblx0XHRpbnB1dC51bmJpbmQoJ2ZvY3VzJywgdGhpcy5fc2hvd0RhdGVwaWNrZXIpO1xuXHRcdGlmIChpbnN0LnRyaWdnZXIpXG5cdFx0XHRpbnN0LnRyaWdnZXIucmVtb3ZlKCk7XG5cdFx0dmFyIHNob3dPbiA9IHRoaXMuX2dldChpbnN0LCAnc2hvd09uJyk7XG5cdFx0aWYgKHNob3dPbiA9PSAnZm9jdXMnIHx8IHNob3dPbiA9PSAnYm90aCcpIC8vIHBvcC11cCBkYXRlIHBpY2tlciB3aGVuIGluIHRoZSBtYXJrZWQgZmllbGRcblx0XHRcdGlucHV0LmZvY3VzKHRoaXMuX3Nob3dEYXRlcGlja2VyKTtcblx0XHRpZiAoc2hvd09uID09ICdidXR0b24nIHx8IHNob3dPbiA9PSAnYm90aCcpIHsgLy8gcG9wLXVwIGRhdGUgcGlja2VyIHdoZW4gYnV0dG9uIGNsaWNrZWRcblx0XHRcdHZhciBidXR0b25UZXh0ID0gdGhpcy5fZ2V0KGluc3QsICdidXR0b25UZXh0Jyk7XG5cdFx0XHR2YXIgYnV0dG9uSW1hZ2UgPSB0aGlzLl9nZXQoaW5zdCwgJ2J1dHRvbkltYWdlJyk7XG5cdFx0XHRpbnN0LnRyaWdnZXIgPSAkKHRoaXMuX2dldChpbnN0LCAnYnV0dG9uSW1hZ2VPbmx5JykgP1xuXHRcdFx0XHQkKCc8aW1nLz4nKS5hZGRDbGFzcyh0aGlzLl90cmlnZ2VyQ2xhc3MpLlxuXHRcdFx0XHRcdGF0dHIoeyBzcmM6IGJ1dHRvbkltYWdlLCBhbHQ6IGJ1dHRvblRleHQsIHRpdGxlOiBidXR0b25UZXh0IH0pIDpcblx0XHRcdFx0JCgnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCI+PC9idXR0b24+JykuYWRkQ2xhc3ModGhpcy5fdHJpZ2dlckNsYXNzKS5cblx0XHRcdFx0XHRodG1sKGJ1dHRvbkltYWdlID09ICcnID8gYnV0dG9uVGV4dCA6ICQoJzxpbWcvPicpLmF0dHIoXG5cdFx0XHRcdFx0eyBzcmM6YnV0dG9uSW1hZ2UsIGFsdDpidXR0b25UZXh0LCB0aXRsZTpidXR0b25UZXh0IH0pKSk7XG5cdFx0XHRpbnB1dFtpc1JUTCA/ICdiZWZvcmUnIDogJ2FmdGVyJ10oaW5zdC50cmlnZ2VyKTtcblx0XHRcdGluc3QudHJpZ2dlci5jbGljayhmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCQuZGF0ZXBpY2tlci5fZGF0ZXBpY2tlclNob3dpbmcgJiYgJC5kYXRlcGlja2VyLl9sYXN0SW5wdXQgPT0gaW5wdXRbMF0pXG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcigpO1xuXHRcdFx0XHRlbHNlIGlmICgkLmRhdGVwaWNrZXIuX2RhdGVwaWNrZXJTaG93aW5nICYmICQuZGF0ZXBpY2tlci5fbGFzdElucHV0ICE9IGlucHV0WzBdKSB7XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcigpO1xuXHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fc2hvd0RhdGVwaWNrZXIoaW5wdXRbMF0pO1xuXHRcdFx0XHR9IGVsc2Vcblx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX3Nob3dEYXRlcGlja2VyKGlucHV0WzBdKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIEFwcGx5IHRoZSBtYXhpbXVtIGxlbmd0aCBmb3IgdGhlIGRhdGUgZm9ybWF0LiAqL1xuXHRfYXV0b1NpemU6IGZ1bmN0aW9uKGluc3QpIHtcblx0XHRpZiAodGhpcy5fZ2V0KGluc3QsICdhdXRvU2l6ZScpICYmICFpbnN0LmlubGluZSkge1xuXHRcdFx0dmFyIGRhdGUgPSBuZXcgRGF0ZSgyMDA5LCAxMiAtIDEsIDIwKTsgLy8gRW5zdXJlIGRvdWJsZSBkaWdpdHNcblx0XHRcdHZhciBkYXRlRm9ybWF0ID0gdGhpcy5fZ2V0KGluc3QsICdkYXRlRm9ybWF0Jyk7XG5cdFx0XHRpZiAoZGF0ZUZvcm1hdC5tYXRjaCgvW0RNXS8pKSB7XG5cdFx0XHRcdHZhciBmaW5kTWF4ID0gZnVuY3Rpb24obmFtZXMpIHtcblx0XHRcdFx0XHR2YXIgbWF4ID0gMDtcblx0XHRcdFx0XHR2YXIgbWF4SSA9IDA7XG5cdFx0XHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBuYW1lcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdFx0aWYgKG5hbWVzW2ldLmxlbmd0aCA+IG1heCkge1xuXHRcdFx0XHRcdFx0XHRtYXggPSBuYW1lc1tpXS5sZW5ndGg7XG5cdFx0XHRcdFx0XHRcdG1heEkgPSBpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gbWF4STtcblx0XHRcdFx0fTtcblx0XHRcdFx0ZGF0ZS5zZXRNb250aChmaW5kTWF4KHRoaXMuX2dldChpbnN0LCAoZGF0ZUZvcm1hdC5tYXRjaCgvTU0vKSA/XG5cdFx0XHRcdFx0J21vbnRoTmFtZXMnIDogJ21vbnRoTmFtZXNTaG9ydCcpKSkpO1xuXHRcdFx0XHRkYXRlLnNldERhdGUoZmluZE1heCh0aGlzLl9nZXQoaW5zdCwgKGRhdGVGb3JtYXQubWF0Y2goL0RELykgP1xuXHRcdFx0XHRcdCdkYXlOYW1lcycgOiAnZGF5TmFtZXNTaG9ydCcpKSkgKyAyMCAtIGRhdGUuZ2V0RGF5KCkpO1xuXHRcdFx0fVxuXHRcdFx0aW5zdC5pbnB1dC5hdHRyKCdzaXplJywgdGhpcy5fZm9ybWF0RGF0ZShpbnN0LCBkYXRlKS5sZW5ndGgpO1xuXHRcdH1cblx0fSxcblxuXHQvKiBBdHRhY2ggYW4gaW5saW5lIGRhdGUgcGlja2VyIHRvIGEgZGl2LiAqL1xuXHRfaW5saW5lRGF0ZXBpY2tlcjogZnVuY3Rpb24odGFyZ2V0LCBpbnN0KSB7XG5cdFx0dmFyIGRpdlNwYW4gPSAkKHRhcmdldCk7XG5cdFx0aWYgKGRpdlNwYW4uaGFzQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpKVxuXHRcdFx0cmV0dXJuO1xuXHRcdGRpdlNwYW4uYWRkQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpLmFwcGVuZChpbnN0LmRwRGl2KS5cblx0XHRcdGJpbmQoXCJzZXREYXRhLmRhdGVwaWNrZXJcIiwgZnVuY3Rpb24oZXZlbnQsIGtleSwgdmFsdWUpe1xuXHRcdFx0XHRpbnN0LnNldHRpbmdzW2tleV0gPSB2YWx1ZTtcblx0XHRcdH0pLmJpbmQoXCJnZXREYXRhLmRhdGVwaWNrZXJcIiwgZnVuY3Rpb24oZXZlbnQsIGtleSl7XG5cdFx0XHRcdHJldHVybiB0aGlzLl9nZXQoaW5zdCwga2V5KTtcblx0XHRcdH0pO1xuXHRcdCQuZGF0YSh0YXJnZXQsIFBST1BfTkFNRSwgaW5zdCk7XG5cdFx0dGhpcy5fc2V0RGF0ZShpbnN0LCB0aGlzLl9nZXREZWZhdWx0RGF0ZShpbnN0KSwgdHJ1ZSk7XG5cdFx0dGhpcy5fdXBkYXRlRGF0ZXBpY2tlcihpbnN0KTtcblx0XHR0aGlzLl91cGRhdGVBbHRlcm5hdGUoaW5zdCk7XG5cdFx0Ly9JZiBkaXNhYmxlZCBvcHRpb24gaXMgdHJ1ZSwgZGlzYWJsZSB0aGUgZGF0ZXBpY2tlciBiZWZvcmUgc2hvd2luZyBpdCAoc2VlIHRpY2tldCAjNTY2NSlcblx0XHRpZiggaW5zdC5zZXR0aW5ncy5kaXNhYmxlZCApIHtcblx0XHRcdHRoaXMuX2Rpc2FibGVEYXRlcGlja2VyKCB0YXJnZXQgKTtcblx0XHR9XG5cdFx0Ly8gU2V0IGRpc3BsYXk6YmxvY2sgaW4gcGxhY2Ugb2YgaW5zdC5kcERpdi5zaG93KCkgd2hpY2ggd29uJ3Qgd29yayBvbiBkaXNjb25uZWN0ZWQgZWxlbWVudHNcblx0XHQvLyBodHRwOi8vYnVncy5qcXVlcnl1aS5jb20vdGlja2V0Lzc1NTIgLSBBIERhdGVwaWNrZXIgY3JlYXRlZCBvbiBhIGRldGFjaGVkIGRpdiBoYXMgemVybyBoZWlnaHRcblx0XHRpbnN0LmRwRGl2LmNzcyggXCJkaXNwbGF5XCIsIFwiYmxvY2tcIiApO1xuXHR9LFxuXG5cdC8qIFBvcC11cCB0aGUgZGF0ZSBwaWNrZXIgaW4gYSBcImRpYWxvZ1wiIGJveC5cblx0ICAgQHBhcmFtICBpbnB1dCAgICAgZWxlbWVudCAtIGlnbm9yZWRcblx0ICAgQHBhcmFtICBkYXRlICAgICAgc3RyaW5nIG9yIERhdGUgLSB0aGUgaW5pdGlhbCBkYXRlIHRvIGRpc3BsYXlcblx0ICAgQHBhcmFtICBvblNlbGVjdCAgZnVuY3Rpb24gLSB0aGUgZnVuY3Rpb24gdG8gY2FsbCB3aGVuIGEgZGF0ZSBpcyBzZWxlY3RlZFxuXHQgICBAcGFyYW0gIHNldHRpbmdzICBvYmplY3QgLSB1cGRhdGUgdGhlIGRpYWxvZyBkYXRlIHBpY2tlciBpbnN0YW5jZSdzIHNldHRpbmdzIChhbm9ueW1vdXMgb2JqZWN0KVxuXHQgICBAcGFyYW0gIHBvcyAgICAgICBpbnRbMl0gLSBjb29yZGluYXRlcyBmb3IgdGhlIGRpYWxvZydzIHBvc2l0aW9uIHdpdGhpbiB0aGUgc2NyZWVuIG9yXG5cdCAgICAgICAgICAgICAgICAgICAgIGV2ZW50IC0gd2l0aCB4L3kgY29vcmRpbmF0ZXMgb3Jcblx0ICAgICAgICAgICAgICAgICAgICAgbGVhdmUgZW1wdHkgZm9yIGRlZmF1bHQgKHNjcmVlbiBjZW50cmUpXG5cdCAgIEByZXR1cm4gdGhlIG1hbmFnZXIgb2JqZWN0ICovXG5cdF9kaWFsb2dEYXRlcGlja2VyOiBmdW5jdGlvbihpbnB1dCwgZGF0ZSwgb25TZWxlY3QsIHNldHRpbmdzLCBwb3MpIHtcblx0XHR2YXIgaW5zdCA9IHRoaXMuX2RpYWxvZ0luc3Q7IC8vIGludGVybmFsIGluc3RhbmNlXG5cdFx0aWYgKCFpbnN0KSB7XG5cdFx0XHR0aGlzLnV1aWQgKz0gMTtcblx0XHRcdHZhciBpZCA9ICdkcCcgKyB0aGlzLnV1aWQ7XG5cdFx0XHR0aGlzLl9kaWFsb2dJbnB1dCA9ICQoJzxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwiJyArIGlkICtcblx0XHRcdFx0J1wiIHN0eWxlPVwicG9zaXRpb246IGFic29sdXRlOyB0b3A6IC0xMDBweDsgd2lkdGg6IDBweDtcIi8+Jyk7XG5cdFx0XHR0aGlzLl9kaWFsb2dJbnB1dC5rZXlkb3duKHRoaXMuX2RvS2V5RG93bik7XG5cdFx0XHQkKCdib2R5JykuYXBwZW5kKHRoaXMuX2RpYWxvZ0lucHV0KTtcblx0XHRcdGluc3QgPSB0aGlzLl9kaWFsb2dJbnN0ID0gdGhpcy5fbmV3SW5zdCh0aGlzLl9kaWFsb2dJbnB1dCwgZmFsc2UpO1xuXHRcdFx0aW5zdC5zZXR0aW5ncyA9IHt9O1xuXHRcdFx0JC5kYXRhKHRoaXMuX2RpYWxvZ0lucHV0WzBdLCBQUk9QX05BTUUsIGluc3QpO1xuXHRcdH1cblx0XHRleHRlbmRSZW1vdmUoaW5zdC5zZXR0aW5ncywgc2V0dGluZ3MgfHwge30pO1xuXHRcdGRhdGUgPSAoZGF0ZSAmJiBkYXRlLmNvbnN0cnVjdG9yID09IERhdGUgPyB0aGlzLl9mb3JtYXREYXRlKGluc3QsIGRhdGUpIDogZGF0ZSk7XG5cdFx0dGhpcy5fZGlhbG9nSW5wdXQudmFsKGRhdGUpO1xuXG5cdFx0dGhpcy5fcG9zID0gKHBvcyA/IChwb3MubGVuZ3RoID8gcG9zIDogW3Bvcy5wYWdlWCwgcG9zLnBhZ2VZXSkgOiBudWxsKTtcblx0XHRpZiAoIXRoaXMuX3Bvcykge1xuXHRcdFx0dmFyIGJyb3dzZXJXaWR0aCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aDtcblx0XHRcdHZhciBicm93c2VySGVpZ2h0ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodDtcblx0XHRcdHZhciBzY3JvbGxYID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxMZWZ0O1xuXHRcdFx0dmFyIHNjcm9sbFkgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wIHx8IGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wO1xuXHRcdFx0dGhpcy5fcG9zID0gLy8gc2hvdWxkIHVzZSBhY3R1YWwgd2lkdGgvaGVpZ2h0IGJlbG93XG5cdFx0XHRcdFsoYnJvd3NlcldpZHRoIC8gMikgLSAxMDAgKyBzY3JvbGxYLCAoYnJvd3NlckhlaWdodCAvIDIpIC0gMTUwICsgc2Nyb2xsWV07XG5cdFx0fVxuXG5cdFx0Ly8gbW92ZSBpbnB1dCBvbiBzY3JlZW4gZm9yIGZvY3VzLCBidXQgaGlkZGVuIGJlaGluZCBkaWFsb2dcblx0XHR0aGlzLl9kaWFsb2dJbnB1dC5jc3MoJ2xlZnQnLCAodGhpcy5fcG9zWzBdICsgMjApICsgJ3B4JykuY3NzKCd0b3AnLCB0aGlzLl9wb3NbMV0gKyAncHgnKTtcblx0XHRpbnN0LnNldHRpbmdzLm9uU2VsZWN0ID0gb25TZWxlY3Q7XG5cdFx0dGhpcy5faW5EaWFsb2cgPSB0cnVlO1xuXHRcdHRoaXMuZHBEaXYuYWRkQ2xhc3ModGhpcy5fZGlhbG9nQ2xhc3MpO1xuXHRcdHRoaXMuX3Nob3dEYXRlcGlja2VyKHRoaXMuX2RpYWxvZ0lucHV0WzBdKTtcblx0XHRpZiAoJC5ibG9ja1VJKVxuXHRcdFx0JC5ibG9ja1VJKHRoaXMuZHBEaXYpO1xuXHRcdCQuZGF0YSh0aGlzLl9kaWFsb2dJbnB1dFswXSwgUFJPUF9OQU1FLCBpbnN0KTtcblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHQvKiBEZXRhY2ggYSBkYXRlcGlja2VyIGZyb20gaXRzIGNvbnRyb2wuXG5cdCAgIEBwYXJhbSAgdGFyZ2V0ICAgIGVsZW1lbnQgLSB0aGUgdGFyZ2V0IGlucHV0IGZpZWxkIG9yIGRpdmlzaW9uIG9yIHNwYW4gKi9cblx0X2Rlc3Ryb3lEYXRlcGlja2VyOiBmdW5jdGlvbih0YXJnZXQpIHtcblx0XHR2YXIgJHRhcmdldCA9ICQodGFyZ2V0KTtcblx0XHR2YXIgaW5zdCA9ICQuZGF0YSh0YXJnZXQsIFBST1BfTkFNRSk7XG5cdFx0aWYgKCEkdGFyZ2V0Lmhhc0NsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHR2YXIgbm9kZU5hbWUgPSB0YXJnZXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHQkLnJlbW92ZURhdGEodGFyZ2V0LCBQUk9QX05BTUUpO1xuXHRcdGlmIChub2RlTmFtZSA9PSAnaW5wdXQnKSB7XG5cdFx0XHRpbnN0LmFwcGVuZC5yZW1vdmUoKTtcblx0XHRcdGluc3QudHJpZ2dlci5yZW1vdmUoKTtcblx0XHRcdCR0YXJnZXQucmVtb3ZlQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpLlxuXHRcdFx0XHR1bmJpbmQoJ2ZvY3VzJywgdGhpcy5fc2hvd0RhdGVwaWNrZXIpLlxuXHRcdFx0XHR1bmJpbmQoJ2tleWRvd24nLCB0aGlzLl9kb0tleURvd24pLlxuXHRcdFx0XHR1bmJpbmQoJ2tleXByZXNzJywgdGhpcy5fZG9LZXlQcmVzcykuXG5cdFx0XHRcdHVuYmluZCgna2V5dXAnLCB0aGlzLl9kb0tleVVwKTtcblx0XHR9IGVsc2UgaWYgKG5vZGVOYW1lID09ICdkaXYnIHx8IG5vZGVOYW1lID09ICdzcGFuJylcblx0XHRcdCR0YXJnZXQucmVtb3ZlQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpLmVtcHR5KCk7XG5cdH0sXG5cblx0LyogRW5hYmxlIHRoZSBkYXRlIHBpY2tlciB0byBhIGpRdWVyeSBzZWxlY3Rpb24uXG5cdCAgIEBwYXJhbSAgdGFyZ2V0ICAgIGVsZW1lbnQgLSB0aGUgdGFyZ2V0IGlucHV0IGZpZWxkIG9yIGRpdmlzaW9uIG9yIHNwYW4gKi9cblx0X2VuYWJsZURhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCkge1xuXHRcdHZhciAkdGFyZ2V0ID0gJCh0YXJnZXQpO1xuXHRcdHZhciBpbnN0ID0gJC5kYXRhKHRhcmdldCwgUFJPUF9OQU1FKTtcblx0XHRpZiAoISR0YXJnZXQuaGFzQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHZhciBub2RlTmFtZSA9IHRhcmdldC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdGlmIChub2RlTmFtZSA9PSAnaW5wdXQnKSB7XG5cdFx0XHR0YXJnZXQuZGlzYWJsZWQgPSBmYWxzZTtcblx0XHRcdGluc3QudHJpZ2dlci5maWx0ZXIoJ2J1dHRvbicpLlxuXHRcdFx0XHRlYWNoKGZ1bmN0aW9uKCkgeyB0aGlzLmRpc2FibGVkID0gZmFsc2U7IH0pLmVuZCgpLlxuXHRcdFx0XHRmaWx0ZXIoJ2ltZycpLmNzcyh7b3BhY2l0eTogJzEuMCcsIGN1cnNvcjogJyd9KTtcblx0XHR9XG5cdFx0ZWxzZSBpZiAobm9kZU5hbWUgPT0gJ2RpdicgfHwgbm9kZU5hbWUgPT0gJ3NwYW4nKSB7XG5cdFx0XHR2YXIgaW5saW5lID0gJHRhcmdldC5jaGlsZHJlbignLicgKyB0aGlzLl9pbmxpbmVDbGFzcyk7XG5cdFx0XHRpbmxpbmUuY2hpbGRyZW4oKS5yZW1vdmVDbGFzcygndWktc3RhdGUtZGlzYWJsZWQnKTtcblx0XHRcdGlubGluZS5maW5kKFwic2VsZWN0LnVpLWRhdGVwaWNrZXItbW9udGgsIHNlbGVjdC51aS1kYXRlcGlja2VyLXllYXJcIikuXG5cdFx0XHRcdHByb3AoXCJkaXNhYmxlZFwiLCBmYWxzZSk7XG5cdFx0fVxuXHRcdHRoaXMuX2Rpc2FibGVkSW5wdXRzID0gJC5tYXAodGhpcy5fZGlzYWJsZWRJbnB1dHMsXG5cdFx0XHRmdW5jdGlvbih2YWx1ZSkgeyByZXR1cm4gKHZhbHVlID09IHRhcmdldCA/IG51bGwgOiB2YWx1ZSk7IH0pOyAvLyBkZWxldGUgZW50cnlcblx0fSxcblxuXHQvKiBEaXNhYmxlIHRoZSBkYXRlIHBpY2tlciB0byBhIGpRdWVyeSBzZWxlY3Rpb24uXG5cdCAgIEBwYXJhbSAgdGFyZ2V0ICAgIGVsZW1lbnQgLSB0aGUgdGFyZ2V0IGlucHV0IGZpZWxkIG9yIGRpdmlzaW9uIG9yIHNwYW4gKi9cblx0X2Rpc2FibGVEYXRlcGlja2VyOiBmdW5jdGlvbih0YXJnZXQpIHtcblx0XHR2YXIgJHRhcmdldCA9ICQodGFyZ2V0KTtcblx0XHR2YXIgaW5zdCA9ICQuZGF0YSh0YXJnZXQsIFBST1BfTkFNRSk7XG5cdFx0aWYgKCEkdGFyZ2V0Lmhhc0NsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHR2YXIgbm9kZU5hbWUgPSB0YXJnZXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRpZiAobm9kZU5hbWUgPT0gJ2lucHV0Jykge1xuXHRcdFx0dGFyZ2V0LmRpc2FibGVkID0gdHJ1ZTtcblx0XHRcdGluc3QudHJpZ2dlci5maWx0ZXIoJ2J1dHRvbicpLlxuXHRcdFx0XHRlYWNoKGZ1bmN0aW9uKCkgeyB0aGlzLmRpc2FibGVkID0gdHJ1ZTsgfSkuZW5kKCkuXG5cdFx0XHRcdGZpbHRlcignaW1nJykuY3NzKHtvcGFjaXR5OiAnMC41JywgY3Vyc29yOiAnZGVmYXVsdCd9KTtcblx0XHR9XG5cdFx0ZWxzZSBpZiAobm9kZU5hbWUgPT0gJ2RpdicgfHwgbm9kZU5hbWUgPT0gJ3NwYW4nKSB7XG5cdFx0XHR2YXIgaW5saW5lID0gJHRhcmdldC5jaGlsZHJlbignLicgKyB0aGlzLl9pbmxpbmVDbGFzcyk7XG5cdFx0XHRpbmxpbmUuY2hpbGRyZW4oKS5hZGRDbGFzcygndWktc3RhdGUtZGlzYWJsZWQnKTtcblx0XHRcdGlubGluZS5maW5kKFwic2VsZWN0LnVpLWRhdGVwaWNrZXItbW9udGgsIHNlbGVjdC51aS1kYXRlcGlja2VyLXllYXJcIikuXG5cdFx0XHRcdHByb3AoXCJkaXNhYmxlZFwiLCB0cnVlKTtcblx0XHR9XG5cdFx0dGhpcy5fZGlzYWJsZWRJbnB1dHMgPSAkLm1hcCh0aGlzLl9kaXNhYmxlZElucHV0cyxcblx0XHRcdGZ1bmN0aW9uKHZhbHVlKSB7IHJldHVybiAodmFsdWUgPT0gdGFyZ2V0ID8gbnVsbCA6IHZhbHVlKTsgfSk7IC8vIGRlbGV0ZSBlbnRyeVxuXHRcdHRoaXMuX2Rpc2FibGVkSW5wdXRzW3RoaXMuX2Rpc2FibGVkSW5wdXRzLmxlbmd0aF0gPSB0YXJnZXQ7XG5cdH0sXG5cblx0LyogSXMgdGhlIGZpcnN0IGZpZWxkIGluIGEgalF1ZXJ5IGNvbGxlY3Rpb24gZGlzYWJsZWQgYXMgYSBkYXRlcGlja2VyP1xuXHQgICBAcGFyYW0gIHRhcmdldCAgICBlbGVtZW50IC0gdGhlIHRhcmdldCBpbnB1dCBmaWVsZCBvciBkaXZpc2lvbiBvciBzcGFuXG5cdCAgIEByZXR1cm4gYm9vbGVhbiAtIHRydWUgaWYgZGlzYWJsZWQsIGZhbHNlIGlmIGVuYWJsZWQgKi9cblx0X2lzRGlzYWJsZWREYXRlcGlja2VyOiBmdW5jdGlvbih0YXJnZXQpIHtcblx0XHRpZiAoIXRhcmdldCkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX2Rpc2FibGVkSW5wdXRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAodGhpcy5fZGlzYWJsZWRJbnB1dHNbaV0gPT0gdGFyZ2V0KVxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9LFxuXG5cdC8qIFJldHJpZXZlIHRoZSBpbnN0YW5jZSBkYXRhIGZvciB0aGUgdGFyZ2V0IGNvbnRyb2wuXG5cdCAgIEBwYXJhbSAgdGFyZ2V0ICBlbGVtZW50IC0gdGhlIHRhcmdldCBpbnB1dCBmaWVsZCBvciBkaXZpc2lvbiBvciBzcGFuXG5cdCAgIEByZXR1cm4gIG9iamVjdCAtIHRoZSBhc3NvY2lhdGVkIGluc3RhbmNlIGRhdGFcblx0ICAgQHRocm93cyAgZXJyb3IgaWYgYSBqUXVlcnkgcHJvYmxlbSBnZXR0aW5nIGRhdGEgKi9cblx0X2dldEluc3Q6IGZ1bmN0aW9uKHRhcmdldCkge1xuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gJC5kYXRhKHRhcmdldCwgUFJPUF9OQU1FKTtcblx0XHR9XG5cdFx0Y2F0Y2ggKGVycikge1xuXHRcdFx0dGhyb3cgJ01pc3NpbmcgaW5zdGFuY2UgZGF0YSBmb3IgdGhpcyBkYXRlcGlja2VyJztcblx0XHR9XG5cdH0sXG5cblx0LyogVXBkYXRlIG9yIHJldHJpZXZlIHRoZSBzZXR0aW5ncyBmb3IgYSBkYXRlIHBpY2tlciBhdHRhY2hlZCB0byBhbiBpbnB1dCBmaWVsZCBvciBkaXZpc2lvbi5cblx0ICAgQHBhcmFtICB0YXJnZXQgIGVsZW1lbnQgLSB0aGUgdGFyZ2V0IGlucHV0IGZpZWxkIG9yIGRpdmlzaW9uIG9yIHNwYW5cblx0ICAgQHBhcmFtICBuYW1lICAgIG9iamVjdCAtIHRoZSBuZXcgc2V0dGluZ3MgdG8gdXBkYXRlIG9yXG5cdCAgICAgICAgICAgICAgICAgICBzdHJpbmcgLSB0aGUgbmFtZSBvZiB0aGUgc2V0dGluZyB0byBjaGFuZ2Ugb3IgcmV0cmlldmUsXG5cdCAgICAgICAgICAgICAgICAgICB3aGVuIHJldHJpZXZpbmcgYWxzbyAnYWxsJyBmb3IgYWxsIGluc3RhbmNlIHNldHRpbmdzIG9yXG5cdCAgICAgICAgICAgICAgICAgICAnZGVmYXVsdHMnIGZvciBhbGwgZ2xvYmFsIGRlZmF1bHRzXG5cdCAgIEBwYXJhbSAgdmFsdWUgICBhbnkgLSB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc2V0dGluZ1xuXHQgICAgICAgICAgICAgICAgICAgKG9taXQgaWYgYWJvdmUgaXMgYW4gb2JqZWN0IG9yIHRvIHJldHJpZXZlIGEgdmFsdWUpICovXG5cdF9vcHRpb25EYXRlcGlja2VyOiBmdW5jdGlvbih0YXJnZXQsIG5hbWUsIHZhbHVlKSB7XG5cdFx0dmFyIGluc3QgPSB0aGlzLl9nZXRJbnN0KHRhcmdldCk7XG5cdFx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMiAmJiB0eXBlb2YgbmFtZSA9PSAnc3RyaW5nJykge1xuXHRcdFx0cmV0dXJuIChuYW1lID09ICdkZWZhdWx0cycgPyAkLmV4dGVuZCh7fSwgJC5kYXRlcGlja2VyLl9kZWZhdWx0cykgOlxuXHRcdFx0XHQoaW5zdCA/IChuYW1lID09ICdhbGwnID8gJC5leHRlbmQoe30sIGluc3Quc2V0dGluZ3MpIDpcblx0XHRcdFx0dGhpcy5fZ2V0KGluc3QsIG5hbWUpKSA6IG51bGwpKTtcblx0XHR9XG5cdFx0dmFyIHNldHRpbmdzID0gbmFtZSB8fCB7fTtcblx0XHRpZiAodHlwZW9mIG5hbWUgPT0gJ3N0cmluZycpIHtcblx0XHRcdHNldHRpbmdzID0ge307XG5cdFx0XHRzZXR0aW5nc1tuYW1lXSA9IHZhbHVlO1xuXHRcdH1cblx0XHRpZiAoaW5zdCkge1xuXHRcdFx0aWYgKHRoaXMuX2N1ckluc3QgPT0gaW5zdCkge1xuXHRcdFx0XHR0aGlzLl9oaWRlRGF0ZXBpY2tlcigpO1xuXHRcdFx0fVxuXHRcdFx0dmFyIGRhdGUgPSB0aGlzLl9nZXREYXRlRGF0ZXBpY2tlcih0YXJnZXQsIHRydWUpO1xuXHRcdFx0dmFyIG1pbkRhdGUgPSB0aGlzLl9nZXRNaW5NYXhEYXRlKGluc3QsICdtaW4nKTtcblx0XHRcdHZhciBtYXhEYXRlID0gdGhpcy5fZ2V0TWluTWF4RGF0ZShpbnN0LCAnbWF4Jyk7XG5cdFx0XHRleHRlbmRSZW1vdmUoaW5zdC5zZXR0aW5ncywgc2V0dGluZ3MpO1xuXHRcdFx0Ly8gcmVmb3JtYXQgdGhlIG9sZCBtaW5EYXRlL21heERhdGUgdmFsdWVzIGlmIGRhdGVGb3JtYXQgY2hhbmdlcyBhbmQgYSBuZXcgbWluRGF0ZS9tYXhEYXRlIGlzbid0IHByb3ZpZGVkXG5cdFx0XHRpZiAobWluRGF0ZSAhPT0gbnVsbCAmJiBzZXR0aW5nc1snZGF0ZUZvcm1hdCddICE9PSB1bmRlZmluZWQgJiYgc2V0dGluZ3NbJ21pbkRhdGUnXSA9PT0gdW5kZWZpbmVkKVxuXHRcdFx0XHRpbnN0LnNldHRpbmdzLm1pbkRhdGUgPSB0aGlzLl9mb3JtYXREYXRlKGluc3QsIG1pbkRhdGUpO1xuXHRcdFx0aWYgKG1heERhdGUgIT09IG51bGwgJiYgc2V0dGluZ3NbJ2RhdGVGb3JtYXQnXSAhPT0gdW5kZWZpbmVkICYmIHNldHRpbmdzWydtYXhEYXRlJ10gPT09IHVuZGVmaW5lZClcblx0XHRcdFx0aW5zdC5zZXR0aW5ncy5tYXhEYXRlID0gdGhpcy5fZm9ybWF0RGF0ZShpbnN0LCBtYXhEYXRlKTtcblx0XHRcdHRoaXMuX2F0dGFjaG1lbnRzKCQodGFyZ2V0KSwgaW5zdCk7XG5cdFx0XHR0aGlzLl9hdXRvU2l6ZShpbnN0KTtcblx0XHRcdHRoaXMuX3NldERhdGUoaW5zdCwgZGF0ZSk7XG5cdFx0XHR0aGlzLl91cGRhdGVBbHRlcm5hdGUoaW5zdCk7XG5cdFx0XHR0aGlzLl91cGRhdGVEYXRlcGlja2VyKGluc3QpO1xuXHRcdH1cblx0fSxcblxuXHQvLyBjaGFuZ2UgbWV0aG9kIGRlcHJlY2F0ZWRcblx0X2NoYW5nZURhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCwgbmFtZSwgdmFsdWUpIHtcblx0XHR0aGlzLl9vcHRpb25EYXRlcGlja2VyKHRhcmdldCwgbmFtZSwgdmFsdWUpO1xuXHR9LFxuXG5cdC8qIFJlZHJhdyB0aGUgZGF0ZSBwaWNrZXIgYXR0YWNoZWQgdG8gYW4gaW5wdXQgZmllbGQgb3IgZGl2aXNpb24uXG5cdCAgIEBwYXJhbSAgdGFyZ2V0ICBlbGVtZW50IC0gdGhlIHRhcmdldCBpbnB1dCBmaWVsZCBvciBkaXZpc2lvbiBvciBzcGFuICovXG5cdF9yZWZyZXNoRGF0ZXBpY2tlcjogZnVuY3Rpb24odGFyZ2V0KSB7XG5cdFx0dmFyIGluc3QgPSB0aGlzLl9nZXRJbnN0KHRhcmdldCk7XG5cdFx0aWYgKGluc3QpIHtcblx0XHRcdHRoaXMuX3VwZGF0ZURhdGVwaWNrZXIoaW5zdCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIFNldCB0aGUgZGF0ZXMgZm9yIGEgalF1ZXJ5IHNlbGVjdGlvbi5cblx0ICAgQHBhcmFtICB0YXJnZXQgICBlbGVtZW50IC0gdGhlIHRhcmdldCBpbnB1dCBmaWVsZCBvciBkaXZpc2lvbiBvciBzcGFuXG5cdCAgIEBwYXJhbSAgZGF0ZSAgICAgRGF0ZSAtIHRoZSBuZXcgZGF0ZSAqL1xuXHRfc2V0RGF0ZURhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCwgZGF0ZSkge1xuXHRcdHZhciBpbnN0ID0gdGhpcy5fZ2V0SW5zdCh0YXJnZXQpO1xuXHRcdGlmIChpbnN0KSB7XG5cdFx0XHR0aGlzLl9zZXREYXRlKGluc3QsIGRhdGUpO1xuXHRcdFx0dGhpcy5fdXBkYXRlRGF0ZXBpY2tlcihpbnN0KTtcblx0XHRcdHRoaXMuX3VwZGF0ZUFsdGVybmF0ZShpbnN0KTtcblx0XHR9XG5cdH0sXG5cblx0LyogR2V0IHRoZSBkYXRlKHMpIGZvciB0aGUgZmlyc3QgZW50cnkgaW4gYSBqUXVlcnkgc2VsZWN0aW9uLlxuXHQgICBAcGFyYW0gIHRhcmdldCAgICAgZWxlbWVudCAtIHRoZSB0YXJnZXQgaW5wdXQgZmllbGQgb3IgZGl2aXNpb24gb3Igc3BhblxuXHQgICBAcGFyYW0gIG5vRGVmYXVsdCAgYm9vbGVhbiAtIHRydWUgaWYgbm8gZGVmYXVsdCBkYXRlIGlzIHRvIGJlIHVzZWRcblx0ICAgQHJldHVybiBEYXRlIC0gdGhlIGN1cnJlbnQgZGF0ZSAqL1xuXHRfZ2V0RGF0ZURhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCwgbm9EZWZhdWx0KSB7XG5cdFx0dmFyIGluc3QgPSB0aGlzLl9nZXRJbnN0KHRhcmdldCk7XG5cdFx0aWYgKGluc3QgJiYgIWluc3QuaW5saW5lKVxuXHRcdFx0dGhpcy5fc2V0RGF0ZUZyb21GaWVsZChpbnN0LCBub0RlZmF1bHQpO1xuXHRcdHJldHVybiAoaW5zdCA/IHRoaXMuX2dldERhdGUoaW5zdCkgOiBudWxsKTtcblx0fSxcblxuXHQvKiBIYW5kbGUga2V5c3Ryb2tlcy4gKi9cblx0X2RvS2V5RG93bjogZnVuY3Rpb24oZXZlbnQpIHtcblx0XHR2YXIgaW5zdCA9ICQuZGF0ZXBpY2tlci5fZ2V0SW5zdChldmVudC50YXJnZXQpO1xuXHRcdHZhciBoYW5kbGVkID0gdHJ1ZTtcblx0XHR2YXIgaXNSVEwgPSBpbnN0LmRwRGl2LmlzKCcudWktZGF0ZXBpY2tlci1ydGwnKTtcblx0XHRpbnN0Ll9rZXlFdmVudCA9IHRydWU7XG5cdFx0aWYgKCQuZGF0ZXBpY2tlci5fZGF0ZXBpY2tlclNob3dpbmcpXG5cdFx0XHRzd2l0Y2ggKGV2ZW50LmtleUNvZGUpIHtcblx0XHRcdFx0Y2FzZSA5OiAkLmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCk7XG5cdFx0XHRcdFx0XHRoYW5kbGVkID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRicmVhazsgLy8gaGlkZSBvbiB0YWIgb3V0XG5cdFx0XHRcdGNhc2UgMTM6IHZhciBzZWwgPSAkKCd0ZC4nICsgJC5kYXRlcGlja2VyLl9kYXlPdmVyQ2xhc3MgKyAnOm5vdCguJyArXG5cdFx0XHRcdFx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX2N1cnJlbnRDbGFzcyArICcpJywgaW5zdC5kcERpdik7XG5cdFx0XHRcdFx0XHRpZiAoc2VsWzBdKVxuXHRcdFx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX3NlbGVjdERheShldmVudC50YXJnZXQsIGluc3Quc2VsZWN0ZWRNb250aCwgaW5zdC5zZWxlY3RlZFllYXIsIHNlbFswXSk7XG5cdFx0XHRcdFx0XHRcdHZhciBvblNlbGVjdCA9ICQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsICdvblNlbGVjdCcpO1xuXHRcdFx0XHRcdFx0XHRpZiAob25TZWxlY3QpIHtcblx0XHRcdFx0XHRcdFx0XHR2YXIgZGF0ZVN0ciA9ICQuZGF0ZXBpY2tlci5fZm9ybWF0RGF0ZShpbnN0KTtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIHRyaWdnZXIgY3VzdG9tIGNhbGxiYWNrXG5cdFx0XHRcdFx0XHRcdFx0b25TZWxlY3QuYXBwbHkoKGluc3QuaW5wdXQgPyBpbnN0LmlucHV0WzBdIDogbnVsbCksIFtkYXRlU3RyLCBpbnN0XSk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGVsc2Vcblx0XHRcdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcigpO1xuXHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlOyAvLyBkb24ndCBzdWJtaXQgdGhlIGZvcm1cblx0XHRcdFx0XHRcdGJyZWFrOyAvLyBzZWxlY3QgdGhlIHZhbHVlIG9uIGVudGVyXG5cdFx0XHRcdGNhc2UgMjc6ICQuZGF0ZXBpY2tlci5faGlkZURhdGVwaWNrZXIoKTtcblx0XHRcdFx0XHRcdGJyZWFrOyAvLyBoaWRlIG9uIGVzY2FwZVxuXHRcdFx0XHRjYXNlIDMzOiAkLmRhdGVwaWNrZXIuX2FkanVzdERhdGUoZXZlbnQudGFyZ2V0LCAoZXZlbnQuY3RybEtleSA/XG5cdFx0XHRcdFx0XHRcdC0kLmRhdGVwaWNrZXIuX2dldChpbnN0LCAnc3RlcEJpZ01vbnRocycpIDpcblx0XHRcdFx0XHRcdFx0LSQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsICdzdGVwTW9udGhzJykpLCAnTScpO1xuXHRcdFx0XHRcdFx0YnJlYWs7IC8vIHByZXZpb3VzIG1vbnRoL3llYXIgb24gcGFnZSB1cC8rIGN0cmxcblx0XHRcdFx0Y2FzZSAzNDogJC5kYXRlcGlja2VyLl9hZGp1c3REYXRlKGV2ZW50LnRhcmdldCwgKGV2ZW50LmN0cmxLZXkgP1xuXHRcdFx0XHRcdFx0XHQrJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgJ3N0ZXBCaWdNb250aHMnKSA6XG5cdFx0XHRcdFx0XHRcdCskLmRhdGVwaWNrZXIuX2dldChpbnN0LCAnc3RlcE1vbnRocycpKSwgJ00nKTtcblx0XHRcdFx0XHRcdGJyZWFrOyAvLyBuZXh0IG1vbnRoL3llYXIgb24gcGFnZSBkb3duLysgY3RybFxuXHRcdFx0XHRjYXNlIDM1OiBpZiAoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5KSAkLmRhdGVwaWNrZXIuX2NsZWFyRGF0ZShldmVudC50YXJnZXQpO1xuXHRcdFx0XHRcdFx0aGFuZGxlZCA9IGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleTtcblx0XHRcdFx0XHRcdGJyZWFrOyAvLyBjbGVhciBvbiBjdHJsIG9yIGNvbW1hbmQgK2VuZFxuXHRcdFx0XHRjYXNlIDM2OiBpZiAoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5KSAkLmRhdGVwaWNrZXIuX2dvdG9Ub2RheShldmVudC50YXJnZXQpO1xuXHRcdFx0XHRcdFx0aGFuZGxlZCA9IGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleTtcblx0XHRcdFx0XHRcdGJyZWFrOyAvLyBjdXJyZW50IG9uIGN0cmwgb3IgY29tbWFuZCAraG9tZVxuXHRcdFx0XHRjYXNlIDM3OiBpZiAoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5KSAkLmRhdGVwaWNrZXIuX2FkanVzdERhdGUoZXZlbnQudGFyZ2V0LCAoaXNSVEwgPyArMSA6IC0xKSwgJ0QnKTtcblx0XHRcdFx0XHRcdGhhbmRsZWQgPSBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXk7XG5cdFx0XHRcdFx0XHQvLyAtMSBkYXkgb24gY3RybCBvciBjb21tYW5kICtsZWZ0XG5cdFx0XHRcdFx0XHRpZiAoZXZlbnQub3JpZ2luYWxFdmVudC5hbHRLZXkpICQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShldmVudC50YXJnZXQsIChldmVudC5jdHJsS2V5ID9cblx0XHRcdFx0XHRcdFx0XHRcdC0kLmRhdGVwaWNrZXIuX2dldChpbnN0LCAnc3RlcEJpZ01vbnRocycpIDpcblx0XHRcdFx0XHRcdFx0XHRcdC0kLmRhdGVwaWNrZXIuX2dldChpbnN0LCAnc3RlcE1vbnRocycpKSwgJ00nKTtcblx0XHRcdFx0XHRcdC8vIG5leHQgbW9udGgveWVhciBvbiBhbHQgK2xlZnQgb24gTWFjXG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAzODogaWYgKGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSkgJC5kYXRlcGlja2VyLl9hZGp1c3REYXRlKGV2ZW50LnRhcmdldCwgLTcsICdEJyk7XG5cdFx0XHRcdFx0XHRoYW5kbGVkID0gZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5O1xuXHRcdFx0XHRcdFx0YnJlYWs7IC8vIC0xIHdlZWsgb24gY3RybCBvciBjb21tYW5kICt1cFxuXHRcdFx0XHRjYXNlIDM5OiBpZiAoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5KSAkLmRhdGVwaWNrZXIuX2FkanVzdERhdGUoZXZlbnQudGFyZ2V0LCAoaXNSVEwgPyAtMSA6ICsxKSwgJ0QnKTtcblx0XHRcdFx0XHRcdGhhbmRsZWQgPSBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXk7XG5cdFx0XHRcdFx0XHQvLyArMSBkYXkgb24gY3RybCBvciBjb21tYW5kICtyaWdodFxuXHRcdFx0XHRcdFx0aWYgKGV2ZW50Lm9yaWdpbmFsRXZlbnQuYWx0S2V5KSAkLmRhdGVwaWNrZXIuX2FkanVzdERhdGUoZXZlbnQudGFyZ2V0LCAoZXZlbnQuY3RybEtleSA/XG5cdFx0XHRcdFx0XHRcdFx0XHQrJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgJ3N0ZXBCaWdNb250aHMnKSA6XG5cdFx0XHRcdFx0XHRcdFx0XHQrJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgJ3N0ZXBNb250aHMnKSksICdNJyk7XG5cdFx0XHRcdFx0XHQvLyBuZXh0IG1vbnRoL3llYXIgb24gYWx0ICtyaWdodFxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgNDA6IGlmIChldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkpICQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShldmVudC50YXJnZXQsICs3LCAnRCcpO1xuXHRcdFx0XHRcdFx0aGFuZGxlZCA9IGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleTtcblx0XHRcdFx0XHRcdGJyZWFrOyAvLyArMSB3ZWVrIG9uIGN0cmwgb3IgY29tbWFuZCArZG93blxuXHRcdFx0XHRkZWZhdWx0OiBoYW5kbGVkID0gZmFsc2U7XG5cdFx0XHR9XG5cdFx0ZWxzZSBpZiAoZXZlbnQua2V5Q29kZSA9PSAzNiAmJiBldmVudC5jdHJsS2V5KSAvLyBkaXNwbGF5IHRoZSBkYXRlIHBpY2tlciBvbiBjdHJsK2hvbWVcblx0XHRcdCQuZGF0ZXBpY2tlci5fc2hvd0RhdGVwaWNrZXIodGhpcyk7XG5cdFx0ZWxzZSB7XG5cdFx0XHRoYW5kbGVkID0gZmFsc2U7XG5cdFx0fVxuXHRcdGlmIChoYW5kbGVkKSB7XG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIEZpbHRlciBlbnRlcmVkIGNoYXJhY3RlcnMgLSBiYXNlZCBvbiBkYXRlIGZvcm1hdC4gKi9cblx0X2RvS2V5UHJlc3M6IGZ1bmN0aW9uKGV2ZW50KSB7XG5cdFx0dmFyIGluc3QgPSAkLmRhdGVwaWNrZXIuX2dldEluc3QoZXZlbnQudGFyZ2V0KTtcblx0XHRpZiAoJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgJ2NvbnN0cmFpbklucHV0JykpIHtcblx0XHRcdHZhciBjaGFycyA9ICQuZGF0ZXBpY2tlci5fcG9zc2libGVDaGFycygkLmRhdGVwaWNrZXIuX2dldChpbnN0LCAnZGF0ZUZvcm1hdCcpKTtcblx0XHRcdHZhciBjaHIgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGV2ZW50LmNoYXJDb2RlID09IHVuZGVmaW5lZCA/IGV2ZW50LmtleUNvZGUgOiBldmVudC5jaGFyQ29kZSk7XG5cdFx0XHRyZXR1cm4gZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5IHx8IChjaHIgPCAnICcgfHwgIWNoYXJzIHx8IGNoYXJzLmluZGV4T2YoY2hyKSA+IC0xKTtcblx0XHR9XG5cdH0sXG5cblx0LyogU3luY2hyb25pc2UgbWFudWFsIGVudHJ5IGFuZCBmaWVsZC9hbHRlcm5hdGUgZmllbGQuICovXG5cdF9kb0tleVVwOiBmdW5jdGlvbihldmVudCkge1xuXHRcdHZhciBpbnN0ID0gJC5kYXRlcGlja2VyLl9nZXRJbnN0KGV2ZW50LnRhcmdldCk7XG5cdFx0aWYgKGluc3QuaW5wdXQudmFsKCkgIT0gaW5zdC5sYXN0VmFsKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHR2YXIgZGF0ZSA9ICQuZGF0ZXBpY2tlci5wYXJzZURhdGUoJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgJ2RhdGVGb3JtYXQnKSxcblx0XHRcdFx0XHQoaW5zdC5pbnB1dCA/IGluc3QuaW5wdXQudmFsKCkgOiBudWxsKSxcblx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX2dldEZvcm1hdENvbmZpZyhpbnN0KSk7XG5cdFx0XHRcdGlmIChkYXRlKSB7IC8vIG9ubHkgaWYgdmFsaWRcblx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX3NldERhdGVGcm9tRmllbGQoaW5zdCk7XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl91cGRhdGVBbHRlcm5hdGUoaW5zdCk7XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl91cGRhdGVEYXRlcGlja2VyKGluc3QpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRjYXRjaCAoZXJyKSB7XG5cdFx0XHRcdCQuZGF0ZXBpY2tlci5sb2coZXJyKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0sXG5cblx0LyogUG9wLXVwIHRoZSBkYXRlIHBpY2tlciBmb3IgYSBnaXZlbiBpbnB1dCBmaWVsZC5cblx0ICAgSWYgZmFsc2UgcmV0dXJuZWQgZnJvbSBiZWZvcmVTaG93IGV2ZW50IGhhbmRsZXIgZG8gbm90IHNob3cuXG5cdCAgIEBwYXJhbSAgaW5wdXQgIGVsZW1lbnQgLSB0aGUgaW5wdXQgZmllbGQgYXR0YWNoZWQgdG8gdGhlIGRhdGUgcGlja2VyIG9yXG5cdCAgICAgICAgICAgICAgICAgIGV2ZW50IC0gaWYgdHJpZ2dlcmVkIGJ5IGZvY3VzICovXG5cdF9zaG93RGF0ZXBpY2tlcjogZnVuY3Rpb24oaW5wdXQpIHtcblx0XHRpbnB1dCA9IGlucHV0LnRhcmdldCB8fCBpbnB1dDtcblx0XHRpZiAoaW5wdXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSAhPSAnaW5wdXQnKSAvLyBmaW5kIGZyb20gYnV0dG9uL2ltYWdlIHRyaWdnZXJcblx0XHRcdGlucHV0ID0gJCgnaW5wdXQnLCBpbnB1dC5wYXJlbnROb2RlKVswXTtcblx0XHRpZiAoJC5kYXRlcGlja2VyLl9pc0Rpc2FibGVkRGF0ZXBpY2tlcihpbnB1dCkgfHwgJC5kYXRlcGlja2VyLl9sYXN0SW5wdXQgPT0gaW5wdXQpIC8vIGFscmVhZHkgaGVyZVxuXHRcdFx0cmV0dXJuO1xuXHRcdHZhciBpbnN0ID0gJC5kYXRlcGlja2VyLl9nZXRJbnN0KGlucHV0KTtcblx0XHRpZiAoJC5kYXRlcGlja2VyLl9jdXJJbnN0ICYmICQuZGF0ZXBpY2tlci5fY3VySW5zdCAhPSBpbnN0KSB7XG5cdFx0XHQkLmRhdGVwaWNrZXIuX2N1ckluc3QuZHBEaXYuc3RvcCh0cnVlLCB0cnVlKTtcblx0XHRcdGlmICggaW5zdCAmJiAkLmRhdGVwaWNrZXIuX2RhdGVwaWNrZXJTaG93aW5nICkge1xuXHRcdFx0XHQkLmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCAkLmRhdGVwaWNrZXIuX2N1ckluc3QuaW5wdXRbMF0gKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0dmFyIGJlZm9yZVNob3cgPSAkLmRhdGVwaWNrZXIuX2dldChpbnN0LCAnYmVmb3JlU2hvdycpO1xuXHRcdHZhciBiZWZvcmVTaG93U2V0dGluZ3MgPSBiZWZvcmVTaG93ID8gYmVmb3JlU2hvdy5hcHBseShpbnB1dCwgW2lucHV0LCBpbnN0XSkgOiB7fTtcblx0XHRpZihiZWZvcmVTaG93U2V0dGluZ3MgPT09IGZhbHNlKXtcblx0XHRcdC8vZmFsc2Vcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0ZXh0ZW5kUmVtb3ZlKGluc3Quc2V0dGluZ3MsIGJlZm9yZVNob3dTZXR0aW5ncyk7XG5cdFx0aW5zdC5sYXN0VmFsID0gbnVsbDtcblx0XHQkLmRhdGVwaWNrZXIuX2xhc3RJbnB1dCA9IGlucHV0O1xuXHRcdCQuZGF0ZXBpY2tlci5fc2V0RGF0ZUZyb21GaWVsZChpbnN0KTtcblx0XHRpZiAoJC5kYXRlcGlja2VyLl9pbkRpYWxvZykgLy8gaGlkZSBjdXJzb3Jcblx0XHRcdGlucHV0LnZhbHVlID0gJyc7XG5cdFx0aWYgKCEkLmRhdGVwaWNrZXIuX3BvcykgeyAvLyBwb3NpdGlvbiBiZWxvdyBpbnB1dFxuXHRcdFx0JC5kYXRlcGlja2VyLl9wb3MgPSAkLmRhdGVwaWNrZXIuX2ZpbmRQb3MoaW5wdXQpO1xuXHRcdFx0JC5kYXRlcGlja2VyLl9wb3NbMV0gKz0gaW5wdXQub2Zmc2V0SGVpZ2h0OyAvLyBhZGQgdGhlIGhlaWdodFxuXHRcdH1cblx0XHR2YXIgaXNGaXhlZCA9IGZhbHNlO1xuXHRcdCQoaW5wdXQpLnBhcmVudHMoKS5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0aXNGaXhlZCB8PSAkKHRoaXMpLmNzcygncG9zaXRpb24nKSA9PSAnZml4ZWQnO1xuXHRcdFx0cmV0dXJuICFpc0ZpeGVkO1xuXHRcdH0pO1xuXHRcdHZhciBvZmZzZXQgPSB7bGVmdDogJC5kYXRlcGlja2VyLl9wb3NbMF0sIHRvcDogJC5kYXRlcGlja2VyLl9wb3NbMV19O1xuXHRcdCQuZGF0ZXBpY2tlci5fcG9zID0gbnVsbDtcblx0XHQvL3RvIGF2b2lkIGZsYXNoZXMgb24gRmlyZWZveFxuXHRcdGluc3QuZHBEaXYuZW1wdHkoKTtcblx0XHQvLyBkZXRlcm1pbmUgc2l6aW5nIG9mZnNjcmVlblxuXHRcdGluc3QuZHBEaXYuY3NzKHtwb3NpdGlvbjogJ2Fic29sdXRlJywgZGlzcGxheTogJ2Jsb2NrJywgdG9wOiAnLTEwMDBweCd9KTtcblx0XHQkLmRhdGVwaWNrZXIuX3VwZGF0ZURhdGVwaWNrZXIoaW5zdCk7XG5cdFx0Ly8gZml4IHdpZHRoIGZvciBkeW5hbWljIG51bWJlciBvZiBkYXRlIHBpY2tlcnNcblx0XHQvLyBhbmQgYWRqdXN0IHBvc2l0aW9uIGJlZm9yZSBzaG93aW5nXG5cdFx0b2Zmc2V0ID0gJC5kYXRlcGlja2VyLl9jaGVja09mZnNldChpbnN0LCBvZmZzZXQsIGlzRml4ZWQpO1xuXHRcdGluc3QuZHBEaXYuY3NzKHtwb3NpdGlvbjogKCQuZGF0ZXBpY2tlci5faW5EaWFsb2cgJiYgJC5ibG9ja1VJID9cblx0XHRcdCdzdGF0aWMnIDogKGlzRml4ZWQgPyAnZml4ZWQnIDogJ2Fic29sdXRlJykpLCBkaXNwbGF5OiAnbm9uZScsXG5cdFx0XHRsZWZ0OiBvZmZzZXQubGVmdCArICdweCcsIHRvcDogb2Zmc2V0LnRvcCArICdweCd9KTtcblx0XHRpZiAoIWluc3QuaW5saW5lKSB7XG5cdFx0XHR2YXIgc2hvd0FuaW0gPSAkLmRhdGVwaWNrZXIuX2dldChpbnN0LCAnc2hvd0FuaW0nKTtcblx0XHRcdHZhciBkdXJhdGlvbiA9ICQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsICdkdXJhdGlvbicpO1xuXHRcdFx0dmFyIHBvc3RQcm9jZXNzID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBjb3ZlciA9IGluc3QuZHBEaXYuZmluZCgnaWZyYW1lLnVpLWRhdGVwaWNrZXItY292ZXInKTsgLy8gSUU2LSBvbmx5XG5cdFx0XHRcdGlmKCAhISBjb3Zlci5sZW5ndGggKXtcblx0XHRcdFx0XHR2YXIgYm9yZGVycyA9ICQuZGF0ZXBpY2tlci5fZ2V0Qm9yZGVycyhpbnN0LmRwRGl2KTtcblx0XHRcdFx0XHRjb3Zlci5jc3Moe2xlZnQ6IC1ib3JkZXJzWzBdLCB0b3A6IC1ib3JkZXJzWzFdLFxuXHRcdFx0XHRcdFx0d2lkdGg6IGluc3QuZHBEaXYub3V0ZXJXaWR0aCgpLCBoZWlnaHQ6IGluc3QuZHBEaXYub3V0ZXJIZWlnaHQoKX0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdFx0aW5zdC5kcERpdi56SW5kZXgoJChpbnB1dCkuekluZGV4KCkrMSk7XG5cdFx0XHQkLmRhdGVwaWNrZXIuX2RhdGVwaWNrZXJTaG93aW5nID0gdHJ1ZTtcblxuXHRcdFx0Ly8gREVQUkVDQVRFRDogYWZ0ZXIgQkMgZm9yIDEuOC54ICQuZWZmZWN0c1sgc2hvd0FuaW0gXSBpcyBub3QgbmVlZGVkXG5cdFx0XHRpZiAoICQuZWZmZWN0cyAmJiAoICQuZWZmZWN0cy5lZmZlY3RbIHNob3dBbmltIF0gfHwgJC5lZmZlY3RzWyBzaG93QW5pbSBdICkgKVxuXHRcdFx0XHRpbnN0LmRwRGl2LnNob3coc2hvd0FuaW0sICQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsICdzaG93T3B0aW9ucycpLCBkdXJhdGlvbiwgcG9zdFByb2Nlc3MpO1xuXHRcdFx0ZWxzZVxuXHRcdFx0XHRpbnN0LmRwRGl2W3Nob3dBbmltIHx8ICdzaG93J10oKHNob3dBbmltID8gZHVyYXRpb24gOiBudWxsKSwgcG9zdFByb2Nlc3MpO1xuXHRcdFx0aWYgKCFzaG93QW5pbSB8fCAhZHVyYXRpb24pXG5cdFx0XHRcdHBvc3RQcm9jZXNzKCk7XG5cdFx0XHRpZiAoaW5zdC5pbnB1dC5pcygnOnZpc2libGUnKSAmJiAhaW5zdC5pbnB1dC5pcygnOmRpc2FibGVkJykpXG5cdFx0XHRcdGluc3QuaW5wdXQuZm9jdXMoKTtcblx0XHRcdCQuZGF0ZXBpY2tlci5fY3VySW5zdCA9IGluc3Q7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIEdlbmVyYXRlIHRoZSBkYXRlIHBpY2tlciBjb250ZW50LiAqL1xuXHRfdXBkYXRlRGF0ZXBpY2tlcjogZnVuY3Rpb24oaW5zdCkge1xuXHRcdHRoaXMubWF4Um93cyA9IDQ7IC8vUmVzZXQgdGhlIG1heCBudW1iZXIgb2Ygcm93cyBiZWluZyBkaXNwbGF5ZWQgKHNlZSAjNzA0Mylcblx0XHR2YXIgYm9yZGVycyA9ICQuZGF0ZXBpY2tlci5fZ2V0Qm9yZGVycyhpbnN0LmRwRGl2KTtcblx0XHRpbnN0QWN0aXZlID0gaW5zdDsgLy8gZm9yIGRlbGVnYXRlIGhvdmVyIGV2ZW50c1xuXHRcdGluc3QuZHBEaXYuZW1wdHkoKS5hcHBlbmQodGhpcy5fZ2VuZXJhdGVIVE1MKGluc3QpKTtcblx0XHR0aGlzLl9hdHRhY2hIYW5kbGVycyhpbnN0KTtcblx0XHR2YXIgY292ZXIgPSBpbnN0LmRwRGl2LmZpbmQoJ2lmcmFtZS51aS1kYXRlcGlja2VyLWNvdmVyJyk7IC8vIElFNi0gb25seVxuXHRcdGlmKCAhIWNvdmVyLmxlbmd0aCApeyAvL2F2b2lkIGNhbGwgdG8gb3V0ZXJYWFhYKCkgd2hlbiBub3QgaW4gSUU2XG5cdFx0XHRjb3Zlci5jc3Moe2xlZnQ6IC1ib3JkZXJzWzBdLCB0b3A6IC1ib3JkZXJzWzFdLCB3aWR0aDogaW5zdC5kcERpdi5vdXRlcldpZHRoKCksIGhlaWdodDogaW5zdC5kcERpdi5vdXRlckhlaWdodCgpfSlcblx0XHR9XG5cdFx0aW5zdC5kcERpdi5maW5kKCcuJyArIHRoaXMuX2RheU92ZXJDbGFzcyArICcgYScpLm1vdXNlb3ZlcigpO1xuXHRcdHZhciBudW1Nb250aHMgPSB0aGlzLl9nZXROdW1iZXJPZk1vbnRocyhpbnN0KTtcblx0XHR2YXIgY29scyA9IG51bU1vbnRoc1sxXTtcblx0XHR2YXIgd2lkdGggPSAxNztcblx0XHRpbnN0LmRwRGl2LnJlbW92ZUNsYXNzKCd1aS1kYXRlcGlja2VyLW11bHRpLTIgdWktZGF0ZXBpY2tlci1tdWx0aS0zIHVpLWRhdGVwaWNrZXItbXVsdGktNCcpLndpZHRoKCcnKTtcblx0XHRpZiAoY29scyA+IDEpXG5cdFx0XHRpbnN0LmRwRGl2LmFkZENsYXNzKCd1aS1kYXRlcGlja2VyLW11bHRpLScgKyBjb2xzKS5jc3MoJ3dpZHRoJywgKHdpZHRoICogY29scykgKyAnZW0nKTtcblx0XHRpbnN0LmRwRGl2WyhudW1Nb250aHNbMF0gIT0gMSB8fCBudW1Nb250aHNbMV0gIT0gMSA/ICdhZGQnIDogJ3JlbW92ZScpICtcblx0XHRcdCdDbGFzcyddKCd1aS1kYXRlcGlja2VyLW11bHRpJyk7XG5cdFx0aW5zdC5kcERpdlsodGhpcy5fZ2V0KGluc3QsICdpc1JUTCcpID8gJ2FkZCcgOiAncmVtb3ZlJykgK1xuXHRcdFx0J0NsYXNzJ10oJ3VpLWRhdGVwaWNrZXItcnRsJyk7XG5cdFx0aWYgKGluc3QgPT0gJC5kYXRlcGlja2VyLl9jdXJJbnN0ICYmICQuZGF0ZXBpY2tlci5fZGF0ZXBpY2tlclNob3dpbmcgJiYgaW5zdC5pbnB1dCAmJlxuXHRcdFx0XHQvLyAjNjY5NCAtIGRvbid0IGZvY3VzIHRoZSBpbnB1dCBpZiBpdCdzIGFscmVhZHkgZm9jdXNlZFxuXHRcdFx0XHQvLyB0aGlzIGJyZWFrcyB0aGUgY2hhbmdlIGV2ZW50IGluIElFXG5cdFx0XHRcdGluc3QuaW5wdXQuaXMoJzp2aXNpYmxlJykgJiYgIWluc3QuaW5wdXQuaXMoJzpkaXNhYmxlZCcpICYmIGluc3QuaW5wdXRbMF0gIT0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudClcblx0XHRcdGluc3QuaW5wdXQuZm9jdXMoKTtcblx0XHQvLyBkZWZmZXJlZCByZW5kZXIgb2YgdGhlIHllYXJzIHNlbGVjdCAodG8gYXZvaWQgZmxhc2hlcyBvbiBGaXJlZm94KVxuXHRcdGlmKCBpbnN0LnllYXJzaHRtbCApe1xuXHRcdFx0dmFyIG9yaWd5ZWFyc2h0bWwgPSBpbnN0LnllYXJzaHRtbDtcblx0XHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcblx0XHRcdFx0Ly9hc3N1cmUgdGhhdCBpbnN0LnllYXJzaHRtbCBkaWRuJ3QgY2hhbmdlLlxuXHRcdFx0XHRpZiggb3JpZ3llYXJzaHRtbCA9PT0gaW5zdC55ZWFyc2h0bWwgJiYgaW5zdC55ZWFyc2h0bWwgKXtcblx0XHRcdFx0XHRpbnN0LmRwRGl2LmZpbmQoJ3NlbGVjdC51aS1kYXRlcGlja2VyLXllYXI6Zmlyc3QnKS5yZXBsYWNlV2l0aChpbnN0LnllYXJzaHRtbCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0b3JpZ3llYXJzaHRtbCA9IGluc3QueWVhcnNodG1sID0gbnVsbDtcblx0XHRcdH0sIDApO1xuXHRcdH1cblx0fSxcblxuXHQvKiBSZXRyaWV2ZSB0aGUgc2l6ZSBvZiBsZWZ0IGFuZCB0b3AgYm9yZGVycyBmb3IgYW4gZWxlbWVudC5cblx0ICAgQHBhcmFtICBlbGVtICAoalF1ZXJ5IG9iamVjdCkgdGhlIGVsZW1lbnQgb2YgaW50ZXJlc3Rcblx0ICAgQHJldHVybiAgKG51bWJlclsyXSkgdGhlIGxlZnQgYW5kIHRvcCBib3JkZXJzICovXG5cdF9nZXRCb3JkZXJzOiBmdW5jdGlvbihlbGVtKSB7XG5cdFx0dmFyIGNvbnZlcnQgPSBmdW5jdGlvbih2YWx1ZSkge1xuXHRcdFx0cmV0dXJuIHt0aGluOiAxLCBtZWRpdW06IDIsIHRoaWNrOiAzfVt2YWx1ZV0gfHwgdmFsdWU7XG5cdFx0fTtcblx0XHRyZXR1cm4gW3BhcnNlRmxvYXQoY29udmVydChlbGVtLmNzcygnYm9yZGVyLWxlZnQtd2lkdGgnKSkpLFxuXHRcdFx0cGFyc2VGbG9hdChjb252ZXJ0KGVsZW0uY3NzKCdib3JkZXItdG9wLXdpZHRoJykpKV07XG5cdH0sXG5cblx0LyogQ2hlY2sgcG9zaXRpb25pbmcgdG8gcmVtYWluIG9uIHNjcmVlbi4gKi9cblx0X2NoZWNrT2Zmc2V0OiBmdW5jdGlvbihpbnN0LCBvZmZzZXQsIGlzRml4ZWQpIHtcblx0XHR2YXIgZHBXaWR0aCA9IGluc3QuZHBEaXYub3V0ZXJXaWR0aCgpO1xuXHRcdHZhciBkcEhlaWdodCA9IGluc3QuZHBEaXYub3V0ZXJIZWlnaHQoKTtcblx0XHR2YXIgaW5wdXRXaWR0aCA9IGluc3QuaW5wdXQgPyBpbnN0LmlucHV0Lm91dGVyV2lkdGgoKSA6IDA7XG5cdFx0dmFyIGlucHV0SGVpZ2h0ID0gaW5zdC5pbnB1dCA/IGluc3QuaW5wdXQub3V0ZXJIZWlnaHQoKSA6IDA7XG5cdFx0dmFyIHZpZXdXaWR0aCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aCArIChpc0ZpeGVkID8gMCA6ICQoZG9jdW1lbnQpLnNjcm9sbExlZnQoKSk7XG5cdFx0dmFyIHZpZXdIZWlnaHQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0ICsgKGlzRml4ZWQgPyAwIDogJChkb2N1bWVudCkuc2Nyb2xsVG9wKCkpO1xuXG5cdFx0b2Zmc2V0LmxlZnQgLT0gKHRoaXMuX2dldChpbnN0LCAnaXNSVEwnKSA/IChkcFdpZHRoIC0gaW5wdXRXaWR0aCkgOiAwKTtcblx0XHRvZmZzZXQubGVmdCAtPSAoaXNGaXhlZCAmJiBvZmZzZXQubGVmdCA9PSBpbnN0LmlucHV0Lm9mZnNldCgpLmxlZnQpID8gJChkb2N1bWVudCkuc2Nyb2xsTGVmdCgpIDogMDtcblx0XHRvZmZzZXQudG9wIC09IChpc0ZpeGVkICYmIG9mZnNldC50b3AgPT0gKGluc3QuaW5wdXQub2Zmc2V0KCkudG9wICsgaW5wdXRIZWlnaHQpKSA/ICQoZG9jdW1lbnQpLnNjcm9sbFRvcCgpIDogMDtcblxuXHRcdC8vIG5vdyBjaGVjayBpZiBkYXRlcGlja2VyIGlzIHNob3dpbmcgb3V0c2lkZSB3aW5kb3cgdmlld3BvcnQgLSBtb3ZlIHRvIGEgYmV0dGVyIHBsYWNlIGlmIHNvLlxuXHRcdG9mZnNldC5sZWZ0IC09IE1hdGgubWluKG9mZnNldC5sZWZ0LCAob2Zmc2V0LmxlZnQgKyBkcFdpZHRoID4gdmlld1dpZHRoICYmIHZpZXdXaWR0aCA+IGRwV2lkdGgpID9cblx0XHRcdE1hdGguYWJzKG9mZnNldC5sZWZ0ICsgZHBXaWR0aCAtIHZpZXdXaWR0aCkgOiAwKTtcblx0XHRvZmZzZXQudG9wIC09IE1hdGgubWluKG9mZnNldC50b3AsIChvZmZzZXQudG9wICsgZHBIZWlnaHQgPiB2aWV3SGVpZ2h0ICYmIHZpZXdIZWlnaHQgPiBkcEhlaWdodCkgP1xuXHRcdFx0TWF0aC5hYnMoZHBIZWlnaHQgKyBpbnB1dEhlaWdodCkgOiAwKTtcblxuXHRcdHJldHVybiBvZmZzZXQ7XG5cdH0sXG5cblx0LyogRmluZCBhbiBvYmplY3QncyBwb3NpdGlvbiBvbiB0aGUgc2NyZWVuLiAqL1xuXHRfZmluZFBvczogZnVuY3Rpb24ob2JqKSB7XG5cdFx0dmFyIGluc3QgPSB0aGlzLl9nZXRJbnN0KG9iaik7XG5cdFx0dmFyIGlzUlRMID0gdGhpcy5fZ2V0KGluc3QsICdpc1JUTCcpO1xuXHRcdHdoaWxlIChvYmogJiYgKG9iai50eXBlID09ICdoaWRkZW4nIHx8IG9iai5ub2RlVHlwZSAhPSAxIHx8ICQuZXhwci5maWx0ZXJzLmhpZGRlbihvYmopKSkge1xuXHRcdFx0b2JqID0gb2JqW2lzUlRMID8gJ3ByZXZpb3VzU2libGluZycgOiAnbmV4dFNpYmxpbmcnXTtcblx0XHR9XG5cdFx0dmFyIHBvc2l0aW9uID0gJChvYmopLm9mZnNldCgpO1xuXHRcdHJldHVybiBbcG9zaXRpb24ubGVmdCwgcG9zaXRpb24udG9wXTtcblx0fSxcblxuXHQvKiBIaWRlIHRoZSBkYXRlIHBpY2tlciBmcm9tIHZpZXcuXG5cdCAgIEBwYXJhbSAgaW5wdXQgIGVsZW1lbnQgLSB0aGUgaW5wdXQgZmllbGQgYXR0YWNoZWQgdG8gdGhlIGRhdGUgcGlja2VyICovXG5cdF9oaWRlRGF0ZXBpY2tlcjogZnVuY3Rpb24oaW5wdXQpIHtcblx0XHR2YXIgaW5zdCA9IHRoaXMuX2N1ckluc3Q7XG5cdFx0aWYgKCFpbnN0IHx8IChpbnB1dCAmJiBpbnN0ICE9ICQuZGF0YShpbnB1dCwgUFJPUF9OQU1FKSkpXG5cdFx0XHRyZXR1cm47XG5cdFx0aWYgKHRoaXMuX2RhdGVwaWNrZXJTaG93aW5nKSB7XG5cdFx0XHR2YXIgc2hvd0FuaW0gPSB0aGlzLl9nZXQoaW5zdCwgJ3Nob3dBbmltJyk7XG5cdFx0XHR2YXIgZHVyYXRpb24gPSB0aGlzLl9nZXQoaW5zdCwgJ2R1cmF0aW9uJyk7XG5cdFx0XHR2YXIgcG9zdFByb2Nlc3MgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0JC5kYXRlcGlja2VyLl90aWR5RGlhbG9nKGluc3QpO1xuXHRcdFx0fTtcblxuXHRcdFx0Ly8gREVQUkVDQVRFRDogYWZ0ZXIgQkMgZm9yIDEuOC54ICQuZWZmZWN0c1sgc2hvd0FuaW0gXSBpcyBub3QgbmVlZGVkXG5cdFx0XHRpZiAoICQuZWZmZWN0cyAmJiAoICQuZWZmZWN0cy5lZmZlY3RbIHNob3dBbmltIF0gfHwgJC5lZmZlY3RzWyBzaG93QW5pbSBdICkgKVxuXHRcdFx0XHRpbnN0LmRwRGl2LmhpZGUoc2hvd0FuaW0sICQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsICdzaG93T3B0aW9ucycpLCBkdXJhdGlvbiwgcG9zdFByb2Nlc3MpO1xuXHRcdFx0ZWxzZVxuXHRcdFx0XHRpbnN0LmRwRGl2WyhzaG93QW5pbSA9PSAnc2xpZGVEb3duJyA/ICdzbGlkZVVwJyA6XG5cdFx0XHRcdFx0KHNob3dBbmltID09ICdmYWRlSW4nID8gJ2ZhZGVPdXQnIDogJ2hpZGUnKSldKChzaG93QW5pbSA/IGR1cmF0aW9uIDogbnVsbCksIHBvc3RQcm9jZXNzKTtcblx0XHRcdGlmICghc2hvd0FuaW0pXG5cdFx0XHRcdHBvc3RQcm9jZXNzKCk7XG5cdFx0XHR0aGlzLl9kYXRlcGlja2VyU2hvd2luZyA9IGZhbHNlO1xuXHRcdFx0dmFyIG9uQ2xvc2UgPSB0aGlzLl9nZXQoaW5zdCwgJ29uQ2xvc2UnKTtcblx0XHRcdGlmIChvbkNsb3NlKVxuXHRcdFx0XHRvbkNsb3NlLmFwcGx5KChpbnN0LmlucHV0ID8gaW5zdC5pbnB1dFswXSA6IG51bGwpLFxuXHRcdFx0XHRcdFsoaW5zdC5pbnB1dCA/IGluc3QuaW5wdXQudmFsKCkgOiAnJyksIGluc3RdKTtcblx0XHRcdHRoaXMuX2xhc3RJbnB1dCA9IG51bGw7XG5cdFx0XHRpZiAodGhpcy5faW5EaWFsb2cpIHtcblx0XHRcdFx0dGhpcy5fZGlhbG9nSW5wdXQuY3NzKHsgcG9zaXRpb246ICdhYnNvbHV0ZScsIGxlZnQ6ICcwJywgdG9wOiAnLTEwMHB4JyB9KTtcblx0XHRcdFx0aWYgKCQuYmxvY2tVSSkge1xuXHRcdFx0XHRcdCQudW5ibG9ja1VJKCk7XG5cdFx0XHRcdFx0JCgnYm9keScpLmFwcGVuZCh0aGlzLmRwRGl2KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0dGhpcy5faW5EaWFsb2cgPSBmYWxzZTtcblx0XHR9XG5cdH0sXG5cblx0LyogVGlkeSB1cCBhZnRlciBhIGRpYWxvZyBkaXNwbGF5LiAqL1xuXHRfdGlkeURpYWxvZzogZnVuY3Rpb24oaW5zdCkge1xuXHRcdGluc3QuZHBEaXYucmVtb3ZlQ2xhc3ModGhpcy5fZGlhbG9nQ2xhc3MpLnVuYmluZCgnLnVpLWRhdGVwaWNrZXItY2FsZW5kYXInKTtcblx0fSxcblxuXHQvKiBDbG9zZSBkYXRlIHBpY2tlciBpZiBjbGlja2VkIGVsc2V3aGVyZS4gKi9cblx0X2NoZWNrRXh0ZXJuYWxDbGljazogZnVuY3Rpb24oZXZlbnQpIHtcblx0XHRpZiAoISQuZGF0ZXBpY2tlci5fY3VySW5zdClcblx0XHRcdHJldHVybjtcblxuXHRcdHZhciAkdGFyZ2V0ID0gJChldmVudC50YXJnZXQpLFxuXHRcdFx0aW5zdCA9ICQuZGF0ZXBpY2tlci5fZ2V0SW5zdCgkdGFyZ2V0WzBdKTtcblxuXHRcdGlmICggKCAoICR0YXJnZXRbMF0uaWQgIT0gJC5kYXRlcGlja2VyLl9tYWluRGl2SWQgJiZcblx0XHRcdFx0JHRhcmdldC5wYXJlbnRzKCcjJyArICQuZGF0ZXBpY2tlci5fbWFpbkRpdklkKS5sZW5ndGggPT0gMCAmJlxuXHRcdFx0XHQhJHRhcmdldC5oYXNDbGFzcygkLmRhdGVwaWNrZXIubWFya2VyQ2xhc3NOYW1lKSAmJlxuXHRcdFx0XHQhJHRhcmdldC5jbG9zZXN0KFwiLlwiICsgJC5kYXRlcGlja2VyLl90cmlnZ2VyQ2xhc3MpLmxlbmd0aCAmJlxuXHRcdFx0XHQkLmRhdGVwaWNrZXIuX2RhdGVwaWNrZXJTaG93aW5nICYmICEoJC5kYXRlcGlja2VyLl9pbkRpYWxvZyAmJiAkLmJsb2NrVUkpICkgKSB8fFxuXHRcdFx0KCAkdGFyZ2V0Lmhhc0NsYXNzKCQuZGF0ZXBpY2tlci5tYXJrZXJDbGFzc05hbWUpICYmICQuZGF0ZXBpY2tlci5fY3VySW5zdCAhPSBpbnN0ICkgKVxuXHRcdFx0JC5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcigpO1xuXHR9LFxuXG5cdC8qIEFkanVzdCBvbmUgb2YgdGhlIGRhdGUgc3ViLWZpZWxkcy4gKi9cblx0X2FkanVzdERhdGU6IGZ1bmN0aW9uKGlkLCBvZmZzZXQsIHBlcmlvZCkge1xuXHRcdHZhciB0YXJnZXQgPSAkKGlkKTtcblx0XHR2YXIgaW5zdCA9IHRoaXMuX2dldEluc3QodGFyZ2V0WzBdKTtcblx0XHRpZiAodGhpcy5faXNEaXNhYmxlZERhdGVwaWNrZXIodGFyZ2V0WzBdKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHR0aGlzLl9hZGp1c3RJbnN0RGF0ZShpbnN0LCBvZmZzZXQgK1xuXHRcdFx0KHBlcmlvZCA9PSAnTScgPyB0aGlzLl9nZXQoaW5zdCwgJ3Nob3dDdXJyZW50QXRQb3MnKSA6IDApLCAvLyB1bmRvIHBvc2l0aW9uaW5nXG5cdFx0XHRwZXJpb2QpO1xuXHRcdHRoaXMuX3VwZGF0ZURhdGVwaWNrZXIoaW5zdCk7XG5cdH0sXG5cblx0LyogQWN0aW9uIGZvciBjdXJyZW50IGxpbmsuICovXG5cdF9nb3RvVG9kYXk6IGZ1bmN0aW9uKGlkKSB7XG5cdFx0dmFyIHRhcmdldCA9ICQoaWQpO1xuXHRcdHZhciBpbnN0ID0gdGhpcy5fZ2V0SW5zdCh0YXJnZXRbMF0pO1xuXHRcdGlmICh0aGlzLl9nZXQoaW5zdCwgJ2dvdG9DdXJyZW50JykgJiYgaW5zdC5jdXJyZW50RGF5KSB7XG5cdFx0XHRpbnN0LnNlbGVjdGVkRGF5ID0gaW5zdC5jdXJyZW50RGF5O1xuXHRcdFx0aW5zdC5kcmF3TW9udGggPSBpbnN0LnNlbGVjdGVkTW9udGggPSBpbnN0LmN1cnJlbnRNb250aDtcblx0XHRcdGluc3QuZHJhd1llYXIgPSBpbnN0LnNlbGVjdGVkWWVhciA9IGluc3QuY3VycmVudFllYXI7XG5cdFx0fVxuXHRcdGVsc2Uge1xuXHRcdFx0dmFyIGRhdGUgPSBuZXcgRGF0ZSgpO1xuXHRcdFx0aW5zdC5zZWxlY3RlZERheSA9IGRhdGUuZ2V0RGF0ZSgpO1xuXHRcdFx0aW5zdC5kcmF3TW9udGggPSBpbnN0LnNlbGVjdGVkTW9udGggPSBkYXRlLmdldE1vbnRoKCk7XG5cdFx0XHRpbnN0LmRyYXdZZWFyID0gaW5zdC5zZWxlY3RlZFllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKCk7XG5cdFx0fVxuXHRcdHRoaXMuX25vdGlmeUNoYW5nZShpbnN0KTtcblx0XHR0aGlzLl9hZGp1c3REYXRlKHRhcmdldCk7XG5cdH0sXG5cblx0LyogQWN0aW9uIGZvciBzZWxlY3RpbmcgYSBuZXcgbW9udGgveWVhci4gKi9cblx0X3NlbGVjdE1vbnRoWWVhcjogZnVuY3Rpb24oaWQsIHNlbGVjdCwgcGVyaW9kKSB7XG5cdFx0dmFyIHRhcmdldCA9ICQoaWQpO1xuXHRcdHZhciBpbnN0ID0gdGhpcy5fZ2V0SW5zdCh0YXJnZXRbMF0pO1xuXHRcdGluc3RbJ3NlbGVjdGVkJyArIChwZXJpb2QgPT0gJ00nID8gJ01vbnRoJyA6ICdZZWFyJyldID1cblx0XHRpbnN0WydkcmF3JyArIChwZXJpb2QgPT0gJ00nID8gJ01vbnRoJyA6ICdZZWFyJyldID1cblx0XHRcdHBhcnNlSW50KHNlbGVjdC5vcHRpb25zW3NlbGVjdC5zZWxlY3RlZEluZGV4XS52YWx1ZSwxMCk7XG5cdFx0dGhpcy5fbm90aWZ5Q2hhbmdlKGluc3QpO1xuXHRcdHRoaXMuX2FkanVzdERhdGUodGFyZ2V0KTtcblx0fSxcblxuXHQvKiBBY3Rpb24gZm9yIHNlbGVjdGluZyBhIGRheS4gKi9cblx0X3NlbGVjdERheTogZnVuY3Rpb24oaWQsIG1vbnRoLCB5ZWFyLCB0ZCkge1xuXHRcdHZhciB0YXJnZXQgPSAkKGlkKTtcblx0XHRpZiAoJCh0ZCkuaGFzQ2xhc3ModGhpcy5fdW5zZWxlY3RhYmxlQ2xhc3MpIHx8IHRoaXMuX2lzRGlzYWJsZWREYXRlcGlja2VyKHRhcmdldFswXSkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dmFyIGluc3QgPSB0aGlzLl9nZXRJbnN0KHRhcmdldFswXSk7XG5cdFx0aW5zdC5zZWxlY3RlZERheSA9IGluc3QuY3VycmVudERheSA9ICQoJ2EnLCB0ZCkuaHRtbCgpO1xuXHRcdGluc3Quc2VsZWN0ZWRNb250aCA9IGluc3QuY3VycmVudE1vbnRoID0gbW9udGg7XG5cdFx0aW5zdC5zZWxlY3RlZFllYXIgPSBpbnN0LmN1cnJlbnRZZWFyID0geWVhcjtcblx0XHR0aGlzLl9zZWxlY3REYXRlKGlkLCB0aGlzLl9mb3JtYXREYXRlKGluc3QsXG5cdFx0XHRpbnN0LmN1cnJlbnREYXksIGluc3QuY3VycmVudE1vbnRoLCBpbnN0LmN1cnJlbnRZZWFyKSk7XG5cdH0sXG5cblx0LyogRXJhc2UgdGhlIGlucHV0IGZpZWxkIGFuZCBoaWRlIHRoZSBkYXRlIHBpY2tlci4gKi9cblx0X2NsZWFyRGF0ZTogZnVuY3Rpb24oaWQpIHtcblx0XHR2YXIgdGFyZ2V0ID0gJChpZCk7XG5cdFx0dmFyIGluc3QgPSB0aGlzLl9nZXRJbnN0KHRhcmdldFswXSk7XG5cdFx0dGhpcy5fc2VsZWN0RGF0ZSh0YXJnZXQsICcnKTtcblx0fSxcblxuXHQvKiBVcGRhdGUgdGhlIGlucHV0IGZpZWxkIHdpdGggdGhlIHNlbGVjdGVkIGRhdGUuICovXG5cdF9zZWxlY3REYXRlOiBmdW5jdGlvbihpZCwgZGF0ZVN0cikge1xuXHRcdHZhciB0YXJnZXQgPSAkKGlkKTtcblx0XHR2YXIgaW5zdCA9IHRoaXMuX2dldEluc3QodGFyZ2V0WzBdKTtcblx0XHRkYXRlU3RyID0gKGRhdGVTdHIgIT0gbnVsbCA/IGRhdGVTdHIgOiB0aGlzLl9mb3JtYXREYXRlKGluc3QpKTtcblx0XHRpZiAoaW5zdC5pbnB1dClcblx0XHRcdGluc3QuaW5wdXQudmFsKGRhdGVTdHIpO1xuXHRcdHRoaXMuX3VwZGF0ZUFsdGVybmF0ZShpbnN0KTtcblx0XHR2YXIgb25TZWxlY3QgPSB0aGlzLl9nZXQoaW5zdCwgJ29uU2VsZWN0Jyk7XG5cdFx0aWYgKG9uU2VsZWN0KVxuXHRcdFx0b25TZWxlY3QuYXBwbHkoKGluc3QuaW5wdXQgPyBpbnN0LmlucHV0WzBdIDogbnVsbCksIFtkYXRlU3RyLCBpbnN0XSk7ICAvLyB0cmlnZ2VyIGN1c3RvbSBjYWxsYmFja1xuXHRcdGVsc2UgaWYgKGluc3QuaW5wdXQpXG5cdFx0XHRpbnN0LmlucHV0LnRyaWdnZXIoJ2NoYW5nZScpOyAvLyBmaXJlIHRoZSBjaGFuZ2UgZXZlbnRcblx0XHRpZiAoaW5zdC5pbmxpbmUpXG5cdFx0XHR0aGlzLl91cGRhdGVEYXRlcGlja2VyKGluc3QpO1xuXHRcdGVsc2Uge1xuXHRcdFx0dGhpcy5faGlkZURhdGVwaWNrZXIoKTtcblx0XHRcdHRoaXMuX2xhc3RJbnB1dCA9IGluc3QuaW5wdXRbMF07XG5cdFx0XHRpZiAodHlwZW9mKGluc3QuaW5wdXRbMF0pICE9ICdvYmplY3QnKVxuXHRcdFx0XHRpbnN0LmlucHV0LmZvY3VzKCk7IC8vIHJlc3RvcmUgZm9jdXNcblx0XHRcdHRoaXMuX2xhc3RJbnB1dCA9IG51bGw7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIFVwZGF0ZSBhbnkgYWx0ZXJuYXRlIGZpZWxkIHRvIHN5bmNocm9uaXNlIHdpdGggdGhlIG1haW4gZmllbGQuICovXG5cdF91cGRhdGVBbHRlcm5hdGU6IGZ1bmN0aW9uKGluc3QpIHtcblx0XHR2YXIgYWx0RmllbGQgPSB0aGlzLl9nZXQoaW5zdCwgJ2FsdEZpZWxkJyk7XG5cdFx0aWYgKGFsdEZpZWxkKSB7IC8vIHVwZGF0ZSBhbHRlcm5hdGUgZmllbGQgdG9vXG5cdFx0XHR2YXIgYWx0Rm9ybWF0ID0gdGhpcy5fZ2V0KGluc3QsICdhbHRGb3JtYXQnKSB8fCB0aGlzLl9nZXQoaW5zdCwgJ2RhdGVGb3JtYXQnKTtcblx0XHRcdHZhciBkYXRlID0gdGhpcy5fZ2V0RGF0ZShpbnN0KTtcblx0XHRcdHZhciBkYXRlU3RyID0gdGhpcy5mb3JtYXREYXRlKGFsdEZvcm1hdCwgZGF0ZSwgdGhpcy5fZ2V0Rm9ybWF0Q29uZmlnKGluc3QpKTtcblx0XHRcdCQoYWx0RmllbGQpLmVhY2goZnVuY3Rpb24oKSB7ICQodGhpcykudmFsKGRhdGVTdHIpOyB9KTtcblx0XHR9XG5cdH0sXG5cblx0LyogU2V0IGFzIGJlZm9yZVNob3dEYXkgZnVuY3Rpb24gdG8gcHJldmVudCBzZWxlY3Rpb24gb2Ygd2Vla2VuZHMuXG5cdCAgIEBwYXJhbSAgZGF0ZSAgRGF0ZSAtIHRoZSBkYXRlIHRvIGN1c3RvbWlzZVxuXHQgICBAcmV0dXJuIFtib29sZWFuLCBzdHJpbmddIC0gaXMgdGhpcyBkYXRlIHNlbGVjdGFibGU/LCB3aGF0IGlzIGl0cyBDU1MgY2xhc3M/ICovXG5cdG5vV2Vla2VuZHM6IGZ1bmN0aW9uKGRhdGUpIHtcblx0XHR2YXIgZGF5ID0gZGF0ZS5nZXREYXkoKTtcblx0XHRyZXR1cm4gWyhkYXkgPiAwICYmIGRheSA8IDYpLCAnJ107XG5cdH0sXG5cblx0LyogU2V0IGFzIGNhbGN1bGF0ZVdlZWsgdG8gZGV0ZXJtaW5lIHRoZSB3ZWVrIG9mIHRoZSB5ZWFyIGJhc2VkIG9uIHRoZSBJU08gODYwMSBkZWZpbml0aW9uLlxuXHQgICBAcGFyYW0gIGRhdGUgIERhdGUgLSB0aGUgZGF0ZSB0byBnZXQgdGhlIHdlZWsgZm9yXG5cdCAgIEByZXR1cm4gIG51bWJlciAtIHRoZSBudW1iZXIgb2YgdGhlIHdlZWsgd2l0aGluIHRoZSB5ZWFyIHRoYXQgY29udGFpbnMgdGhpcyBkYXRlICovXG5cdGlzbzg2MDFXZWVrOiBmdW5jdGlvbihkYXRlKSB7XG5cdFx0dmFyIGNoZWNrRGF0ZSA9IG5ldyBEYXRlKGRhdGUuZ2V0VGltZSgpKTtcblx0XHQvLyBGaW5kIFRodXJzZGF5IG9mIHRoaXMgd2VlayBzdGFydGluZyBvbiBNb25kYXlcblx0XHRjaGVja0RhdGUuc2V0RGF0ZShjaGVja0RhdGUuZ2V0RGF0ZSgpICsgNCAtIChjaGVja0RhdGUuZ2V0RGF5KCkgfHwgNykpO1xuXHRcdHZhciB0aW1lID0gY2hlY2tEYXRlLmdldFRpbWUoKTtcblx0XHRjaGVja0RhdGUuc2V0TW9udGgoMCk7IC8vIENvbXBhcmUgd2l0aCBKYW4gMVxuXHRcdGNoZWNrRGF0ZS5zZXREYXRlKDEpO1xuXHRcdHJldHVybiBNYXRoLmZsb29yKE1hdGgucm91bmQoKHRpbWUgLSBjaGVja0RhdGUpIC8gODY0MDAwMDApIC8gNykgKyAxO1xuXHR9LFxuXG5cdC8qIFBhcnNlIGEgc3RyaW5nIHZhbHVlIGludG8gYSBkYXRlIG9iamVjdC5cblx0ICAgU2VlIGZvcm1hdERhdGUgYmVsb3cgZm9yIHRoZSBwb3NzaWJsZSBmb3JtYXRzLlxuXG5cdCAgIEBwYXJhbSAgZm9ybWF0ICAgIHN0cmluZyAtIHRoZSBleHBlY3RlZCBmb3JtYXQgb2YgdGhlIGRhdGVcblx0ICAgQHBhcmFtICB2YWx1ZSAgICAgc3RyaW5nIC0gdGhlIGRhdGUgaW4gdGhlIGFib3ZlIGZvcm1hdFxuXHQgICBAcGFyYW0gIHNldHRpbmdzICBPYmplY3QgLSBhdHRyaWJ1dGVzIGluY2x1ZGU6XG5cdCAgICAgICAgICAgICAgICAgICAgIHNob3J0WWVhckN1dG9mZiAgbnVtYmVyIC0gdGhlIGN1dG9mZiB5ZWFyIGZvciBkZXRlcm1pbmluZyB0aGUgY2VudHVyeSAob3B0aW9uYWwpXG5cdCAgICAgICAgICAgICAgICAgICAgIGRheU5hbWVzU2hvcnQgICAgc3RyaW5nWzddIC0gYWJicmV2aWF0ZWQgbmFtZXMgb2YgdGhlIGRheXMgZnJvbSBTdW5kYXkgKG9wdGlvbmFsKVxuXHQgICAgICAgICAgICAgICAgICAgICBkYXlOYW1lcyAgICAgICAgIHN0cmluZ1s3XSAtIG5hbWVzIG9mIHRoZSBkYXlzIGZyb20gU3VuZGF5IChvcHRpb25hbClcblx0ICAgICAgICAgICAgICAgICAgICAgbW9udGhOYW1lc1Nob3J0ICBzdHJpbmdbMTJdIC0gYWJicmV2aWF0ZWQgbmFtZXMgb2YgdGhlIG1vbnRocyAob3B0aW9uYWwpXG5cdCAgICAgICAgICAgICAgICAgICAgIG1vbnRoTmFtZXMgICAgICAgc3RyaW5nWzEyXSAtIG5hbWVzIG9mIHRoZSBtb250aHMgKG9wdGlvbmFsKVxuXHQgICBAcmV0dXJuICBEYXRlIC0gdGhlIGV4dHJhY3RlZCBkYXRlIHZhbHVlIG9yIG51bGwgaWYgdmFsdWUgaXMgYmxhbmsgKi9cblx0cGFyc2VEYXRlOiBmdW5jdGlvbiAoZm9ybWF0LCB2YWx1ZSwgc2V0dGluZ3MpIHtcblx0XHRpZiAoZm9ybWF0ID09IG51bGwgfHwgdmFsdWUgPT0gbnVsbClcblx0XHRcdHRocm93ICdJbnZhbGlkIGFyZ3VtZW50cyc7XG5cdFx0dmFsdWUgPSAodHlwZW9mIHZhbHVlID09ICdvYmplY3QnID8gdmFsdWUudG9TdHJpbmcoKSA6IHZhbHVlICsgJycpO1xuXHRcdGlmICh2YWx1ZSA9PSAnJylcblx0XHRcdHJldHVybiBudWxsO1xuXHRcdHZhciBzaG9ydFllYXJDdXRvZmYgPSAoc2V0dGluZ3MgPyBzZXR0aW5ncy5zaG9ydFllYXJDdXRvZmYgOiBudWxsKSB8fCB0aGlzLl9kZWZhdWx0cy5zaG9ydFllYXJDdXRvZmY7XG5cdFx0c2hvcnRZZWFyQ3V0b2ZmID0gKHR5cGVvZiBzaG9ydFllYXJDdXRvZmYgIT0gJ3N0cmluZycgPyBzaG9ydFllYXJDdXRvZmYgOlxuXHRcdFx0XHRuZXcgRGF0ZSgpLmdldEZ1bGxZZWFyKCkgJSAxMDAgKyBwYXJzZUludChzaG9ydFllYXJDdXRvZmYsIDEwKSk7XG5cdFx0dmFyIGRheU5hbWVzU2hvcnQgPSAoc2V0dGluZ3MgPyBzZXR0aW5ncy5kYXlOYW1lc1Nob3J0IDogbnVsbCkgfHwgdGhpcy5fZGVmYXVsdHMuZGF5TmFtZXNTaG9ydDtcblx0XHR2YXIgZGF5TmFtZXMgPSAoc2V0dGluZ3MgPyBzZXR0aW5ncy5kYXlOYW1lcyA6IG51bGwpIHx8IHRoaXMuX2RlZmF1bHRzLmRheU5hbWVzO1xuXHRcdHZhciBtb250aE5hbWVzU2hvcnQgPSAoc2V0dGluZ3MgPyBzZXR0aW5ncy5tb250aE5hbWVzU2hvcnQgOiBudWxsKSB8fCB0aGlzLl9kZWZhdWx0cy5tb250aE5hbWVzU2hvcnQ7XG5cdFx0dmFyIG1vbnRoTmFtZXMgPSAoc2V0dGluZ3MgPyBzZXR0aW5ncy5tb250aE5hbWVzIDogbnVsbCkgfHwgdGhpcy5fZGVmYXVsdHMubW9udGhOYW1lcztcblx0XHR2YXIgeWVhciA9IC0xO1xuXHRcdHZhciBtb250aCA9IC0xO1xuXHRcdHZhciBkYXkgPSAtMTtcblx0XHR2YXIgZG95ID0gLTE7XG5cdFx0dmFyIGxpdGVyYWwgPSBmYWxzZTtcblx0XHQvLyBDaGVjayB3aGV0aGVyIGEgZm9ybWF0IGNoYXJhY3RlciBpcyBkb3VibGVkXG5cdFx0dmFyIGxvb2tBaGVhZCA9IGZ1bmN0aW9uKG1hdGNoKSB7XG5cdFx0XHR2YXIgbWF0Y2hlcyA9IChpRm9ybWF0ICsgMSA8IGZvcm1hdC5sZW5ndGggJiYgZm9ybWF0LmNoYXJBdChpRm9ybWF0ICsgMSkgPT0gbWF0Y2gpO1xuXHRcdFx0aWYgKG1hdGNoZXMpXG5cdFx0XHRcdGlGb3JtYXQrKztcblx0XHRcdHJldHVybiBtYXRjaGVzO1xuXHRcdH07XG5cdFx0Ly8gRXh0cmFjdCBhIG51bWJlciBmcm9tIHRoZSBzdHJpbmcgdmFsdWVcblx0XHR2YXIgZ2V0TnVtYmVyID0gZnVuY3Rpb24obWF0Y2gpIHtcblx0XHRcdHZhciBpc0RvdWJsZWQgPSBsb29rQWhlYWQobWF0Y2gpO1xuXHRcdFx0dmFyIHNpemUgPSAobWF0Y2ggPT0gJ0AnID8gMTQgOiAobWF0Y2ggPT0gJyEnID8gMjAgOlxuXHRcdFx0XHQobWF0Y2ggPT0gJ3knICYmIGlzRG91YmxlZCA/IDQgOiAobWF0Y2ggPT0gJ28nID8gMyA6IDIpKSkpO1xuXHRcdFx0dmFyIGRpZ2l0cyA9IG5ldyBSZWdFeHAoJ15cXFxcZHsxLCcgKyBzaXplICsgJ30nKTtcblx0XHRcdHZhciBudW0gPSB2YWx1ZS5zdWJzdHJpbmcoaVZhbHVlKS5tYXRjaChkaWdpdHMpO1xuXHRcdFx0aWYgKCFudW0pXG5cdFx0XHRcdHRocm93ICdNaXNzaW5nIG51bWJlciBhdCBwb3NpdGlvbiAnICsgaVZhbHVlO1xuXHRcdFx0aVZhbHVlICs9IG51bVswXS5sZW5ndGg7XG5cdFx0XHRyZXR1cm4gcGFyc2VJbnQobnVtWzBdLCAxMCk7XG5cdFx0fTtcblx0XHQvLyBFeHRyYWN0IGEgbmFtZSBmcm9tIHRoZSBzdHJpbmcgdmFsdWUgYW5kIGNvbnZlcnQgdG8gYW4gaW5kZXhcblx0XHR2YXIgZ2V0TmFtZSA9IGZ1bmN0aW9uKG1hdGNoLCBzaG9ydE5hbWVzLCBsb25nTmFtZXMpIHtcblx0XHRcdHZhciBuYW1lcyA9ICQubWFwKGxvb2tBaGVhZChtYXRjaCkgPyBsb25nTmFtZXMgOiBzaG9ydE5hbWVzLCBmdW5jdGlvbiAodiwgaykge1xuXHRcdFx0XHRyZXR1cm4gWyBbaywgdl0gXTtcblx0XHRcdH0pLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcblx0XHRcdFx0cmV0dXJuIC0oYVsxXS5sZW5ndGggLSBiWzFdLmxlbmd0aCk7XG5cdFx0XHR9KTtcblx0XHRcdHZhciBpbmRleCA9IC0xO1xuXHRcdFx0JC5lYWNoKG5hbWVzLCBmdW5jdGlvbiAoaSwgcGFpcikge1xuXHRcdFx0XHR2YXIgbmFtZSA9IHBhaXJbMV07XG5cdFx0XHRcdGlmICh2YWx1ZS5zdWJzdHIoaVZhbHVlLCBuYW1lLmxlbmd0aCkudG9Mb3dlckNhc2UoKSA9PSBuYW1lLnRvTG93ZXJDYXNlKCkpIHtcblx0XHRcdFx0XHRpbmRleCA9IHBhaXJbMF07XG5cdFx0XHRcdFx0aVZhbHVlICs9IG5hbWUubGVuZ3RoO1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHRpZiAoaW5kZXggIT0gLTEpXG5cdFx0XHRcdHJldHVybiBpbmRleCArIDE7XG5cdFx0XHRlbHNlXG5cdFx0XHRcdHRocm93ICdVbmtub3duIG5hbWUgYXQgcG9zaXRpb24gJyArIGlWYWx1ZTtcblx0XHR9O1xuXHRcdC8vIENvbmZpcm0gdGhhdCBhIGxpdGVyYWwgY2hhcmFjdGVyIG1hdGNoZXMgdGhlIHN0cmluZyB2YWx1ZVxuXHRcdHZhciBjaGVja0xpdGVyYWwgPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmICh2YWx1ZS5jaGFyQXQoaVZhbHVlKSAhPSBmb3JtYXQuY2hhckF0KGlGb3JtYXQpKVxuXHRcdFx0XHR0aHJvdyAnVW5leHBlY3RlZCBsaXRlcmFsIGF0IHBvc2l0aW9uICcgKyBpVmFsdWU7XG5cdFx0XHRpVmFsdWUrKztcblx0XHR9O1xuXHRcdHZhciBpVmFsdWUgPSAwO1xuXHRcdGZvciAodmFyIGlGb3JtYXQgPSAwOyBpRm9ybWF0IDwgZm9ybWF0Lmxlbmd0aDsgaUZvcm1hdCsrKSB7XG5cdFx0XHRpZiAobGl0ZXJhbClcblx0XHRcdFx0aWYgKGZvcm1hdC5jaGFyQXQoaUZvcm1hdCkgPT0gXCInXCIgJiYgIWxvb2tBaGVhZChcIidcIikpXG5cdFx0XHRcdFx0bGl0ZXJhbCA9IGZhbHNlO1xuXHRcdFx0XHRlbHNlXG5cdFx0XHRcdFx0Y2hlY2tMaXRlcmFsKCk7XG5cdFx0XHRlbHNlXG5cdFx0XHRcdHN3aXRjaCAoZm9ybWF0LmNoYXJBdChpRm9ybWF0KSkge1xuXHRcdFx0XHRcdGNhc2UgJ2QnOlxuXHRcdFx0XHRcdFx0ZGF5ID0gZ2V0TnVtYmVyKCdkJyk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdEJzpcblx0XHRcdFx0XHRcdGdldE5hbWUoJ0QnLCBkYXlOYW1lc1Nob3J0LCBkYXlOYW1lcyk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdvJzpcblx0XHRcdFx0XHRcdGRveSA9IGdldE51bWJlcignbycpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnbSc6XG5cdFx0XHRcdFx0XHRtb250aCA9IGdldE51bWJlcignbScpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnTSc6XG5cdFx0XHRcdFx0XHRtb250aCA9IGdldE5hbWUoJ00nLCBtb250aE5hbWVzU2hvcnQsIG1vbnRoTmFtZXMpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAneSc6XG5cdFx0XHRcdFx0XHR5ZWFyID0gZ2V0TnVtYmVyKCd5Jyk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdAJzpcblx0XHRcdFx0XHRcdHZhciBkYXRlID0gbmV3IERhdGUoZ2V0TnVtYmVyKCdAJykpO1xuXHRcdFx0XHRcdFx0eWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKTtcblx0XHRcdFx0XHRcdG1vbnRoID0gZGF0ZS5nZXRNb250aCgpICsgMTtcblx0XHRcdFx0XHRcdGRheSA9IGRhdGUuZ2V0RGF0ZSgpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnISc6XG5cdFx0XHRcdFx0XHR2YXIgZGF0ZSA9IG5ldyBEYXRlKChnZXROdW1iZXIoJyEnKSAtIHRoaXMuX3RpY2tzVG8xOTcwKSAvIDEwMDAwKTtcblx0XHRcdFx0XHRcdHllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKCk7XG5cdFx0XHRcdFx0XHRtb250aCA9IGRhdGUuZ2V0TW9udGgoKSArIDE7XG5cdFx0XHRcdFx0XHRkYXkgPSBkYXRlLmdldERhdGUoKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgXCInXCI6XG5cdFx0XHRcdFx0XHRpZiAobG9va0FoZWFkKFwiJ1wiKSlcblx0XHRcdFx0XHRcdFx0Y2hlY2tMaXRlcmFsKCk7XG5cdFx0XHRcdFx0XHRlbHNlXG5cdFx0XHRcdFx0XHRcdGxpdGVyYWwgPSB0cnVlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRcdGNoZWNrTGl0ZXJhbCgpO1xuXHRcdFx0XHR9XG5cdFx0fVxuXHRcdGlmIChpVmFsdWUgPCB2YWx1ZS5sZW5ndGgpe1xuXHRcdFx0dmFyIGV4dHJhID0gdmFsdWUuc3Vic3RyKGlWYWx1ZSk7XG5cdFx0XHRpZiAoIS9eXFxzKy8udGVzdChleHRyYSkpIHtcblx0XHRcdFx0dGhyb3cgXCJFeHRyYS91bnBhcnNlZCBjaGFyYWN0ZXJzIGZvdW5kIGluIGRhdGU6IFwiICsgZXh0cmE7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmICh5ZWFyID09IC0xKVxuXHRcdFx0eWVhciA9IG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKTtcblx0XHRlbHNlIGlmICh5ZWFyIDwgMTAwKVxuXHRcdFx0eWVhciArPSBuZXcgRGF0ZSgpLmdldEZ1bGxZZWFyKCkgLSBuZXcgRGF0ZSgpLmdldEZ1bGxZZWFyKCkgJSAxMDAgK1xuXHRcdFx0XHQoeWVhciA8PSBzaG9ydFllYXJDdXRvZmYgPyAwIDogLTEwMCk7XG5cdFx0aWYgKGRveSA+IC0xKSB7XG5cdFx0XHRtb250aCA9IDE7XG5cdFx0XHRkYXkgPSBkb3k7XG5cdFx0XHRkbyB7XG5cdFx0XHRcdHZhciBkaW0gPSB0aGlzLl9nZXREYXlzSW5Nb250aCh5ZWFyLCBtb250aCAtIDEpO1xuXHRcdFx0XHRpZiAoZGF5IDw9IGRpbSlcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0bW9udGgrKztcblx0XHRcdFx0ZGF5IC09IGRpbTtcblx0XHRcdH0gd2hpbGUgKHRydWUpO1xuXHRcdH1cblx0XHR2YXIgZGF0ZSA9IHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKHllYXIsIG1vbnRoIC0gMSwgZGF5KSk7XG5cdFx0aWYgKGRhdGUuZ2V0RnVsbFllYXIoKSAhPSB5ZWFyIHx8IGRhdGUuZ2V0TW9udGgoKSArIDEgIT0gbW9udGggfHwgZGF0ZS5nZXREYXRlKCkgIT0gZGF5KVxuXHRcdFx0dGhyb3cgJ0ludmFsaWQgZGF0ZSc7IC8vIEUuZy4gMzEvMDIvMDBcblx0XHRyZXR1cm4gZGF0ZTtcblx0fSxcblxuXHQvKiBTdGFuZGFyZCBkYXRlIGZvcm1hdHMuICovXG5cdEFUT006ICd5eS1tbS1kZCcsIC8vIFJGQyAzMzM5IChJU08gODYwMSlcblx0Q09PS0lFOiAnRCwgZGQgTSB5eScsXG5cdElTT184NjAxOiAneXktbW0tZGQnLFxuXHRSRkNfODIyOiAnRCwgZCBNIHknLFxuXHRSRkNfODUwOiAnREQsIGRkLU0teScsXG5cdFJGQ18xMDM2OiAnRCwgZCBNIHknLFxuXHRSRkNfMTEyMzogJ0QsIGQgTSB5eScsXG5cdFJGQ18yODIyOiAnRCwgZCBNIHl5Jyxcblx0UlNTOiAnRCwgZCBNIHknLCAvLyBSRkMgODIyXG5cdFRJQ0tTOiAnIScsXG5cdFRJTUVTVEFNUDogJ0AnLFxuXHRXM0M6ICd5eS1tbS1kZCcsIC8vIElTTyA4NjAxXG5cblx0X3RpY2tzVG8xOTcwOiAoKCgxOTcwIC0gMSkgKiAzNjUgKyBNYXRoLmZsb29yKDE5NzAgLyA0KSAtIE1hdGguZmxvb3IoMTk3MCAvIDEwMCkgK1xuXHRcdE1hdGguZmxvb3IoMTk3MCAvIDQwMCkpICogMjQgKiA2MCAqIDYwICogMTAwMDAwMDApLFxuXG5cdC8qIEZvcm1hdCBhIGRhdGUgb2JqZWN0IGludG8gYSBzdHJpbmcgdmFsdWUuXG5cdCAgIFRoZSBmb3JtYXQgY2FuIGJlIGNvbWJpbmF0aW9ucyBvZiB0aGUgZm9sbG93aW5nOlxuXHQgICBkICAtIGRheSBvZiBtb250aCAobm8gbGVhZGluZyB6ZXJvKVxuXHQgICBkZCAtIGRheSBvZiBtb250aCAodHdvIGRpZ2l0KVxuXHQgICBvICAtIGRheSBvZiB5ZWFyIChubyBsZWFkaW5nIHplcm9zKVxuXHQgICBvbyAtIGRheSBvZiB5ZWFyICh0aHJlZSBkaWdpdClcblx0ICAgRCAgLSBkYXkgbmFtZSBzaG9ydFxuXHQgICBERCAtIGRheSBuYW1lIGxvbmdcblx0ICAgbSAgLSBtb250aCBvZiB5ZWFyIChubyBsZWFkaW5nIHplcm8pXG5cdCAgIG1tIC0gbW9udGggb2YgeWVhciAodHdvIGRpZ2l0KVxuXHQgICBNICAtIG1vbnRoIG5hbWUgc2hvcnRcblx0ICAgTU0gLSBtb250aCBuYW1lIGxvbmdcblx0ICAgeSAgLSB5ZWFyICh0d28gZGlnaXQpXG5cdCAgIHl5IC0geWVhciAoZm91ciBkaWdpdClcblx0ICAgQCAtIFVuaXggdGltZXN0YW1wIChtcyBzaW5jZSAwMS8wMS8xOTcwKVxuXHQgICAhIC0gV2luZG93cyB0aWNrcyAoMTAwbnMgc2luY2UgMDEvMDEvMDAwMSlcblx0ICAgJy4uLicgLSBsaXRlcmFsIHRleHRcblx0ICAgJycgLSBzaW5nbGUgcXVvdGVcblxuXHQgICBAcGFyYW0gIGZvcm1hdCAgICBzdHJpbmcgLSB0aGUgZGVzaXJlZCBmb3JtYXQgb2YgdGhlIGRhdGVcblx0ICAgQHBhcmFtICBkYXRlICAgICAgRGF0ZSAtIHRoZSBkYXRlIHZhbHVlIHRvIGZvcm1hdFxuXHQgICBAcGFyYW0gIHNldHRpbmdzICBPYmplY3QgLSBhdHRyaWJ1dGVzIGluY2x1ZGU6XG5cdCAgICAgICAgICAgICAgICAgICAgIGRheU5hbWVzU2hvcnQgICAgc3RyaW5nWzddIC0gYWJicmV2aWF0ZWQgbmFtZXMgb2YgdGhlIGRheXMgZnJvbSBTdW5kYXkgKG9wdGlvbmFsKVxuXHQgICAgICAgICAgICAgICAgICAgICBkYXlOYW1lcyAgICAgICAgIHN0cmluZ1s3XSAtIG5hbWVzIG9mIHRoZSBkYXlzIGZyb20gU3VuZGF5IChvcHRpb25hbClcblx0ICAgICAgICAgICAgICAgICAgICAgbW9udGhOYW1lc1Nob3J0ICBzdHJpbmdbMTJdIC0gYWJicmV2aWF0ZWQgbmFtZXMgb2YgdGhlIG1vbnRocyAob3B0aW9uYWwpXG5cdCAgICAgICAgICAgICAgICAgICAgIG1vbnRoTmFtZXMgICAgICAgc3RyaW5nWzEyXSAtIG5hbWVzIG9mIHRoZSBtb250aHMgKG9wdGlvbmFsKVxuXHQgICBAcmV0dXJuICBzdHJpbmcgLSB0aGUgZGF0ZSBpbiB0aGUgYWJvdmUgZm9ybWF0ICovXG5cdGZvcm1hdERhdGU6IGZ1bmN0aW9uIChmb3JtYXQsIGRhdGUsIHNldHRpbmdzKSB7XG5cdFx0aWYgKCFkYXRlKVxuXHRcdFx0cmV0dXJuICcnO1xuXHRcdHZhciBkYXlOYW1lc1Nob3J0ID0gKHNldHRpbmdzID8gc2V0dGluZ3MuZGF5TmFtZXNTaG9ydCA6IG51bGwpIHx8IHRoaXMuX2RlZmF1bHRzLmRheU5hbWVzU2hvcnQ7XG5cdFx0dmFyIGRheU5hbWVzID0gKHNldHRpbmdzID8gc2V0dGluZ3MuZGF5TmFtZXMgOiBudWxsKSB8fCB0aGlzLl9kZWZhdWx0cy5kYXlOYW1lcztcblx0XHR2YXIgbW9udGhOYW1lc1Nob3J0ID0gKHNldHRpbmdzID8gc2V0dGluZ3MubW9udGhOYW1lc1Nob3J0IDogbnVsbCkgfHwgdGhpcy5fZGVmYXVsdHMubW9udGhOYW1lc1Nob3J0O1xuXHRcdHZhciBtb250aE5hbWVzID0gKHNldHRpbmdzID8gc2V0dGluZ3MubW9udGhOYW1lcyA6IG51bGwpIHx8IHRoaXMuX2RlZmF1bHRzLm1vbnRoTmFtZXM7XG5cdFx0Ly8gQ2hlY2sgd2hldGhlciBhIGZvcm1hdCBjaGFyYWN0ZXIgaXMgZG91YmxlZFxuXHRcdHZhciBsb29rQWhlYWQgPSBmdW5jdGlvbihtYXRjaCkge1xuXHRcdFx0dmFyIG1hdGNoZXMgPSAoaUZvcm1hdCArIDEgPCBmb3JtYXQubGVuZ3RoICYmIGZvcm1hdC5jaGFyQXQoaUZvcm1hdCArIDEpID09IG1hdGNoKTtcblx0XHRcdGlmIChtYXRjaGVzKVxuXHRcdFx0XHRpRm9ybWF0Kys7XG5cdFx0XHRyZXR1cm4gbWF0Y2hlcztcblx0XHR9O1xuXHRcdC8vIEZvcm1hdCBhIG51bWJlciwgd2l0aCBsZWFkaW5nIHplcm8gaWYgbmVjZXNzYXJ5XG5cdFx0dmFyIGZvcm1hdE51bWJlciA9IGZ1bmN0aW9uKG1hdGNoLCB2YWx1ZSwgbGVuKSB7XG5cdFx0XHR2YXIgbnVtID0gJycgKyB2YWx1ZTtcblx0XHRcdGlmIChsb29rQWhlYWQobWF0Y2gpKVxuXHRcdFx0XHR3aGlsZSAobnVtLmxlbmd0aCA8IGxlbilcblx0XHRcdFx0XHRudW0gPSAnMCcgKyBudW07XG5cdFx0XHRyZXR1cm4gbnVtO1xuXHRcdH07XG5cdFx0Ly8gRm9ybWF0IGEgbmFtZSwgc2hvcnQgb3IgbG9uZyBhcyByZXF1ZXN0ZWRcblx0XHR2YXIgZm9ybWF0TmFtZSA9IGZ1bmN0aW9uKG1hdGNoLCB2YWx1ZSwgc2hvcnROYW1lcywgbG9uZ05hbWVzKSB7XG5cdFx0XHRyZXR1cm4gKGxvb2tBaGVhZChtYXRjaCkgPyBsb25nTmFtZXNbdmFsdWVdIDogc2hvcnROYW1lc1t2YWx1ZV0pO1xuXHRcdH07XG5cdFx0dmFyIG91dHB1dCA9ICcnO1xuXHRcdHZhciBsaXRlcmFsID0gZmFsc2U7XG5cdFx0aWYgKGRhdGUpXG5cdFx0XHRmb3IgKHZhciBpRm9ybWF0ID0gMDsgaUZvcm1hdCA8IGZvcm1hdC5sZW5ndGg7IGlGb3JtYXQrKykge1xuXHRcdFx0XHRpZiAobGl0ZXJhbClcblx0XHRcdFx0XHRpZiAoZm9ybWF0LmNoYXJBdChpRm9ybWF0KSA9PSBcIidcIiAmJiAhbG9va0FoZWFkKFwiJ1wiKSlcblx0XHRcdFx0XHRcdGxpdGVyYWwgPSBmYWxzZTtcblx0XHRcdFx0XHRlbHNlXG5cdFx0XHRcdFx0XHRvdXRwdXQgKz0gZm9ybWF0LmNoYXJBdChpRm9ybWF0KTtcblx0XHRcdFx0ZWxzZVxuXHRcdFx0XHRcdHN3aXRjaCAoZm9ybWF0LmNoYXJBdChpRm9ybWF0KSkge1xuXHRcdFx0XHRcdFx0Y2FzZSAnZCc6XG5cdFx0XHRcdFx0XHRcdG91dHB1dCArPSBmb3JtYXROdW1iZXIoJ2QnLCBkYXRlLmdldERhdGUoKSwgMik7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSAnRCc6XG5cdFx0XHRcdFx0XHRcdG91dHB1dCArPSBmb3JtYXROYW1lKCdEJywgZGF0ZS5nZXREYXkoKSwgZGF5TmFtZXNTaG9ydCwgZGF5TmFtZXMpO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdGNhc2UgJ28nOlxuXHRcdFx0XHRcdFx0XHRvdXRwdXQgKz0gZm9ybWF0TnVtYmVyKCdvJyxcblx0XHRcdFx0XHRcdFx0XHRNYXRoLnJvdW5kKChuZXcgRGF0ZShkYXRlLmdldEZ1bGxZZWFyKCksIGRhdGUuZ2V0TW9udGgoKSwgZGF0ZS5nZXREYXRlKCkpLmdldFRpbWUoKSAtIG5ldyBEYXRlKGRhdGUuZ2V0RnVsbFllYXIoKSwgMCwgMCkuZ2V0VGltZSgpKSAvIDg2NDAwMDAwKSwgMyk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSAnbSc6XG5cdFx0XHRcdFx0XHRcdG91dHB1dCArPSBmb3JtYXROdW1iZXIoJ20nLCBkYXRlLmdldE1vbnRoKCkgKyAxLCAyKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRjYXNlICdNJzpcblx0XHRcdFx0XHRcdFx0b3V0cHV0ICs9IGZvcm1hdE5hbWUoJ00nLCBkYXRlLmdldE1vbnRoKCksIG1vbnRoTmFtZXNTaG9ydCwgbW9udGhOYW1lcyk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSAneSc6XG5cdFx0XHRcdFx0XHRcdG91dHB1dCArPSAobG9va0FoZWFkKCd5JykgPyBkYXRlLmdldEZ1bGxZZWFyKCkgOlxuXHRcdFx0XHRcdFx0XHRcdChkYXRlLmdldFllYXIoKSAlIDEwMCA8IDEwID8gJzAnIDogJycpICsgZGF0ZS5nZXRZZWFyKCkgJSAxMDApO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdGNhc2UgJ0AnOlxuXHRcdFx0XHRcdFx0XHRvdXRwdXQgKz0gZGF0ZS5nZXRUaW1lKCk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSAnISc6XG5cdFx0XHRcdFx0XHRcdG91dHB1dCArPSBkYXRlLmdldFRpbWUoKSAqIDEwMDAwICsgdGhpcy5fdGlja3NUbzE5NzA7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSBcIidcIjpcblx0XHRcdFx0XHRcdFx0aWYgKGxvb2tBaGVhZChcIidcIikpXG5cdFx0XHRcdFx0XHRcdFx0b3V0cHV0ICs9IFwiJ1wiO1xuXHRcdFx0XHRcdFx0XHRlbHNlXG5cdFx0XHRcdFx0XHRcdFx0bGl0ZXJhbCA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRcdFx0b3V0cHV0ICs9IGZvcm1hdC5jaGFyQXQoaUZvcm1hdCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdHJldHVybiBvdXRwdXQ7XG5cdH0sXG5cblx0LyogRXh0cmFjdCBhbGwgcG9zc2libGUgY2hhcmFjdGVycyBmcm9tIHRoZSBkYXRlIGZvcm1hdC4gKi9cblx0X3Bvc3NpYmxlQ2hhcnM6IGZ1bmN0aW9uIChmb3JtYXQpIHtcblx0XHR2YXIgY2hhcnMgPSAnJztcblx0XHR2YXIgbGl0ZXJhbCA9IGZhbHNlO1xuXHRcdC8vIENoZWNrIHdoZXRoZXIgYSBmb3JtYXQgY2hhcmFjdGVyIGlzIGRvdWJsZWRcblx0XHR2YXIgbG9va0FoZWFkID0gZnVuY3Rpb24obWF0Y2gpIHtcblx0XHRcdHZhciBtYXRjaGVzID0gKGlGb3JtYXQgKyAxIDwgZm9ybWF0Lmxlbmd0aCAmJiBmb3JtYXQuY2hhckF0KGlGb3JtYXQgKyAxKSA9PSBtYXRjaCk7XG5cdFx0XHRpZiAobWF0Y2hlcylcblx0XHRcdFx0aUZvcm1hdCsrO1xuXHRcdFx0cmV0dXJuIG1hdGNoZXM7XG5cdFx0fTtcblx0XHRmb3IgKHZhciBpRm9ybWF0ID0gMDsgaUZvcm1hdCA8IGZvcm1hdC5sZW5ndGg7IGlGb3JtYXQrKylcblx0XHRcdGlmIChsaXRlcmFsKVxuXHRcdFx0XHRpZiAoZm9ybWF0LmNoYXJBdChpRm9ybWF0KSA9PSBcIidcIiAmJiAhbG9va0FoZWFkKFwiJ1wiKSlcblx0XHRcdFx0XHRsaXRlcmFsID0gZmFsc2U7XG5cdFx0XHRcdGVsc2Vcblx0XHRcdFx0XHRjaGFycyArPSBmb3JtYXQuY2hhckF0KGlGb3JtYXQpO1xuXHRcdFx0ZWxzZVxuXHRcdFx0XHRzd2l0Y2ggKGZvcm1hdC5jaGFyQXQoaUZvcm1hdCkpIHtcblx0XHRcdFx0XHRjYXNlICdkJzogY2FzZSAnbSc6IGNhc2UgJ3knOiBjYXNlICdAJzpcblx0XHRcdFx0XHRcdGNoYXJzICs9ICcwMTIzNDU2Nzg5Jztcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ0QnOiBjYXNlICdNJzpcblx0XHRcdFx0XHRcdHJldHVybiBudWxsOyAvLyBBY2NlcHQgYW55dGhpbmdcblx0XHRcdFx0XHRjYXNlIFwiJ1wiOlxuXHRcdFx0XHRcdFx0aWYgKGxvb2tBaGVhZChcIidcIikpXG5cdFx0XHRcdFx0XHRcdGNoYXJzICs9IFwiJ1wiO1xuXHRcdFx0XHRcdFx0ZWxzZVxuXHRcdFx0XHRcdFx0XHRsaXRlcmFsID0gdHJ1ZTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0XHRjaGFycyArPSBmb3JtYXQuY2hhckF0KGlGb3JtYXQpO1xuXHRcdFx0XHR9XG5cdFx0cmV0dXJuIGNoYXJzO1xuXHR9LFxuXG5cdC8qIEdldCBhIHNldHRpbmcgdmFsdWUsIGRlZmF1bHRpbmcgaWYgbmVjZXNzYXJ5LiAqL1xuXHRfZ2V0OiBmdW5jdGlvbihpbnN0LCBuYW1lKSB7XG5cdFx0cmV0dXJuIGluc3Quc2V0dGluZ3NbbmFtZV0gIT09IHVuZGVmaW5lZCA/XG5cdFx0XHRpbnN0LnNldHRpbmdzW25hbWVdIDogdGhpcy5fZGVmYXVsdHNbbmFtZV07XG5cdH0sXG5cblx0LyogUGFyc2UgZXhpc3RpbmcgZGF0ZSBhbmQgaW5pdGlhbGlzZSBkYXRlIHBpY2tlci4gKi9cblx0X3NldERhdGVGcm9tRmllbGQ6IGZ1bmN0aW9uKGluc3QsIG5vRGVmYXVsdCkge1xuXHRcdGlmIChpbnN0LmlucHV0LnZhbCgpID09IGluc3QubGFzdFZhbCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHR2YXIgZGF0ZUZvcm1hdCA9IHRoaXMuX2dldChpbnN0LCAnZGF0ZUZvcm1hdCcpO1xuXHRcdHZhciBkYXRlcyA9IGluc3QubGFzdFZhbCA9IGluc3QuaW5wdXQgPyBpbnN0LmlucHV0LnZhbCgpIDogbnVsbDtcblx0XHR2YXIgZGF0ZSwgZGVmYXVsdERhdGU7XG5cdFx0ZGF0ZSA9IGRlZmF1bHREYXRlID0gdGhpcy5fZ2V0RGVmYXVsdERhdGUoaW5zdCk7XG5cdFx0dmFyIHNldHRpbmdzID0gdGhpcy5fZ2V0Rm9ybWF0Q29uZmlnKGluc3QpO1xuXHRcdHRyeSB7XG5cdFx0XHRkYXRlID0gdGhpcy5wYXJzZURhdGUoZGF0ZUZvcm1hdCwgZGF0ZXMsIHNldHRpbmdzKSB8fCBkZWZhdWx0RGF0ZTtcblx0XHR9IGNhdGNoIChldmVudCkge1xuXHRcdFx0dGhpcy5sb2coZXZlbnQpO1xuXHRcdFx0ZGF0ZXMgPSAobm9EZWZhdWx0ID8gJycgOiBkYXRlcyk7XG5cdFx0fVxuXHRcdGluc3Quc2VsZWN0ZWREYXkgPSBkYXRlLmdldERhdGUoKTtcblx0XHRpbnN0LmRyYXdNb250aCA9IGluc3Quc2VsZWN0ZWRNb250aCA9IGRhdGUuZ2V0TW9udGgoKTtcblx0XHRpbnN0LmRyYXdZZWFyID0gaW5zdC5zZWxlY3RlZFllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKCk7XG5cdFx0aW5zdC5jdXJyZW50RGF5ID0gKGRhdGVzID8gZGF0ZS5nZXREYXRlKCkgOiAwKTtcblx0XHRpbnN0LmN1cnJlbnRNb250aCA9IChkYXRlcyA/IGRhdGUuZ2V0TW9udGgoKSA6IDApO1xuXHRcdGluc3QuY3VycmVudFllYXIgPSAoZGF0ZXMgPyBkYXRlLmdldEZ1bGxZZWFyKCkgOiAwKTtcblx0XHR0aGlzLl9hZGp1c3RJbnN0RGF0ZShpbnN0KTtcblx0fSxcblxuXHQvKiBSZXRyaWV2ZSB0aGUgZGVmYXVsdCBkYXRlIHNob3duIG9uIG9wZW5pbmcuICovXG5cdF9nZXREZWZhdWx0RGF0ZTogZnVuY3Rpb24oaW5zdCkge1xuXHRcdHJldHVybiB0aGlzLl9yZXN0cmljdE1pbk1heChpbnN0LFxuXHRcdFx0dGhpcy5fZGV0ZXJtaW5lRGF0ZShpbnN0LCB0aGlzLl9nZXQoaW5zdCwgJ2RlZmF1bHREYXRlJyksIG5ldyBEYXRlKCkpKTtcblx0fSxcblxuXHQvKiBBIGRhdGUgbWF5IGJlIHNwZWNpZmllZCBhcyBhbiBleGFjdCB2YWx1ZSBvciBhIHJlbGF0aXZlIG9uZS4gKi9cblx0X2RldGVybWluZURhdGU6IGZ1bmN0aW9uKGluc3QsIGRhdGUsIGRlZmF1bHREYXRlKSB7XG5cdFx0dmFyIG9mZnNldE51bWVyaWMgPSBmdW5jdGlvbihvZmZzZXQpIHtcblx0XHRcdHZhciBkYXRlID0gbmV3IERhdGUoKTtcblx0XHRcdGRhdGUuc2V0RGF0ZShkYXRlLmdldERhdGUoKSArIG9mZnNldCk7XG5cdFx0XHRyZXR1cm4gZGF0ZTtcblx0XHR9O1xuXHRcdHZhciBvZmZzZXRTdHJpbmcgPSBmdW5jdGlvbihvZmZzZXQpIHtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdHJldHVybiAkLmRhdGVwaWNrZXIucGFyc2VEYXRlKCQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsICdkYXRlRm9ybWF0JyksXG5cdFx0XHRcdFx0b2Zmc2V0LCAkLmRhdGVwaWNrZXIuX2dldEZvcm1hdENvbmZpZyhpbnN0KSk7XG5cdFx0XHR9XG5cdFx0XHRjYXRjaCAoZSkge1xuXHRcdFx0XHQvLyBJZ25vcmVcblx0XHRcdH1cblx0XHRcdHZhciBkYXRlID0gKG9mZnNldC50b0xvd2VyQ2FzZSgpLm1hdGNoKC9eYy8pID9cblx0XHRcdFx0JC5kYXRlcGlja2VyLl9nZXREYXRlKGluc3QpIDogbnVsbCkgfHwgbmV3IERhdGUoKTtcblx0XHRcdHZhciB5ZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpO1xuXHRcdFx0dmFyIG1vbnRoID0gZGF0ZS5nZXRNb250aCgpO1xuXHRcdFx0dmFyIGRheSA9IGRhdGUuZ2V0RGF0ZSgpO1xuXHRcdFx0dmFyIHBhdHRlcm4gPSAvKFsrLV0/WzAtOV0rKVxccyooZHxEfHd8V3xtfE18eXxZKT8vZztcblx0XHRcdHZhciBtYXRjaGVzID0gcGF0dGVybi5leGVjKG9mZnNldCk7XG5cdFx0XHR3aGlsZSAobWF0Y2hlcykge1xuXHRcdFx0XHRzd2l0Y2ggKG1hdGNoZXNbMl0gfHwgJ2QnKSB7XG5cdFx0XHRcdFx0Y2FzZSAnZCcgOiBjYXNlICdEJyA6XG5cdFx0XHRcdFx0XHRkYXkgKz0gcGFyc2VJbnQobWF0Y2hlc1sxXSwxMCk7IGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ3cnIDogY2FzZSAnVycgOlxuXHRcdFx0XHRcdFx0ZGF5ICs9IHBhcnNlSW50KG1hdGNoZXNbMV0sMTApICogNzsgYnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnbScgOiBjYXNlICdNJyA6XG5cdFx0XHRcdFx0XHRtb250aCArPSBwYXJzZUludChtYXRjaGVzWzFdLDEwKTtcblx0XHRcdFx0XHRcdGRheSA9IE1hdGgubWluKGRheSwgJC5kYXRlcGlja2VyLl9nZXREYXlzSW5Nb250aCh5ZWFyLCBtb250aCkpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAneSc6IGNhc2UgJ1knIDpcblx0XHRcdFx0XHRcdHllYXIgKz0gcGFyc2VJbnQobWF0Y2hlc1sxXSwxMCk7XG5cdFx0XHRcdFx0XHRkYXkgPSBNYXRoLm1pbihkYXksICQuZGF0ZXBpY2tlci5fZ2V0RGF5c0luTW9udGgoeWVhciwgbW9udGgpKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHRcdG1hdGNoZXMgPSBwYXR0ZXJuLmV4ZWMob2Zmc2V0KTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZGF5KTtcblx0XHR9O1xuXHRcdHZhciBuZXdEYXRlID0gKGRhdGUgPT0gbnVsbCB8fCBkYXRlID09PSAnJyA/IGRlZmF1bHREYXRlIDogKHR5cGVvZiBkYXRlID09ICdzdHJpbmcnID8gb2Zmc2V0U3RyaW5nKGRhdGUpIDpcblx0XHRcdCh0eXBlb2YgZGF0ZSA9PSAnbnVtYmVyJyA/IChpc05hTihkYXRlKSA/IGRlZmF1bHREYXRlIDogb2Zmc2V0TnVtZXJpYyhkYXRlKSkgOiBuZXcgRGF0ZShkYXRlLmdldFRpbWUoKSkpKSk7XG5cdFx0bmV3RGF0ZSA9IChuZXdEYXRlICYmIG5ld0RhdGUudG9TdHJpbmcoKSA9PSAnSW52YWxpZCBEYXRlJyA/IGRlZmF1bHREYXRlIDogbmV3RGF0ZSk7XG5cdFx0aWYgKG5ld0RhdGUpIHtcblx0XHRcdG5ld0RhdGUuc2V0SG91cnMoMCk7XG5cdFx0XHRuZXdEYXRlLnNldE1pbnV0ZXMoMCk7XG5cdFx0XHRuZXdEYXRlLnNldFNlY29uZHMoMCk7XG5cdFx0XHRuZXdEYXRlLnNldE1pbGxpc2Vjb25kcygwKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ld0RhdGUpO1xuXHR9LFxuXG5cdC8qIEhhbmRsZSBzd2l0Y2ggdG8vZnJvbSBkYXlsaWdodCBzYXZpbmcuXG5cdCAgIEhvdXJzIG1heSBiZSBub24temVybyBvbiBkYXlsaWdodCBzYXZpbmcgY3V0LW92ZXI6XG5cdCAgID4gMTIgd2hlbiBtaWRuaWdodCBjaGFuZ2VvdmVyLCBidXQgdGhlbiBjYW5ub3QgZ2VuZXJhdGVcblx0ICAgbWlkbmlnaHQgZGF0ZXRpbWUsIHNvIGp1bXAgdG8gMUFNLCBvdGhlcndpc2UgcmVzZXQuXG5cdCAgIEBwYXJhbSAgZGF0ZSAgKERhdGUpIHRoZSBkYXRlIHRvIGNoZWNrXG5cdCAgIEByZXR1cm4gIChEYXRlKSB0aGUgY29ycmVjdGVkIGRhdGUgKi9cblx0X2RheWxpZ2h0U2F2aW5nQWRqdXN0OiBmdW5jdGlvbihkYXRlKSB7XG5cdFx0aWYgKCFkYXRlKSByZXR1cm4gbnVsbDtcblx0XHRkYXRlLnNldEhvdXJzKGRhdGUuZ2V0SG91cnMoKSA+IDEyID8gZGF0ZS5nZXRIb3VycygpICsgMiA6IDApO1xuXHRcdHJldHVybiBkYXRlO1xuXHR9LFxuXG5cdC8qIFNldCB0aGUgZGF0ZShzKSBkaXJlY3RseS4gKi9cblx0X3NldERhdGU6IGZ1bmN0aW9uKGluc3QsIGRhdGUsIG5vQ2hhbmdlKSB7XG5cdFx0dmFyIGNsZWFyID0gIWRhdGU7XG5cdFx0dmFyIG9yaWdNb250aCA9IGluc3Quc2VsZWN0ZWRNb250aDtcblx0XHR2YXIgb3JpZ1llYXIgPSBpbnN0LnNlbGVjdGVkWWVhcjtcblx0XHR2YXIgbmV3RGF0ZSA9IHRoaXMuX3Jlc3RyaWN0TWluTWF4KGluc3QsIHRoaXMuX2RldGVybWluZURhdGUoaW5zdCwgZGF0ZSwgbmV3IERhdGUoKSkpO1xuXHRcdGluc3Quc2VsZWN0ZWREYXkgPSBpbnN0LmN1cnJlbnREYXkgPSBuZXdEYXRlLmdldERhdGUoKTtcblx0XHRpbnN0LmRyYXdNb250aCA9IGluc3Quc2VsZWN0ZWRNb250aCA9IGluc3QuY3VycmVudE1vbnRoID0gbmV3RGF0ZS5nZXRNb250aCgpO1xuXHRcdGluc3QuZHJhd1llYXIgPSBpbnN0LnNlbGVjdGVkWWVhciA9IGluc3QuY3VycmVudFllYXIgPSBuZXdEYXRlLmdldEZ1bGxZZWFyKCk7XG5cdFx0aWYgKChvcmlnTW9udGggIT0gaW5zdC5zZWxlY3RlZE1vbnRoIHx8IG9yaWdZZWFyICE9IGluc3Quc2VsZWN0ZWRZZWFyKSAmJiAhbm9DaGFuZ2UpXG5cdFx0XHR0aGlzLl9ub3RpZnlDaGFuZ2UoaW5zdCk7XG5cdFx0dGhpcy5fYWRqdXN0SW5zdERhdGUoaW5zdCk7XG5cdFx0aWYgKGluc3QuaW5wdXQpIHtcblx0XHRcdGluc3QuaW5wdXQudmFsKGNsZWFyID8gJycgOiB0aGlzLl9mb3JtYXREYXRlKGluc3QpKTtcblx0XHR9XG5cdH0sXG5cblx0LyogUmV0cmlldmUgdGhlIGRhdGUocykgZGlyZWN0bHkuICovXG5cdF9nZXREYXRlOiBmdW5jdGlvbihpbnN0KSB7XG5cdFx0dmFyIHN0YXJ0RGF0ZSA9ICghaW5zdC5jdXJyZW50WWVhciB8fCAoaW5zdC5pbnB1dCAmJiBpbnN0LmlucHV0LnZhbCgpID09ICcnKSA/IG51bGwgOlxuXHRcdFx0dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoXG5cdFx0XHRpbnN0LmN1cnJlbnRZZWFyLCBpbnN0LmN1cnJlbnRNb250aCwgaW5zdC5jdXJyZW50RGF5KSkpO1xuXHRcdFx0cmV0dXJuIHN0YXJ0RGF0ZTtcblx0fSxcblxuXHQvKiBBdHRhY2ggdGhlIG9ueHh4IGhhbmRsZXJzLiAgVGhlc2UgYXJlIGRlY2xhcmVkIHN0YXRpY2FsbHkgc29cblx0ICogdGhleSB3b3JrIHdpdGggc3RhdGljIGNvZGUgdHJhbnNmb3JtZXJzIGxpa2UgQ2FqYS5cblx0ICovXG5cdF9hdHRhY2hIYW5kbGVyczogZnVuY3Rpb24oaW5zdCkge1xuXHRcdHZhciBzdGVwTW9udGhzID0gdGhpcy5fZ2V0KGluc3QsICdzdGVwTW9udGhzJyk7XG5cdFx0dmFyIGlkID0gJyMnICsgaW5zdC5pZC5yZXBsYWNlKCAvXFxcXFxcXFwvZywgXCJcXFxcXCIgKTtcblx0XHRpbnN0LmRwRGl2LmZpbmQoJ1tkYXRhLWhhbmRsZXJdJykubWFwKGZ1bmN0aW9uICgpIHtcblx0XHRcdHZhciBoYW5kbGVyID0ge1xuXHRcdFx0XHRwcmV2OiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0d2luZG93WydEUF9qUXVlcnlfJyArIGRwdXVpZF0uZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShpZCwgLXN0ZXBNb250aHMsICdNJyk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdG5leHQ6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHR3aW5kb3dbJ0RQX2pRdWVyeV8nICsgZHB1dWlkXS5kYXRlcGlja2VyLl9hZGp1c3REYXRlKGlkLCArc3RlcE1vbnRocywgJ00nKTtcblx0XHRcdFx0fSxcblx0XHRcdFx0aGlkZTogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdHdpbmRvd1snRFBfalF1ZXJ5XycgKyBkcHV1aWRdLmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHRvZGF5OiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0d2luZG93WydEUF9qUXVlcnlfJyArIGRwdXVpZF0uZGF0ZXBpY2tlci5fZ290b1RvZGF5KGlkKTtcblx0XHRcdFx0fSxcblx0XHRcdFx0c2VsZWN0RGF5OiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0d2luZG93WydEUF9qUXVlcnlfJyArIGRwdXVpZF0uZGF0ZXBpY2tlci5fc2VsZWN0RGF5KGlkLCArdGhpcy5nZXRBdHRyaWJ1dGUoJ2RhdGEtbW9udGgnKSwgK3RoaXMuZ2V0QXR0cmlidXRlKCdkYXRhLXllYXInKSwgdGhpcyk7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRzZWxlY3RNb250aDogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdHdpbmRvd1snRFBfalF1ZXJ5XycgKyBkcHV1aWRdLmRhdGVwaWNrZXIuX3NlbGVjdE1vbnRoWWVhcihpZCwgdGhpcywgJ00nKTtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHNlbGVjdFllYXI6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHR3aW5kb3dbJ0RQX2pRdWVyeV8nICsgZHB1dWlkXS5kYXRlcGlja2VyLl9zZWxlY3RNb250aFllYXIoaWQsIHRoaXMsICdZJyk7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdFx0JCh0aGlzKS5iaW5kKHRoaXMuZ2V0QXR0cmlidXRlKCdkYXRhLWV2ZW50JyksIGhhbmRsZXJbdGhpcy5nZXRBdHRyaWJ1dGUoJ2RhdGEtaGFuZGxlcicpXSk7XG5cdFx0fSk7XG5cdH0sXG5cblx0LyogR2VuZXJhdGUgdGhlIEhUTUwgZm9yIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBkYXRlIHBpY2tlci4gKi9cblx0X2dlbmVyYXRlSFRNTDogZnVuY3Rpb24oaW5zdCkge1xuXHRcdHZhciB0b2RheSA9IG5ldyBEYXRlKCk7XG5cdFx0dG9kYXkgPSB0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChcblx0XHRcdG5ldyBEYXRlKHRvZGF5LmdldEZ1bGxZZWFyKCksIHRvZGF5LmdldE1vbnRoKCksIHRvZGF5LmdldERhdGUoKSkpOyAvLyBjbGVhciB0aW1lXG5cdFx0dmFyIGlzUlRMID0gdGhpcy5fZ2V0KGluc3QsICdpc1JUTCcpO1xuXHRcdHZhciBzaG93QnV0dG9uUGFuZWwgPSB0aGlzLl9nZXQoaW5zdCwgJ3Nob3dCdXR0b25QYW5lbCcpO1xuXHRcdHZhciBoaWRlSWZOb1ByZXZOZXh0ID0gdGhpcy5fZ2V0KGluc3QsICdoaWRlSWZOb1ByZXZOZXh0Jyk7XG5cdFx0dmFyIG5hdmlnYXRpb25Bc0RhdGVGb3JtYXQgPSB0aGlzLl9nZXQoaW5zdCwgJ25hdmlnYXRpb25Bc0RhdGVGb3JtYXQnKTtcblx0XHR2YXIgbnVtTW9udGhzID0gdGhpcy5fZ2V0TnVtYmVyT2ZNb250aHMoaW5zdCk7XG5cdFx0dmFyIHNob3dDdXJyZW50QXRQb3MgPSB0aGlzLl9nZXQoaW5zdCwgJ3Nob3dDdXJyZW50QXRQb3MnKTtcblx0XHR2YXIgc3RlcE1vbnRocyA9IHRoaXMuX2dldChpbnN0LCAnc3RlcE1vbnRocycpO1xuXHRcdHZhciBpc011bHRpTW9udGggPSAobnVtTW9udGhzWzBdICE9IDEgfHwgbnVtTW9udGhzWzFdICE9IDEpO1xuXHRcdHZhciBjdXJyZW50RGF0ZSA9IHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KCghaW5zdC5jdXJyZW50RGF5ID8gbmV3IERhdGUoOTk5OSwgOSwgOSkgOlxuXHRcdFx0bmV3IERhdGUoaW5zdC5jdXJyZW50WWVhciwgaW5zdC5jdXJyZW50TW9udGgsIGluc3QuY3VycmVudERheSkpKTtcblx0XHR2YXIgbWluRGF0ZSA9IHRoaXMuX2dldE1pbk1heERhdGUoaW5zdCwgJ21pbicpO1xuXHRcdHZhciBtYXhEYXRlID0gdGhpcy5fZ2V0TWluTWF4RGF0ZShpbnN0LCAnbWF4Jyk7XG5cdFx0dmFyIGRyYXdNb250aCA9IGluc3QuZHJhd01vbnRoIC0gc2hvd0N1cnJlbnRBdFBvcztcblx0XHR2YXIgZHJhd1llYXIgPSBpbnN0LmRyYXdZZWFyO1xuXHRcdGlmIChkcmF3TW9udGggPCAwKSB7XG5cdFx0XHRkcmF3TW9udGggKz0gMTI7XG5cdFx0XHRkcmF3WWVhci0tO1xuXHRcdH1cblx0XHRpZiAobWF4RGF0ZSkge1xuXHRcdFx0dmFyIG1heERyYXcgPSB0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZShtYXhEYXRlLmdldEZ1bGxZZWFyKCksXG5cdFx0XHRcdG1heERhdGUuZ2V0TW9udGgoKSAtIChudW1Nb250aHNbMF0gKiBudW1Nb250aHNbMV0pICsgMSwgbWF4RGF0ZS5nZXREYXRlKCkpKTtcblx0XHRcdG1heERyYXcgPSAobWluRGF0ZSAmJiBtYXhEcmF3IDwgbWluRGF0ZSA/IG1pbkRhdGUgOiBtYXhEcmF3KTtcblx0XHRcdHdoaWxlICh0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZShkcmF3WWVhciwgZHJhd01vbnRoLCAxKSkgPiBtYXhEcmF3KSB7XG5cdFx0XHRcdGRyYXdNb250aC0tO1xuXHRcdFx0XHRpZiAoZHJhd01vbnRoIDwgMCkge1xuXHRcdFx0XHRcdGRyYXdNb250aCA9IDExO1xuXHRcdFx0XHRcdGRyYXdZZWFyLS07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0aW5zdC5kcmF3TW9udGggPSBkcmF3TW9udGg7XG5cdFx0aW5zdC5kcmF3WWVhciA9IGRyYXdZZWFyO1xuXHRcdHZhciBwcmV2VGV4dCA9IHRoaXMuX2dldChpbnN0LCAncHJldlRleHQnKTtcblx0XHRwcmV2VGV4dCA9ICghbmF2aWdhdGlvbkFzRGF0ZUZvcm1hdCA/IHByZXZUZXh0IDogdGhpcy5mb3JtYXREYXRlKHByZXZUZXh0LFxuXHRcdFx0dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoZHJhd1llYXIsIGRyYXdNb250aCAtIHN0ZXBNb250aHMsIDEpKSxcblx0XHRcdHRoaXMuX2dldEZvcm1hdENvbmZpZyhpbnN0KSkpO1xuXHRcdHZhciBwcmV2ID0gKHRoaXMuX2NhbkFkanVzdE1vbnRoKGluc3QsIC0xLCBkcmF3WWVhciwgZHJhd01vbnRoKSA/XG5cdFx0XHQnPGEgY2xhc3M9XCJ1aS1kYXRlcGlja2VyLXByZXYgdWktY29ybmVyLWFsbFwiIGRhdGEtaGFuZGxlcj1cInByZXZcIiBkYXRhLWV2ZW50PVwiY2xpY2tcIicgK1xuXHRcdFx0JyB0aXRsZT1cIicgKyBwcmV2VGV4dCArICdcIj48c3BhbiBjbGFzcz1cInVpLWljb24gdWktaWNvbi1jaXJjbGUtdHJpYW5nbGUtJyArICggaXNSVEwgPyAnZScgOiAndycpICsgJ1wiPicgKyBwcmV2VGV4dCArICc8L3NwYW4+PC9hPicgOlxuXHRcdFx0KGhpZGVJZk5vUHJldk5leHQgPyAnJyA6ICc8YSBjbGFzcz1cInVpLWRhdGVwaWNrZXItcHJldiB1aS1jb3JuZXItYWxsIHVpLXN0YXRlLWRpc2FibGVkXCIgdGl0bGU9XCInKyBwcmV2VGV4dCArJ1wiPjxzcGFuIGNsYXNzPVwidWktaWNvbiB1aS1pY29uLWNpcmNsZS10cmlhbmdsZS0nICsgKCBpc1JUTCA/ICdlJyA6ICd3JykgKyAnXCI+JyArIHByZXZUZXh0ICsgJzwvc3Bhbj48L2E+JykpO1xuXHRcdHZhciBuZXh0VGV4dCA9IHRoaXMuX2dldChpbnN0LCAnbmV4dFRleHQnKTtcblx0XHRuZXh0VGV4dCA9ICghbmF2aWdhdGlvbkFzRGF0ZUZvcm1hdCA/IG5leHRUZXh0IDogdGhpcy5mb3JtYXREYXRlKG5leHRUZXh0LFxuXHRcdFx0dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoZHJhd1llYXIsIGRyYXdNb250aCArIHN0ZXBNb250aHMsIDEpKSxcblx0XHRcdHRoaXMuX2dldEZvcm1hdENvbmZpZyhpbnN0KSkpO1xuXHRcdHZhciBuZXh0ID0gKHRoaXMuX2NhbkFkanVzdE1vbnRoKGluc3QsICsxLCBkcmF3WWVhciwgZHJhd01vbnRoKSA/XG5cdFx0XHQnPGEgY2xhc3M9XCJ1aS1kYXRlcGlja2VyLW5leHQgdWktY29ybmVyLWFsbFwiIGRhdGEtaGFuZGxlcj1cIm5leHRcIiBkYXRhLWV2ZW50PVwiY2xpY2tcIicgK1xuXHRcdFx0JyB0aXRsZT1cIicgKyBuZXh0VGV4dCArICdcIj48c3BhbiBjbGFzcz1cInVpLWljb24gdWktaWNvbi1jaXJjbGUtdHJpYW5nbGUtJyArICggaXNSVEwgPyAndycgOiAnZScpICsgJ1wiPicgKyBuZXh0VGV4dCArICc8L3NwYW4+PC9hPicgOlxuXHRcdFx0KGhpZGVJZk5vUHJldk5leHQgPyAnJyA6ICc8YSBjbGFzcz1cInVpLWRhdGVwaWNrZXItbmV4dCB1aS1jb3JuZXItYWxsIHVpLXN0YXRlLWRpc2FibGVkXCIgdGl0bGU9XCInKyBuZXh0VGV4dCArICdcIj48c3BhbiBjbGFzcz1cInVpLWljb24gdWktaWNvbi1jaXJjbGUtdHJpYW5nbGUtJyArICggaXNSVEwgPyAndycgOiAnZScpICsgJ1wiPicgKyBuZXh0VGV4dCArICc8L3NwYW4+PC9hPicpKTtcblx0XHR2YXIgY3VycmVudFRleHQgPSB0aGlzLl9nZXQoaW5zdCwgJ2N1cnJlbnRUZXh0Jyk7XG5cdFx0dmFyIGdvdG9EYXRlID0gKHRoaXMuX2dldChpbnN0LCAnZ290b0N1cnJlbnQnKSAmJiBpbnN0LmN1cnJlbnREYXkgPyBjdXJyZW50RGF0ZSA6IHRvZGF5KTtcblx0XHRjdXJyZW50VGV4dCA9ICghbmF2aWdhdGlvbkFzRGF0ZUZvcm1hdCA/IGN1cnJlbnRUZXh0IDpcblx0XHRcdHRoaXMuZm9ybWF0RGF0ZShjdXJyZW50VGV4dCwgZ290b0RhdGUsIHRoaXMuX2dldEZvcm1hdENvbmZpZyhpbnN0KSkpO1xuXHRcdHZhciBjb250cm9scyA9ICghaW5zdC5pbmxpbmUgPyAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJ1aS1kYXRlcGlja2VyLWNsb3NlIHVpLXN0YXRlLWRlZmF1bHQgdWktcHJpb3JpdHktcHJpbWFyeSB1aS1jb3JuZXItYWxsXCIgZGF0YS1oYW5kbGVyPVwiaGlkZVwiIGRhdGEtZXZlbnQ9XCJjbGlja1wiPicgK1xuXHRcdFx0dGhpcy5fZ2V0KGluc3QsICdjbG9zZVRleHQnKSArICc8L2J1dHRvbj4nIDogJycpO1xuXHRcdHZhciBidXR0b25QYW5lbCA9IChzaG93QnV0dG9uUGFuZWwpID8gJzxkaXYgY2xhc3M9XCJ1aS1kYXRlcGlja2VyLWJ1dHRvbnBhbmUgdWktd2lkZ2V0LWNvbnRlbnRcIj4nICsgKGlzUlRMID8gY29udHJvbHMgOiAnJykgK1xuXHRcdFx0KHRoaXMuX2lzSW5SYW5nZShpbnN0LCBnb3RvRGF0ZSkgPyAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJ1aS1kYXRlcGlja2VyLWN1cnJlbnQgdWktc3RhdGUtZGVmYXVsdCB1aS1wcmlvcml0eS1zZWNvbmRhcnkgdWktY29ybmVyLWFsbFwiIGRhdGEtaGFuZGxlcj1cInRvZGF5XCIgZGF0YS1ldmVudD1cImNsaWNrXCInICtcblx0XHRcdCc+JyArIGN1cnJlbnRUZXh0ICsgJzwvYnV0dG9uPicgOiAnJykgKyAoaXNSVEwgPyAnJyA6IGNvbnRyb2xzKSArICc8L2Rpdj4nIDogJyc7XG5cdFx0dmFyIGZpcnN0RGF5ID0gcGFyc2VJbnQodGhpcy5fZ2V0KGluc3QsICdmaXJzdERheScpLDEwKTtcblx0XHRmaXJzdERheSA9IChpc05hTihmaXJzdERheSkgPyAwIDogZmlyc3REYXkpO1xuXHRcdHZhciBzaG93V2VlayA9IHRoaXMuX2dldChpbnN0LCAnc2hvd1dlZWsnKTtcblx0XHR2YXIgZGF5TmFtZXMgPSB0aGlzLl9nZXQoaW5zdCwgJ2RheU5hbWVzJyk7XG5cdFx0dmFyIGRheU5hbWVzU2hvcnQgPSB0aGlzLl9nZXQoaW5zdCwgJ2RheU5hbWVzU2hvcnQnKTtcblx0XHR2YXIgZGF5TmFtZXNNaW4gPSB0aGlzLl9nZXQoaW5zdCwgJ2RheU5hbWVzTWluJyk7XG5cdFx0dmFyIG1vbnRoTmFtZXMgPSB0aGlzLl9nZXQoaW5zdCwgJ21vbnRoTmFtZXMnKTtcblx0XHR2YXIgbW9udGhOYW1lc1Nob3J0ID0gdGhpcy5fZ2V0KGluc3QsICdtb250aE5hbWVzU2hvcnQnKTtcblx0XHR2YXIgYmVmb3JlU2hvd0RheSA9IHRoaXMuX2dldChpbnN0LCAnYmVmb3JlU2hvd0RheScpO1xuXHRcdHZhciBzaG93T3RoZXJNb250aHMgPSB0aGlzLl9nZXQoaW5zdCwgJ3Nob3dPdGhlck1vbnRocycpO1xuXHRcdHZhciBzZWxlY3RPdGhlck1vbnRocyA9IHRoaXMuX2dldChpbnN0LCAnc2VsZWN0T3RoZXJNb250aHMnKTtcblx0XHR2YXIgY2FsY3VsYXRlV2VlayA9IHRoaXMuX2dldChpbnN0LCAnY2FsY3VsYXRlV2VlaycpIHx8IHRoaXMuaXNvODYwMVdlZWs7XG5cdFx0dmFyIGRlZmF1bHREYXRlID0gdGhpcy5fZ2V0RGVmYXVsdERhdGUoaW5zdCk7XG5cdFx0dmFyIGh0bWwgPSAnJztcblx0XHRmb3IgKHZhciByb3cgPSAwOyByb3cgPCBudW1Nb250aHNbMF07IHJvdysrKSB7XG5cdFx0XHR2YXIgZ3JvdXAgPSAnJztcblx0XHRcdHRoaXMubWF4Um93cyA9IDQ7XG5cdFx0XHRmb3IgKHZhciBjb2wgPSAwOyBjb2wgPCBudW1Nb250aHNbMV07IGNvbCsrKSB7XG5cdFx0XHRcdHZhciBzZWxlY3RlZERhdGUgPSB0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZShkcmF3WWVhciwgZHJhd01vbnRoLCBpbnN0LnNlbGVjdGVkRGF5KSk7XG5cdFx0XHRcdHZhciBjb3JuZXJDbGFzcyA9ICcgdWktY29ybmVyLWFsbCc7XG5cdFx0XHRcdHZhciBjYWxlbmRlciA9ICcnO1xuXHRcdFx0XHRpZiAoaXNNdWx0aU1vbnRoKSB7XG5cdFx0XHRcdFx0Y2FsZW5kZXIgKz0gJzxkaXYgY2xhc3M9XCJ1aS1kYXRlcGlja2VyLWdyb3VwJztcblx0XHRcdFx0XHRpZiAobnVtTW9udGhzWzFdID4gMSlcblx0XHRcdFx0XHRcdHN3aXRjaCAoY29sKSB7XG5cdFx0XHRcdFx0XHRcdGNhc2UgMDogY2FsZW5kZXIgKz0gJyB1aS1kYXRlcGlja2VyLWdyb3VwLWZpcnN0Jztcblx0XHRcdFx0XHRcdFx0XHRjb3JuZXJDbGFzcyA9ICcgdWktY29ybmVyLScgKyAoaXNSVEwgPyAncmlnaHQnIDogJ2xlZnQnKTsgYnJlYWs7XG5cdFx0XHRcdFx0XHRcdGNhc2UgbnVtTW9udGhzWzFdLTE6IGNhbGVuZGVyICs9ICcgdWktZGF0ZXBpY2tlci1ncm91cC1sYXN0Jztcblx0XHRcdFx0XHRcdFx0XHRjb3JuZXJDbGFzcyA9ICcgdWktY29ybmVyLScgKyAoaXNSVEwgPyAnbGVmdCcgOiAncmlnaHQnKTsgYnJlYWs7XG5cdFx0XHRcdFx0XHRcdGRlZmF1bHQ6IGNhbGVuZGVyICs9ICcgdWktZGF0ZXBpY2tlci1ncm91cC1taWRkbGUnOyBjb3JuZXJDbGFzcyA9ICcnOyBicmVhaztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjYWxlbmRlciArPSAnXCI+Jztcblx0XHRcdFx0fVxuXHRcdFx0XHRjYWxlbmRlciArPSAnPGRpdiBjbGFzcz1cInVpLWRhdGVwaWNrZXItaGVhZGVyIHVpLXdpZGdldC1oZWFkZXIgdWktaGVscGVyLWNsZWFyZml4JyArIGNvcm5lckNsYXNzICsgJ1wiPicgK1xuXHRcdFx0XHRcdCgvYWxsfGxlZnQvLnRlc3QoY29ybmVyQ2xhc3MpICYmIHJvdyA9PSAwID8gKGlzUlRMID8gbmV4dCA6IHByZXYpIDogJycpICtcblx0XHRcdFx0XHQoL2FsbHxyaWdodC8udGVzdChjb3JuZXJDbGFzcykgJiYgcm93ID09IDAgPyAoaXNSVEwgPyBwcmV2IDogbmV4dCkgOiAnJykgK1xuXHRcdFx0XHRcdHRoaXMuX2dlbmVyYXRlTW9udGhZZWFySGVhZGVyKGluc3QsIGRyYXdNb250aCwgZHJhd1llYXIsIG1pbkRhdGUsIG1heERhdGUsXG5cdFx0XHRcdFx0cm93ID4gMCB8fCBjb2wgPiAwLCBtb250aE5hbWVzLCBtb250aE5hbWVzU2hvcnQpICsgLy8gZHJhdyBtb250aCBoZWFkZXJzXG5cdFx0XHRcdFx0JzwvZGl2Pjx0YWJsZSBjbGFzcz1cInVpLWRhdGVwaWNrZXItY2FsZW5kYXJcIj48dGhlYWQ+JyArXG5cdFx0XHRcdFx0Jzx0cj4nO1xuXHRcdFx0XHR2YXIgdGhlYWQgPSAoc2hvd1dlZWsgPyAnPHRoIGNsYXNzPVwidWktZGF0ZXBpY2tlci13ZWVrLWNvbFwiPicgKyB0aGlzLl9nZXQoaW5zdCwgJ3dlZWtIZWFkZXInKSArICc8L3RoPicgOiAnJyk7XG5cdFx0XHRcdGZvciAodmFyIGRvdyA9IDA7IGRvdyA8IDc7IGRvdysrKSB7IC8vIGRheXMgb2YgdGhlIHdlZWtcblx0XHRcdFx0XHR2YXIgZGF5ID0gKGRvdyArIGZpcnN0RGF5KSAlIDc7XG5cdFx0XHRcdFx0dGhlYWQgKz0gJzx0aCcgKyAoKGRvdyArIGZpcnN0RGF5ICsgNikgJSA3ID49IDUgPyAnIGNsYXNzPVwidWktZGF0ZXBpY2tlci13ZWVrLWVuZFwiJyA6ICcnKSArICc+JyArXG5cdFx0XHRcdFx0XHQnPHNwYW4gdGl0bGU9XCInICsgZGF5TmFtZXNbZGF5XSArICdcIj4nICsgZGF5TmFtZXNNaW5bZGF5XSArICc8L3NwYW4+PC90aD4nO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNhbGVuZGVyICs9IHRoZWFkICsgJzwvdHI+PC90aGVhZD48dGJvZHk+Jztcblx0XHRcdFx0dmFyIGRheXNJbk1vbnRoID0gdGhpcy5fZ2V0RGF5c0luTW9udGgoZHJhd1llYXIsIGRyYXdNb250aCk7XG5cdFx0XHRcdGlmIChkcmF3WWVhciA9PSBpbnN0LnNlbGVjdGVkWWVhciAmJiBkcmF3TW9udGggPT0gaW5zdC5zZWxlY3RlZE1vbnRoKVxuXHRcdFx0XHRcdGluc3Quc2VsZWN0ZWREYXkgPSBNYXRoLm1pbihpbnN0LnNlbGVjdGVkRGF5LCBkYXlzSW5Nb250aCk7XG5cdFx0XHRcdHZhciBsZWFkRGF5cyA9ICh0aGlzLl9nZXRGaXJzdERheU9mTW9udGgoZHJhd1llYXIsIGRyYXdNb250aCkgLSBmaXJzdERheSArIDcpICUgNztcblx0XHRcdFx0dmFyIGN1clJvd3MgPSBNYXRoLmNlaWwoKGxlYWREYXlzICsgZGF5c0luTW9udGgpIC8gNyk7IC8vIGNhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIHJvd3MgdG8gZ2VuZXJhdGVcblx0XHRcdFx0dmFyIG51bVJvd3MgPSAoaXNNdWx0aU1vbnRoID8gdGhpcy5tYXhSb3dzID4gY3VyUm93cyA/IHRoaXMubWF4Um93cyA6IGN1clJvd3MgOiBjdXJSb3dzKTsgLy9JZiBtdWx0aXBsZSBtb250aHMsIHVzZSB0aGUgaGlnaGVyIG51bWJlciBvZiByb3dzIChzZWUgIzcwNDMpXG5cdFx0XHRcdHRoaXMubWF4Um93cyA9IG51bVJvd3M7XG5cdFx0XHRcdHZhciBwcmludERhdGUgPSB0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZShkcmF3WWVhciwgZHJhd01vbnRoLCAxIC0gbGVhZERheXMpKTtcblx0XHRcdFx0Zm9yICh2YXIgZFJvdyA9IDA7IGRSb3cgPCBudW1Sb3dzOyBkUm93KyspIHsgLy8gY3JlYXRlIGRhdGUgcGlja2VyIHJvd3Ncblx0XHRcdFx0XHRjYWxlbmRlciArPSAnPHRyPic7XG5cdFx0XHRcdFx0dmFyIHRib2R5ID0gKCFzaG93V2VlayA/ICcnIDogJzx0ZCBjbGFzcz1cInVpLWRhdGVwaWNrZXItd2Vlay1jb2xcIj4nICtcblx0XHRcdFx0XHRcdHRoaXMuX2dldChpbnN0LCAnY2FsY3VsYXRlV2VlaycpKHByaW50RGF0ZSkgKyAnPC90ZD4nKTtcblx0XHRcdFx0XHRmb3IgKHZhciBkb3cgPSAwOyBkb3cgPCA3OyBkb3crKykgeyAvLyBjcmVhdGUgZGF0ZSBwaWNrZXIgZGF5c1xuXHRcdFx0XHRcdFx0dmFyIGRheVNldHRpbmdzID0gKGJlZm9yZVNob3dEYXkgP1xuXHRcdFx0XHRcdFx0XHRiZWZvcmVTaG93RGF5LmFwcGx5KChpbnN0LmlucHV0ID8gaW5zdC5pbnB1dFswXSA6IG51bGwpLCBbcHJpbnREYXRlXSkgOiBbdHJ1ZSwgJyddKTtcblx0XHRcdFx0XHRcdHZhciBvdGhlck1vbnRoID0gKHByaW50RGF0ZS5nZXRNb250aCgpICE9IGRyYXdNb250aCk7XG5cdFx0XHRcdFx0XHR2YXIgdW5zZWxlY3RhYmxlID0gKG90aGVyTW9udGggJiYgIXNlbGVjdE90aGVyTW9udGhzKSB8fCAhZGF5U2V0dGluZ3NbMF0gfHxcblx0XHRcdFx0XHRcdFx0KG1pbkRhdGUgJiYgcHJpbnREYXRlIDwgbWluRGF0ZSkgfHwgKG1heERhdGUgJiYgcHJpbnREYXRlID4gbWF4RGF0ZSk7XG5cdFx0XHRcdFx0XHR0Ym9keSArPSAnPHRkIGNsYXNzPVwiJyArXG5cdFx0XHRcdFx0XHRcdCgoZG93ICsgZmlyc3REYXkgKyA2KSAlIDcgPj0gNSA/ICcgdWktZGF0ZXBpY2tlci13ZWVrLWVuZCcgOiAnJykgKyAvLyBoaWdobGlnaHQgd2Vla2VuZHNcblx0XHRcdFx0XHRcdFx0KG90aGVyTW9udGggPyAnIHVpLWRhdGVwaWNrZXItb3RoZXItbW9udGgnIDogJycpICsgLy8gaGlnaGxpZ2h0IGRheXMgZnJvbSBvdGhlciBtb250aHNcblx0XHRcdFx0XHRcdFx0KChwcmludERhdGUuZ2V0VGltZSgpID09IHNlbGVjdGVkRGF0ZS5nZXRUaW1lKCkgJiYgZHJhd01vbnRoID09IGluc3Quc2VsZWN0ZWRNb250aCAmJiBpbnN0Ll9rZXlFdmVudCkgfHwgLy8gdXNlciBwcmVzc2VkIGtleVxuXHRcdFx0XHRcdFx0XHQoZGVmYXVsdERhdGUuZ2V0VGltZSgpID09IHByaW50RGF0ZS5nZXRUaW1lKCkgJiYgZGVmYXVsdERhdGUuZ2V0VGltZSgpID09IHNlbGVjdGVkRGF0ZS5nZXRUaW1lKCkpID9cblx0XHRcdFx0XHRcdFx0Ly8gb3IgZGVmYXVsdERhdGUgaXMgY3VycmVudCBwcmludGVkRGF0ZSBhbmQgZGVmYXVsdERhdGUgaXMgc2VsZWN0ZWREYXRlXG5cdFx0XHRcdFx0XHRcdCcgJyArIHRoaXMuX2RheU92ZXJDbGFzcyA6ICcnKSArIC8vIGhpZ2hsaWdodCBzZWxlY3RlZCBkYXlcblx0XHRcdFx0XHRcdFx0KHVuc2VsZWN0YWJsZSA/ICcgJyArIHRoaXMuX3Vuc2VsZWN0YWJsZUNsYXNzICsgJyB1aS1zdGF0ZS1kaXNhYmxlZCc6ICcnKSArICAvLyBoaWdobGlnaHQgdW5zZWxlY3RhYmxlIGRheXNcblx0XHRcdFx0XHRcdFx0KG90aGVyTW9udGggJiYgIXNob3dPdGhlck1vbnRocyA/ICcnIDogJyAnICsgZGF5U2V0dGluZ3NbMV0gKyAvLyBoaWdobGlnaHQgY3VzdG9tIGRhdGVzXG5cdFx0XHRcdFx0XHRcdChwcmludERhdGUuZ2V0VGltZSgpID09IGN1cnJlbnREYXRlLmdldFRpbWUoKSA/ICcgJyArIHRoaXMuX2N1cnJlbnRDbGFzcyA6ICcnKSArIC8vIGhpZ2hsaWdodCBzZWxlY3RlZCBkYXlcblx0XHRcdFx0XHRcdFx0KHByaW50RGF0ZS5nZXRUaW1lKCkgPT0gdG9kYXkuZ2V0VGltZSgpID8gJyB1aS1kYXRlcGlja2VyLXRvZGF5JyA6ICcnKSkgKyAnXCInICsgLy8gaGlnaGxpZ2h0IHRvZGF5IChpZiBkaWZmZXJlbnQpXG5cdFx0XHRcdFx0XHRcdCgoIW90aGVyTW9udGggfHwgc2hvd090aGVyTW9udGhzKSAmJiBkYXlTZXR0aW5nc1syXSA/ICcgdGl0bGU9XCInICsgZGF5U2V0dGluZ3NbMl0gKyAnXCInIDogJycpICsgLy8gY2VsbCB0aXRsZVxuXHRcdFx0XHRcdFx0XHQodW5zZWxlY3RhYmxlID8gJycgOiAnIGRhdGEtaGFuZGxlcj1cInNlbGVjdERheVwiIGRhdGEtZXZlbnQ9XCJjbGlja1wiIGRhdGEtbW9udGg9XCInICsgcHJpbnREYXRlLmdldE1vbnRoKCkgKyAnXCIgZGF0YS15ZWFyPVwiJyArIHByaW50RGF0ZS5nZXRGdWxsWWVhcigpICsgJ1wiJykgKyAnPicgKyAvLyBhY3Rpb25zXG5cdFx0XHRcdFx0XHRcdChvdGhlck1vbnRoICYmICFzaG93T3RoZXJNb250aHMgPyAnJiN4YTA7JyA6IC8vIGRpc3BsYXkgZm9yIG90aGVyIG1vbnRoc1xuXHRcdFx0XHRcdFx0XHQodW5zZWxlY3RhYmxlID8gJzxzcGFuIGNsYXNzPVwidWktc3RhdGUtZGVmYXVsdFwiPicgKyBwcmludERhdGUuZ2V0RGF0ZSgpICsgJzwvc3Bhbj4nIDogJzxhIGNsYXNzPVwidWktc3RhdGUtZGVmYXVsdCcgK1xuXHRcdFx0XHRcdFx0XHQocHJpbnREYXRlLmdldFRpbWUoKSA9PSB0b2RheS5nZXRUaW1lKCkgPyAnIHVpLXN0YXRlLWhpZ2hsaWdodCcgOiAnJykgK1xuXHRcdFx0XHRcdFx0XHQocHJpbnREYXRlLmdldFRpbWUoKSA9PSBjdXJyZW50RGF0ZS5nZXRUaW1lKCkgPyAnIHVpLXN0YXRlLWFjdGl2ZScgOiAnJykgKyAvLyBoaWdobGlnaHQgc2VsZWN0ZWQgZGF5XG5cdFx0XHRcdFx0XHRcdChvdGhlck1vbnRoID8gJyB1aS1wcmlvcml0eS1zZWNvbmRhcnknIDogJycpICsgLy8gZGlzdGluZ3Vpc2ggZGF0ZXMgZnJvbSBvdGhlciBtb250aHNcblx0XHRcdFx0XHRcdFx0J1wiIGhyZWY9XCIjXCI+JyArIHByaW50RGF0ZS5nZXREYXRlKCkgKyAnPC9hPicpKSArICc8L3RkPic7IC8vIGRpc3BsYXkgc2VsZWN0YWJsZSBkYXRlXG5cdFx0XHRcdFx0XHRwcmludERhdGUuc2V0RGF0ZShwcmludERhdGUuZ2V0RGF0ZSgpICsgMSk7XG5cdFx0XHRcdFx0XHRwcmludERhdGUgPSB0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChwcmludERhdGUpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjYWxlbmRlciArPSB0Ym9keSArICc8L3RyPic7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZHJhd01vbnRoKys7XG5cdFx0XHRcdGlmIChkcmF3TW9udGggPiAxMSkge1xuXHRcdFx0XHRcdGRyYXdNb250aCA9IDA7XG5cdFx0XHRcdFx0ZHJhd1llYXIrKztcblx0XHRcdFx0fVxuXHRcdFx0XHRjYWxlbmRlciArPSAnPC90Ym9keT48L3RhYmxlPicgKyAoaXNNdWx0aU1vbnRoID8gJzwvZGl2PicgK1xuXHRcdFx0XHRcdFx0XHQoKG51bU1vbnRoc1swXSA+IDAgJiYgY29sID09IG51bU1vbnRoc1sxXS0xKSA/ICc8ZGl2IGNsYXNzPVwidWktZGF0ZXBpY2tlci1yb3ctYnJlYWtcIj48L2Rpdj4nIDogJycpIDogJycpO1xuXHRcdFx0XHRncm91cCArPSBjYWxlbmRlcjtcblx0XHRcdH1cblx0XHRcdGh0bWwgKz0gZ3JvdXA7XG5cdFx0fVxuXHRcdGh0bWwgKz0gYnV0dG9uUGFuZWwgKyAoJC51aS5pZTYgJiYgIWluc3QuaW5saW5lID9cblx0XHRcdCc8aWZyYW1lIHNyYz1cImphdmFzY3JpcHQ6ZmFsc2U7XCIgY2xhc3M9XCJ1aS1kYXRlcGlja2VyLWNvdmVyXCIgZnJhbWVib3JkZXI9XCIwXCI+PC9pZnJhbWU+JyA6ICcnKTtcblx0XHRpbnN0Ll9rZXlFdmVudCA9IGZhbHNlO1xuXHRcdHJldHVybiBodG1sO1xuXHR9LFxuXG5cdC8qIEdlbmVyYXRlIHRoZSBtb250aCBhbmQgeWVhciBoZWFkZXIuICovXG5cdF9nZW5lcmF0ZU1vbnRoWWVhckhlYWRlcjogZnVuY3Rpb24oaW5zdCwgZHJhd01vbnRoLCBkcmF3WWVhciwgbWluRGF0ZSwgbWF4RGF0ZSxcblx0XHRcdHNlY29uZGFyeSwgbW9udGhOYW1lcywgbW9udGhOYW1lc1Nob3J0KSB7XG5cdFx0dmFyIGNoYW5nZU1vbnRoID0gdGhpcy5fZ2V0KGluc3QsICdjaGFuZ2VNb250aCcpO1xuXHRcdHZhciBjaGFuZ2VZZWFyID0gdGhpcy5fZ2V0KGluc3QsICdjaGFuZ2VZZWFyJyk7XG5cdFx0dmFyIHNob3dNb250aEFmdGVyWWVhciA9IHRoaXMuX2dldChpbnN0LCAnc2hvd01vbnRoQWZ0ZXJZZWFyJyk7XG5cdFx0dmFyIGh0bWwgPSAnPGRpdiBjbGFzcz1cInVpLWRhdGVwaWNrZXItdGl0bGVcIj4nO1xuXHRcdHZhciBtb250aEh0bWwgPSAnJztcblx0XHQvLyBtb250aCBzZWxlY3Rpb25cblx0XHRpZiAoc2Vjb25kYXJ5IHx8ICFjaGFuZ2VNb250aClcblx0XHRcdG1vbnRoSHRtbCArPSAnPHNwYW4gY2xhc3M9XCJ1aS1kYXRlcGlja2VyLW1vbnRoXCI+JyArIG1vbnRoTmFtZXNbZHJhd01vbnRoXSArICc8L3NwYW4+Jztcblx0XHRlbHNlIHtcblx0XHRcdHZhciBpbk1pblllYXIgPSAobWluRGF0ZSAmJiBtaW5EYXRlLmdldEZ1bGxZZWFyKCkgPT0gZHJhd1llYXIpO1xuXHRcdFx0dmFyIGluTWF4WWVhciA9IChtYXhEYXRlICYmIG1heERhdGUuZ2V0RnVsbFllYXIoKSA9PSBkcmF3WWVhcik7XG5cdFx0XHRtb250aEh0bWwgKz0gJzxzZWxlY3QgY2xhc3M9XCJ1aS1kYXRlcGlja2VyLW1vbnRoXCIgZGF0YS1oYW5kbGVyPVwic2VsZWN0TW9udGhcIiBkYXRhLWV2ZW50PVwiY2hhbmdlXCI+Jztcblx0XHRcdGZvciAodmFyIG1vbnRoID0gMDsgbW9udGggPCAxMjsgbW9udGgrKykge1xuXHRcdFx0XHRpZiAoKCFpbk1pblllYXIgfHwgbW9udGggPj0gbWluRGF0ZS5nZXRNb250aCgpKSAmJlxuXHRcdFx0XHRcdFx0KCFpbk1heFllYXIgfHwgbW9udGggPD0gbWF4RGF0ZS5nZXRNb250aCgpKSlcblx0XHRcdFx0XHRtb250aEh0bWwgKz0gJzxvcHRpb24gdmFsdWU9XCInICsgbW9udGggKyAnXCInICtcblx0XHRcdFx0XHRcdChtb250aCA9PSBkcmF3TW9udGggPyAnIHNlbGVjdGVkPVwic2VsZWN0ZWRcIicgOiAnJykgK1xuXHRcdFx0XHRcdFx0Jz4nICsgbW9udGhOYW1lc1Nob3J0W21vbnRoXSArICc8L29wdGlvbj4nO1xuXHRcdFx0fVxuXHRcdFx0bW9udGhIdG1sICs9ICc8L3NlbGVjdD4nO1xuXHRcdH1cblx0XHRpZiAoIXNob3dNb250aEFmdGVyWWVhcilcblx0XHRcdGh0bWwgKz0gbW9udGhIdG1sICsgKHNlY29uZGFyeSB8fCAhKGNoYW5nZU1vbnRoICYmIGNoYW5nZVllYXIpID8gJyYjeGEwOycgOiAnJyk7XG5cdFx0Ly8geWVhciBzZWxlY3Rpb25cblx0XHRpZiAoICFpbnN0LnllYXJzaHRtbCApIHtcblx0XHRcdGluc3QueWVhcnNodG1sID0gJyc7XG5cdFx0XHRpZiAoc2Vjb25kYXJ5IHx8ICFjaGFuZ2VZZWFyKVxuXHRcdFx0XHRodG1sICs9ICc8c3BhbiBjbGFzcz1cInVpLWRhdGVwaWNrZXIteWVhclwiPicgKyBkcmF3WWVhciArICc8L3NwYW4+Jztcblx0XHRcdGVsc2Uge1xuXHRcdFx0XHQvLyBkZXRlcm1pbmUgcmFuZ2Ugb2YgeWVhcnMgdG8gZGlzcGxheVxuXHRcdFx0XHR2YXIgeWVhcnMgPSB0aGlzLl9nZXQoaW5zdCwgJ3llYXJSYW5nZScpLnNwbGl0KCc6Jyk7XG5cdFx0XHRcdHZhciB0aGlzWWVhciA9IG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKTtcblx0XHRcdFx0dmFyIGRldGVybWluZVllYXIgPSBmdW5jdGlvbih2YWx1ZSkge1xuXHRcdFx0XHRcdHZhciB5ZWFyID0gKHZhbHVlLm1hdGNoKC9jWystXS4qLykgPyBkcmF3WWVhciArIHBhcnNlSW50KHZhbHVlLnN1YnN0cmluZygxKSwgMTApIDpcblx0XHRcdFx0XHRcdCh2YWx1ZS5tYXRjaCgvWystXS4qLykgPyB0aGlzWWVhciArIHBhcnNlSW50KHZhbHVlLCAxMCkgOlxuXHRcdFx0XHRcdFx0cGFyc2VJbnQodmFsdWUsIDEwKSkpO1xuXHRcdFx0XHRcdHJldHVybiAoaXNOYU4oeWVhcikgPyB0aGlzWWVhciA6IHllYXIpO1xuXHRcdFx0XHR9O1xuXHRcdFx0XHR2YXIgeWVhciA9IGRldGVybWluZVllYXIoeWVhcnNbMF0pO1xuXHRcdFx0XHR2YXIgZW5kWWVhciA9IE1hdGgubWF4KHllYXIsIGRldGVybWluZVllYXIoeWVhcnNbMV0gfHwgJycpKTtcblx0XHRcdFx0eWVhciA9IChtaW5EYXRlID8gTWF0aC5tYXgoeWVhciwgbWluRGF0ZS5nZXRGdWxsWWVhcigpKSA6IHllYXIpO1xuXHRcdFx0XHRlbmRZZWFyID0gKG1heERhdGUgPyBNYXRoLm1pbihlbmRZZWFyLCBtYXhEYXRlLmdldEZ1bGxZZWFyKCkpIDogZW5kWWVhcik7XG5cdFx0XHRcdGluc3QueWVhcnNodG1sICs9ICc8c2VsZWN0IGNsYXNzPVwidWktZGF0ZXBpY2tlci15ZWFyXCIgZGF0YS1oYW5kbGVyPVwic2VsZWN0WWVhclwiIGRhdGEtZXZlbnQ9XCJjaGFuZ2VcIj4nO1xuXHRcdFx0XHRmb3IgKDsgeWVhciA8PSBlbmRZZWFyOyB5ZWFyKyspIHtcblx0XHRcdFx0XHRpbnN0LnllYXJzaHRtbCArPSAnPG9wdGlvbiB2YWx1ZT1cIicgKyB5ZWFyICsgJ1wiJyArXG5cdFx0XHRcdFx0XHQoeWVhciA9PSBkcmF3WWVhciA/ICcgc2VsZWN0ZWQ9XCJzZWxlY3RlZFwiJyA6ICcnKSArXG5cdFx0XHRcdFx0XHQnPicgKyB5ZWFyICsgJzwvb3B0aW9uPic7XG5cdFx0XHRcdH1cblx0XHRcdFx0aW5zdC55ZWFyc2h0bWwgKz0gJzwvc2VsZWN0Pic7XG5cblx0XHRcdFx0aHRtbCArPSBpbnN0LnllYXJzaHRtbDtcblx0XHRcdFx0aW5zdC55ZWFyc2h0bWwgPSBudWxsO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRodG1sICs9IHRoaXMuX2dldChpbnN0LCAneWVhclN1ZmZpeCcpO1xuXHRcdGlmIChzaG93TW9udGhBZnRlclllYXIpXG5cdFx0XHRodG1sICs9IChzZWNvbmRhcnkgfHwgIShjaGFuZ2VNb250aCAmJiBjaGFuZ2VZZWFyKSA/ICcmI3hhMDsnIDogJycpICsgbW9udGhIdG1sO1xuXHRcdGh0bWwgKz0gJzwvZGl2Pic7IC8vIENsb3NlIGRhdGVwaWNrZXJfaGVhZGVyXG5cdFx0cmV0dXJuIGh0bWw7XG5cdH0sXG5cblx0LyogQWRqdXN0IG9uZSBvZiB0aGUgZGF0ZSBzdWItZmllbGRzLiAqL1xuXHRfYWRqdXN0SW5zdERhdGU6IGZ1bmN0aW9uKGluc3QsIG9mZnNldCwgcGVyaW9kKSB7XG5cdFx0dmFyIHllYXIgPSBpbnN0LmRyYXdZZWFyICsgKHBlcmlvZCA9PSAnWScgPyBvZmZzZXQgOiAwKTtcblx0XHR2YXIgbW9udGggPSBpbnN0LmRyYXdNb250aCArIChwZXJpb2QgPT0gJ00nID8gb2Zmc2V0IDogMCk7XG5cdFx0dmFyIGRheSA9IE1hdGgubWluKGluc3Quc2VsZWN0ZWREYXksIHRoaXMuX2dldERheXNJbk1vbnRoKHllYXIsIG1vbnRoKSkgK1xuXHRcdFx0KHBlcmlvZCA9PSAnRCcgPyBvZmZzZXQgOiAwKTtcblx0XHR2YXIgZGF0ZSA9IHRoaXMuX3Jlc3RyaWN0TWluTWF4KGluc3QsXG5cdFx0XHR0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZGF5KSkpO1xuXHRcdGluc3Quc2VsZWN0ZWREYXkgPSBkYXRlLmdldERhdGUoKTtcblx0XHRpbnN0LmRyYXdNb250aCA9IGluc3Quc2VsZWN0ZWRNb250aCA9IGRhdGUuZ2V0TW9udGgoKTtcblx0XHRpbnN0LmRyYXdZZWFyID0gaW5zdC5zZWxlY3RlZFllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKCk7XG5cdFx0aWYgKHBlcmlvZCA9PSAnTScgfHwgcGVyaW9kID09ICdZJylcblx0XHRcdHRoaXMuX25vdGlmeUNoYW5nZShpbnN0KTtcblx0fSxcblxuXHQvKiBFbnN1cmUgYSBkYXRlIGlzIHdpdGhpbiBhbnkgbWluL21heCBib3VuZHMuICovXG5cdF9yZXN0cmljdE1pbk1heDogZnVuY3Rpb24oaW5zdCwgZGF0ZSkge1xuXHRcdHZhciBtaW5EYXRlID0gdGhpcy5fZ2V0TWluTWF4RGF0ZShpbnN0LCAnbWluJyk7XG5cdFx0dmFyIG1heERhdGUgPSB0aGlzLl9nZXRNaW5NYXhEYXRlKGluc3QsICdtYXgnKTtcblx0XHR2YXIgbmV3RGF0ZSA9IChtaW5EYXRlICYmIGRhdGUgPCBtaW5EYXRlID8gbWluRGF0ZSA6IGRhdGUpO1xuXHRcdG5ld0RhdGUgPSAobWF4RGF0ZSAmJiBuZXdEYXRlID4gbWF4RGF0ZSA/IG1heERhdGUgOiBuZXdEYXRlKTtcblx0XHRyZXR1cm4gbmV3RGF0ZTtcblx0fSxcblxuXHQvKiBOb3RpZnkgY2hhbmdlIG9mIG1vbnRoL3llYXIuICovXG5cdF9ub3RpZnlDaGFuZ2U6IGZ1bmN0aW9uKGluc3QpIHtcblx0XHR2YXIgb25DaGFuZ2UgPSB0aGlzLl9nZXQoaW5zdCwgJ29uQ2hhbmdlTW9udGhZZWFyJyk7XG5cdFx0aWYgKG9uQ2hhbmdlKVxuXHRcdFx0b25DaGFuZ2UuYXBwbHkoKGluc3QuaW5wdXQgPyBpbnN0LmlucHV0WzBdIDogbnVsbCksXG5cdFx0XHRcdFtpbnN0LnNlbGVjdGVkWWVhciwgaW5zdC5zZWxlY3RlZE1vbnRoICsgMSwgaW5zdF0pO1xuXHR9LFxuXG5cdC8qIERldGVybWluZSB0aGUgbnVtYmVyIG9mIG1vbnRocyB0byBzaG93LiAqL1xuXHRfZ2V0TnVtYmVyT2ZNb250aHM6IGZ1bmN0aW9uKGluc3QpIHtcblx0XHR2YXIgbnVtTW9udGhzID0gdGhpcy5fZ2V0KGluc3QsICdudW1iZXJPZk1vbnRocycpO1xuXHRcdHJldHVybiAobnVtTW9udGhzID09IG51bGwgPyBbMSwgMV0gOiAodHlwZW9mIG51bU1vbnRocyA9PSAnbnVtYmVyJyA/IFsxLCBudW1Nb250aHNdIDogbnVtTW9udGhzKSk7XG5cdH0sXG5cblx0LyogRGV0ZXJtaW5lIHRoZSBjdXJyZW50IG1heGltdW0gZGF0ZSAtIGVuc3VyZSBubyB0aW1lIGNvbXBvbmVudHMgYXJlIHNldC4gKi9cblx0X2dldE1pbk1heERhdGU6IGZ1bmN0aW9uKGluc3QsIG1pbk1heCkge1xuXHRcdHJldHVybiB0aGlzLl9kZXRlcm1pbmVEYXRlKGluc3QsIHRoaXMuX2dldChpbnN0LCBtaW5NYXggKyAnRGF0ZScpLCBudWxsKTtcblx0fSxcblxuXHQvKiBGaW5kIHRoZSBudW1iZXIgb2YgZGF5cyBpbiBhIGdpdmVuIG1vbnRoLiAqL1xuXHRfZ2V0RGF5c0luTW9udGg6IGZ1bmN0aW9uKHllYXIsIG1vbnRoKSB7XG5cdFx0cmV0dXJuIDMyIC0gdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoeWVhciwgbW9udGgsIDMyKSkuZ2V0RGF0ZSgpO1xuXHR9LFxuXG5cdC8qIEZpbmQgdGhlIGRheSBvZiB0aGUgd2VlayBvZiB0aGUgZmlyc3Qgb2YgYSBtb250aC4gKi9cblx0X2dldEZpcnN0RGF5T2ZNb250aDogZnVuY3Rpb24oeWVhciwgbW9udGgpIHtcblx0XHRyZXR1cm4gbmV3IERhdGUoeWVhciwgbW9udGgsIDEpLmdldERheSgpO1xuXHR9LFxuXG5cdC8qIERldGVybWluZXMgaWYgd2Ugc2hvdWxkIGFsbG93IGEgXCJuZXh0L3ByZXZcIiBtb250aCBkaXNwbGF5IGNoYW5nZS4gKi9cblx0X2NhbkFkanVzdE1vbnRoOiBmdW5jdGlvbihpbnN0LCBvZmZzZXQsIGN1clllYXIsIGN1ck1vbnRoKSB7XG5cdFx0dmFyIG51bU1vbnRocyA9IHRoaXMuX2dldE51bWJlck9mTW9udGhzKGluc3QpO1xuXHRcdHZhciBkYXRlID0gdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoY3VyWWVhcixcblx0XHRcdGN1ck1vbnRoICsgKG9mZnNldCA8IDAgPyBvZmZzZXQgOiBudW1Nb250aHNbMF0gKiBudW1Nb250aHNbMV0pLCAxKSk7XG5cdFx0aWYgKG9mZnNldCA8IDApXG5cdFx0XHRkYXRlLnNldERhdGUodGhpcy5fZ2V0RGF5c0luTW9udGgoZGF0ZS5nZXRGdWxsWWVhcigpLCBkYXRlLmdldE1vbnRoKCkpKTtcblx0XHRyZXR1cm4gdGhpcy5faXNJblJhbmdlKGluc3QsIGRhdGUpO1xuXHR9LFxuXG5cdC8qIElzIHRoZSBnaXZlbiBkYXRlIGluIHRoZSBhY2NlcHRlZCByYW5nZT8gKi9cblx0X2lzSW5SYW5nZTogZnVuY3Rpb24oaW5zdCwgZGF0ZSkge1xuXHRcdHZhciBtaW5EYXRlID0gdGhpcy5fZ2V0TWluTWF4RGF0ZShpbnN0LCAnbWluJyk7XG5cdFx0dmFyIG1heERhdGUgPSB0aGlzLl9nZXRNaW5NYXhEYXRlKGluc3QsICdtYXgnKTtcblx0XHRyZXR1cm4gKCghbWluRGF0ZSB8fCBkYXRlLmdldFRpbWUoKSA+PSBtaW5EYXRlLmdldFRpbWUoKSkgJiZcblx0XHRcdCghbWF4RGF0ZSB8fCBkYXRlLmdldFRpbWUoKSA8PSBtYXhEYXRlLmdldFRpbWUoKSkpO1xuXHR9LFxuXG5cdC8qIFByb3ZpZGUgdGhlIGNvbmZpZ3VyYXRpb24gc2V0dGluZ3MgZm9yIGZvcm1hdHRpbmcvcGFyc2luZy4gKi9cblx0X2dldEZvcm1hdENvbmZpZzogZnVuY3Rpb24oaW5zdCkge1xuXHRcdHZhciBzaG9ydFllYXJDdXRvZmYgPSB0aGlzLl9nZXQoaW5zdCwgJ3Nob3J0WWVhckN1dG9mZicpO1xuXHRcdHNob3J0WWVhckN1dG9mZiA9ICh0eXBlb2Ygc2hvcnRZZWFyQ3V0b2ZmICE9ICdzdHJpbmcnID8gc2hvcnRZZWFyQ3V0b2ZmIDpcblx0XHRcdG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKSAlIDEwMCArIHBhcnNlSW50KHNob3J0WWVhckN1dG9mZiwgMTApKTtcblx0XHRyZXR1cm4ge3Nob3J0WWVhckN1dG9mZjogc2hvcnRZZWFyQ3V0b2ZmLFxuXHRcdFx0ZGF5TmFtZXNTaG9ydDogdGhpcy5fZ2V0KGluc3QsICdkYXlOYW1lc1Nob3J0JyksIGRheU5hbWVzOiB0aGlzLl9nZXQoaW5zdCwgJ2RheU5hbWVzJyksXG5cdFx0XHRtb250aE5hbWVzU2hvcnQ6IHRoaXMuX2dldChpbnN0LCAnbW9udGhOYW1lc1Nob3J0JyksIG1vbnRoTmFtZXM6IHRoaXMuX2dldChpbnN0LCAnbW9udGhOYW1lcycpfTtcblx0fSxcblxuXHQvKiBGb3JtYXQgdGhlIGdpdmVuIGRhdGUgZm9yIGRpc3BsYXkuICovXG5cdF9mb3JtYXREYXRlOiBmdW5jdGlvbihpbnN0LCBkYXksIG1vbnRoLCB5ZWFyKSB7XG5cdFx0aWYgKCFkYXkpIHtcblx0XHRcdGluc3QuY3VycmVudERheSA9IGluc3Quc2VsZWN0ZWREYXk7XG5cdFx0XHRpbnN0LmN1cnJlbnRNb250aCA9IGluc3Quc2VsZWN0ZWRNb250aDtcblx0XHRcdGluc3QuY3VycmVudFllYXIgPSBpbnN0LnNlbGVjdGVkWWVhcjtcblx0XHR9XG5cdFx0dmFyIGRhdGUgPSAoZGF5ID8gKHR5cGVvZiBkYXkgPT0gJ29iamVjdCcgPyBkYXkgOlxuXHRcdFx0dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoeWVhciwgbW9udGgsIGRheSkpKSA6XG5cdFx0XHR0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZShpbnN0LmN1cnJlbnRZZWFyLCBpbnN0LmN1cnJlbnRNb250aCwgaW5zdC5jdXJyZW50RGF5KSkpO1xuXHRcdHJldHVybiB0aGlzLmZvcm1hdERhdGUodGhpcy5fZ2V0KGluc3QsICdkYXRlRm9ybWF0JyksIGRhdGUsIHRoaXMuX2dldEZvcm1hdENvbmZpZyhpbnN0KSk7XG5cdH1cbn0pO1xuXG4vKlxuICogQmluZCBob3ZlciBldmVudHMgZm9yIGRhdGVwaWNrZXIgZWxlbWVudHMuXG4gKiBEb25lIHZpYSBkZWxlZ2F0ZSBzbyB0aGUgYmluZGluZyBvbmx5IG9jY3VycyBvbmNlIGluIHRoZSBsaWZldGltZSBvZiB0aGUgcGFyZW50IGRpdi5cbiAqIEdsb2JhbCBpbnN0QWN0aXZlLCBzZXQgYnkgX3VwZGF0ZURhdGVwaWNrZXIgYWxsb3dzIHRoZSBoYW5kbGVycyB0byBmaW5kIHRoZWlyIHdheSBiYWNrIHRvIHRoZSBhY3RpdmUgcGlja2VyLlxuICovXG5mdW5jdGlvbiBiaW5kSG92ZXIoZHBEaXYpIHtcblx0dmFyIHNlbGVjdG9yID0gJ2J1dHRvbiwgLnVpLWRhdGVwaWNrZXItcHJldiwgLnVpLWRhdGVwaWNrZXItbmV4dCwgLnVpLWRhdGVwaWNrZXItY2FsZW5kYXIgdGQgYSc7XG5cdHJldHVybiBkcERpdi5kZWxlZ2F0ZShzZWxlY3RvciwgJ21vdXNlb3V0JywgZnVuY3Rpb24oKSB7XG5cdFx0XHQkKHRoaXMpLnJlbW92ZUNsYXNzKCd1aS1zdGF0ZS1ob3ZlcicpO1xuXHRcdFx0aWYgKHRoaXMuY2xhc3NOYW1lLmluZGV4T2YoJ3VpLWRhdGVwaWNrZXItcHJldicpICE9IC0xKSAkKHRoaXMpLnJlbW92ZUNsYXNzKCd1aS1kYXRlcGlja2VyLXByZXYtaG92ZXInKTtcblx0XHRcdGlmICh0aGlzLmNsYXNzTmFtZS5pbmRleE9mKCd1aS1kYXRlcGlja2VyLW5leHQnKSAhPSAtMSkgJCh0aGlzKS5yZW1vdmVDbGFzcygndWktZGF0ZXBpY2tlci1uZXh0LWhvdmVyJyk7XG5cdFx0fSlcblx0XHQuZGVsZWdhdGUoc2VsZWN0b3IsICdtb3VzZW92ZXInLCBmdW5jdGlvbigpe1xuXHRcdFx0aWYgKCEkLmRhdGVwaWNrZXIuX2lzRGlzYWJsZWREYXRlcGlja2VyKCBpbnN0QWN0aXZlLmlubGluZSA/IGRwRGl2LnBhcmVudCgpWzBdIDogaW5zdEFjdGl2ZS5pbnB1dFswXSkpIHtcblx0XHRcdFx0JCh0aGlzKS5wYXJlbnRzKCcudWktZGF0ZXBpY2tlci1jYWxlbmRhcicpLmZpbmQoJ2EnKS5yZW1vdmVDbGFzcygndWktc3RhdGUtaG92ZXInKTtcblx0XHRcdFx0JCh0aGlzKS5hZGRDbGFzcygndWktc3RhdGUtaG92ZXInKTtcblx0XHRcdFx0aWYgKHRoaXMuY2xhc3NOYW1lLmluZGV4T2YoJ3VpLWRhdGVwaWNrZXItcHJldicpICE9IC0xKSAkKHRoaXMpLmFkZENsYXNzKCd1aS1kYXRlcGlja2VyLXByZXYtaG92ZXInKTtcblx0XHRcdFx0aWYgKHRoaXMuY2xhc3NOYW1lLmluZGV4T2YoJ3VpLWRhdGVwaWNrZXItbmV4dCcpICE9IC0xKSAkKHRoaXMpLmFkZENsYXNzKCd1aS1kYXRlcGlja2VyLW5leHQtaG92ZXInKTtcblx0XHRcdH1cblx0XHR9KTtcbn1cblxuLyogalF1ZXJ5IGV4dGVuZCBub3cgaWdub3JlcyBudWxscyEgKi9cbmZ1bmN0aW9uIGV4dGVuZFJlbW92ZSh0YXJnZXQsIHByb3BzKSB7XG5cdCQuZXh0ZW5kKHRhcmdldCwgcHJvcHMpO1xuXHRmb3IgKHZhciBuYW1lIGluIHByb3BzKVxuXHRcdGlmIChwcm9wc1tuYW1lXSA9PSBudWxsIHx8IHByb3BzW25hbWVdID09IHVuZGVmaW5lZClcblx0XHRcdHRhcmdldFtuYW1lXSA9IHByb3BzW25hbWVdO1xuXHRyZXR1cm4gdGFyZ2V0O1xufTtcblxuLyogSW52b2tlIHRoZSBkYXRlcGlja2VyIGZ1bmN0aW9uYWxpdHkuXG4gICBAcGFyYW0gIG9wdGlvbnMgIHN0cmluZyAtIGEgY29tbWFuZCwgb3B0aW9uYWxseSBmb2xsb3dlZCBieSBhZGRpdGlvbmFsIHBhcmFtZXRlcnMgb3Jcblx0ICAgICAgICAgICAgICAgIE9iamVjdCAtIHNldHRpbmdzIGZvciBhdHRhY2hpbmcgbmV3IGRhdGVwaWNrZXIgZnVuY3Rpb25hbGl0eVxuICAgQHJldHVybiAgalF1ZXJ5IG9iamVjdCAqL1xuJC5mbi5kYXRlcGlja2VyID0gZnVuY3Rpb24ob3B0aW9ucyl7XG5cblx0LyogVmVyaWZ5IGFuIGVtcHR5IGNvbGxlY3Rpb24gd2Fzbid0IHBhc3NlZCAtIEZpeGVzICM2OTc2ICovXG5cdGlmICggIXRoaXMubGVuZ3RoICkge1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyogSW5pdGlhbGlzZSB0aGUgZGF0ZSBwaWNrZXIuICovXG5cdGlmICghJC5kYXRlcGlja2VyLmluaXRpYWxpemVkKSB7XG5cdFx0JChkb2N1bWVudCkubW91c2Vkb3duKCQuZGF0ZXBpY2tlci5fY2hlY2tFeHRlcm5hbENsaWNrKS5cblx0XHRcdGZpbmQoZG9jdW1lbnQuYm9keSkuYXBwZW5kKCQuZGF0ZXBpY2tlci5kcERpdik7XG5cdFx0JC5kYXRlcGlja2VyLmluaXRpYWxpemVkID0gdHJ1ZTtcblx0fVxuXG5cdHZhciBvdGhlckFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXHRpZiAodHlwZW9mIG9wdGlvbnMgPT0gJ3N0cmluZycgJiYgKG9wdGlvbnMgPT0gJ2lzRGlzYWJsZWQnIHx8IG9wdGlvbnMgPT0gJ2dldERhdGUnIHx8IG9wdGlvbnMgPT0gJ3dpZGdldCcpKVxuXHRcdHJldHVybiAkLmRhdGVwaWNrZXJbJ18nICsgb3B0aW9ucyArICdEYXRlcGlja2VyJ10uXG5cdFx0XHRhcHBseSgkLmRhdGVwaWNrZXIsIFt0aGlzWzBdXS5jb25jYXQob3RoZXJBcmdzKSk7XG5cdGlmIChvcHRpb25zID09ICdvcHRpb24nICYmIGFyZ3VtZW50cy5sZW5ndGggPT0gMiAmJiB0eXBlb2YgYXJndW1lbnRzWzFdID09ICdzdHJpbmcnKVxuXHRcdHJldHVybiAkLmRhdGVwaWNrZXJbJ18nICsgb3B0aW9ucyArICdEYXRlcGlja2VyJ10uXG5cdFx0XHRhcHBseSgkLmRhdGVwaWNrZXIsIFt0aGlzWzBdXS5jb25jYXQob3RoZXJBcmdzKSk7XG5cdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0dHlwZW9mIG9wdGlvbnMgPT0gJ3N0cmluZycgP1xuXHRcdFx0JC5kYXRlcGlja2VyWydfJyArIG9wdGlvbnMgKyAnRGF0ZXBpY2tlciddLlxuXHRcdFx0XHRhcHBseSgkLmRhdGVwaWNrZXIsIFt0aGlzXS5jb25jYXQob3RoZXJBcmdzKSkgOlxuXHRcdFx0JC5kYXRlcGlja2VyLl9hdHRhY2hEYXRlcGlja2VyKHRoaXMsIG9wdGlvbnMpO1xuXHR9KTtcbn07XG5cbiQuZGF0ZXBpY2tlciA9IG5ldyBEYXRlcGlja2VyKCk7IC8vIHNpbmdsZXRvbiBpbnN0YW5jZVxuJC5kYXRlcGlja2VyLmluaXRpYWxpemVkID0gZmFsc2U7XG4kLmRhdGVwaWNrZXIudXVpZCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuJC5kYXRlcGlja2VyLnZlcnNpb24gPSBcIjEuOS4yXCI7XG5cbi8vIFdvcmthcm91bmQgZm9yICM0MDU1XG4vLyBBZGQgYW5vdGhlciBnbG9iYWwgdG8gYXZvaWQgbm9Db25mbGljdCBpc3N1ZXMgd2l0aCBpbmxpbmUgZXZlbnQgaGFuZGxlcnNcbndpbmRvd1snRFBfalF1ZXJ5XycgKyBkcHV1aWRdID0gJDtcblxufSkoalF1ZXJ5KTtcbiJdLCJmaWxlIjoianF1ZXJ5dWkvanF1ZXJ5LnVpLmRhdGVwaWNrZXIuanMifQ==
3974</script><script>
3975/*! Selectric ϟ v1.13.0 (2017-08-22) - git.io/tjl9sQ - Copyright (c) 2017 Leonardo Santos - MIT License */
3976$(document).on("ready", function () {
3977!function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof module&&module.exports?module.exports=function(t,s){return void 0===s&&(s="undefined"!=typeof window?require("jquery"):require("jquery")(t)),e(s),s}:e(jQuery)}(function(e){"use strict";var t=e(document),s=e(window),l=["a","e","i","o","u","n","c","y"],i=[/[\xE0-\xE5]/g,/[\xE8-\xEB]/g,/[\xEC-\xEF]/g,/[\xF2-\xF6]/g,/[\xF9-\xFC]/g,/[\xF1]/g,/[\xE7]/g,/[\xFD-\xFF]/g],n=function(t,s){var l=this;l.element=t,l.$element=e(t),l.state={multiple:!!l.$element.attr("multiple"),enabled:!1,opened:!1,currValue:-1,selectedIdx:-1,highlightedIdx:-1},l.eventTriggers={open:l.open,close:l.close,destroy:l.destroy,refresh:l.refresh,init:l.init},l.init(s)};n.prototype={utils:{isMobile:function(){return/android|ip(hone|od|ad)/i.test(navigator.userAgent)},escapeRegExp:function(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},replaceDiacritics:function(e){for(var t=i.length;t--;)e=e.toLowerCase().replace(i[t],l[t]);return e},format:function(e){var t=arguments;return(""+e).replace(/\{(?:(\d+)|(\w+))\}/g,function(e,s,l){return l&&t[1]?t[1][l]:t[s]})},nextEnabledItem:function(e,t){for(;e[t=(t+1)%e.length].disabled;);return t},previousEnabledItem:function(e,t){for(;e[t=(t>0?t:e.length)-1].disabled;);return t},toDash:function(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()},triggerCallback:function(t,s){var l=s.element,i=s.options["on"+t],n=[l].concat([].slice.call(arguments).slice(1));e.isFunction(i)&&i.apply(l,n),e(l).trigger("selectric-"+this.toDash(t),n)},arrayToClassname:function(t){var s=e.grep(t,function(e){return!!e});return e.trim(s.join(" "))}},init:function(t){var s=this;if(s.options=e.extend(!0,{},e.fn.selectric.defaults,s.options,t),s.utils.triggerCallback("BeforeInit",s),s.destroy(!0),s.options.disableOnMobile&&s.utils.isMobile())return void(s.disableOnMobile=!0);s.classes=s.getClassNames();var l=e("<input/>",{class:s.classes.input,readonly:s.utils.isMobile()}),i=e("<div/>",{class:s.classes.items,tabindex:-1}),n=e("<div/>",{class:s.classes.scroll}),a=e("<div/>",{class:s.classes.prefix,html:s.options.arrowButtonMarkup}),o=e("<span/>",{class:"label"}),r=s.$element.wrap("<div/>").parent().append(a.prepend(o),i,l),u=e("<div/>",{class:s.classes.hideselect});s.elements={input:l,items:i,itemsScroll:n,wrapper:a,label:o,outerWrapper:r},s.options.nativeOnMobile&&s.utils.isMobile()&&(s.elements.input=void 0,u.addClass(s.classes.prefix+"-is-native"),s.$element.on("change",function(){s.refresh()})),s.$element.on(s.eventTriggers).wrap(u),s.originalTabindex=s.$element.prop("tabindex"),s.$element.prop("tabindex",-1),s.populate(),s.activate(),s.utils.triggerCallback("Init",s)},activate:function(){var e=this,t=e.elements.items.closest(":visible").children(":hidden").addClass(e.classes.tempshow),s=e.$element.width();t.removeClass(e.classes.tempshow),e.utils.triggerCallback("BeforeActivate",e),e.elements.outerWrapper.prop("class",e.utils.arrayToClassname([e.classes.wrapper,e.$element.prop("class").replace(/\S+/g,e.classes.prefix+"-$&"),e.options.responsive?e.classes.responsive:""])),e.options.inheritOriginalWidth&&s>0&&e.elements.outerWrapper.width(s),e.unbindEvents(),e.$element.prop("disabled")?(e.elements.outerWrapper.addClass(e.classes.disabled),e.elements.input&&e.elements.input.prop("disabled",!0)):(e.state.enabled=!0,e.elements.outerWrapper.removeClass(e.classes.disabled),e.$li=e.elements.items.removeAttr("style").find("li"),e.bindEvents()),e.utils.triggerCallback("Activate",e)},getClassNames:function(){var t=this,s=t.options.customClass,l={};return e.each("Input Items Open Disabled TempShow HideSelect Wrapper Focus Hover Responsive Above Below Scroll Group GroupLabel".split(" "),function(e,i){var n=s.prefix+i;l[i.toLowerCase()]=s.camelCase?n:t.utils.toDash(n)}),l.prefix=s.prefix,l},setLabel:function(){var t=this,s=t.options.labelBuilder;if(t.state.multiple){var l=e.isArray(t.state.currValue)?t.state.currValue:[t.state.currValue];l=0===l.length?[0]:l;var i=e.map(l,function(s){return e.grep(t.lookupItems,function(e){return e.index===s})[0]});i=e.grep(i,function(t){return i.length>1||0===i.length?""!==e.trim(t.value):t}),i=e.map(i,function(l){return e.isFunction(s)?s(l):t.utils.format(s,l)}),t.options.multiple.maxLabelEntries&&(i.length>=t.options.multiple.maxLabelEntries+1?(i=i.slice(0,t.options.multiple.maxLabelEntries),i.push(e.isFunction(s)?s({text:"..."}):t.utils.format(s,{text:"..."}))):i.slice(i.length-1)),t.elements.label.html(i.join(t.options.multiple.separator))}else{var n=t.lookupItems[t.state.currValue];t.elements.label.html(e.isFunction(s)?s(n):t.utils.format(s,n))}},populate:function(){var t=this,s=t.$element.children(),l=t.$element.find("option"),i=l.filter(":selected"),n=l.index(i),a=0,o=t.state.multiple?[]:0;i.length>1&&t.state.multiple&&(n=[],i.each(function(){n.push(e(this).index())})),t.state.currValue=~n?n:o,t.state.selectedIdx=t.state.currValue,t.state.highlightedIdx=t.state.currValue,t.items=[],t.lookupItems=[],s.length&&(s.each(function(s){var l=e(this);if(l.is("optgroup")){var i={element:l,label:l.prop("label"),groupDisabled:l.prop("disabled"),items:[]};l.children().each(function(s){var l=e(this);i.items[s]=t.getItemData(a,l,i.groupDisabled||l.prop("disabled")),t.lookupItems[a]=i.items[s],a++}),t.items[s]=i}else t.items[s]=t.getItemData(a,l,l.prop("disabled")),t.lookupItems[a]=t.items[s],a++}),t.setLabel(),t.elements.items.append(t.elements.itemsScroll.html(t.getItemsMarkup(t.items))))},getItemData:function(t,s,l){var i=this;return{index:t,element:s,value:s.val(),className:s.prop("class"),text:s.html(),slug:e.trim(i.utils.replaceDiacritics(s.html())),alt:s.attr("data-alt"),selected:s.prop("selected"),disabled:l}},getItemsMarkup:function(t){var s=this,l="<ul>";return e.isFunction(s.options.listBuilder)&&s.options.listBuilder&&(t=s.options.listBuilder(t)),e.each(t,function(t,i){void 0!==i.label?(l+=s.utils.format('<ul class="{1}"><li class="{2}">{3}</li>',s.utils.arrayToClassname([s.classes.group,i.groupDisabled?"disabled":"",i.element.prop("class")]),s.classes.grouplabel,i.element.prop("label")),e.each(i.items,function(e,t){l+=s.getItemMarkup(t.index,t)}),l+="</ul>"):l+=s.getItemMarkup(i.index,i)}),l+"</ul>"},getItemMarkup:function(t,s){var l=this,i=l.options.optionsItemBuilder,n={value:s.value,text:s.text,slug:s.slug,index:s.index};return l.utils.format('<li data-index="{1}" class="{2}">{3}</li>',t,l.utils.arrayToClassname([s.className,t===l.items.length-1?"last":"",s.disabled?"disabled":"",s.selected?"selected":""]),e.isFunction(i)?l.utils.format(i(s,this.$element,t),s):l.utils.format(i,n))},unbindEvents:function(){var e=this;e.elements.wrapper.add(e.$element).add(e.elements.outerWrapper).add(e.elements.input).off(".sl")},bindEvents:function(){var t=this;t.elements.outerWrapper.on("mouseenter.sl mouseleave.sl",function(s){e(this).toggleClass(t.classes.hover,"mouseenter"===s.type),t.options.openOnHover&&(clearTimeout(t.closeTimer),"mouseleave"===s.type?t.closeTimer=setTimeout(e.proxy(t.close,t),t.options.hoverIntentTimeout):t.open())}),t.elements.wrapper.on("click.sl",function(e){t.state.opened?t.close():t.open(e)}),t.options.nativeOnMobile&&t.utils.isMobile()||(t.$element.on("focus.sl",function(){t.elements.input.focus()}),t.elements.input.prop({tabindex:t.originalTabindex,disabled:!1}).on("keydown.sl",e.proxy(t.handleKeys,t)).on("focusin.sl",function(e){t.elements.outerWrapper.addClass(t.classes.focus),t.elements.input.one("blur",function(){t.elements.input.blur()}),t.options.openOnFocus&&!t.state.opened&&t.open(e)}).on("focusout.sl",function(){t.elements.outerWrapper.removeClass(t.classes.focus)}).on("input propertychange",function(){var s=t.elements.input.val(),l=new RegExp("^"+t.utils.escapeRegExp(s),"i");clearTimeout(t.resetStr),t.resetStr=setTimeout(function(){t.elements.input.val("")},t.options.keySearchTimeout),s.length&&e.each(t.items,function(e,s){if(!s.disabled){if(l.test(s.text)||l.test(s.slug))return void t.highlight(e);if(s.alt)for(var i=s.alt.split("|"),n=0;n<i.length&&i[n];n++)if(l.test(i[n].trim()))return void t.highlight(e)}})})),t.$li.on({mousedown:function(e){e.preventDefault(),e.stopPropagation()},click:function(){return t.select(e(this).data("index")),!1}})},handleKeys:function(t){var s=this,l=t.which,i=s.options.keys,n=e.inArray(l,i.previous)>-1,a=e.inArray(l,i.next)>-1,o=e.inArray(l,i.select)>-1,r=e.inArray(l,i.open)>-1,u=s.state.highlightedIdx,p=n&&0===u||a&&u+1===s.items.length,c=0;if(13!==l&&32!==l||t.preventDefault(),n||a){if(!s.options.allowWrap&&p)return;n&&(c=s.utils.previousEnabledItem(s.lookupItems,u)),a&&(c=s.utils.nextEnabledItem(s.lookupItems,u)),s.highlight(c)}if(o&&s.state.opened)return s.select(u),void(s.state.multiple&&s.options.multiple.keepMenuOpen||s.close());r&&!s.state.opened&&s.open()},refresh:function(){var e=this;e.populate(),e.activate(),e.utils.triggerCallback("Refresh",e)},setOptionsDimensions:function(){var e=this,t=e.elements.items.closest(":visible").children(":hidden").addClass(e.classes.tempshow),s=e.options.maxHeight,l=e.elements.items.outerWidth(),i=e.elements.wrapper.outerWidth()-(l-e.elements.items.width());!e.options.expandToItemText||i>l?e.finalWidth=i:(e.elements.items.css("overflow","scroll"),e.elements.outerWrapper.width(9e4),e.finalWidth=e.elements.items.width(),e.elements.items.css("overflow",""),e.elements.outerWrapper.width("")),e.elements.items.width(e.finalWidth).height()>s&&e.elements.items.height(s),t.removeClass(e.classes.tempshow)},isInViewport:function(){var e=this;if(!0===e.options.forceRenderAbove)e.elements.outerWrapper.addClass(e.classes.above);else if(!0===e.options.forceRenderBelow)e.elements.outerWrapper.addClass(e.classes.below);else{var t=s.scrollTop(),l=s.height(),i=e.elements.outerWrapper.offset().top,n=e.elements.outerWrapper.outerHeight(),a=i+n+e.itemsHeight<=t+l,o=i-e.itemsHeight>t,r=!a&&o,u=!r;e.elements.outerWrapper.toggleClass(e.classes.above,r),e.elements.outerWrapper.toggleClass(e.classes.below,u)}},detectItemVisibility:function(t){var s=this,l=s.$li.filter("[data-index]");s.state.multiple&&(t=e.isArray(t)&&0===t.length?0:t,t=e.isArray(t)?Math.min.apply(Math,t):t);var i=l.eq(t).outerHeight(),n=l[t].offsetTop,a=s.elements.itemsScroll.scrollTop(),o=n+2*i;s.elements.itemsScroll.scrollTop(o>a+s.itemsHeight?o-s.itemsHeight:n-i<a?n-i:a)},open:function(s){var l=this;if(l.options.nativeOnMobile&&l.utils.isMobile())return!1;l.utils.triggerCallback("BeforeOpen",l),s&&(s.preventDefault(),l.options.stopPropagation&&s.stopPropagation()),l.state.enabled&&(l.setOptionsDimensions(),e("."+l.classes.hideselect,"."+l.classes.open).children().selectric("close"),l.state.opened=!0,l.itemsHeight=l.elements.items.outerHeight(),l.itemsInnerHeight=l.elements.items.height(),l.elements.outerWrapper.addClass(l.classes.open),l.elements.input.val(""),s&&"focusin"!==s.type&&l.elements.input.focus(),setTimeout(function(){t.on("click.sl",e.proxy(l.close,l)).on("scroll.sl",e.proxy(l.isInViewport,l))},1),l.isInViewport(),l.options.preventWindowScroll&&t.on("mousewheel.sl DOMMouseScroll.sl","."+l.classes.scroll,function(t){var s=t.originalEvent,i=e(this).scrollTop(),n=0;"detail"in s&&(n=-1*s.detail),"wheelDelta"in s&&(n=s.wheelDelta),"wheelDeltaY"in s&&(n=s.wheelDeltaY),"deltaY"in s&&(n=-1*s.deltaY),(i===this.scrollHeight-l.itemsInnerHeight&&n<0||0===i&&n>0)&&t.preventDefault()}),l.detectItemVisibility(l.state.selectedIdx),l.highlight(l.state.multiple?-1:l.state.selectedIdx),l.utils.triggerCallback("Open",l))},close:function(){var e=this;e.utils.triggerCallback("BeforeClose",e),t.off(".sl"),e.elements.outerWrapper.removeClass(e.classes.open),e.state.opened=!1,e.utils.triggerCallback("Close",e)},change:function(){var t=this;t.utils.triggerCallback("BeforeChange",t),t.state.multiple?(e.each(t.lookupItems,function(e){t.lookupItems[e].selected=!1,t.$element.find("option").prop("selected",!1)}),e.each(t.state.selectedIdx,function(e,s){t.lookupItems[s].selected=!0,t.$element.find("option").eq(s).prop("selected",!0)}),t.state.currValue=t.state.selectedIdx,t.setLabel(),t.utils.triggerCallback("Change",t)):t.state.currValue!==t.state.selectedIdx&&(t.$element.prop("selectedIndex",t.state.currValue=t.state.selectedIdx).data("value",t.lookupItems[t.state.selectedIdx].text),t.setLabel(),t.utils.triggerCallback("Change",t))},highlight:function(e){var t=this,s=t.$li.filter("[data-index]").removeClass("highlighted");t.utils.triggerCallback("BeforeHighlight",t),void 0===e||-1===e||t.lookupItems[e].disabled||(s.eq(t.state.highlightedIdx=e).addClass("highlighted"),t.detectItemVisibility(e),t.utils.triggerCallback("Highlight",t))},select:function(t){var s=this,l=s.$li.filter("[data-index]");if(s.utils.triggerCallback("BeforeSelect",s,t),void 0!==t&&-1!==t&&!s.lookupItems[t].disabled){if(s.state.multiple){s.state.selectedIdx=e.isArray(s.state.selectedIdx)?s.state.selectedIdx:[s.state.selectedIdx];var i=e.inArray(t,s.state.selectedIdx);-1!==i?s.state.selectedIdx.splice(i,1):s.state.selectedIdx.push(t),l.removeClass("selected").filter(function(t){return-1!==e.inArray(t,s.state.selectedIdx)}).addClass("selected")}else l.removeClass("selected").eq(s.state.selectedIdx=t).addClass("selected");s.state.multiple&&s.options.multiple.keepMenuOpen||s.close(),s.change(),s.utils.triggerCallback("Select",s,t)}},destroy:function(e){var t=this;t.state&&t.state.enabled&&(t.elements.items.add(t.elements.wrapper).add(t.elements.input).remove(),e||t.$element.removeData("selectric").removeData("value"),t.$element.prop("tabindex",t.originalTabindex).off(".sl").off(t.eventTriggers).unwrap().unwrap(),t.state.enabled=!1)}},e.fn.selectric=function(t){return this.each(function(){var s=e.data(this,"selectric");s&&!s.disableOnMobile?"string"==typeof t&&s[t]?s[t]():s.init(t):e.data(this,"selectric",new n(this,t))})},e.fn.selectric.defaults={onChange:function(t){e(t).change()},maxHeight:300,keySearchTimeout:500,arrowButtonMarkup:'<b class="button">▾</b>',disableOnMobile:!1,nativeOnMobile:!0,openOnFocus:!0,openOnHover:!1,hoverIntentTimeout:500,expandToItemText:!1,responsive:!1,preventWindowScroll:!0,inheritOriginalWidth:!1,allowWrap:!0,forceRenderAbove:!1,forceRenderBelow:!1,stopPropagation:!0,optionsItemBuilder:"{text}",labelBuilder:"{text}",listBuilder:!1,keys:{previous:[37,38],next:[39,40],select:[9,13,27],open:[13,32,37,38,39,40],close:[9,27]},customClass:{prefix:"selectric",camelCase:!1},multiple:{separator:", ",keepMenuOpen:!0,maxLabelEntries:!1}}});
3978});
3979</script><script>
3980 $('.b-search__input').attr('autocomplete','off');
3981 $(document).ready(function(){
3982
3983 //setModal();
3984 //setTabs();
3985
3986 });
3987
3988
3989
3990 function setModalMaxHeight(element) {
3991
3992 this.$element = $(element);
3993 this.$content = this.$element.find('.b-modal__wrapper');
3994 var contentHeight = $(window).height();
3995 var headerHeight = this.$element.find('.b-modal__header').outerHeight(true) || 0;
3996 var footerHeight = this.$element.find('.b-modal__footer').outerHeight(true) || 0;
3997 var magicMargin = $(window).width() < 768 ? 0 : 70;
3998 var maxHeight = contentHeight - (headerHeight + footerHeight + magicMargin);
3999
4000 this.$content.css({
4001 'overflow': 'hidden'
4002 });
4003
4004 this.$element
4005 .find('.b-modal__content').css({
4006 'max-height': maxHeight,
4007 'overflow-y': 'auto'
4008 });
4009 }
4010
4011 $('.b-modal').on('show.bs.modal', function() {
4012 $(this).show();
4013 setModalMaxHeight(this);
4014 });
4015
4016 $(window).resize(function() {
4017 if ($('.b-modal').length != 0) {
4018 $('.b-modal').each(function (index, item) {
4019 setModalMaxHeight(item);
4020 });
4021 }
4022 });
4023
4024 $(document)
4025 .on("hover", ".js-hover-active", function() {
4026 $(this).toggleClass("active");
4027 $( ".b-shadow").toggleClass("active");
4028 });
4029
4030 $(".js-togg-active").mouseover(function(){
4031 //.on("mouseup", ".js-togg-active", function() {
4032 $(this).addClass("active");
4033 });
4034 $(".js-togg-active").mouseout(function(){
4035 $(this).removeClass("active");
4036 });
4037
4038
4039 $(document).on("click", ".js-open-button", function() {
4040
4041 $(this).siblings( ".js-close-button" ).addClass("active");
4042 $(this).siblings( ".js-close-button" ).removeClass("hide");
4043
4044 $(this).siblings(".js-hide").addClass("active");
4045
4046 var _row = $(this).closest(".b-comments__table-row");
4047 $(_row).next(".js-hide").addClass("active");
4048 //$('.js-close-button, .js-hide').addClass("active");
4049 $(this).addClass("hide");
4050 //$('.js-close-button').removeClass("hide");
4051 });
4052
4053 $(document).on("click", ".js-close-button", function() {
4054 $(this).removeClass("active");
4055 $(this).siblings( ".js-open-button" ).removeClass("hide");
4056
4057 $(this).siblings(".js-hide").removeClass("active");
4058
4059 var _row = $(this).closest(".b-comments__table-row");
4060 $(_row).next(".js-hide").removeClass("active");
4061
4062 //$('.js-close-button, .js-hide').removeClass("active");
4063 //$('.js-open-button').removeClass("hide");
4064 $(this).addClass("hide");
4065 });
4066
4067 $(document).on("click", ".js-open", function() {
4068 if ($(this).hasClass("container-open"))
4069 {
4070 $('#container_comments').toggle();
4071 }
4072 else
4073 {
4074 $('.b-competere').toggle();
4075 }
4076 $(this).toggleClass('active');
4077 $('.js-toggle-active').toggleClass('active');
4078 });
4079
4080 $(document).on("click", ".js-togg-active", function() {
4081 $(this).toggleClass("active");
4082 });
4083
4084 $(document).on("click", ".b-personal-info__open-button.prew", function() {
4085 $('.b-icon__open.little').toggleClass("active");
4086 $('.b-personal-info__table-row.prew').toggleClass("hide");
4087 });
4088
4089
4090 //menu
4091 /*$(function(){
4092 $('.b-header__toggle-menu').click(function(){
4093 $('.b-header__toggle-menu').toggleClass('is-close');
4094 });
4095 });
4096
4097 $(function(){
4098 $(".b-header__toggle-menu").click(function(){
4099 $('.b-header__menu').toggleClass('active');
4100 $('.col-lg-9.col-md-9.hidden-xs').toggleClass('show-xs');
4101 });
4102 });
4103
4104
4105 //tabs
4106 /*function setTabs(){
4107 $(".js-tab-content").hide();
4108 $(".js-tab-item.active").each(function(){
4109 var activeTabPre = $(this).attr('rel');
4110 $("#"+activeTabPre).show();
4111 })
4112
4113 $(".js-tab-item").click(function() {
4114 $(this).closest(".js-tab").next(".js-tab-group").children(".js-tab-content").hide();
4115 var activeTab = $(this).attr("rel");
4116 $("#"+activeTab).show();
4117
4118 $(this).closest(".js-tab").find(".js-tab-item").removeClass("active");
4119 $(this).addClass("active");
4120 });
4121 }
4122
4123 $(".b-textarea, .b-input").on("focusout", function () {
4124 $(this).css("color", "black");
4125 });
4126
4127
4128 // Модалки
4129 $(".js-open-modal").click(function(){
4130 $(".b-modal, .b-shadow").show();
4131 $("body").addClass("off-scroll");
4132 });
4133
4134 $(".js-close-modal, .b-shadow").click(function(){
4135 $(".b-modal, .b-shadow").hide();
4136 $("body").removeClass("off-scroll");
4137 });
4138
4139
4140
4141
4142 /* Sticky-kit v1.1.2 */
4143 (function() {
4144 var $, win;
4145
4146 $ = this.jQuery || window.jQuery;
4147
4148 win = $(window);
4149
4150 $.fn.stick_in_parent = function(opts) {
4151 var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, parent_selector, recalc_every, sticky_class;
4152 if (opts == null) {
4153 opts = {};
4154 }
4155 sticky_class = opts.sticky_class, inner_scrolling = opts.inner_scrolling, recalc_every = opts.recalc_every, parent_selector = opts.parent, offset_top = opts.offset_top, manual_spacer = opts.spacer, enable_bottoming = opts.bottoming;
4156 if (offset_top == null) {
4157 offset_top = 0;
4158 }
4159 if (parent_selector == null) {
4160 parent_selector = void 0;
4161 }
4162 if (inner_scrolling == null) {
4163 inner_scrolling = true;
4164 }
4165 if (sticky_class == null) {
4166 sticky_class = "is_stuck";
4167 }
4168 doc = $(document);
4169 if (enable_bottoming == null) {
4170 enable_bottoming = true;
4171 }
4172 fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) {
4173 var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick;
4174 if (elm.data("sticky_kit")) {
4175 return;
4176 }
4177 elm.data("sticky_kit", true);
4178 last_scroll_height = doc.height();
4179 parent = elm.parent();
4180 if (parent_selector != null) {
4181 parent = parent.closest(parent_selector);
4182 }
4183 if (!parent.length) {
4184 throw "failed to find stick parent";
4185 }
4186 fixed = false;
4187 bottomed = false;
4188 spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />");
4189 if (spacer) {
4190 spacer.css('position', elm.css('position'));
4191 }
4192 recalc = function() {
4193 var border_top, padding_top, restore;
4194 if (detached) {
4195 return;
4196 }
4197 last_scroll_height = doc.height();
4198 border_top = parseInt(parent.css("border-top-width"), 10);
4199 padding_top = parseInt(parent.css("padding-top"), 10);
4200 padding_bottom = parseInt(parent.css("padding-bottom"), 10);
4201 parent_top = parent.offset().top + border_top + padding_top;
4202 parent_height = parent.height();
4203 if (fixed) {
4204 fixed = false;
4205 bottomed = false;
4206 if (manual_spacer == null) {
4207 elm.insertAfter(spacer);
4208 spacer.detach();
4209 }
4210 elm.css({
4211 position: "",
4212 top: "",
4213 width: "",
4214 bottom: ""
4215 }).removeClass(sticky_class);
4216 restore = true;
4217 }
4218 top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top;
4219 height = elm.outerHeight(true);
4220 el_float = elm.css("float");
4221 if (spacer) {
4222 spacer.css({
4223 width: elm.outerWidth(true),
4224 height: height,
4225 display: elm.css("display"),
4226 "vertical-align": elm.css("vertical-align"),
4227 "float": el_float
4228 });
4229 }
4230 if (restore) {
4231 return tick();
4232 }
4233 };
4234 recalc();
4235 if (height === parent_height) {
4236 return;
4237 }
4238 last_pos = void 0;
4239 offset = offset_top;
4240 recalc_counter = recalc_every;
4241 tick = function() {
4242 var css, delta, recalced, scroll, will_bottom, win_height;
4243 if (detached) {
4244 return;
4245 }
4246 recalced = false;
4247 if (recalc_counter != null) {
4248 recalc_counter -= 1;
4249 if (recalc_counter <= 0) {
4250 recalc_counter = recalc_every;
4251 recalc();
4252 recalced = true;
4253 }
4254 }
4255 if (!recalced && doc.height() !== last_scroll_height) {
4256 recalc();
4257 recalced = true;
4258 }
4259 scroll = win.scrollTop();
4260 if (last_pos != null) {
4261 delta = scroll - last_pos;
4262 }
4263 last_pos = scroll;
4264 if (fixed) {
4265 if (enable_bottoming) {
4266 will_bottom = scroll + height + offset > parent_height + parent_top;
4267 if (bottomed && !will_bottom) {
4268 bottomed = false;
4269 elm.css({
4270 position: "fixed",
4271 bottom: "",
4272 top: offset
4273 }).trigger("sticky_kit:unbottom");
4274 }
4275 }
4276 if (scroll < top) {
4277 fixed = false;
4278 offset = offset_top;
4279 if (manual_spacer == null) {
4280 if (el_float === "left" || el_float === "right") {
4281 elm.insertAfter(spacer);
4282 }
4283 spacer.detach();
4284 }
4285 css = {
4286 position: "",
4287 width: "",
4288 top: ""
4289 };
4290 elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick");
4291 }
4292 if (inner_scrolling) {
4293 win_height = win.height();
4294 if (height + offset_top > win_height) {
4295 if (!bottomed) {
4296 offset -= delta;
4297 offset = Math.max(win_height - height, offset);
4298 offset = Math.min(offset_top, offset);
4299 if (fixed) {
4300 elm.css({
4301 top: offset + "px"
4302 });
4303 }
4304 }
4305 }
4306 }
4307 } else {
4308 if (scroll > top) {
4309 fixed = true;
4310 css = {
4311 position: "fixed",
4312 top: offset
4313 };
4314 css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px";
4315 elm.css(css).addClass(sticky_class);
4316 if (manual_spacer == null) {
4317 elm.after(spacer);
4318 if (el_float === "left" || el_float === "right") {
4319 spacer.append(elm);
4320 }
4321 }
4322 elm.trigger("sticky_kit:stick");
4323 }
4324 }
4325 if (fixed && enable_bottoming) {
4326 if (will_bottom == null) {
4327 will_bottom = scroll + height + offset > parent_height + parent_top;
4328 }
4329 if (!bottomed && will_bottom) {
4330 bottomed = true;
4331 if (parent.css("position") === "static") {
4332 parent.css({
4333 position: "relative"
4334 });
4335 }
4336 return elm.css({
4337 position: "absolute",
4338 bottom: padding_bottom,
4339 top: "auto"
4340 }).trigger("sticky_kit:bottom");
4341 }
4342 }
4343 };
4344 recalc_and_tick = function() {
4345 recalc();
4346 return tick();
4347 };
4348 detach = function() {
4349 detached = true;
4350 win.off("touchmove", tick);
4351 win.off("scroll", tick);
4352 win.off("resize", recalc_and_tick);
4353 $(document.body).off("sticky_kit:recalc", recalc_and_tick);
4354 elm.off("sticky_kit:detach", detach);
4355 elm.removeData("sticky_kit");
4356 elm.css({
4357 position: "",
4358 bottom: "",
4359 top: "",
4360 width: ""
4361 });
4362 parent.position("position", "");
4363 if (fixed) {
4364 if (manual_spacer == null) {
4365 if (el_float === "left" || el_float === "right") {
4366 elm.insertAfter(spacer);
4367 }
4368 spacer.remove();
4369 }
4370 return elm.removeClass(sticky_class);
4371 }
4372 };
4373 win.on("touchmove", tick);
4374 win.on("scroll", tick);
4375 win.on("resize", recalc_and_tick);
4376 $(document.body).on("sticky_kit:recalc", recalc_and_tick);
4377 elm.on("sticky_kit:detach", detach);
4378 return setTimeout(tick, 0);
4379 };
4380 for (i = 0, len = this.length; i < len; i++) {
4381 elm = this[i];
4382 fn($(elm));
4383 }
4384 return this;
4385 };
4386
4387 }).call(this);
4388
4389
4390
4391
4392 /*! Selectric ϟ v1.13.0 (2017-08-22) - git.io/tjl9sQ - Copyright (c) 2017 Leonardo Santos - MIT License */
4393 !function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof module&&module.exports?module.exports=function(t,s){return void 0===s&&(s="undefined"!=typeof window?require("jquery"):require("jquery")(t)),e(s),s}:e(jQuery)}(function(e){"use strict";var t=e(document),s=e(window),l=["a","e","i","o","u","n","c","y"],i=[/[\xE0-\xE5]/g,/[\xE8-\xEB]/g,/[\xEC-\xEF]/g,/[\xF2-\xF6]/g,/[\xF9-\xFC]/g,/[\xF1]/g,/[\xE7]/g,/[\xFD-\xFF]/g],n=function(t,s){var l=this;l.element=t,l.$element=e(t),l.state={multiple:!!l.$element.attr("multiple"),enabled:!1,opened:!1,currValue:-1,selectedIdx:-1,highlightedIdx:-1},l.eventTriggers={open:l.open,close:l.close,destroy:l.destroy,refresh:l.refresh,init:l.init},l.init(s)};n.prototype={utils:{isMobile:function(){return/android|ip(hone|od|ad)/i.test(navigator.userAgent)},escapeRegExp:function(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},replaceDiacritics:function(e){for(var t=i.length;t--;)e=e.toLowerCase().replace(i[t],l[t]);return e},format:function(e){var t=arguments;return(""+e).replace(/\{(?:(\d+)|(\w+))\}/g,function(e,s,l){return l&&t[1]?t[1][l]:t[s]})},nextEnabledItem:function(e,t){for(;e[t=(t+1)%e.length].disabled;);return t},previousEnabledItem:function(e,t){for(;e[t=(t>0?t:e.length)-1].disabled;);return t},toDash:function(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()},triggerCallback:function(t,s){var l=s.element,i=s.options["on"+t],n=[l].concat([].slice.call(arguments).slice(1));e.isFunction(i)&&i.apply(l,n),e(l).trigger("selectric-"+this.toDash(t),n)},arrayToClassname:function(t){var s=e.grep(t,function(e){return!!e});return e.trim(s.join(" "))}},init:function(t){var s=this;if(s.options=e.extend(!0,{},e.fn.selectric.defaults,s.options,t),s.utils.triggerCallback("BeforeInit",s),s.destroy(!0),s.options.disableOnMobile&&s.utils.isMobile())return void(s.disableOnMobile=!0);s.classes=s.getClassNames();var l=e("<input/>",{class:s.classes.input,readonly:s.utils.isMobile()}),i=e("<div/>",{class:s.classes.items,tabindex:-1}),n=e("<div/>",{class:s.classes.scroll}),a=e("<div/>",{class:s.classes.prefix,html:s.options.arrowButtonMarkup}),o=e("<span/>",{class:"label"}),r=s.$element.wrap("<div/>").parent().append(a.prepend(o),i,l),u=e("<div/>",{class:s.classes.hideselect});s.elements={input:l,items:i,itemsScroll:n,wrapper:a,label:o,outerWrapper:r},s.options.nativeOnMobile&&s.utils.isMobile()&&(s.elements.input=void 0,u.addClass(s.classes.prefix+"-is-native"),s.$element.on("change",function(){s.refresh()})),s.$element.on(s.eventTriggers).wrap(u),s.originalTabindex=s.$element.prop("tabindex"),s.$element.prop("tabindex",-1),s.populate(),s.activate(),s.utils.triggerCallback("Init",s)},activate:function(){var e=this,t=e.elements.items.closest(":visible").children(":hidden").addClass(e.classes.tempshow),s=e.$element.width();t.removeClass(e.classes.tempshow),e.utils.triggerCallback("BeforeActivate",e),e.elements.outerWrapper.prop("class",e.utils.arrayToClassname([e.classes.wrapper,e.$element.prop("class").replace(/\S+/g,e.classes.prefix+"-$&"),e.options.responsive?e.classes.responsive:""])),e.options.inheritOriginalWidth&&s>0&&e.elements.outerWrapper.width(s),e.unbindEvents(),e.$element.prop("disabled")?(e.elements.outerWrapper.addClass(e.classes.disabled),e.elements.input&&e.elements.input.prop("disabled",!0)):(e.state.enabled=!0,e.elements.outerWrapper.removeClass(e.classes.disabled),e.$li=e.elements.items.removeAttr("style").find("li"),e.bindEvents()),e.utils.triggerCallback("Activate",e)},getClassNames:function(){var t=this,s=t.options.customClass,l={};return e.each("Input Items Open Disabled TempShow HideSelect Wrapper Focus Hover Responsive Above Below Scroll Group GroupLabel".split(" "),function(e,i){var n=s.prefix+i;l[i.toLowerCase()]=s.camelCase?n:t.utils.toDash(n)}),l.prefix=s.prefix,l},setLabel:function(){var t=this,s=t.options.labelBuilder;if(t.state.multiple){var l=e.isArray(t.state.currValue)?t.state.currValue:[t.state.currValue];l=0===l.length?[0]:l;var i=e.map(l,function(s){return e.grep(t.lookupItems,function(e){return e.index===s})[0]});i=e.grep(i,function(t){return i.length>1||0===i.length?""!==e.trim(t.value):t}),i=e.map(i,function(l){return e.isFunction(s)?s(l):t.utils.format(s,l)}),t.options.multiple.maxLabelEntries&&(i.length>=t.options.multiple.maxLabelEntries+1?(i=i.slice(0,t.options.multiple.maxLabelEntries),i.push(e.isFunction(s)?s({text:"..."}):t.utils.format(s,{text:"..."}))):i.slice(i.length-1)),t.elements.label.html(i.join(t.options.multiple.separator))}else{var n=t.lookupItems[t.state.currValue];t.elements.label.html(e.isFunction(s)?s(n):t.utils.format(s,n))}},populate:function(){var t=this,s=t.$element.children(),l=t.$element.find("option"),i=l.filter(":selected"),n=l.index(i),a=0,o=t.state.multiple?[]:0;i.length>1&&t.state.multiple&&(n=[],i.each(function(){n.push(e(this).index())})),t.state.currValue=~n?n:o,t.state.selectedIdx=t.state.currValue,t.state.highlightedIdx=t.state.currValue,t.items=[],t.lookupItems=[],s.length&&(s.each(function(s){var l=e(this);if(l.is("optgroup")){var i={element:l,label:l.prop("label"),groupDisabled:l.prop("disabled"),items:[]};l.children().each(function(s){var l=e(this);i.items[s]=t.getItemData(a,l,i.groupDisabled||l.prop("disabled")),t.lookupItems[a]=i.items[s],a++}),t.items[s]=i}else t.items[s]=t.getItemData(a,l,l.prop("disabled")),t.lookupItems[a]=t.items[s],a++}),t.setLabel(),t.elements.items.append(t.elements.itemsScroll.html(t.getItemsMarkup(t.items))))},getItemData:function(t,s,l){var i=this;return{index:t,element:s,value:s.val(),className:s.prop("class"),text:s.html(),slug:e.trim(i.utils.replaceDiacritics(s.html())),alt:s.attr("data-alt"),selected:s.prop("selected"),disabled:l}},getItemsMarkup:function(t){var s=this,l="<ul>";return e.isFunction(s.options.listBuilder)&&s.options.listBuilder&&(t=s.options.listBuilder(t)),e.each(t,function(t,i){void 0!==i.label?(l+=s.utils.format('<ul class="{1}"><li class="{2}">{3}</li>',s.utils.arrayToClassname([s.classes.group,i.groupDisabled?"disabled":"",i.element.prop("class")]),s.classes.grouplabel,i.element.prop("label")),e.each(i.items,function(e,t){l+=s.getItemMarkup(t.index,t)}),l+="</ul>"):l+=s.getItemMarkup(i.index,i)}),l+"</ul>"},getItemMarkup:function(t,s){var l=this,i=l.options.optionsItemBuilder,n={value:s.value,text:s.text,slug:s.slug,index:s.index};return l.utils.format('<li data-index="{1}" class="{2}">{3}</li>',t,l.utils.arrayToClassname([s.className,t===l.items.length-1?"last":"",s.disabled?"disabled":"",s.selected?"selected":""]),e.isFunction(i)?l.utils.format(i(s,this.$element,t),s):l.utils.format(i,n))},unbindEvents:function(){var e=this;e.elements.wrapper.add(e.$element).add(e.elements.outerWrapper).add(e.elements.input).off(".sl")},bindEvents:function(){var t=this;t.elements.outerWrapper.on("mouseenter.sl mouseleave.sl",function(s){e(this).toggleClass(t.classes.hover,"mouseenter"===s.type),t.options.openOnHover&&(clearTimeout(t.closeTimer),"mouseleave"===s.type?t.closeTimer=setTimeout(e.proxy(t.close,t),t.options.hoverIntentTimeout):t.open())}),t.elements.wrapper.on("click.sl",function(e){t.state.opened?t.close():t.open(e)}),t.options.nativeOnMobile&&t.utils.isMobile()||(t.$element.on("focus.sl",function(){t.elements.input.focus()}),t.elements.input.prop({tabindex:t.originalTabindex,disabled:!1}).on("keydown.sl",e.proxy(t.handleKeys,t)).on("focusin.sl",function(e){t.elements.outerWrapper.addClass(t.classes.focus),t.elements.input.one("blur",function(){t.elements.input.blur()}),t.options.openOnFocus&&!t.state.opened&&t.open(e)}).on("focusout.sl",function(){t.elements.outerWrapper.removeClass(t.classes.focus)}).on("input propertychange",function(){var s=t.elements.input.val(),l=new RegExp("^"+t.utils.escapeRegExp(s),"i");clearTimeout(t.resetStr),t.resetStr=setTimeout(function(){t.elements.input.val("")},t.options.keySearchTimeout),s.length&&e.each(t.items,function(e,s){if(!s.disabled){if(l.test(s.text)||l.test(s.slug))return void t.highlight(e);if(s.alt)for(var i=s.alt.split("|"),n=0;n<i.length&&i[n];n++)if(l.test(i[n].trim()))return void t.highlight(e)}})})),t.$li.on({mousedown:function(e){e.preventDefault(),e.stopPropagation()},click:function(){return t.select(e(this).data("index")),!1}})},handleKeys:function(t){var s=this,l=t.which,i=s.options.keys,n=e.inArray(l,i.previous)>-1,a=e.inArray(l,i.next)>-1,o=e.inArray(l,i.select)>-1,r=e.inArray(l,i.open)>-1,u=s.state.highlightedIdx,p=n&&0===u||a&&u+1===s.items.length,c=0;if(13!==l&&32!==l||t.preventDefault(),n||a){if(!s.options.allowWrap&&p)return;n&&(c=s.utils.previousEnabledItem(s.lookupItems,u)),a&&(c=s.utils.nextEnabledItem(s.lookupItems,u)),s.highlight(c)}if(o&&s.state.opened)return s.select(u),void(s.state.multiple&&s.options.multiple.keepMenuOpen||s.close());r&&!s.state.opened&&s.open()},refresh:function(){var e=this;e.populate(),e.activate(),e.utils.triggerCallback("Refresh",e)},setOptionsDimensions:function(){var e=this,t=e.elements.items.closest(":visible").children(":hidden").addClass(e.classes.tempshow),s=e.options.maxHeight,l=e.elements.items.outerWidth(),i=e.elements.wrapper.outerWidth()-(l-e.elements.items.width());!e.options.expandToItemText||i>l?e.finalWidth=i:(e.elements.items.css("overflow","scroll"),e.elements.outerWrapper.width(9e4),e.finalWidth=e.elements.items.width(),e.elements.items.css("overflow",""),e.elements.outerWrapper.width("")),e.elements.items.width(e.finalWidth).height()>s&&e.elements.items.height(s),t.removeClass(e.classes.tempshow)},isInViewport:function(){var e=this;if(!0===e.options.forceRenderAbove)e.elements.outerWrapper.addClass(e.classes.above);else if(!0===e.options.forceRenderBelow)e.elements.outerWrapper.addClass(e.classes.below);else{var t=s.scrollTop(),l=s.height(),i=e.elements.outerWrapper.offset().top,n=e.elements.outerWrapper.outerHeight(),a=i+n+e.itemsHeight<=t+l,o=i-e.itemsHeight>t,r=!a&&o,u=!r;e.elements.outerWrapper.toggleClass(e.classes.above,r),e.elements.outerWrapper.toggleClass(e.classes.below,u)}},detectItemVisibility:function(t){var s=this,l=s.$li.filter("[data-index]");s.state.multiple&&(t=e.isArray(t)&&0===t.length?0:t,t=e.isArray(t)?Math.min.apply(Math,t):t);var i=l.eq(t).outerHeight(),n=l[t].offsetTop,a=s.elements.itemsScroll.scrollTop(),o=n+2*i;s.elements.itemsScroll.scrollTop(o>a+s.itemsHeight?o-s.itemsHeight:n-i<a?n-i:a)},open:function(s){var l=this;if(l.options.nativeOnMobile&&l.utils.isMobile())return!1;l.utils.triggerCallback("BeforeOpen",l),s&&(s.preventDefault(),l.options.stopPropagation&&s.stopPropagation()),l.state.enabled&&(l.setOptionsDimensions(),e("."+l.classes.hideselect,"."+l.classes.open).children().selectric("close"),l.state.opened=!0,l.itemsHeight=l.elements.items.outerHeight(),l.itemsInnerHeight=l.elements.items.height(),l.elements.outerWrapper.addClass(l.classes.open),l.elements.input.val(""),s&&"focusin"!==s.type&&l.elements.input.focus(),setTimeout(function(){t.on("click.sl",e.proxy(l.close,l)).on("scroll.sl",e.proxy(l.isInViewport,l))},1),l.isInViewport(),l.options.preventWindowScroll&&t.on("mousewheel.sl DOMMouseScroll.sl","."+l.classes.scroll,function(t){var s=t.originalEvent,i=e(this).scrollTop(),n=0;"detail"in s&&(n=-1*s.detail),"wheelDelta"in s&&(n=s.wheelDelta),"wheelDeltaY"in s&&(n=s.wheelDeltaY),"deltaY"in s&&(n=-1*s.deltaY),(i===this.scrollHeight-l.itemsInnerHeight&&n<0||0===i&&n>0)&&t.preventDefault()}),l.detectItemVisibility(l.state.selectedIdx),l.highlight(l.state.multiple?-1:l.state.selectedIdx),l.utils.triggerCallback("Open",l))},close:function(){var e=this;e.utils.triggerCallback("BeforeClose",e),t.off(".sl"),e.elements.outerWrapper.removeClass(e.classes.open),e.state.opened=!1,e.utils.triggerCallback("Close",e)},change:function(){var t=this;t.utils.triggerCallback("BeforeChange",t),t.state.multiple?(e.each(t.lookupItems,function(e){t.lookupItems[e].selected=!1,t.$element.find("option").prop("selected",!1)}),e.each(t.state.selectedIdx,function(e,s){t.lookupItems[s].selected=!0,t.$element.find("option").eq(s).prop("selected",!0)}),t.state.currValue=t.state.selectedIdx,t.setLabel(),t.utils.triggerCallback("Change",t)):t.state.currValue!==t.state.selectedIdx&&(t.$element.prop("selectedIndex",t.state.currValue=t.state.selectedIdx).data("value",t.lookupItems[t.state.selectedIdx].text),t.setLabel(),t.utils.triggerCallback("Change",t))},highlight:function(e){var t=this,s=t.$li.filter("[data-index]").removeClass("highlighted");t.utils.triggerCallback("BeforeHighlight",t),void 0===e||-1===e||t.lookupItems[e].disabled||(s.eq(t.state.highlightedIdx=e).addClass("highlighted"),t.detectItemVisibility(e),t.utils.triggerCallback("Highlight",t))},select:function(t){var s=this,l=s.$li.filter("[data-index]");if(s.utils.triggerCallback("BeforeSelect",s,t),void 0!==t&&-1!==t&&!s.lookupItems[t].disabled){if(s.state.multiple){s.state.selectedIdx=e.isArray(s.state.selectedIdx)?s.state.selectedIdx:[s.state.selectedIdx];var i=e.inArray(t,s.state.selectedIdx);-1!==i?s.state.selectedIdx.splice(i,1):s.state.selectedIdx.push(t),l.removeClass("selected").filter(function(t){return-1!==e.inArray(t,s.state.selectedIdx)}).addClass("selected")}else l.removeClass("selected").eq(s.state.selectedIdx=t).addClass("selected");s.state.multiple&&s.options.multiple.keepMenuOpen||s.close(),s.change(),s.utils.triggerCallback("Select",s,t)}},destroy:function(e){var t=this;t.state&&t.state.enabled&&(t.elements.items.add(t.elements.wrapper).add(t.elements.input).remove(),e||t.$element.removeData("selectric").removeData("value"),t.$element.prop("tabindex",t.originalTabindex).off(".sl").off(t.eventTriggers).unwrap().unwrap(),t.state.enabled=!1)}},e.fn.selectric=function(t){return this.each(function(){var s=e.data(this,"selectric");s&&!s.disableOnMobile?"string"==typeof t&&s[t]?s[t]():s.init(t):e.data(this,"selectric",new n(this,t))})},e.fn.selectric.defaults={onChange:function(t){e(t).change()},maxHeight:300,keySearchTimeout:500,arrowButtonMarkup:'<b class="button">▾</b>',disableOnMobile:!1,nativeOnMobile:!0,openOnFocus:!0,openOnHover:!1,hoverIntentTimeout:500,expandToItemText:!1,responsive:!1,preventWindowScroll:!0,inheritOriginalWidth:!1,allowWrap:!0,forceRenderAbove:!1,forceRenderBelow:!1,stopPropagation:!0,optionsItemBuilder:"{text}",labelBuilder:"{text}",listBuilder:!1,keys:{previous:[37,38],next:[39,40],select:[9,13,27],open:[13,32,37,38,39,40],close:[9,27]},customClass:{prefix:"selectric",camelCase:!1},multiple:{separator:", ",keepMenuOpen:!0,maxLabelEntries:!1}}});
4394
4395
4396
4397 /*
4398 * jQuery autoResize (textarea auto-resizer)
4399 * @copyright James Padolsey http://james.padolsey.com
4400 * @version 1.04
4401 */
4402
4403 (function($){
4404
4405 $.fn.autoResize = function(options) {
4406
4407 // Just some abstracted details,
4408 // to make plugin users happy:
4409 var settings = $.extend({
4410 onResize : function(){
4411
4412 },
4413 animate : true,
4414 animateDuration : 150,
4415 animateCallback : function(){},
4416 extraSpace : 20,
4417 limit: 1000
4418 }, options);
4419
4420 // Only textarea's auto-resize:
4421 this.filter('textarea').each(function(){
4422
4423 // Get rid of scrollbars and disable WebKit resizing:
4424 var textarea = $(this).css({resize:'none','overflow-y':'hidden'}),
4425
4426 // Cache original height, for use later:
4427 origHeight = textarea.height(),
4428
4429
4430 // Need clone of textarea, hidden off screen:
4431 clone = (function(){
4432
4433 // Properties which may effect space taken up by chracters:
4434 var props = ['height','width','lineHeight','textDecoration','letterSpacing'],
4435 propOb = {};
4436
4437 // Create object of styles to apply:
4438 $.each(props, function(i, prop){
4439 propOb[prop] = textarea.css(prop);
4440 });
4441
4442 // Clone the actual textarea removing unique properties
4443 // and insert before original textarea:
4444 return textarea.clone().removeAttr('id').removeAttr('name').css({
4445 position: 'absolute',
4446 top: 0,
4447 left: -9999
4448 }).css(propOb).attr('tabIndex','-1').insertBefore(textarea);
4449
4450 })(),
4451 lastScrollTop = null,
4452 updateSize = function() {
4453 // Prepare the clone:
4454 clone.height(0).val($(this).val()).scrollTop(10000);
4455
4456 // Find the height of text:
4457 var scrollTop = Math.max(clone.scrollTop(), origHeight) + settings.extraSpace,
4458 toChange = $(this).add(clone);
4459
4460 // Don't do anything if scrollTip hasen't changed:
4461 if (lastScrollTop === scrollTop) { return; }
4462 lastScrollTop = scrollTop;
4463
4464 // Check for limit:
4465 if ( scrollTop >= settings.limit ) {
4466 $(this).css('overflow-y','');
4467 return;
4468 }
4469 // Fire off callback:
4470 settings.onResize.call(this);
4471
4472 // Either animate or directly apply height:
4473 settings.animate && textarea.css('display') === 'block' ?
4474 toChange.stop().animate({height:scrollTop}, settings.animateDuration, settings.animateCallback)
4475 : toChange.height(scrollTop);
4476
4477
4478 };
4479
4480 // Bind namespaced handlers to appropriate events:
4481 textarea
4482 .unbind('.dynSiz')
4483 .bind('keyup.dynSiz', updateSize)
4484 .bind('keydown.dynSiz', updateSize)
4485 .bind('change.dynSiz', updateSize);
4486
4487 });
4488
4489 // Chain:
4490 return this;
4491
4492 };
4493
4494
4495
4496 })(jQuery);/*
4497 * jQuery autoResize (textarea auto-resizer)
4498 * @copyright James Padolsey http://james.padolsey.com
4499 * @version 1.04
4500 */
4501
4502 (function($){
4503
4504 $.fn.autoResize = function(options) {
4505
4506 // Just some abstracted details,
4507 // to make plugin users happy:
4508 var settings = $.extend({
4509 onResize : function(){
4510
4511 },
4512 animate : true,
4513 animateDuration : 150,
4514 animateCallback : function(){},
4515 extraSpace : 20,
4516 limit: 1000
4517 }, options);
4518
4519 // Only textarea's auto-resize:
4520 this.filter('textarea').each(function(){
4521
4522 // Get rid of scrollbars and disable WebKit resizing:
4523 var textarea = $(this).css({resize:'none','overflow-y':'hidden'}),
4524
4525 // Cache original height, for use later:
4526 origHeight = textarea.height(),
4527
4528
4529 // Need clone of textarea, hidden off screen:
4530 clone = (function(){
4531
4532 // Properties which may effect space taken up by chracters:
4533 var props = ['height','width','lineHeight','textDecoration','letterSpacing'],
4534 propOb = {};
4535
4536 // Create object of styles to apply:
4537 $.each(props, function(i, prop){
4538 propOb[prop] = textarea.css(prop);
4539 });
4540
4541 // Clone the actual textarea removing unique properties
4542 // and insert before original textarea:
4543 return textarea.clone().removeAttr('id').removeAttr('name').css({
4544 position: 'absolute',
4545 top: 0,
4546 left: -9999
4547 }).css(propOb).attr('tabIndex','-1').insertBefore(textarea);
4548
4549 })(),
4550 lastScrollTop = null,
4551 updateSize = function() {
4552 // Prepare the clone:
4553 clone.height(0).val($(this).val()).scrollTop(10000);
4554
4555 // Find the height of text:
4556 var scrollTop = Math.max(clone.scrollTop(), origHeight) + settings.extraSpace,
4557 toChange = $(this).add(clone);
4558
4559 // Don't do anything if scrollTip hasen't changed:
4560 if (lastScrollTop === scrollTop) { return; }
4561 lastScrollTop = scrollTop;
4562
4563 // Check for limit:
4564 if ( scrollTop >= settings.limit ) {
4565 $(this).css('overflow-y','');
4566 return;
4567 }
4568 // Fire off callback:
4569 settings.onResize.call(this);
4570
4571 // Either animate or directly apply height:
4572 settings.animate && textarea.css('display') === 'block' ?
4573 toChange.stop().animate({height:scrollTop}, settings.animateDuration, settings.animateCallback)
4574 : toChange.height(scrollTop);
4575
4576
4577 };
4578
4579 // Bind namespaced handlers to appropriate events:
4580 textarea
4581 .unbind('.dynSiz')
4582 .bind('keyup.dynSiz', updateSize)
4583 .bind('keydown.dynSiz', updateSize)
4584 .bind('change.dynSiz', updateSize);
4585
4586 });
4587
4588 // Chain:
4589 return this;
4590
4591 };
4592
4593
4594
4595 })(jQuery);
4596
4597
4598
4599 /*!
4600 * jQuery UI Touch Punch 0.2.3
4601 *
4602 * Copyright 2011–2014, Dave Furfero
4603 * Dual licensed under the MIT or GPL Version 2 licenses.
4604 *
4605 * Depends:
4606 * jquery.ui.widget.js
4607 * jquery.ui.mouse.js
4608 */
4609 !function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);
4610
4611 </script><script>
4612/*!
4613 * Masonry PACKAGED v3.3.2
4614 * Cascading grid layout library
4615 * http://masonry.desandro.com
4616 * MIT License
4617 * by David DeSandro
4618 */
4619
4620!function(a){function b(){}function c(a){function c(b){b.prototype.option||(b.prototype.option=function(b){a.isPlainObject(b)&&(this.options=a.extend(!0,this.options,b))})}function e(b,c){a.fn[b]=function(e){if("string"==typeof e){for(var g=d.call(arguments,1),h=0,i=this.length;i>h;h++){var j=this[h],k=a.data(j,b);if(k)if(a.isFunction(k[e])&&"_"!==e.charAt(0)){var l=k[e].apply(k,g);if(void 0!==l)return l}else f("no such method '"+e+"' for "+b+" instance");else f("cannot call methods on "+b+" prior to initialization; attempted to call '"+e+"'")}return this}return this.each(function(){var d=a.data(this,b);d?(d.option(e),d._init()):(d=new c(this,e),a.data(this,b,d))})}}if(a){var f="undefined"==typeof console?b:function(a){console.error(a)};return a.bridget=function(a,b){c(b),e(a,b)},a.bridget}}var d=Array.prototype.slice;"function"==typeof define&&define.amd?define("jquery-bridget/jquery.bridget",["jquery"],c):c("object"==typeof exports?require("jquery"):a.jQuery)}(window),function(a){function b(b){var c=a.event;return c.target=c.target||c.srcElement||b,c}var c=document.documentElement,d=function(){};c.addEventListener?d=function(a,b,c){a.addEventListener(b,c,!1)}:c.attachEvent&&(d=function(a,c,d){a[c+d]=d.handleEvent?function(){var c=b(a);d.handleEvent.call(d,c)}:function(){var c=b(a);d.call(a,c)},a.attachEvent("on"+c,a[c+d])});var e=function(){};c.removeEventListener?e=function(a,b,c){a.removeEventListener(b,c,!1)}:c.detachEvent&&(e=function(a,b,c){a.detachEvent("on"+b,a[b+c]);try{delete a[b+c]}catch(d){a[b+c]=void 0}});var f={bind:d,unbind:e};"function"==typeof define&&define.amd?define("eventie/eventie",f):"object"==typeof exports?module.exports=f:a.eventie=f}(window),function(){function a(){}function b(a,b){for(var c=a.length;c--;)if(a[c].listener===b)return c;return-1}function c(a){return function(){return this[a].apply(this,arguments)}}var d=a.prototype,e=this,f=e.EventEmitter;d.getListeners=function(a){var b,c,d=this._getEvents();if(a instanceof RegExp){b={};for(c in d)d.hasOwnProperty(c)&&a.test(c)&&(b[c]=d[c])}else b=d[a]||(d[a]=[]);return b},d.flattenListeners=function(a){var b,c=[];for(b=0;b<a.length;b+=1)c.push(a[b].listener);return c},d.getListenersAsObject=function(a){var b,c=this.getListeners(a);return c instanceof Array&&(b={},b[a]=c),b||c},d.addListener=function(a,c){var d,e=this.getListenersAsObject(a),f="object"==typeof c;for(d in e)e.hasOwnProperty(d)&&-1===b(e[d],c)&&e[d].push(f?c:{listener:c,once:!1});return this},d.on=c("addListener"),d.addOnceListener=function(a,b){return this.addListener(a,{listener:b,once:!0})},d.once=c("addOnceListener"),d.defineEvent=function(a){return this.getListeners(a),this},d.defineEvents=function(a){for(var b=0;b<a.length;b+=1)this.defineEvent(a[b]);return this},d.removeListener=function(a,c){var d,e,f=this.getListenersAsObject(a);for(e in f)f.hasOwnProperty(e)&&(d=b(f[e],c),-1!==d&&f[e].splice(d,1));return this},d.off=c("removeListener"),d.addListeners=function(a,b){return this.manipulateListeners(!1,a,b)},d.removeListeners=function(a,b){return this.manipulateListeners(!0,a,b)},d.manipulateListeners=function(a,b,c){var d,e,f=a?this.removeListener:this.addListener,g=a?this.removeListeners:this.addListeners;if("object"!=typeof b||b instanceof RegExp)for(d=c.length;d--;)f.call(this,b,c[d]);else for(d in b)b.hasOwnProperty(d)&&(e=b[d])&&("function"==typeof e?f.call(this,d,e):g.call(this,d,e));return this},d.removeEvent=function(a){var b,c=typeof a,d=this._getEvents();if("string"===c)delete d[a];else if(a instanceof RegExp)for(b in d)d.hasOwnProperty(b)&&a.test(b)&&delete d[b];else delete this._events;return this},d.removeAllListeners=c("removeEvent"),d.emitEvent=function(a,b){var c,d,e,f,g=this.getListenersAsObject(a);for(e in g)if(g.hasOwnProperty(e))for(d=g[e].length;d--;)c=g[e][d],c.once===!0&&this.removeListener(a,c.listener),f=c.listener.apply(this,b||[]),f===this._getOnceReturnValue()&&this.removeListener(a,c.listener);return this},d.trigger=c("emitEvent"),d.emit=function(a){var b=Array.prototype.slice.call(arguments,1);return this.emitEvent(a,b)},d.setOnceReturnValue=function(a){return this._onceReturnValue=a,this},d._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},d._getEvents=function(){return this._events||(this._events={})},a.noConflict=function(){return e.EventEmitter=f,a},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return a}):"object"==typeof module&&module.exports?module.exports=a:e.EventEmitter=a}.call(this),function(a){function b(a){if(a){if("string"==typeof d[a])return a;a=a.charAt(0).toUpperCase()+a.slice(1);for(var b,e=0,f=c.length;f>e;e++)if(b=c[e]+a,"string"==typeof d[b])return b}}var c="Webkit Moz ms Ms O".split(" "),d=document.documentElement.style;"function"==typeof define&&define.amd?define("get-style-property/get-style-property",[],function(){return b}):"object"==typeof exports?module.exports=b:a.getStyleProperty=b}(window),function(a){function b(a){var b=parseFloat(a),c=-1===a.indexOf("%")&&!isNaN(b);return c&&b}function c(){}function d(){for(var a={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},b=0,c=g.length;c>b;b++){var d=g[b];a[d]=0}return a}function e(c){function e(){if(!m){m=!0;var d=a.getComputedStyle;if(j=function(){var a=d?function(a){return d(a,null)}:function(a){return a.currentStyle};return function(b){var c=a(b);return c||f("Style returned "+c+". Are you running this code in a hidden iframe on Firefox? See http://bit.ly/getsizebug1"),c}}(),k=c("boxSizing")){var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style[k]="border-box";var g=document.body||document.documentElement;g.appendChild(e);var h=j(e);l=200===b(h.width),g.removeChild(e)}}}function h(a){if(e(),"string"==typeof a&&(a=document.querySelector(a)),a&&"object"==typeof a&&a.nodeType){var c=j(a);if("none"===c.display)return d();var f={};f.width=a.offsetWidth,f.height=a.offsetHeight;for(var h=f.isBorderBox=!(!k||!c[k]||"border-box"!==c[k]),m=0,n=g.length;n>m;m++){var o=g[m],p=c[o];p=i(a,p);var q=parseFloat(p);f[o]=isNaN(q)?0:q}var r=f.paddingLeft+f.paddingRight,s=f.paddingTop+f.paddingBottom,t=f.marginLeft+f.marginRight,u=f.marginTop+f.marginBottom,v=f.borderLeftWidth+f.borderRightWidth,w=f.borderTopWidth+f.borderBottomWidth,x=h&&l,y=b(c.width);y!==!1&&(f.width=y+(x?0:r+v));var z=b(c.height);return z!==!1&&(f.height=z+(x?0:s+w)),f.innerWidth=f.width-(r+v),f.innerHeight=f.height-(s+w),f.outerWidth=f.width+t,f.outerHeight=f.height+u,f}}function i(b,c){if(a.getComputedStyle||-1===c.indexOf("%"))return c;var d=b.style,e=d.left,f=b.runtimeStyle,g=f&&f.left;return g&&(f.left=b.currentStyle.left),d.left=c,c=d.pixelLeft,d.left=e,g&&(f.left=g),c}var j,k,l,m=!1;return h}var f="undefined"==typeof console?c:function(a){console.error(a)},g=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"];"function"==typeof define&&define.amd?define("get-size/get-size",["get-style-property/get-style-property"],e):"object"==typeof exports?module.exports=e(require("desandro-get-style-property")):a.getSize=e(a.getStyleProperty)}(window),function(a){function b(a){"function"==typeof a&&(b.isReady?a():g.push(a))}function c(a){var c="readystatechange"===a.type&&"complete"!==f.readyState;b.isReady||c||d()}function d(){b.isReady=!0;for(var a=0,c=g.length;c>a;a++){var d=g[a];d()}}function e(e){return"complete"===f.readyState?d():(e.bind(f,"DOMContentLoaded",c),e.bind(f,"readystatechange",c),e.bind(a,"load",c)),b}var f=a.document,g=[];b.isReady=!1,"function"==typeof define&&define.amd?define("doc-ready/doc-ready",["eventie/eventie"],e):"object"==typeof exports?module.exports=e(require("eventie")):a.docReady=e(a.eventie)}(window),function(a){function b(a,b){return a[g](b)}function c(a){if(!a.parentNode){var b=document.createDocumentFragment();b.appendChild(a)}}function d(a,b){c(a);for(var d=a.parentNode.querySelectorAll(b),e=0,f=d.length;f>e;e++)if(d[e]===a)return!0;return!1}function e(a,d){return c(a),b(a,d)}var f,g=function(){if(a.matches)return"matches";if(a.matchesSelector)return"matchesSelector";for(var b=["webkit","moz","ms","o"],c=0,d=b.length;d>c;c++){var e=b[c],f=e+"MatchesSelector";if(a[f])return f}}();if(g){var h=document.createElement("div"),i=b(h,"div");f=i?b:e}else f=d;"function"==typeof define&&define.amd?define("matches-selector/matches-selector",[],function(){return f}):"object"==typeof exports?module.exports=f:window.matchesSelector=f}(Element.prototype),function(a,b){"function"==typeof define&&define.amd?define("fizzy-ui-utils/utils",["doc-ready/doc-ready","matches-selector/matches-selector"],function(c,d){return b(a,c,d)}):"object"==typeof exports?module.exports=b(a,require("doc-ready"),require("desandro-matches-selector")):a.fizzyUIUtils=b(a,a.docReady,a.matchesSelector)}(window,function(a,b,c){var d={};d.extend=function(a,b){for(var c in b)a[c]=b[c];return a},d.modulo=function(a,b){return(a%b+b)%b};var e=Object.prototype.toString;d.isArray=function(a){return"[object Array]"==e.call(a)},d.makeArray=function(a){var b=[];if(d.isArray(a))b=a;else if(a&&"number"==typeof a.length)for(var c=0,e=a.length;e>c;c++)b.push(a[c]);else b.push(a);return b},d.indexOf=Array.prototype.indexOf?function(a,b){return a.indexOf(b)}:function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},d.removeFrom=function(a,b){var c=d.indexOf(a,b);-1!=c&&a.splice(c,1)},d.isElement="function"==typeof HTMLElement||"object"==typeof HTMLElement?function(a){return a instanceof HTMLElement}:function(a){return a&&"object"==typeof a&&1==a.nodeType&&"string"==typeof a.nodeName},d.setText=function(){function a(a,c){b=b||(void 0!==document.documentElement.textContent?"textContent":"innerText"),a[b]=c}var b;return a}(),d.getParent=function(a,b){for(;a!=document.body;)if(a=a.parentNode,c(a,b))return a},d.getQueryElement=function(a){return"string"==typeof a?document.querySelector(a):a},d.handleEvent=function(a){var b="on"+a.type;this[b]&&this[b](a)},d.filterFindElements=function(a,b){a=d.makeArray(a);for(var e=[],f=0,g=a.length;g>f;f++){var h=a[f];if(d.isElement(h))if(b){c(h,b)&&e.push(h);for(var i=h.querySelectorAll(b),j=0,k=i.length;k>j;j++)e.push(i[j])}else e.push(h)}return e},d.debounceMethod=function(a,b,c){var d=a.prototype[b],e=b+"Timeout";a.prototype[b]=function(){var a=this[e];a&&clearTimeout(a);var b=arguments,f=this;this[e]=setTimeout(function(){d.apply(f,b),delete f[e]},c||100)}},d.toDashed=function(a){return a.replace(/(.)([A-Z])/g,function(a,b,c){return b+"-"+c}).toLowerCase()};var f=a.console;return d.htmlInit=function(c,e){b(function(){for(var b=d.toDashed(e),g=document.querySelectorAll(".js-"+b),h="data-"+b+"-options",i=0,j=g.length;j>i;i++){var k,l=g[i],m=l.getAttribute(h);try{k=m&&JSON.parse(m)}catch(n){f&&f.error("Error parsing "+h+" on "+l.nodeName.toLowerCase()+(l.id?"#"+l.id:"")+": "+n);continue}var o=new c(l,k),p=a.jQuery;p&&p.data(l,e,o)}})},d}),function(a,b){"function"==typeof define&&define.amd?define("outlayer/item",["eventEmitter/EventEmitter","get-size/get-size","get-style-property/get-style-property","fizzy-ui-utils/utils"],function(c,d,e,f){return b(a,c,d,e,f)}):"object"==typeof exports?module.exports=b(a,require("wolfy87-eventemitter"),require("get-size"),require("desandro-get-style-property"),require("fizzy-ui-utils")):(a.Outlayer={},a.Outlayer.Item=b(a,a.EventEmitter,a.getSize,a.getStyleProperty,a.fizzyUIUtils))}(window,function(a,b,c,d,e){function f(a){for(var b in a)return!1;return b=null,!0}function g(a,b){a&&(this.element=a,this.layout=b,this.position={x:0,y:0},this._create())}function h(a){return a.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()})}var i=a.getComputedStyle,j=i?function(a){return i(a,null)}:function(a){return a.currentStyle},k=d("transition"),l=d("transform"),m=k&&l,n=!!d("perspective"),o={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend",transition:"transitionend"}[k],p=["transform","transition","transitionDuration","transitionProperty"],q=function(){for(var a={},b=0,c=p.length;c>b;b++){var e=p[b],f=d(e);f&&f!==e&&(a[e]=f)}return a}();e.extend(g.prototype,b.prototype),g.prototype._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},g.prototype.handleEvent=function(a){var b="on"+a.type;this[b]&&this[b](a)},g.prototype.getSize=function(){this.size=c(this.element)},g.prototype.css=function(a){var b=this.element.style;for(var c in a){var d=q[c]||c;b[d]=a[c]}},g.prototype.getPosition=function(){var a=j(this.element),b=this.layout.options,c=b.isOriginLeft,d=b.isOriginTop,e=a[c?"left":"right"],f=a[d?"top":"bottom"],g=this.layout.size,h=-1!=e.indexOf("%")?parseFloat(e)/100*g.width:parseInt(e,10),i=-1!=f.indexOf("%")?parseFloat(f)/100*g.height:parseInt(f,10);h=isNaN(h)?0:h,i=isNaN(i)?0:i,h-=c?g.paddingLeft:g.paddingRight,i-=d?g.paddingTop:g.paddingBottom,this.position.x=h,this.position.y=i},g.prototype.layoutPosition=function(){var a=this.layout.size,b=this.layout.options,c={},d=b.isOriginLeft?"paddingLeft":"paddingRight",e=b.isOriginLeft?"left":"right",f=b.isOriginLeft?"right":"left",g=this.position.x+a[d];c[e]=this.getXValue(g),c[f]="";var h=b.isOriginTop?"paddingTop":"paddingBottom",i=b.isOriginTop?"top":"bottom",j=b.isOriginTop?"bottom":"top",k=this.position.y+a[h];c[i]=this.getYValue(k),c[j]="",this.css(c),this.emitEvent("layout",[this])},g.prototype.getXValue=function(a){var b=this.layout.options;return b.percentPosition&&!b.isHorizontal?a/this.layout.size.width*100+"%":a+"px"},g.prototype.getYValue=function(a){var b=this.layout.options;return b.percentPosition&&b.isHorizontal?a/this.layout.size.height*100+"%":a+"px"},g.prototype._transitionTo=function(a,b){this.getPosition();var c=this.position.x,d=this.position.y,e=parseInt(a,10),f=parseInt(b,10),g=e===this.position.x&&f===this.position.y;if(this.setPosition(a,b),g&&!this.isTransitioning)return void this.layoutPosition();var h=a-c,i=b-d,j={};j.transform=this.getTranslate(h,i),this.transition({to:j,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},g.prototype.getTranslate=function(a,b){var c=this.layout.options;return a=c.isOriginLeft?a:-a,b=c.isOriginTop?b:-b,n?"translate3d("+a+"px, "+b+"px, 0)":"translate("+a+"px, "+b+"px)"},g.prototype.goTo=function(a,b){this.setPosition(a,b),this.layoutPosition()},g.prototype.moveTo=m?g.prototype._transitionTo:g.prototype.goTo,g.prototype.setPosition=function(a,b){this.position.x=parseInt(a,10),this.position.y=parseInt(b,10)},g.prototype._nonTransition=function(a){this.css(a.to),a.isCleaning&&this._removeStyles(a.to);for(var b in a.onTransitionEnd)a.onTransitionEnd[b].call(this)},g.prototype._transition=function(a){if(!parseFloat(this.layout.options.transitionDuration))return void this._nonTransition(a);var b=this._transn;for(var c in a.onTransitionEnd)b.onEnd[c]=a.onTransitionEnd[c];for(c in a.to)b.ingProperties[c]=!0,a.isCleaning&&(b.clean[c]=!0);if(a.from){this.css(a.from);var d=this.element.offsetHeight;d=null}this.enableTransition(a.to),this.css(a.to),this.isTransitioning=!0};var r="opacity,"+h(q.transform||"transform");g.prototype.enableTransition=function(){this.isTransitioning||(this.css({transitionProperty:r,transitionDuration:this.layout.options.transitionDuration}),this.element.addEventListener(o,this,!1))},g.prototype.transition=g.prototype[k?"_transition":"_nonTransition"],g.prototype.onwebkitTransitionEnd=function(a){this.ontransitionend(a)},g.prototype.onotransitionend=function(a){this.ontransitionend(a)};var s={"-webkit-transform":"transform","-moz-transform":"transform","-o-transform":"transform"};g.prototype.ontransitionend=function(a){if(a.target===this.element){var b=this._transn,c=s[a.propertyName]||a.propertyName;if(delete b.ingProperties[c],f(b.ingProperties)&&this.disableTransition(),c in b.clean&&(this.element.style[a.propertyName]="",delete b.clean[c]),c in b.onEnd){var d=b.onEnd[c];d.call(this),delete b.onEnd[c]}this.emitEvent("transitionEnd",[this])}},g.prototype.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(o,this,!1),this.isTransitioning=!1},g.prototype._removeStyles=function(a){var b={};for(var c in a)b[c]="";this.css(b)};var t={transitionProperty:"",transitionDuration:""};return g.prototype.removeTransitionStyles=function(){this.css(t)},g.prototype.removeElem=function(){this.element.parentNode.removeChild(this.element),this.css({display:""}),this.emitEvent("remove",[this])},g.prototype.remove=function(){if(!k||!parseFloat(this.layout.options.transitionDuration))return void this.removeElem();var a=this;this.once("transitionEnd",function(){a.removeElem()}),this.hide()},g.prototype.reveal=function(){delete this.isHidden,this.css({display:""});var a=this.layout.options,b={},c=this.getHideRevealTransitionEndProperty("visibleStyle");b[c]=this.onRevealTransitionEnd,this.transition({from:a.hiddenStyle,to:a.visibleStyle,isCleaning:!0,onTransitionEnd:b})},g.prototype.onRevealTransitionEnd=function(){this.isHidden||this.emitEvent("reveal")},g.prototype.getHideRevealTransitionEndProperty=function(a){var b=this.layout.options[a];if(b.opacity)return"opacity";for(var c in b)return c},g.prototype.hide=function(){this.isHidden=!0,this.css({display:""});var a=this.layout.options,b={},c=this.getHideRevealTransitionEndProperty("hiddenStyle");b[c]=this.onHideTransitionEnd,this.transition({from:a.visibleStyle,to:a.hiddenStyle,isCleaning:!0,onTransitionEnd:b})},g.prototype.onHideTransitionEnd=function(){this.isHidden&&(this.css({display:"none"}),this.emitEvent("hide"))},g.prototype.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},g}),function(a,b){"function"==typeof define&&define.amd?define("outlayer/outlayer",["eventie/eventie","eventEmitter/EventEmitter","get-size/get-size","fizzy-ui-utils/utils","./item"],function(c,d,e,f,g){return b(a,c,d,e,f,g)}):"object"==typeof exports?module.exports=b(a,require("eventie"),require("wolfy87-eventemitter"),require("get-size"),require("fizzy-ui-utils"),require("./item")):a.Outlayer=b(a,a.eventie,a.EventEmitter,a.getSize,a.fizzyUIUtils,a.Outlayer.Item)}(window,function(a,b,c,d,e,f){function g(a,b){var c=e.getQueryElement(a);if(!c)return void(h&&h.error("Bad element for "+this.constructor.namespace+": "+(c||a)));this.element=c,i&&(this.$element=i(this.element)),this.options=e.extend({},this.constructor.defaults),this.option(b);var d=++k;this.element.outlayerGUID=d,l[d]=this,this._create(),this.options.isInitLayout&&this.layout()}var h=a.console,i=a.jQuery,j=function(){},k=0,l={};return g.namespace="outlayer",g.Item=f,g.defaults={containerStyle:{position:"relative"},isInitLayout:!0,isOriginLeft:!0,isOriginTop:!0,isResizeBound:!0,isResizingContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}},e.extend(g.prototype,c.prototype),g.prototype.option=function(a){e.extend(this.options,a)},g.prototype._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),e.extend(this.element.style,this.options.containerStyle),this.options.isResizeBound&&this.bindResize()},g.prototype.reloadItems=function(){this.items=this._itemize(this.element.children)},g.prototype._itemize=function(a){for(var b=this._filterFindItemElements(a),c=this.constructor.Item,d=[],e=0,f=b.length;f>e;e++){var g=b[e],h=new c(g,this);d.push(h)}return d},g.prototype._filterFindItemElements=function(a){return e.filterFindElements(a,this.options.itemSelector)},g.prototype.getItemElements=function(){for(var a=[],b=0,c=this.items.length;c>b;b++)a.push(this.items[b].element);return a},g.prototype.layout=function(){this._resetLayout(),this._manageStamps();var a=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;this.layoutItems(this.items,a),this._isLayoutInited=!0},g.prototype._init=g.prototype.layout,g.prototype._resetLayout=function(){this.getSize()},g.prototype.getSize=function(){this.size=d(this.element)},g.prototype._getMeasurement=function(a,b){var c,f=this.options[a];f?("string"==typeof f?c=this.element.querySelector(f):e.isElement(f)&&(c=f),this[a]=c?d(c)[b]:f):this[a]=0},g.prototype.layoutItems=function(a,b){a=this._getItemsForLayout(a),this._layoutItems(a,b),this._postLayout()},g.prototype._getItemsForLayout=function(a){for(var b=[],c=0,d=a.length;d>c;c++){var e=a[c];e.isIgnored||b.push(e)}return b},g.prototype._layoutItems=function(a,b){if(this._emitCompleteOnItems("layout",a),a&&a.length){for(var c=[],d=0,e=a.length;e>d;d++){var f=a[d],g=this._getItemLayoutPosition(f);g.item=f,g.isInstant=b||f.isLayoutInstant,c.push(g)}this._processLayoutQueue(c)}},g.prototype._getItemLayoutPosition=function(){return{x:0,y:0}},g.prototype._processLayoutQueue=function(a){for(var b=0,c=a.length;c>b;b++){var d=a[b];this._positionItem(d.item,d.x,d.y,d.isInstant)}},g.prototype._positionItem=function(a,b,c,d){d?a.goTo(b,c):a.moveTo(b,c)},g.prototype._postLayout=function(){this.resizeContainer()},g.prototype.resizeContainer=function(){if(this.options.isResizingContainer){var a=this._getContainerSize();a&&(this._setContainerMeasure(a.width,!0),this._setContainerMeasure(a.height,!1))}},g.prototype._getContainerSize=j,g.prototype._setContainerMeasure=function(a,b){if(void 0!==a){var c=this.size;c.isBorderBox&&(a+=b?c.paddingLeft+c.paddingRight+c.borderLeftWidth+c.borderRightWidth:c.paddingBottom+c.paddingTop+c.borderTopWidth+c.borderBottomWidth),a=Math.max(a,0),this.element.style[b?"width":"height"]=a+"px"}},g.prototype._emitCompleteOnItems=function(a,b){function c(){e.dispatchEvent(a+"Complete",null,[b])}function d(){g++,g===f&&c()}var e=this,f=b.length;if(!b||!f)return void c();for(var g=0,h=0,i=b.length;i>h;h++){var j=b[h];j.once(a,d)}},g.prototype.dispatchEvent=function(a,b,c){var d=b?[b].concat(c):c;if(this.emitEvent(a,d),i)if(this.$element=this.$element||i(this.element),b){var e=i.Event(b);e.type=a,this.$element.trigger(e,c)}else this.$element.trigger(a,c)},g.prototype.ignore=function(a){var b=this.getItem(a);b&&(b.isIgnored=!0)},g.prototype.unignore=function(a){var b=this.getItem(a);b&&delete b.isIgnored},g.prototype.stamp=function(a){if(a=this._find(a)){this.stamps=this.stamps.concat(a);for(var b=0,c=a.length;c>b;b++){var d=a[b];this.ignore(d)}}},g.prototype.unstamp=function(a){if(a=this._find(a))for(var b=0,c=a.length;c>b;b++){var d=a[b];e.removeFrom(this.stamps,d),this.unignore(d)}},g.prototype._find=function(a){return a?("string"==typeof a&&(a=this.element.querySelectorAll(a)),a=e.makeArray(a)):void 0},g.prototype._manageStamps=function(){if(this.stamps&&this.stamps.length){this._getBoundingRect();for(var a=0,b=this.stamps.length;b>a;a++){var c=this.stamps[a];this._manageStamp(c)}}},g.prototype._getBoundingRect=function(){var a=this.element.getBoundingClientRect(),b=this.size;this._boundingRect={left:a.left+b.paddingLeft+b.borderLeftWidth,top:a.top+b.paddingTop+b.borderTopWidth,right:a.right-(b.paddingRight+b.borderRightWidth),bottom:a.bottom-(b.paddingBottom+b.borderBottomWidth)}},g.prototype._manageStamp=j,g.prototype._getElementOffset=function(a){var b=a.getBoundingClientRect(),c=this._boundingRect,e=d(a),f={left:b.left-c.left-e.marginLeft,top:b.top-c.top-e.marginTop,right:c.right-b.right-e.marginRight,bottom:c.bottom-b.bottom-e.marginBottom};return f},g.prototype.handleEvent=function(a){var b="on"+a.type;this[b]&&this[b](a)},g.prototype.bindResize=function(){this.isResizeBound||(b.bind(a,"resize",this),this.isResizeBound=!0)},g.prototype.unbindResize=function(){this.isResizeBound&&b.unbind(a,"resize",this),this.isResizeBound=!1},g.prototype.onresize=function(){function a(){b.resize(),delete b.resizeTimeout}this.resizeTimeout&&clearTimeout(this.resizeTimeout);var b=this;this.resizeTimeout=setTimeout(a,100)},g.prototype.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},g.prototype.needsResizeLayout=function(){var a=d(this.element),b=this.size&&a;return b&&a.innerWidth!==this.size.innerWidth},g.prototype.addItems=function(a){var b=this._itemize(a);return b.length&&(this.items=this.items.concat(b)),b},g.prototype.appended=function(a){var b=this.addItems(a);b.length&&(this.layoutItems(b,!0),this.reveal(b))},g.prototype.prepended=function(a){var b=this._itemize(a);if(b.length){var c=this.items.slice(0);this.items=b.concat(c),this._resetLayout(),this._manageStamps(),this.layoutItems(b,!0),this.reveal(b),this.layoutItems(c)}},g.prototype.reveal=function(a){this._emitCompleteOnItems("reveal",a);for(var b=a&&a.length,c=0;b&&b>c;c++){var d=a[c];d.reveal()}},g.prototype.hide=function(a){this._emitCompleteOnItems("hide",a);for(var b=a&&a.length,c=0;b&&b>c;c++){var d=a[c];d.hide()}},g.prototype.revealItemElements=function(a){var b=this.getItems(a);this.reveal(b)},g.prototype.hideItemElements=function(a){var b=this.getItems(a);this.hide(b)},g.prototype.getItem=function(a){for(var b=0,c=this.items.length;c>b;b++){var d=this.items[b];if(d.element===a)return d}},g.prototype.getItems=function(a){a=e.makeArray(a);for(var b=[],c=0,d=a.length;d>c;c++){var f=a[c],g=this.getItem(f);g&&b.push(g)}return b},g.prototype.remove=function(a){var b=this.getItems(a);if(this._emitCompleteOnItems("remove",b),b&&b.length)for(var c=0,d=b.length;d>c;c++){var f=b[c];f.remove(),e.removeFrom(this.items,f)}},g.prototype.destroy=function(){var a=this.element.style;a.height="",a.position="",a.width="";for(var b=0,c=this.items.length;c>b;b++){var d=this.items[b];d.destroy()}this.unbindResize();var e=this.element.outlayerGUID;delete l[e],delete this.element.outlayerGUID,i&&i.removeData(this.element,this.constructor.namespace)},g.data=function(a){a=e.getQueryElement(a);var b=a&&a.outlayerGUID;return b&&l[b]},g.create=function(a,b){function c(){g.apply(this,arguments)}return Object.create?c.prototype=Object.create(g.prototype):e.extend(c.prototype,g.prototype),c.prototype.constructor=c,c.defaults=e.extend({},g.defaults),e.extend(c.defaults,b),c.prototype.settings={},c.namespace=a,c.data=g.data,c.Item=function(){f.apply(this,arguments)},c.Item.prototype=new f,e.htmlInit(c,a),i&&i.bridget&&i.bridget(a,c),c},g.Item=f,g}),function(a,b){"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size","fizzy-ui-utils/utils"],b):"object"==typeof exports?module.exports=b(require("outlayer"),require("get-size"),require("fizzy-ui-utils")):a.Masonry=b(a.Outlayer,a.getSize,a.fizzyUIUtils)}(window,function(a,b,c){var d=a.create("masonry");return d.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns();var a=this.cols;for(this.colYs=[];a--;)this.colYs.push(0);this.maxY=0},d.prototype.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var a=this.items[0],c=a&&a.element;this.columnWidth=c&&b(c).outerWidth||this.containerWidth}var d=this.columnWidth+=this.gutter,e=this.containerWidth+this.gutter,f=e/d,g=d-e%d,h=g&&1>g?"round":"floor";f=Math[h](f),this.cols=Math.max(f,1)},d.prototype.getContainerWidth=function(){var a=this.options.isFitWidth?this.element.parentNode:this.element,c=b(a);this.containerWidth=c&&c.innerWidth},d.prototype._getItemLayoutPosition=function(a){a.getSize();var b=a.size.outerWidth%this.columnWidth,d=b&&1>b?"round":"ceil",e=Math[d](a.size.outerWidth/this.columnWidth);e=Math.min(e,this.cols);for(var f=this._getColGroup(e),g=Math.min.apply(Math,f),h=c.indexOf(f,g),i={x:this.columnWidth*h,y:g},j=g+a.size.outerHeight,k=this.cols+1-f.length,l=0;k>l;l++)this.colYs[h+l]=j;return i},d.prototype._getColGroup=function(a){if(2>a)return this.colYs;for(var b=[],c=this.cols+1-a,d=0;c>d;d++){var e=this.colYs.slice(d,d+a);b[d]=Math.max.apply(Math,e)}return b},d.prototype._manageStamp=function(a){var c=b(a),d=this._getElementOffset(a),e=this.options.isOriginLeft?d.left:d.right,f=e+c.outerWidth,g=Math.floor(e/this.columnWidth);g=Math.max(0,g);var h=Math.floor(f/this.columnWidth);h-=f%this.columnWidth?0:1,h=Math.min(this.cols-1,h);for(var i=(this.options.isOriginTop?d.top:d.bottom)+c.outerHeight,j=g;h>=j;j++)this.colYs[j]=Math.max(i,this.colYs[j])},d.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var a={height:this.maxY};return this.options.isFitWidth&&(a.width=this._getContainerFitWidth()),a},d.prototype._getContainerFitWidth=function(){for(var a=0,b=this.cols;--b&&0===this.colYs[b];)a++;return(this.cols-a)*this.columnWidth-this.gutter},d.prototype.needsResizeLayout=function(){var a=this.containerWidth;return this.getContainerWidth(),a!==this.containerWidth},d});
4621</script>
4622<style>
4623.hidden {
4624 display: none !important;
4625}
4626</style>
4627<script type="text/javascript">
4628(function(course_data){
4629"use strict";
4630function GetLearningData(){
4631 preloaderOn();
4632 $.ajax({
4633 type: "POST",
4634 url: "/pp/Ext/extjs_json_collection_data.html",
4635 dataType: "json",
4636 data: {
4637 collection_code: "beluga_course_data_rc",
4638 parameters: "learning_id="+course_data.learningID
4639 },
4640 success: function (data, textStatus, jqXHR) {
4641 preloaderOff();
4642 RenderLearningData(data.results[0]);
4643 }
4644 });
4645};
4646function RenderLearningData(data){
4647 $("#start_learning").off();
4648 $("#finish_learning").off();
4649 $("#learning_title").text(data.name);
4650 data.categories.forEach(function(el){
4651 $("#categories").after(
4652 '<li class="b-test__breadcrumbs-item"><a href="javascript:void(0);" class="b-test__breadcrumbs-link">'+el+'</a></li>'
4653 );
4654 });
4655 $("#categories").remove();
4656 if (data.course_resource != undefined && data.course_resource != ""){
4657 $("#course_image").css("background", "url('download_file.html?file_id="+data.course_resource+"') no-repeat center center");
4658 } else {
4659 $("#course_image").remove();
4660 }
4661 switch (data.status) {
4662 case 0:
4663 $("#course_status").text("Назначен");
4664 $("#finish_learning").addClass("hidden");
4665 $("#start_learning").text("Начать");
4666 break;
4667 case 1:
4668 $("#course_status").text("В процессе");
4669 $("#start_learning").text("Продолжить");
4670 if(!data.has_unfinished_required_parts || data.finish_without_mastery_score){
4671 $("#finish_learning").removeClass("hidden");
4672 } else {
4673 $("#finish_learning").addClass("hidden");
4674 }
4675 if(!data.has_unfinished_parts){
4676 $("#start_learning").addClass("hidden");
4677 } else {
4678 $("#start_learning").removeClass("hidden");
4679 }
4680 break;
4681 case 2:
4682 $("#course_status").text("Завершен");
4683 $("#finish_learning").removeClass("hidden");
4684 if(data.is_self_enrolled){
4685 $("#start_learning").text("Начать заново");
4686 } else {
4687 $("#start_learning").addClass("hidden");
4688 }
4689 if (data.feedback_type_id != null) {
4690 $("#feedback").attr("href", "view_doc.html?mode=response&doc_id=&response_object_id="+data.course_id+"&response_type_id="+data.feedback_type_id);
4691 $("#feedback").show();
4692 }
4693 break;
4694 case 3:
4695 $("#course_status").text("Не пройден");
4696 $("#finish_learning").removeClass("hidden");
4697 if(data.is_self_enrolled){
4698 $("#start_learning").text("Начать заново");
4699 } else {
4700 $("#start_learning").addClass("hidden");
4701 }
4702 if (data.feedback_type_id != null) {
4703 $("#feedback").attr("href", "view_doc.html?mode=response&doc_id=&response_object_id="+data.course_id+"&response_type_id="+data.feedback_type_id);
4704 $("#feedback").show();
4705 }
4706 break;
4707 case 4:
4708 $("#course_status").text("Пройден");
4709 $("#finish_learning").removeClass("hidden");
4710 if(data.is_self_enrolled){
4711 $("#start_learning").text("Начать заново");
4712 } else {
4713 $("#start_learning").addClass("hidden");
4714 }
4715 if (data.feedback_type_id != null) {
4716 $("#feedback").attr("href", "view_doc.html?mode=response&doc_id=&response_object_id="+data.course_id+"&response_type_id="+data.feedback_type_id);
4717 $("#feedback").show();
4718 }
4719 break;
4720 case 5:
4721 $("#course_status").text("Просмотрен");
4722 $("#finish_learning").removeClass("hidden");
4723 if(data.is_self_enrolled){
4724 $("#start_learning").text("Начать заново");
4725 } else {
4726 $("#start_learning").addClass("hidden");
4727 }
4728 if (data.feedback_type_id != null) {
4729 $("#feedback").attr("href", "view_doc.html?mode=response&doc_id=&response_object_id="+data.course_id+"&response_type_id="+data.feedback_type_id);
4730 $("#feedback").show();
4731 }
4732 break;
4733 case 10:
4734 if(data.is_self_enrolled){
4735 $("#course_status").text("Не назначен");
4736 $("#start_learning").text("Начать");
4737 } else {
4738 $("#course_status").text("Не доступен");
4739 $("#start_learning").off();
4740 $("#start_learning").addClass("hidden");
4741 }
4742 $("#finish_learning").addClass("hidden");
4743 break;
4744 case 11:
4745 $("#course_status").text("Не доступен");
4746 $("#start_learning").addClass("hidden");
4747 $("#finish_learning").addClass("hidden");
4748 $("#start_learning").off();
4749 $("#finish_learning").off();
4750 break;
4751 default:
4752 break;
4753 }
4754 if(data.a_l_id == ""){
4755 $("#finish_learning").addClass("hidden");
4756 }
4757 if(data.status != 11){
4758 $("#course_score").text(data.course_score);
4759 $("#date_start").text(data.date_start != '' ? data.date_start : '-');
4760 $("#date_l_start").text(data.date_l_start != '' ? data.date_l_start : '-');
4761 $("#date_finish").text(data.date_finish != '' ? data.date_finish : '-');
4762 if(data.description != ""){
4763 $("#course_desc").html(data.description);
4764 } else {
4765 $("#course_desc").remove();
4766 }
4767
4768 $("#course_materials").empty();
4769 $("#course_map").empty();
4770 if(data.course_map.length > 0){
4771 data.course_map.forEach(function(el){
4772 switch (el.type) {
4773 case 'Курс':
4774 var btn = (function(){
4775 if(data.status == 10){
4776 return ''
4777 } else if (el.state_id <= 1 && data.status <= 2) {
4778 return $('<div>')
4779 .addClass("b-test__table-cell b-course__table-cell b-course__table-but")
4780 .append(
4781 $("<div>").addClass("b-course__table-cell-wrap").append(
4782 $('<a>')
4783 .attr('href', 'javascript:void(0);')
4784 .addClass("b-course__button-empty b-course__table-button")
4785 .text(el.state_id == 0 ? "Начать":"Продолжить")
4786 .on('click', function(){
4787 var _form = new FormData;
4788 _form.append("course_id", data.course_id);
4789 $.ajax({
4790 url: "/custom_web_template.html?object_code=beluga_get_session_id_sum",
4791 type: "POST",
4792 data: _form,
4793 dataType: "json",
4794 processData: false,
4795 contentType: false,
4796 success: function(res) {
4797 var courseWindow = window.open( 'course_launch.html?course_id='+data.course_id+'&object_id='+data.a_l_id+'&sid='+res.responseText+ "&part_code="+ el.parts);
4798 var _intrval_mod = setInterval(function(){
4799 if (courseWindow.closed) {
4800 clearInterval(_intrval_mod);
4801 location.href = 'view_doc.html?mode=course_page&object_id='+course_data.learningID;
4802 }
4803 }, 500);
4804 }
4805 });
4806 }),
4807 (function(){
4808 if(el.cur_attempt < el.attempts){
4809 return $('<a>')
4810 .attr('href', 'javascript:void(0);')
4811 .addClass("b-course__complete-attempt-link")
4812 .text("Завершить попытку")
4813 .on('click', function(){
4814 var _form = new FormData;
4815 _form.append("course_id", data.course_id);
4816 _form.append("learning_id", data.a_l_id);
4817 _form.append("part_code", el.parts);
4818 $.ajax({
4819 url: "/custom_web_template.html?object_code=beluga_course_finish_attempt",
4820 type: "POST",
4821 data: _form,
4822 dataType: "json",
4823 processData: false,
4824 contentType: false,
4825 success: function(res) {
4826 GetLearningData();
4827 }
4828 });
4829 })
4830 }
4831 })()
4832 )
4833 )
4834 } else {
4835 var score = 0;
4836 if(el.max_score != 0){
4837 score = el.score/el.max_score;
4838 } else {
4839 score = 1;
4840 }
4841 return $("<div>")
4842 .addClass("b-test__table-cell b-course__table-cell b-course__table-no-but")
4843 .append(
4844 $("<div>").addClass("b-course__table-cell-wrap").append(
4845 $("<div>").addClass("b-course__type-wrap").append(
4846 $("<div>")
4847 .addClass('goal-map__type '+(el.state_id != 3 ? "ready":"not-ready")+' b-course__type')
4848 .append(
4849 $('<span>')
4850 .text(el.state_name)
4851 .on('click', function(){
4852 var _form = new FormData;
4853 _form.append("course_id", data.course_id);
4854 $.ajax({
4855 url: "/custom_web_template.html?object_code=beluga_get_session_id_sum",
4856 type: "POST",
4857 data: _form,
4858 dataType: "json",
4859 processData: false,
4860 contentType: false,
4861 success: function(res) {
4862 var courseWindow = window.open( 'course_launch.html?course_id='+data.course_id+'&object_id='+data.a_l_id+'&sid='+res.responseText+ "&part_code="+ el.parts);
4863 var _intrval_mod = setInterval(function(){
4864 if (courseWindow.closed) {
4865 clearInterval(_intrval_mod);
4866 location.href = 'view_doc.html?mode=course_page&object_id='+course_data.learningID;
4867 }
4868 }, 500);
4869 }
4870 });
4871 }),
4872 $('<span>')
4873 .addClass("b-course__text-last")
4874 .text(Math.round(score*100)+"%")
4875 )
4876 ),
4877 (function(){
4878 if(el.cur_attempt < el.attempts){
4879 return $('<a>')
4880 .attr('href', 'javascript:void(0);')
4881 .addClass("b-course__complete-attempt-link new")
4882 .text("Пройти заново")
4883 .on('click', function(){
4884 var _form = new FormData;
4885 _form.append("course_id", data.course_id);
4886 _form.append("learning_id", data.a_l_id);
4887 _form.append("part_code", el.parts);
4888 $.ajax({
4889 url: "/custom_web_template.html?object_code=beluga_course_finish_attempt",
4890 type: "POST",
4891 data: _form,
4892 dataType: "json",
4893 processData: false,
4894 contentType: false,
4895 success: function(res) {
4896 GetLearningData();
4897 }
4898 });
4899 })
4900 }
4901 })()
4902 )
4903 )
4904 }
4905 })();
4906 break;
4907 case 'Тест':
4908 var btn = (function(){
4909 if(data.status == 10 || data.status == 11){
4910 return;
4911 } else if (el.state_id <= 1 && data.status <= 2) {
4912 return $('<div>')
4913 .addClass("b-test__table-cell b-course__table-cell b-course__table-but")
4914 .append(
4915 $("<div>").addClass("b-course__table-cell-wrap").append(
4916 '<a href="javascript:void(0);" class="b-course__button-empty b-course__table-button">'+(el.state_id == 0 ? "Начать":"Продолжить")+'</a>'
4917 )
4918 )
4919 .on('click', function(){
4920 location.href = "view_doc.html?mode=test_page&object_id="+el.test_id+"&course_id="+data.course_id+"&part_code="+el.parts+(data.a_l_id != "" ? "&learning_id="+data.a_l_id : "");
4921 });
4922 } else {
4923 if(!el.is_locked){
4924 var score = 0;
4925 if(el.max_score != 0){
4926 score = el.score/el.max_score;
4927 } else {
4928 score = 1;
4929 }
4930 return $("<div>")
4931 .addClass("b-test__table-cell b-course__table-cell b-course__table-no-but")
4932 .append(
4933 $("<div>").addClass("b-course__table-cell-wrap").append(
4934 $("<div>").addClass("b-course__type-wrap").append(
4935 $("<div>")
4936 .addClass("goal-map__type "+(el.state_id != 3 ? "ready":"not-ready")+" b-course__type")
4937 .append(
4938 $("<span>").text(el.state_name),
4939 $("<span>").addClass("b-course__text-last").text(Math.round((score)*100)+"%")
4940 )
4941 ).on('click', function(){
4942 location.href = "view_doc.html?mode=test_page&object_id="+el.test_id+"&course_id="+data.course_id+"&part_code="+el.parts+(data.a_l_id != "" ? "&learning_id="+data.a_l_id : "");
4943 })
4944 )
4945 );
4946 }
4947 }
4948 })();
4949 break;
4950 default:
4951 var btn = (function(){
4952 if(data.status == 10 || data.status == 11){
4953 return;
4954 } else {
4955 return $('<div>')
4956 .addClass("b-test__table-cell b-course__table-cell b-course__table-but")
4957 .append(
4958 $("<div>").addClass("b-course__table-cell-wrap").append(
4959 '<a href="javascript:void(0);" class="b-course__button-empty b-course__table-button">Открыть</a>'
4960 )
4961 )
4962 .on('click', function(){
4963 var _form = new FormData;
4964 _form.append("course_id", data.course_id);
4965 $.ajax({
4966 url: "/custom_web_template.html?object_code=beluga_get_session_id_sum",
4967 type: "POST",
4968 data: _form,
4969 dataType: "json",
4970 processData: false,
4971 contentType: false,
4972 success: function(res) {
4973 var url = 'course_launch.html?course_id='+data.course_id+'&object_id='+data.a_l_id+'&sid='+res.responseText+ "&part_code="+ el.parts;
4974 if(data.a_l_id == "" && el.type == 'Файл'){
4975 url = el.url;
4976 }
4977 var courseWindow = window.open(url);
4978 var _intrval_mod = setInterval(function(){
4979 if (courseWindow.closed) {
4980 clearInterval(_intrval_mod);
4981 location.href = 'view_doc.html?mode=course_page&object_id='+course_data.learningID;
4982 }
4983 }, 500);
4984 }
4985 });
4986 });
4987 }
4988 })();
4989 break;
4990 }
4991 $("#course_map").append(
4992 $("<div>")
4993 .addClass("b-test__table-row b-course__table-row")
4994 .append(
4995 $("<div>")
4996 .addClass("b-test__table-cell b-course__table-cell")
4997 .append(
4998 '<a href="javascript:void(0);" class="b-course__title-link">'+el.name+'</a>'
4999 ),
5000 $("<div>")
5001 .addClass("b-test__table-cell b-text__grey b-course__table-cell clearfix")
5002 .append(
5003 '<span class="b-course__table-text">'+el.type+'</span><span class="b-course__table-num">'+el.score+(el.max_score != 0 && el.max_score != '-' ? '/'+el.max_score : '')+'</span>'
5004 ),
5005 btn
5006 )
5007 );
5008 });
5009 } else {
5010 $("#map_block").remove();
5011 }
5012 if(data.docs.length != 0){
5013 data.docs.forEach(function(el){
5014 $("#course_materials").append(
5015 $("<div>")
5016 .addClass("b-test__table-row b-course__table-row" + (el.type == 'video' ? " b-course__table-row-video": ""))
5017 .append(
5018 $("<div>")
5019 .addClass("b-test__table-cell b-course__table-cell b-course__material-cell")
5020 .append(
5021 (function(){
5022 if(el.type == 'video'){
5023 return '<div class="b-course__material-icon-video"><i class="b-icon__play b-course__material-icon"></i></div>';
5024 } else {
5025 return '';
5026 }
5027 }),
5028 ' <a href="javascript:void(0);" class="b-course__title-link">'+el.name+'</a>'
5029 ),
5030 '<div class="b-test__table-cell b-text__grey clearfix b-course__material-cell">'+
5031 ' <span class="b-course__table-text b-course__big-text">'+el.type+'</span>'+
5032 ' <span class="b-course__table-num b-course__material-text">'+el.size+'</span></div>'+
5033 '</div>',
5034 $('<div>')
5035 .addClass("b-test__table-cell b-course__table-cell b-course__table-but b-course__material-cell")
5036 .append('<a href="javascript:void(0);" class="b-course__button-empty b-course__table-button b-course__material-button float-right b-course__material-button-download">Скачать</a>')
5037 .on("click", function(){
5038 window.open(el.url );
5039 })
5040 )
5041 );
5042 });
5043 } else {
5044 $("#materials_block").remove();
5045 }
5046 } else {
5047 $("#course_block").empty().append(
5048 '<h2 class="b-title__h2 b-course__h2">Курс находится в разработке.</h2>'
5049 )
5050 }
5051 if($("#start_learning").hasClass("hidden") && $("#finish_learning").hasClass("hidden")){
5052 $(".b-fixpanel").hide();
5053 }
5054
5055 $("#start_learning").on("click", function(){
5056 if(data.status == 0 || data.status == 1){
5057 var _form = new FormData;
5058 _form.append("course_id", data.course_id);
5059 $.ajax({
5060 url: "/custom_web_template.html?object_code=beluga_get_session_id_sum",
5061 type: "POST",
5062 data: _form,
5063 dataType: "json",
5064 processData: false,
5065 contentType: false,
5066 success: function(res) {
5067 var courseWindow = window.open( 'course_launch.html?course_id='+data.course_id+'&object_id='+data.a_l_id+'&sid='+res.responseText+ "&part_code="+ data.c_part);
5068 var _intrval_mod = setInterval(function(){
5069 if (courseWindow.closed) {
5070 clearInterval(_intrval_mod);
5071 location.href = 'view_doc.html?mode=course_page&object_id='+course_data.learningID;
5072 }
5073 }, 500);
5074 }
5075 });
5076 } else {
5077 var form_data = new FormData();
5078 form_data.append("course_id", data.course_id)
5079 form_data.append("course_part", data.c_part)
5080 $.ajax({
5081 url: "/custom_web_template.html?object_code=beluga_activate_course",
5082 type: "POST",
5083 data: form_data,
5084 dataType: "json",
5085 processData: false,
5086 contentType: false,
5087 success: function(res) {
5088 if(!res.error){
5089 var courseWindow = window.open(res.url);
5090 var _intrval_mod = setInterval(function(){
5091 if (courseWindow.closed) {
5092 clearInterval(_intrval_mod);
5093 location.href = 'view_doc.html?mode=course_page&object_id='+course_data.learningID;
5094 }
5095 }, 500);
5096 } else {
5097 alert(data.message);
5098 }
5099 }
5100 });
5101 }
5102 });
5103 $("#finish_learning").click(function(){
5104 var form_data = new FormData();
5105 form_data.append("course_id", data.course_id);
5106 $.ajax({
5107 url: "/custom_web_template.html?object_code=beluga_finish_course",
5108 type: "POST",
5109 data: form_data,
5110 dataType: "json",
5111 processData: false,
5112 contentType: false,
5113 success: function(data) {
5114 location.href = 'view_doc.html?mode=course_page&object_id='+course_data.learningID;
5115 },
5116 error: function(){
5117 location.href = 'view_doc.html?mode=course_page&object_id='+course_data.learningID;
5118 }
5119 });
5120 });
5121 var h = $(".b-fixpanel").outerHeight();
5122 $("#panel_fix_height").css("height", h+"px");
5123 $(".b-course__title-link").on("click", function(){
5124 $(this).parent().next().next().click();
5125 });
5126}
5127function init(){
5128 GetLearningData();
5129}
5130init();
5131$(window).on('load, resize, scroll', function(){
5132 var h = $(".b-footer").outerHeight();
5133 if (Math.round($(window).scrollTop()) == $(document).outerHeight() - $(window).outerHeight())
5134 {
5135 //Пользователь долистал до низа страницы
5136 $(".b-fixpanel").css("bottom", h+"px");
5137 }
5138 else {
5139 $(".b-fixpanel").css("bottom", "");
5140 }
5141});
5142})({"learningID":"6541234634070967339"});
5143</script>
5144 <div class="b-page__title">
5145 <div class="b-container">
5146 <h1 class="b-title__h1 b-course__h1" id="learning_title"></h1>
5147 </div>
5148 </div>
5149 <div class="b-test__breadcrumbs">
5150 <div class="b-container">
5151 <div class="b-test__breadcrumbs-wrap b-course__breadcrumbs-wrap">
5152 <ul class="b-test__breadcrumbs-ul">
5153 <li class="b-test__breadcrumbs-item"><a href="javascript:void(0);"><div class="b-icon-course b-test__icon-course b-test__icon-test float-left"></div>Курс</a></li>
5154 <li class="b-test__breadcrumbs-item" id="categories"><a href="javascript:void(0);" class="b-test__breadcrumbs-link" >Вводные тесты</a></li>
5155 <li class="b-test__breadcrumbs-item active"><a href="javascript:void(0);" class="b-test__breadcrumbs-link b-test__breadcrumbs-link-last"><div class="icon-play b-test__icon-play float-left"></div> <span id="course_status">В процессе</span></a></li>
5156 </ul>
5157 </div>
5158 </div>
5159 </div>
5160 <div class="b-container" id="course_block">
5161 <div class="b-course__image" id="course_image"></div>
5162 <div class="b-test__table b-course__table">
5163 <div class="b-test__table-row">
5164 <div class="b-test__table-cell b-text__grey b-course__text-little">Баллы</div>
5165 <div class="b-test__table-cell"><span class="wl-text__orange" id="course_score"></span></div>
5166 </div>
5167 <div class="b-test__table-row">
5168 <div class="b-test__table-cell b-text__grey b-course__text-little">Дата активации</div>
5169 <div class="b-test__table-cell" id="date_start"></div>
5170 </div>
5171 <div class="b-test__table-row">
5172 <div class="b-test__table-cell b-text__grey b-course__text-little">Дата последнего посещения</div>
5173 <div class="b-test__table-cell" id="date_l_start"></div>
5174 </div>
5175 <div class="b-test__table-row">
5176 <div class="b-test__table-cell b-text__grey b-course__text-little">Дата планируемого завершения</div>
5177 <div class="b-test__table-cell" id="date_finish"></div>
5178 </div>
5179 </div>
5180 <div class="b-test__description" id="course_desc">
5181
5182 </div>
5183 <div id="map_block">
5184 <h3 class="b-test__h3">Карта курса</h3>
5185 <div class="b-course__table-wrap" >
5186 <div class="b-test__table b-course__table" id="course_map">
5187 </div>
5188 </div>
5189 </div>
5190 <div id="materials_block">
5191 <h3 class="b-test__h3">Материалы курса</h3>
5192 <div class="b-course__table-wrap">
5193 <div class="b-test__table b-course__table b-course__table-material" id="course_materials">
5194
5195 </div>
5196 </div>
5197 </div>
5198 </div>
5199 <div id="panel_fix_height"></div>
5200 <div class="b-fixpanel">
5201 <div class="b-container">
5202 <a href="javascript:void(0);" class="b-fixpanel__save" style="margin-right: 10px;" id="start_learning">Продолжить</a>
5203 <a href="javascript:void(0);" class="b-fixpanel__complete" id="finish_learning">Завершить</a>
5204 <a href="javascript:void(0);" class="b-fixpanel__complete" style="margin-right: 10px; display: none;" id="feedback">Оставить отзыв</a>
5205 </div>
5206 </div>
5207 <!--footer end -->
5208 <script type="text/javascript" src="scorm_api.js" language="javascript"></script>
5209
5210
5211 <script type="text/javascript">
5212 /*jQuery(function(){
5213 jQuery('textarea').autoResize();
5214 });*/
5215 $('select').selectric({
5216 maxHeight: 200
5217 });
5218 </script>
5219 <script type="text/javascript">
5220 $(".b-library__container").masonry({
5221 itemSelector: '.item',
5222 columnWidth: ".item",
5223 gutter: 10,
5224 isInitLayout: true,
5225 //isFitWidth: true,
5226 isResizeBound: true,
5227 });
5228 </script>
5229 <div class="b-container">
5230 </div><div class="b-container"><a style="margin-bottom: 100px; " class="b-button__blue full" href='view_print_form.html?print_form_id=6473426798783395895&object_id=6716797818596368129&sid=6473426798783395895'><h2>РАСПЕЧАТАТЬ СЕРТИФИКАТ</h2></a>
5231</div><!-- старт сокрытие рамки новостей-->
5232
5233<!-- конец сокрытие рамки новостей--><!-- старт Ссылка на страницу новости со страницу одной новости-->
5234
5235<!-- конец Ссылка на страницу новости со страницу одной новости--><script>
5236$(document).ready(function(){
5237
5238 $(".portalhelp").click(function(){
5239 if(!$(".introjs-overlay").length>0)
5240{
5241 introJs().start();
5242}
5243 })
5244})
5245</script>
5246 </div>
5247 </div>
5248
5249<footer class="b-footer blue">
5250 <div class="b-container">
5251 <div class="b-footer__wrap">
5252 <div class="b-footer__header clearfix">
5253 <div class="b-footer__nav float-left">
5254 <nav id="footer_menu_main">
5255 </nav>
5256 </div>
5257 <div class="b-footer__link">
5258 <a id="footer_send_admin" href="javascript:void(0)">Написать администратору</a>
5259 </div>
5260 </div>
5261 <div class="b-footer__footer clearfix">
5262 <div class="b-footer__logo float-left">
5263 <a href="javascript:void(0)"><img src="download_file.html?file_id=6621426380956391193" alt="logo"></a>
5264 </div>
5265 <div class="b-footer__group float-left">
5266 <a id="footer_copy" href="javascript:void(0)"></a>
5267 </div>
5268 <div class="b-footer__logo-lab float-right">
5269 <a href="https://labmedia.su/">
5270 <img src="download_file.html?file_id=6621426457715887988" alt="logo">
5271 </a>
5272 </div>
5273 </div>
5274 </div>
5275 </div>
5276 <div id="footer_modal_admin"></div>
5277</footer>
5278<script>
5279 $(document).ready(function () {
5280 'use strict';
5281
5282 //модальное окно
5283 var Modal = (function () {
5284 var defaultText = 'Не более 5 МБ',
5285 maxFileSize = 1024 * 1024 * 5; //5 МБ
5286 function Constructor (config) {
5287 var self = this,
5288
5289 emailTextArea = config.curUserEmail != "" ? $() : $('<textarea/>')
5290 .addClass("comment_input b-textarea comments")
5291 .attr({
5292 "id": "footer_send_from",
5293 "rows": 1,
5294 "placeholder": "Введите ваш адрес электронной почты",
5295 "style": "margin-top: 0; margin-bottom: 23px;"
5296 }),
5297 textarea = $('<textarea/>')
5298 .attr('maxlength', '3000')
5299 .addClass("b-write-to-admin__textarea-item"),
5300 label = $('<span/>')
5301 .addClass('b-write-to-admin__desc')
5302 .text(defaultText),
5303 delFileBtn = $('<a/>')
5304 .addClass('delete_file_btn')
5305 .attr('href', 'javascript:void(0);')
5306 .append(
5307 $('<i/>')
5308 .addClass('b-icon__delete')
5309 .css({
5310 'position': 'absolute',
5311 'margin-top': '23px',
5312 'margin-left': '5px'
5313 })
5314 ),
5315 sendBtn = $('<a/>')
5316 .attr('href', 'javascript:void(0);')
5317 .addClass('b-write-to-admin__blue')
5318 .text('Отправить'),
5319 cancelBtn = $('<a/>')
5320 .attr('href', 'javascript:void(0);')
5321 .addClass('b-button__empty')
5322 .text('Отмена'),
5323 loadFileBtn = $('<a/>')
5324 .addClass('b-write-to-admin__but')
5325 .attr('href', 'javascript:void(0);')
5326 .append(
5327 $("<span/>")
5328 .text('Загрузить файл')
5329 ),
5330 fileInput = $('<input/>')
5331 .hide()
5332 .attr('accept', '.jpg, .jpeg, .png')
5333 .attr('type', 'file'),
5334 fileBlock = $('<div/>')
5335 .addClass('b-write-to-admin__download')
5336 .append(
5337 loadFileBtn,
5338 fileInput,
5339 label,
5340 delFileBtn
5341 ),
5342 domElement = $('<div/>')
5343 .addClass('b-shadow fade in')
5344 .hide()
5345 .append(
5346 $('<div/>')
5347 .addClass('b-modal b-report-selection b-write-to-admin')
5348 .hide()
5349 .append(
5350 $('<div/>')
5351 .addClass('b-modal__wrapper')
5352 .css('overflow', 'hidden')
5353 .append(
5354 $('<div/>')
5355 .addClass('b-modal__header b-report-selection__header')
5356 .append(
5357 $('<h3/>')
5358 .addClass('b-modal__title b-report-selection__title')
5359 .text('Написать администратору')
5360 ),
5361 $('<div/>')
5362 .addClass('b-modal__content')
5363 .css({
5364 'max-height': '247px;',
5365 'overflow-y': 'auto;'
5366 })
5367 .append(
5368 $('<div/>')
5369 .addClass('b-write-to-admin__textarea')
5370 .append(
5371 emailTextArea,
5372 textarea
5373 ),
5374 fileBlock
5375 ),
5376 $('<div/>')
5377 .addClass('b-report-selection__footer b-write-to-admin__footer')
5378 .append(
5379 sendBtn,
5380 cancelBtn
5381 )
5382 )
5383 )
5384 );
5385
5386 //если в браузере нет FormData картинки не грузим
5387 if (!('FileReader' in window)) {
5388 fileBlock.hide();
5389 }
5390
5391 //клик по кнопке Загрузить файл
5392 loadFileBtn.on('click', function (event) {
5393 fileInput.click();
5394 });
5395 //клик по кнопке Удалить файл
5396 delFileBtn.on('click', function (event) {
5397 fileInput.val('');
5398 self.fileText(defaultText);
5399 $(".delete_file_btn").hide();
5400 })
5401 //клик по кнопке Отправить
5402 sendBtn.on('click', function (event) {
5403 //клик обрабатывается если кнопка активна и передан колбэк и указана почта по требованию
5404 if (sendBtn.hasClass('active')) {
5405 var files = fileInput.prop("files"), form_data;
5406
5407 if (files.length > 0) {
5408
5409 var fr = new FileReader();
5410 fr.onload = function (res) {
5411 self.sendAjax(self.textarea.val(), fr.result, files[0].name);
5412 };
5413
5414 fr.readAsBinaryString(files[0]);
5415 } else {
5416 self.sendAjax(self.textarea.val(), '', '');
5417 }
5418 sendBtn.removeClass('active');
5419 }
5420 });
5421
5422 //добавление картинки
5423 fileInput.on('change', function (event) {
5424 var files = fileInput.prop("files"), form_data;
5425
5426 if (files.length > 0) {
5427 //проверяем размер файла
5428 if (maxFileSize >= files[0].size) {
5429 $(".delete_file_btn").show();
5430 self.fileText(files[0].name);
5431 } else {
5432 $(".delete_file_btn").hide();
5433 self.errorFileText('Размер файла превышает 5 МБ');
5434 }
5435 }
5436 });
5437
5438 //клик по кнопке Отменить
5439 cancelBtn.on('click', function (event) {
5440 self.hide();
5441 });
5442
5443 //обработчик для textarea
5444
5445 textarea.on('input change keyup', function (event) {
5446 sendBtn.toggleClass('active', self.validateInput());
5447 });
5448
5449 emailTextArea.on('input change keyup', function (event) {
5450 sendBtn.toggleClass('active', self.validateInput());
5451 });
5452
5453 //рендер на странице
5454 if (config.renderToId)
5455 $('#' + config.renderToId).append(domElement);
5456
5457 //интерфейс класса
5458 self.domElement = domElement;
5459 self.label = label;
5460 self.emailTextArea = emailTextArea;
5461 self.textarea = textarea;
5462 self.fileInput = fileInput;
5463 self.sendBtn = sendBtn;
5464 self.curUserEmail = config.curUserEmail;
5465 }
5466 Constructor.prototype.deleteFile = function() {
5467 var self = this;
5468 self.fileText(defaultText);
5469 $(".delete_file_btn").hide();
5470 }
5471 Constructor.prototype.show = function () {
5472 var self = this;
5473
5474 //при повторном открытии очищаем введенный текст, выбранный файл, кнопку отправить делаем не активной
5475 self.textarea.val('');
5476 self.fileText(defaultText);
5477 self.fileInput.val('');
5478 self.sendBtn.removeClass('active');
5479 $(".delete_file_btn").hide();
5480 self.domElement.show();
5481 $(".b-modal", self.domElement).show();
5482 $("body").addClass("off-scroll");
5483 }
5484
5485 Constructor.prototype.hide = function () {
5486 var self = this;
5487
5488 $("body").removeClass("off-scroll");
5489 $(".b-modal", self.domElement).hide();
5490 self.domElement.hide();
5491 }
5492
5493 Constructor.prototype.getDomElement = function () {
5494 return this.domElement;
5495 }
5496
5497 Constructor.prototype.errorFileText = function (str) {
5498 var self = this;
5499
5500 self.label
5501 .text(str)
5502 .css('color', 'red');
5503 }
5504
5505 Constructor.prototype.fileText = function (str) {
5506 var self = this;
5507
5508 self.label
5509 .text(str)
5510 .css('color', '');
5511 }
5512
5513 Constructor.prototype.validateInput = function () {
5514 var self = this,
5515 validator = new RegExp(/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/gim),
5516 isFilledTextarea = self.textarea.val().trim() != "";
5517
5518 if (self.curUserEmail == "") {
5519 isFilledTextarea = validator.test(self.emailTextArea.val()) && isFilledTextarea;
5520 }
5521
5522 return isFilledTextarea;
5523 }
5524
5525 Constructor.prototype.sendAjax = function (text, fileString, file_name) {
5526 var self = this;
5527 $.ajax({
5528 url: "/custom_web_template.html?object_code=beluga_send_admin_server",
5529 type: "POST",
5530 data: {
5531 text: text,
5532 file: fileString,
5533 file_name: file_name,
5534 cur_user_email: self.curUserEmail || self.emailTextArea.val()
5535 },
5536 dataType: "json",
5537 success: function (data, textStatus, jqXHR) {
5538 self.hide();
5539 },
5540 error: function () {
5541 alert('Возникла ошибка при отправке');
5542 }
5543 });
5544 }
5545
5546 return Constructor;
5547 })();
5548
5549 var options = {"menuItems":[{"name":"Каталог курсов","link_href":"view_doc.html?mode=edu_catalog&doc_id=6628161676399233617"},{"name":"Документы","link_href":"view_doc.html?mode=lib&doc_id=6628162092753246374"},{"name":"Обучение","link_href":"view_doc.html?mode=doc&doc_id=5800376573543914533"},{"name":"МИРР","link_href":"view_doc.html?mode=self_assessment&doc_id=6631857937049990730"},{"name":"Библиотека","link_href":"view_doc.html?mode=doc&doc_id=6522717384966615904"},{"name":"Заявки","link_href":"view_doc.html?mode=doc&doc_id=6148914691236517176"},{"name":"Вакансии компании","link_href":"view_doc.html?mode=company_vacancys&doc_id=6711191531803911194"}],"cur_user_email":"LebedevDO@belugagroup.ru"};
5550
5551 //создание модального окна Написать администратору
5552 var modalAdmin = new Modal({
5553 renderToId: 'footer_modal_admin',
5554 curUserEmail: options.cur_user_email
5555 });
5556
5557 //открытие модалки Написать администратору
5558 $('#footer_send_admin').on('click', function (event) {
5559 modalAdmin.show();
5560 });
5561
5562 //меню
5563 var mainMenuContainer = $('#footer_menu_main');
5564 options.menuItems.forEach(function (item) {
5565 var a = $('<a href="' + item.link_href + '"></a>');
5566 a.text(item.name);
5567 mainMenuContainer.append(a);
5568 });
5569
5570 $('#footer_copy').text('© ' + new Date().getFullYear() + ' BELUGA GROUP')
5571 });
5572</script>
5573 <!--footer -->
5574
5575
5576
5577
5578
5579</body>
5580</html>