![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/cartforge.co/pub/static/adminhtml/Magento/backend/en_US/js/bundle/ |
require.config({"config": { "jsbuild":{"mage/calendar.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/*eslint max-depth: 0*/\ndefine([\n 'jquery',\n 'jquery-ui-modules/widget',\n 'jquery-ui-modules/datepicker',\n 'jquery-ui-modules/timepicker'\n], function ($) {\n 'use strict';\n\n var calendarBasePrototype,\n datepickerPrototype = $.datepicker.constructor.prototype;\n\n $.datepicker.markerClassName = '_has-datepicker';\n\n /**\n * Extend JQuery date picker prototype with store local time methods\n */\n $.extend(datepickerPrototype, {\n /**\n * Get date/time according to store settings.\n * We use serverTimezoneOffset (in seconds) instead of serverTimezoneSeconds\n * in order to have ability to know actual store time even if page hadn't been reloaded\n * @returns {Date}\n */\n _getTimezoneDate: function (options) {\n // local time in ms\n var ms = Date.now();\n\n options = options || $.calendarConfig || {};\n\n // Adjust milliseconds according to store timezone offset,\n // mind the GMT zero offset\n if (typeof options.serverTimezoneOffset !== 'undefined') {\n // Make UTC time and add store timezone offset in seconds\n ms += new Date().getTimezoneOffset() * 60 * 1000 + options.serverTimezoneOffset * 1000;\n } else if (typeof options.serverTimezoneSeconds !== 'undefined') {\n //Set milliseconds according to client local timezone offset\n ms = (options.serverTimezoneSeconds + new Date().getTimezoneOffset() * 60) * 1000;\n }\n\n return new Date(ms);\n },\n\n /**\n * Set date/time according to store settings.\n * @param {String|Object} target - the target input field or division or span\n */\n _setTimezoneDateDatepicker: function (target) {\n this._setDateDatepicker(target, this._getTimezoneDate());\n }\n });\n\n /**\n * Widget calendar\n */\n $.widget('mage.calendar', {\n options: {\n autoComplete: true\n },\n\n /**\n * Merge global options with options passed to widget invoke\n * @protected\n */\n _create: function () {\n this._enableAMPM();\n this.options = $.extend(\n {},\n $.calendarConfig ? $.calendarConfig : {},\n this.options.showsTime ? {\n showTime: true,\n showHour: true,\n showMinute: true\n } : {},\n this.options\n );\n this._initPicker(this.element);\n this._overwriteGenerateHtml();\n },\n\n /**\n * Get picker name\n * @protected\n */\n _picker: function () {\n return this.options.showsTime ? 'datetimepicker' : 'datepicker';\n },\n\n /**\n * Fix for Timepicker - Set ampm option for Timepicker if timeformat contains string 'tt'\n * @protected\n */\n _enableAMPM: function () {\n if (this.options.timeFormat && this.options.timeFormat.indexOf('tt') >= 0) {\n this.options.ampm = true;\n }\n },\n\n /**\n * Wrapper for overwrite jQuery UI datepicker function.\n */\n _overwriteGenerateHtml: function () {\n /**\n * Overwrite jQuery UI datepicker function.\n * Reason: magento date could be set before calendar show\n * but local date will be styled as current in original _generateHTML\n *\n * @param {Object} inst - instance datepicker.\n * @return {String} html template\n */\n $.datepicker.constructor.prototype._generateHTML = function (inst) {\n var today = this._getTimezoneDate(),\n isRTL = this._get(inst, 'isRTL'),\n showButtonPanel = this._get(inst, 'showButtonPanel'),\n hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext'),\n navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat'),\n numMonths = this._getNumberOfMonths(inst),\n showCurrentAtPos = this._get(inst, 'showCurrentAtPos'),\n stepMonths = this._get(inst, 'stepMonths'),\n isMultiMonth = parseInt(numMonths[0], 10) !== 1 || parseInt(numMonths[1], 10) !== 1,\n currentDate = this._daylightSavingAdjust(!inst.currentDay ? new Date(9999, 9, 9) :\n new Date(inst.currentYear, inst.currentMonth, inst.currentDay)),\n minDate = this._getMinMaxDate(inst, 'min'),\n maxDate = this._getMinMaxDate(inst, 'max'),\n drawMonth = inst.drawMonth - showCurrentAtPos,\n drawYear = inst.drawYear,\n maxDraw,\n prevText = this._get(inst, 'prevText'),\n prev,\n nextText = this._get(inst, 'nextText'),\n next,\n currentText = this._get(inst, 'currentText'),\n gotoDate,\n controls,\n buttonPanel,\n firstDay,\n showWeek = this._get(inst, 'showWeek'),\n dayNames = this._get(inst, 'dayNames'),\n dayNamesMin = this._get(inst, 'dayNamesMin'),\n monthNames = this._get(inst, 'monthNames'),\n monthNamesShort = this._get(inst, 'monthNamesShort'),\n beforeShowDay = this._get(inst, 'beforeShowDay'),\n showOtherMonths = this._get(inst, 'showOtherMonths'),\n selectOtherMonths = this._get(inst, 'selectOtherMonths'),\n defaultDate = this._getDefaultDate(inst),\n html = '',\n row = 0,\n col = 0,\n selectedDate,\n cornerClass = ' ui-corner-all',\n group = '',\n calender = '',\n dow = 0,\n thead,\n day,\n daysInMonth,\n leadDays,\n curRows,\n numRows,\n printDate,\n dRow = 0,\n tbody,\n daySettings,\n otherMonth,\n unselectable;\n\n if (drawMonth < 0) {\n drawMonth += 12;\n drawYear--;\n }\n\n if (maxDate) {\n maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),\n maxDate.getMonth() - numMonths[0] * numMonths[1] + 1, maxDate.getDate()));\n maxDraw = minDate && maxDraw < minDate ? minDate : maxDraw;\n\n while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {\n drawMonth--;\n\n if (drawMonth < 0) {\n drawMonth = 11;\n drawYear--;\n\n }\n }\n }\n inst.drawMonth = drawMonth;\n inst.drawYear = drawYear;\n prevText = !navigationAsDateFormat ? prevText : this.formatDate(prevText,\n this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),\n this._getFormatConfig(inst));\n prev = this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?\n '<a class=\"ui-datepicker-prev ui-corner-all\" data-handler=\"prev\" data-event=\"click\"' +\n ' title=\"' + prevText + '\">' +\n '<span class=\"ui-icon ui-icon-circle-triangle-' + (isRTL ? 'e' : 'w') + '\">' +\n '' + prevText + '</span></a>'\n : hideIfNoPrevNext ? ''\n : '<a class=\"ui-datepicker-prev ui-corner-all ui-state-disabled\" title=\"' +\n '' + prevText + '\"><span class=\"ui-icon ui-icon-circle-triangle-' +\n '' + (isRTL ? 'e' : 'w') + '\">' + prevText + '</span></a>';\n nextText = !navigationAsDateFormat ?\n nextText\n : this.formatDate(nextText,\n this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),\n this._getFormatConfig(inst));\n next = this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?\n '<a class=\"ui-datepicker-next ui-corner-all\" data-handler=\"next\" data-event=\"click\"' +\n 'title=\"' + nextText + '\"><span class=\"ui-icon ui-icon-circle-triangle-' +\n '' + (isRTL ? 'w' : 'e') + '\">' + nextText + '</span></a>'\n : hideIfNoPrevNext ? ''\n : '<a class=\"ui-datepicker-next ui-corner-all ui-state-disabled\" title=\"' + nextText + '\">' +\n '<span class=\"ui-icon ui-icon-circle-triangle-' + (isRTL ? 'w' : 'e') + '\">' + nextText +\n '</span></a>';\n gotoDate = this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today;\n currentText = !navigationAsDateFormat ? currentText :\n this.formatDate(currentText, gotoDate, this._getFormatConfig(inst));\n controls = !inst.inline ?\n '<button type=\"button\" class=\"ui-datepicker-close ui-state-default ui-priority-primary ' +\n 'ui-corner-all\" data-handler=\"hide\" data-event=\"click\">' +\n this._get(inst, 'closeText') + '</button>'\n : '';\n buttonPanel = showButtonPanel ?\n '<div class=\"ui-datepicker-buttonpane ui-widget-content\">' + (isRTL ? controls : '') +\n (this._isInRange(inst, gotoDate) ? '<button type=\"button\" class=\"ui-datepicker-current ' +\n 'ui-state-default ui-priority-secondary ui-corner-all\" data-handler=\"today\" data-event=\"click\"' +\n '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';\n firstDay = parseInt(this._get(inst, 'firstDay'), 10);\n firstDay = isNaN(firstDay) ? 0 : firstDay;\n\n for (row = 0; row < numMonths[0]; row++) {\n this.maxRows = 4;\n\n for (col = 0; col < numMonths[1]; col++) {\n selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));\n\n calender = '';\n\n if (isMultiMonth) {\n calender += '<div class=\"ui-datepicker-group';\n\n if (numMonths[1] > 1) {\n switch (col) {\n case 0: calender += ' ui-datepicker-group-first';\n cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left');\n break;\n\n case numMonths[1] - 1: calender += ' ui-datepicker-group-last';\n cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right');\n break;\n\n default: calender += ' ui-datepicker-group-middle'; cornerClass = '';\n }\n }\n calender += '\">';\n }\n calender += '<div class=\"ui-datepicker-header ' +\n 'ui-widget-header ui-helper-clearfix' + cornerClass + '\">' +\n (/all|left/.test(cornerClass) && parseInt(row, 10) === 0 ? isRTL ? next : prev : '') +\n (/all|right/.test(cornerClass) && parseInt(row, 10) === 0 ? isRTL ? prev : next : '') +\n this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,\n row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers\n '</div><table class=\"ui-datepicker-calendar\"><thead>' +\n '<tr>';\n thead = showWeek ?\n '<th class=\"ui-datepicker-week-col\">' + this._get(inst, 'weekHeader') + '</th>' : '';\n\n for (dow = 0; dow < 7; dow++) { // days of the week\n day = (dow + firstDay) % 7;\n thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ?\n ' class=\"ui-datepicker-week-end\"' : '') + '>' +\n '<span title=\"' + dayNames[day] + '\">' + dayNamesMin[day] + '</span></th>';\n }\n calender += thead + '</tr></thead><tbody>';\n daysInMonth = this._getDaysInMonth(drawYear, drawMonth);\n\n if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {\n inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);\n }\n leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;\n curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate\n numRows = isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows;\n this.maxRows = numRows;\n printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));\n\n for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows\n calender += '<tr>';\n tbody = !showWeek ? '' : '<td class=\"ui-datepicker-week-col\">' +\n this._get(inst, 'calculateWeek')(printDate) + '</td>';\n\n for (dow = 0; dow < 7; dow++) { // create date picker days\n daySettings = beforeShowDay ?\n beforeShowDay.apply(inst.input ? inst.input[0] : null, [printDate]) : [true, ''];\n otherMonth = printDate.getMonth() !== drawMonth;\n unselectable = otherMonth && !selectOtherMonths || !daySettings[0] ||\n minDate && printDate < minDate || maxDate && printDate > maxDate;\n tbody += '<td class=\"' +\n ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends\n (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months\n (printDate.getTime() === selectedDate.getTime() &&\n drawMonth === inst.selectedMonth && inst._keyEvent || // user pressed key\n defaultDate.getTime() === printDate.getTime() &&\n defaultDate.getTime() === selectedDate.getTime() ?\n // or defaultDate is current printedDate and defaultDate is selectedDate\n ' ' + this._dayOverClass : '') + // highlight selected day\n (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled' : '') +\n (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates\n (printDate.getTime() === currentDate.getTime() ? ' ' + this._currentClass : '') +\n (printDate.getDate() === today.getDate() && printDate.getMonth() === today.getMonth() &&\n printDate.getYear() === today.getYear() ? ' ui-datepicker-today' : '')) + '\"' +\n ((!otherMonth || showOtherMonths) && daySettings[2] ?\n ' title=\"' + daySettings[2] + '\"' : '') + // cell title\n (unselectable ? '' : ' data-handler=\"selectDay\" data-event=\"click\" data-month=\"' +\n '' + printDate.getMonth() + '\" data-year=\"' + printDate.getFullYear() + '\"') + '>' +\n (otherMonth && !showOtherMonths ? ' ' : // display for other months\n unselectable ? '<span class=\"ui-state-default\">' + printDate.getDate() + '</span>'\n : '<a class=\"ui-state-default' +\n (printDate.getTime() === today.getTime() ? ' ' : '') +\n (printDate.getTime() === currentDate.getTime() ? ' ui-state-active' : '') +\n (otherMonth ? ' ui-priority-secondary' : '') +\n '\" data-date=\"' + printDate.getDate() + '\" href=\"#\">' +\n printDate.getDate() + '</a>') + '</td>';\n printDate.setDate(printDate.getDate() + 1);\n printDate = this._daylightSavingAdjust(printDate);\n }\n calender += tbody + '</tr>';\n }\n drawMonth++;\n\n if (drawMonth > 11) {\n drawMonth = 0;\n drawYear++;\n }\n calender += '</tbody></table>' + (isMultiMonth ? '</div>' +\n (numMonths[0] > 0 && col === numMonths[1] - 1 ? '<div class=\"ui-datepicker-row-break\"></div>'\n : '') : '');\n group += calender;\n }\n html += group;\n }\n html += buttonPanel + ($.ui.ie6 && !inst.inline ?\n '<iframe src=\"javascript:false;\" class=\"ui-datepicker-cover\" frameborder=\"0\"></iframe>' : '');\n inst._keyEvent = false;\n\n return html;\n };\n },\n\n /**\n * Set current date if the date is not set\n * @protected\n * @param {Object} element\n */\n _setCurrentDate: function (element) {\n if (!element.val()) {\n element[this._picker()]('setTimezoneDate').val('');\n }\n },\n\n /**\n * Init Datetimepicker\n * @protected\n * @param {Object} element\n */\n _initPicker: function (element) {\n var picker = element[this._picker()](this.options),\n pickerButtonText = picker.next('.ui-datepicker-trigger')\n .find('img')\n .attr('title');\n\n picker.next('.ui-datepicker-trigger')\n .addClass('v-middle')\n .text('') // Remove jQuery UI datepicker generated image\n .append('<span>' + pickerButtonText + '</span>');\n\n $(element).attr('autocomplete', this.options.autoComplete ? 'on' : 'off');\n\n this._setCurrentDate(element);\n },\n\n /**\n * destroy instance of datetimepicker\n */\n _destroy: function () {\n this.element[this._picker()]('destroy');\n this._super();\n },\n\n /**\n * Method is kept for backward compatibility and unit-tests acceptance\n * see \\mage\\calendar\\calendar-test.js\n * @return {Object} date\n */\n getTimezoneDate: function () {\n return datepickerPrototype._getTimezoneDate.call(this, this.options);\n }\n });\n\n calendarBasePrototype = $.mage.calendar.prototype;\n\n /**\n * Extension for Calendar - date and time format convert functionality\n * @var {Object}\n */\n $.widget('mage.calendar', $.extend({}, calendarBasePrototype,\n /** @lends {$.mage.calendar.prototype} */ {\n /**\n * key - backend format, value - jquery format\n * @type {Object}\n * @private\n */\n dateTimeFormat: {\n date: {\n 'EEEE': 'DD',\n 'EEE': 'D',\n 'EE': 'D',\n 'E': 'D',\n 'D': 'o',\n 'MMMM': 'MM',\n 'MMM': 'M',\n 'MM': 'mm',\n 'M': 'mm',\n 'yyyy': 'yy',\n 'y': 'yy',\n 'Y': 'yy',\n 'yy': 'yy' // Always long year format on frontend\n },\n time: {\n 'a': 'TT'\n }\n },\n\n /**\n * Add Date and Time converting to _create method\n * @protected\n */\n _create: function () {\n if (this.options.dateFormat) {\n this.options.dateFormat = this._convertFormat(this.options.dateFormat, 'date');\n }\n\n if (this.options.timeFormat) {\n this.options.timeFormat = this._convertFormat(this.options.timeFormat, 'time');\n }\n calendarBasePrototype._create.apply(this, arguments);\n },\n\n /**\n * Converting date or time format\n * @protected\n * @param {String} format\n * @param {String} type\n * @return {String}\n */\n _convertFormat: function (format, type) {\n var symbols = format.match(/([a-z]+)/ig),\n separators = format.match(/([^a-z]+)/ig),\n self = this,\n convertedFormat = '';\n\n if (symbols) {\n $.each(symbols, function (key, val) {\n convertedFormat +=\n (self.dateTimeFormat[type][val] || val) +\n (separators[key] || '');\n });\n }\n\n return convertedFormat;\n }\n })\n );\n\n /**\n * Widget dateRange\n * @extends $.mage.calendar\n */\n $.widget('mage.dateRange', $.mage.calendar, {\n\n /**\n * creates two instances of datetimepicker for date range selection\n * @protected\n */\n _initPicker: function () {\n var from,\n to;\n\n if (this.options.from && this.options.to) {\n from = this.element.find('#' + this.options.from.id);\n to = this.element.find('#' + this.options.to.id);\n this.options.onSelect = $.proxy(function (selectedDate) {\n to[this._picker()]('option', 'minDate', selectedDate);\n }, this);\n $.mage.calendar.prototype._initPicker.call(this, from);\n from.on('change', $.proxy(function () {\n to[this._picker()]('option', 'minDate', from[this._picker()]('getDate'));\n }, this));\n this.options.onSelect = $.proxy(function (selectedDate) {\n from[this._picker()]('option', 'maxDate', selectedDate);\n }, this);\n $.mage.calendar.prototype._initPicker.call(this, to);\n to.on('change', $.proxy(function () {\n from[this._picker()]('option', 'maxDate', to[this._picker()]('getDate'));\n }, this));\n }\n },\n\n /**\n * destroy two instances of datetimepicker\n */\n _destroy: function () {\n if (this.options.from) {\n this.element.find('#' + this.options.from.id)[this._picker()]('destroy');\n }\n\n if (this.options.to) {\n this.element.find('#' + this.options.to.id)[this._picker()]('destroy');\n }\n this._super();\n }\n });\n\n // Overrides the \"today\" button functionality to select today's date when clicked.\n $.datepicker._gotoTodayOriginal = $.datepicker._gotoToday;\n\n /**\n * overwrite jQuery UI _showDatepicker function for proper HTML generation conditions.\n *\n */\n $.datepicker._showDatepickerOriginal = $.datepicker._showDatepicker;\n\n /**\n * Triggers original method showDataPicker for rendering calendar\n * @param {HTMLObject} input\n * @private\n */\n $.datepicker._showDatepicker = function (input) {\n if (!input.disabled) {\n $.datepicker._showDatepickerOriginal.call(this, input);\n }\n };\n\n /**\n * _gotoToday\n * @param {Object} el\n */\n $.datepicker._gotoToday = function (el) {\n //Set date/time according to timezone offset\n $(el).datepicker('setTimezoneDate')\n // To ensure that user can re-select date field without clicking outside it first.\n .trigger('blur').trigger('change');\n };\n\n return {\n dateRange: $.mage.dateRange,\n calendar: $.mage.calendar\n };\n});\n","mage/multiselect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'jquery',\n 'text!mage/multiselect.html',\n 'Magento_Ui/js/modal/alert',\n 'jquery-ui-modules/widget',\n 'jquery/editableMultiselect/js/jquery.multiselect'\n], function (_, $, searchTemplate, alert) {\n 'use strict';\n\n $.widget('mage.multiselect2', {\n options: {\n mselectContainer: 'section.mselect-list',\n mselectItemsWrapperClass: 'mselect-items-wrapper',\n mselectCheckedClass: 'mselect-checked',\n containerClass: 'paginated',\n searchInputClass: 'admin__action-multiselect-search',\n selectedItemsCountClass: 'admin__action-multiselect-items-selected',\n currentPage: 1,\n lastAppendValue: 0,\n updateDelay: 1000,\n optionsLoaded: false\n },\n\n /** @inheritdoc */\n _create: function () {\n $.fn.multiselect.call(this.element, this.options);\n },\n\n /** @inheritdoc */\n _init: function () {\n this.domElement = this.element.get(0);\n\n this.$container = $(this.options.mselectContainer);\n this.$wrapper = this.$container.find('.' + this.options.mselectItemsWrapperClass);\n this.$item = this.$wrapper.find('div').first();\n this.selectedValues = [];\n this.values = {};\n\n this.$container.addClass(this.options.containerClass).prepend(searchTemplate);\n this.$input = this.$container.find('.' + this.options.searchInputClass);\n this.$selectedCounter = this.$container.find('.' + this.options.selectedItemsCountClass);\n this.filter = '';\n\n if (this.domElement.options.length) {\n this._setLastAppendOption(this.domElement.options[this.domElement.options.length - 1].value);\n }\n\n this._initElement();\n this._events();\n },\n\n /**\n * Leave only saved/selected options in select element.\n *\n * @private\n */\n _initElement: function () {\n this.element.empty();\n _.each(this.options.selectedValues, function (value) {\n this._createSelectedOption({\n value: value,\n label: value\n });\n }, this);\n },\n\n /**\n * Attach required events.\n *\n * @private\n */\n _events: function () {\n var onKeyUp = _.debounce(this.onKeyUp, this.options.updateDelay);\n\n _.bindAll(this, 'onScroll', 'onCheck', 'onOptionsChange');\n\n this.$wrapper.on('scroll', this.onScroll);\n this.$wrapper.on('change.mselectCheck', '[type=checkbox]', this.onCheck);\n this.$input.on('keyup', _.bind(onKeyUp, this));\n this.element.on('change.hiddenSelect', this.onOptionsChange);\n },\n\n /**\n * Behaves multiselect scroll.\n */\n onScroll: function () {\n var height = this.$wrapper.height(),\n scrollHeight = this.$wrapper.prop('scrollHeight'),\n scrollTop = Math.ceil(this.$wrapper.prop('scrollTop'));\n\n if (!this.options.optionsLoaded && scrollHeight - height <= scrollTop) {\n this.loadOptions();\n }\n },\n\n /**\n * Behaves keyup event on input search\n */\n onKeyUp: function () {\n if (this.getSearchCriteria() === this.filter) {\n return false;\n }\n\n this.setFilter();\n this.clearMultiselectOptions();\n this.setCurrentPage(0);\n this.loadOptions();\n },\n\n /**\n * Callback for select change event\n */\n onOptionsChange: function () {\n this.selectedValues = _.map(this.domElement.options, function (option) {\n this.values[option.value] = true;\n\n return option.value;\n }, this);\n\n this._updateSelectedCounter();\n },\n\n /**\n * Overrides native check behaviour.\n *\n * @param {Event} event\n */\n onCheck: function (event) {\n var checkbox = event.target,\n option = {\n value: checkbox.value,\n label: $(checkbox).parent('label').text()\n };\n\n checkbox.checked ? this._createSelectedOption(option) : this._removeSelectedOption(option);\n event.stopPropagation();\n },\n\n /**\n * Show error message.\n *\n * @param {String} message\n */\n onError: function (message) {\n alert({\n content: message\n });\n },\n\n /**\n * Updates current filter state.\n */\n setFilter: function () {\n this.filter = this.getSearchCriteria() || '';\n },\n\n /**\n * Reads search input value.\n *\n * @return {String}\n */\n getSearchCriteria: function () {\n return this.$input.val().trim();\n },\n\n /**\n * Load options data.\n */\n loadOptions: function () {\n var nextPage = this.getCurrentPage() + 1;\n\n this.$wrapper.trigger('processStart');\n this.$input.prop('disabled', true);\n\n $.get(this.options.nextPageUrl, {\n p: nextPage,\n s: this.filter\n })\n .done(function (response) {\n if (response.success) {\n this.appendOptions(response.result);\n this.setCurrentPage(nextPage);\n } else {\n this.onError(response.errorMessage);\n }\n }.bind(this))\n .always(function () {\n this.$wrapper.trigger('processStop');\n this.$input.prop('disabled', false);\n\n if (this.filter) {\n this.$input.focus();\n }\n }.bind(this));\n },\n\n /**\n * Append loaded options\n *\n * @param {Array} options\n */\n appendOptions: function (options) {\n var divOptions = [];\n\n if (!options.length) {\n return false;\n }\n\n if (this.isOptionsLoaded(options)) {\n return;\n }\n\n options.forEach(function (option) {\n if (!this.values[option.value]) {\n this.values[option.value] = true;\n option.selected = this._isOptionSelected(option);\n divOptions.push(this._createMultiSelectOption(option));\n this._setLastAppendOption(option.value);\n }\n }, this);\n\n this.$wrapper.append(divOptions);\n },\n\n /**\n * Clear multiselect options\n */\n clearMultiselectOptions: function () {\n this._setLastAppendOption(0);\n this.values = {};\n this.$wrapper.empty();\n },\n\n /**\n * Checks if all options are already loaded\n *\n * @return {Boolean}\n */\n isOptionsLoaded: function (options) {\n this.options.optionsLoaded = this.options.lastAppendValue === options[options.length - 1].value;\n\n return this.options.optionsLoaded;\n },\n\n /**\n * Setter for current page.\n *\n * @param {Number} page\n */\n setCurrentPage: function (page) {\n this.options.currentPage = page;\n },\n\n /**\n * Getter for current page.\n *\n * @return {Number}\n */\n getCurrentPage: function () {\n return this.options.currentPage;\n },\n\n /**\n * Creates new selected option for select element\n *\n * @param {Object} option - option object\n * @param {String} option.value - option value\n * @param {String} option.label - option label\n * @private\n */\n _createSelectedOption: function (option) {\n var selectOption = new Option(option.label, option.value, false, true);\n\n this.element.append(selectOption);\n this.selectedValues.push(option.value);\n this._updateSelectedCounter();\n\n return selectOption;\n },\n\n /**\n * Remove passed option from select element\n *\n * @param {Object} option - option object\n * @param {String} option.value - option value\n * @param {String} option.label - option label\n * @return {Object} option\n * @private\n */\n _removeSelectedOption: function (option) {\n var unselectedOption = _.findWhere(this.domElement.options, {\n value: option.value\n });\n\n if (!_.isUndefined(unselectedOption)) {\n this.domElement.remove(unselectedOption.index);\n this.selectedValues.splice(_.indexOf(this.selectedValues, option.value), 1);\n this._updateSelectedCounter();\n }\n\n return unselectedOption;\n },\n\n /**\n * Creates new DIV option for multiselect widget\n *\n * @param {Object} option - option object\n * @param {String} option.value - option value\n * @param {String} option.label - option label\n * @param {Boolean} option.selected - is option selected\n * @private\n */\n _createMultiSelectOption: function (option) {\n var item = this.$item.clone(),\n checkbox = item.find('input'),\n isSelected = !!option.selected;\n\n checkbox.val(option.value)\n .prop('checked', isSelected)\n .toggleClass(this.options.mselectCheckedClass, isSelected);\n\n item.find('label > span').text(option.label);\n\n return item;\n },\n\n /**\n * Checks if passed option should be selected\n *\n * @param {Object} option - option object\n * @param {String} option.value - option value\n * @param {String} option.label - option label\n * @param {Boolean} option.selected - is option selected\n * @return {Boolean}\n * @private\n */\n _isOptionSelected: function (option) {\n return !!~this.selectedValues.indexOf(option.value);\n },\n\n /**\n * Saves last added option value.\n *\n * @param {Number} value\n * @private\n */\n _setLastAppendOption: function (value) {\n this.options.lastAppendValue = value;\n },\n\n /**\n * Updates counter of selected items.\n *\n * @private\n */\n _updateSelectedCounter: function () {\n this.$selectedCounter.text(this.selectedValues.length);\n }\n });\n\n return $.mage.multiselect2;\n});\n","mage/polyfill.js":"(function (root, doc) {\n 'use strict';\n\n var Storage;\n\n try {\n if (!root.localStorage || !root.sessionStorage) {\n throw new Error();\n }\n\n localStorage.setItem('storage_test', 1);\n localStorage.removeItem('storage_test');\n } catch (e) {\n /**\n * Returns a storage object to shim local or sessionStorage\n * @param {String} type - either 'local' or 'session'\n */\n Storage = function (type) {\n var data;\n\n /**\n * Creates a cookie\n * @param {String} name\n * @param {String} value\n * @param {Integer} days\n */\n function createCookie(name, value, days) {\n var date, expires;\n\n if (days) {\n date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toGMTString();\n } else {\n expires = '';\n }\n doc.cookie = name + '=' + value + expires + '; path=/';\n }\n\n /**\n * Reads value of a cookie\n * @param {String} name\n */\n function readCookie(name) {\n var nameEQ = name + '=',\n ca = doc.cookie.split(';'),\n i = 0,\n c;\n\n for (i = 0; i < ca.length; i++) {\n c = ca[i];\n\n while (c.charAt(0) === ' ') {\n c = c.substring(1, c.length);\n }\n\n if (c.indexOf(nameEQ) === 0) {\n return c.substring(nameEQ.length, c.length);\n }\n }\n\n return null;\n }\n\n /**\n * Returns cookie name based upon the storage type.\n * If this is session storage, the function returns a unique cookie per tab\n */\n function getCookieName() {\n\n if (type !== 'session') {\n return 'localstorage';\n }\n\n if (!root.name) {\n root.name = new Date().getTime();\n }\n\n return 'sessionStorage' + root.name;\n }\n\n /**\n * Sets storage cookie to a data object\n * @param {Object} dataObject\n */\n function setData(dataObject) {\n data = encodeURIComponent(JSON.stringify(dataObject));\n createCookie(getCookieName(), data, 365);\n }\n\n /**\n * Clears value of cookie data\n */\n function clearData() {\n createCookie(getCookieName(), '', 365);\n }\n\n /**\n * @returns value of cookie data\n */\n function getData() {\n var dataResponse = readCookie(getCookieName());\n\n return dataResponse ? JSON.parse(decodeURIComponent(dataResponse)) : {};\n }\n\n data = getData();\n\n return {\n length: 0,\n\n /**\n * Clears data from storage\n */\n clear: function () {\n data = {};\n this.length = 0;\n clearData();\n },\n\n /**\n * Gets an item from storage\n * @param {String} key\n */\n getItem: function (key) {\n return data[key] === undefined ? null : data[key];\n },\n\n /**\n * Gets an item by index from storage\n * @param {Integer} i\n */\n key: function (i) {\n var ctr = 0,\n k;\n\n for (k in data) {\n\n if (data.hasOwnProperty(k)) {\n\n // eslint-disable-next-line max-depth\n if (ctr.toString() === i.toString()) {\n return k;\n }\n ctr++;\n }\n }\n\n return null;\n },\n\n /**\n * Removes an item from storage\n * @param {String} key\n */\n removeItem: function (key) {\n delete data[key];\n this.length--;\n setData(data);\n },\n\n /**\n * Sets an item from storage\n * @param {String} key\n * @param {String} value\n */\n setItem: function (key, value) {\n data[key] = value.toString();\n this.length++;\n setData(data);\n }\n };\n };\n\n root.localStorage.prototype = root.localStorage = new Storage('local');\n root.sessionStorage.prototype = root.sessionStorage = new Storage('session');\n }\n})(window, document);\n","mage/accordion.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'mage/tabs'\n], function ($, tabs) {\n 'use strict';\n\n $.widget('mage.accordion', tabs, {\n options: {\n active: [0],\n multipleCollapsible: false,\n openOnFocus: false\n },\n\n /**\n * @private\n */\n _callCollapsible: function () {\n var self = this,\n disabled = false,\n active = false;\n\n if (typeof this.options.active === 'string') {\n this.options.active = this.options.active.split(' ').map(function (item) {\n return parseInt(item, 10);\n });\n }\n\n $.each(this.collapsibles, function (i) {\n disabled = active = false;\n\n if ($.inArray(i, self.options.disabled) !== -1) {\n disabled = true;\n }\n\n if ($.inArray(i, self.options.active) !== -1) {\n active = true;\n }\n self._instantiateCollapsible(this, i, active, disabled);\n });\n },\n\n /**\n * Overwrites default functionality to provide the option to activate/deactivate multiple sections simultaneous\n * @param {*} action\n * @param {*} index\n * @private\n */\n _toggleActivate: function (action, index) {\n var self = this;\n\n if (Array.isArray(index && this.options.multipleCollapsible)) {\n $.each(index, function () {\n self.collapsibles.eq(this).collapsible(action);\n });\n } else if (index === undefined && this.options.multipleCollapsible) {\n this.collapsibles.collapsible(action);\n } else {\n this._super(action, index);\n }\n },\n\n /**\n * If the Accordion allows multiple section to be active at the same time, if deep linking is used\n * sections that don't contain the id from anchor shouldn't be closed, otherwise the accordion uses the\n * tabs behavior\n * @private\n */\n _handleDeepLinking: function () {\n if (!this.options.multipleCollapsible) {\n this._super();\n }\n },\n\n /**\n * Prevent default behavior that closes the other sections when one gets activated if the Accordion allows\n * multiple sections simultaneous\n * @private\n */\n _closeOthers: function () {\n var self = this;\n\n if (!this.options.multipleCollapsible) {\n $.each(this.collapsibles, function () {\n $(this).on('beforeOpen', function () {\n self.collapsibles.not(this).collapsible('deactivate');\n });\n });\n }\n $.each(this.collapsibles, function () {\n $(this).on('beforeOpen', function () {\n var section = $(this);\n\n section.addClass('allow').prevAll().addClass('allow');\n section.nextAll().removeClass('allow');\n });\n });\n }\n });\n\n return $.mage.accordion;\n});\n","mage/bootstrap.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'mage/apply/main',\n 'Magento_Ui/js/lib/knockout/bootstrap'\n], function ($, mage) {\n 'use strict';\n\n $.ajaxSetup({\n cache: false\n });\n\n /**\n * Init all components defined via data-mage-init attribute.\n * Execute in a separate task to prevent main thread blocking.\n */\n setTimeout(mage.apply);\n});\n","mage/template.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore'\n], function (_) {\n 'use strict';\n\n /**\n * Checks if provided string is a valid DOM selector.\n *\n * @param {String} selector - Selector to be checked.\n * @returns {Boolean}\n */\n function isSelector(selector) {\n try {\n document.querySelector(selector);\n\n return true;\n } catch (e) {\n return false;\n }\n }\n\n /**\n * Unescapes characters used in underscore templates.\n *\n * @param {String} str - String to be processed.\n * @returns {String}\n */\n function unescape(str) {\n return str.replace(/<%|%3C%/g, '<%').replace(/%>|%%3E/g, '%>');\n }\n\n /**\n * If 'tmpl' is a valid selector, returns target node's innerHTML if found.\n * Else, returns empty string and emits console warning.\n * If 'tmpl' is not a selector, returns 'tmpl' as is.\n *\n * @param {String} tmpl\n * @returns {String}\n */\n function getTmplString(tmpl) {\n if (isSelector(tmpl)) {\n tmpl = document.querySelector(tmpl);\n\n if (tmpl) {\n tmpl = tmpl.innerHTML.trim();\n } else {\n console.warn('No template was found by selector: ' + tmpl);\n\n tmpl = '';\n }\n }\n\n return unescape(tmpl);\n }\n\n /**\n * Compiles or renders template provided either\n * by selector or by the template string.\n *\n * @param {String} tmpl - Template string or selector.\n * @param {(Object|Array|Function)} [data] - Data object with which to render template.\n * @returns {String|Function}\n */\n return function (tmpl, data) {\n var render;\n\n tmpl = getTmplString(tmpl);\n render = _.template(tmpl);\n\n return !_.isUndefined(data) ?\n render(data) :\n render;\n };\n});\n","mage/translate.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'mage/mage',\n 'mageTranslationDictionary',\n 'underscore'\n], function ($, mage, dictionary, _) {\n 'use strict';\n\n $.extend(true, $, {\n mage: {\n translate: (function () {\n /**\n * Key-value translations storage\n * @type {Object}\n * @private\n */\n var _data = dictionary;\n\n return {\n /**\n * Add new translation (two string parameters) or several translations (object)\n */\n add: function () {\n if (arguments.length > 1) {\n _data[arguments[0]] = arguments[1];\n } else if (typeof arguments[0] === 'object') {\n $.extend(_data, arguments[0]);\n }\n },\n\n /**\n * Make a translation with parsing (to handle case when _data represents tuple)\n * @param {String} text\n * @return {String}\n */\n translate: function (text) {\n return typeof _data[text] !== 'undefined' ? _data[text] : text;\n }\n };\n }())\n }\n });\n $.mage.__ = $.proxy($.mage.translate.translate, $.mage.translate);\n\n // Provide i18n wrapper to be used in underscore templates for translation\n _.extend(_, {\n /**\n * Make a translation using $.mage.__\n *\n * @param {String} text\n * @return {String}\n */\n i18n: function (text) {\n return $.mage.__(text);\n }\n });\n\n return $.mage.__;\n});\n","mage/tabs.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'jquery-ui-modules/widget',\n 'jquery/ui-modules/widgets/tabs',\n 'mage/mage',\n 'mage/collapsible'\n], function ($) {\n 'use strict';\n\n $.widget('mage.tabs', {\n options: {\n active: 0,\n disabled: [],\n openOnFocus: true,\n collapsible: false,\n collapsibleElement: '[data-role=collapsible]',\n header: '[data-role=title]',\n content: '[data-role=content]',\n trigger: '[data-role=trigger]',\n closedState: null,\n openedState: null,\n disabledState: null,\n ajaxUrlElement: '[data-ajax=true]',\n ajaxContent: false,\n loadingClass: null,\n saveState: false,\n animate: false,\n icons: {\n activeHeader: null,\n header: null\n }\n },\n\n /**\n * @private\n */\n _create: function () {\n if (typeof this.options.disabled === 'string') {\n this.options.disabled = this.options.disabled.split(' ').map(function (item) {\n return parseInt(item, 10);\n });\n }\n this._processPanels();\n this._handleDeepLinking();\n this._processTabIndex();\n this._closeOthers();\n this._bind();\n },\n\n /**\n * @private\n */\n _destroy: function () {\n $.each(this.collapsibles, function () {\n $(this).collapsible('destroy');\n });\n },\n\n /**\n * If deep linking is used, all sections must be closed but the one that contains the anchor.\n * @private\n */\n _handleDeepLinking: function () {\n var self = this,\n anchor = window.location.hash,\n isValid = $.mage.isValidSelector(anchor),\n anchorId = anchor.replace('#', '');\n\n if (anchor && isValid) {\n $.each(self.contents, function (i) {\n if ($(this).attr('id') === anchorId || $(this).find('#' + anchorId).length) {\n self.collapsibles.not(self.collapsibles.eq(i)).collapsible('forceDeactivate');\n\n return false;\n }\n });\n }\n },\n\n /**\n * When the widget gets instantiated, the first tab that is not disabled receive focusable property\n * All tabs receive tabIndex 0\n * @private\n */\n _processTabIndex: function () {\n var self = this;\n\n self.triggers.attr('tabIndex', 0);\n $.each(this.collapsibles, function (i) {\n self.triggers.attr('tabIndex', 0);\n self.triggers.eq(i).attr('tabIndex', 0);\n });\n },\n\n /**\n * Prepare the elements for instantiating the collapsible widget\n * @private\n */\n _processPanels: function () {\n var isNotNested = this._isNotNested.bind(this);\n\n this.contents = this.element\n .find(this.options.content)\n .filter(isNotNested);\n\n this.collapsibles = this.element\n .find(this.options.collapsibleElement)\n .filter(isNotNested);\n\n this.collapsibles\n .attr('role', 'presentation')\n .parent()\n .attr('role', 'tablist');\n\n this.headers = this.element\n .find(this.options.header)\n .filter(isNotNested);\n\n if (this.headers.length === 0) {\n this.headers = this.collapsibles;\n }\n this.triggers = this.element\n .find(this.options.trigger)\n .filter(isNotNested);\n\n if (this.triggers.length === 0) {\n this.triggers = this.headers;\n }\n this._callCollapsible();\n },\n\n /**\n * Checks if element is not in nested container to keep the correct scope of collapsible\n * @param {Number} index\n * @param {HTMLElement} element\n * @private\n * @return {Boolean}\n */\n _isNotNested: function (index, element) {\n var parentContent = $(element).parents(this.options.content);\n\n return !parentContent.length || !this.element.find(parentContent).length;\n },\n\n /**\n * Setting the disabled and active tabs and calling instantiation of collapsible\n * @private\n */\n _callCollapsible: function () {\n var self = this,\n disabled = false,\n active = false;\n\n $.each(this.collapsibles, function (i) {\n disabled = active = false;\n\n if ($.inArray(i, self.options.disabled) !== -1) {\n disabled = true;\n }\n\n if (i === self.options.active) {\n active = true;\n }\n self._instantiateCollapsible(this, i, active, disabled);\n });\n },\n\n /**\n * Instantiate collapsible.\n *\n * @param {HTMLElement} element\n * @param {Number} index\n * @param {*} active\n * @param {*} disabled\n * @private\n */\n _instantiateCollapsible: function (element, index, active, disabled) {\n $(element).collapsible(\n $.extend({}, this.options, {\n active: active,\n disabled: disabled,\n header: this.headers.eq(index),\n content: this.contents.eq(index),\n trigger: this.triggers.eq(index)\n })\n );\n },\n\n /**\n * Adding callback to close others tabs when one gets opened\n * @private\n */\n _closeOthers: function () {\n var self = this;\n\n $.each(this.collapsibles, function () {\n $(this).on('beforeOpen', function () {\n self.collapsibles.not(this).collapsible('forceDeactivate');\n });\n });\n },\n\n /**\n * @param {*} index\n */\n activate: function (index) {\n this._toggleActivate('activate', index);\n },\n\n /**\n * @param {*} index\n */\n deactivate: function (index) {\n this._toggleActivate('deactivate', index);\n },\n\n /**\n * @param {*} action\n * @param {*} index\n * @private\n */\n _toggleActivate: function (action, index) {\n this.collapsibles.eq(index).collapsible(action);\n },\n\n /**\n * @param {*} index\n */\n disable: function (index) {\n this._toggleEnable('disable', index);\n },\n\n /**\n * @param {*} index\n */\n enable: function (index) {\n this._toggleEnable('enable', index);\n },\n\n /**\n * @param {*} action\n * @param {*} index\n * @private\n */\n _toggleEnable: function (action, index) {\n var self = this;\n\n if (Array.isArray(index)) {\n $.each(index, function () {\n self.collapsibles.eq(this).collapsible(action);\n });\n } else if (index === undefined) {\n this.collapsibles.collapsible(action);\n } else {\n this.collapsibles.eq(index).collapsible(action);\n }\n },\n\n /**\n * @param {jQuery.Event} event\n * @private\n */\n _keydown: function (event) {\n var self = this,\n keyCode, toFocus, toFocusIndex, enabledTriggers, length, currentIndex, nextToFocus;\n\n if (event.altKey || event.ctrlKey) {\n return;\n }\n keyCode = $.ui.keyCode;\n toFocus = false;\n enabledTriggers = [];\n\n $.each(this.triggers, function () {\n if (!self.collapsibles.eq(self.triggers.index($(this))).collapsible('option', 'disabled')) {\n enabledTriggers.push(this);\n }\n });\n length = $(enabledTriggers).length;\n currentIndex = $(enabledTriggers).index(event.target);\n\n /**\n * @param {String} direction\n * @return {*}\n */\n nextToFocus = function (direction) {\n if (length > 0) {\n if (direction === 'right') {\n toFocusIndex = (currentIndex + 1) % length;\n } else {\n toFocusIndex = (currentIndex + length - 1) % length;\n }\n\n return enabledTriggers[toFocusIndex];\n }\n\n return event.target;\n };\n\n switch (event.keyCode) {\n case keyCode.RIGHT:\n case keyCode.DOWN:\n toFocus = nextToFocus('right');\n break;\n\n case keyCode.LEFT:\n case keyCode.UP:\n toFocus = nextToFocus('left');\n break;\n\n case keyCode.HOME:\n toFocus = enabledTriggers[0];\n break;\n\n case keyCode.END:\n toFocus = enabledTriggers[length - 1];\n break;\n }\n\n if (toFocus) {\n toFocusIndex = this.triggers.index(toFocus);\n $(event.target).attr('tabIndex', -1);\n $(toFocus).attr('tabIndex', 0);\n toFocus.focus();\n\n if (this.options.openOnFocus) {\n this.activate(toFocusIndex);\n }\n event.preventDefault();\n }\n },\n\n /**\n * @private\n */\n _bind: function () {\n var events = {\n keydown: '_keydown'\n };\n\n this._off(this.triggers);\n this._on(this.triggers, events);\n }\n });\n\n return $.mage.tabs;\n});\n","mage/popup-window.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'jquery-ui-modules/widget'\n], function ($) {\n 'use strict';\n\n $.widget('mage.popupWindow', {\n options: {\n centerBrowser: 0, // center window over browser window? {1 (YES) or 0 (NO)}. overrides top and left\n centerScreen: 0, // center window over entire screen? {1 (YES) or 0 (NO)}. overrides top and left\n height: 500, // sets the height in pixels of the window.\n left: 0, // left position when the window appears.\n location: 0, // determines whether the address bar is displayed {1 (YES) or 0 (NO)}.\n menubar: 0, // determines whether the menu bar is displayed {1 (YES) or 0 (NO)}.\n resizable: 0, // whether the window can be resized {1 (YES) or 0 (NO)}.\n scrollbars: 0, // determines whether scrollbars appear on the window {1 (YES) or 0 (NO)}.\n status: 0, // whether a status line appears at the bottom of the window {1 (YES) or 0 (NO)}.\n width: 500, // sets the width in pixels of the window.\n windowName: null, // name of window set from the name attribute of the element that invokes the click\n windowURL: null, // url used for the popup\n top: 0, // top position when the window appears.\n toolbar: 0 // determines whether a toolbar is displayed {1 (YES) or 0 (NO)}.\n },\n\n /**\n * @private\n */\n _create: function () {\n this.element.on('click', $.proxy(this._openPopupWindow, this));\n },\n\n /**\n * @param {jQuery.Event} event\n * @private\n */\n _openPopupWindow: function (event) {\n var element = $(event.target),\n settings = this.options,\n windowFeatures =\n 'height=' + settings.height +\n ',width=' + settings.width +\n ',toolbar=' + settings.toolbar +\n ',scrollbars=' + settings.scrollbars +\n ',status=' + settings.status +\n ',resizable=' + settings.resizable +\n ',location=' + settings.location +\n ',menuBar=' + settings.menubar,\n centeredX,\n centeredY;\n\n settings.windowName = settings.windowName || element.attr('name');\n settings.windowURL = settings.windowURL || element.attr('href');\n\n if (settings.centerBrowser) {\n centeredY = window.screenY + (window.outerHeight / 2 - settings.height / 2);\n centeredX = window.screenX + (window.outerWidth / 2 - settings.width / 2);\n windowFeatures += ',left=' + centeredX + ',top=' + centeredY;\n } else if (settings.centerScreen) {\n centeredY = (screen.height - settings.height) / 2;\n centeredX = (screen.width - settings.width) / 2;\n windowFeatures += ',left=' + centeredX + ',top=' + centeredY;\n } else {\n windowFeatures += ',left=' + settings.left + ',top=' + settings.top;\n }\n\n window.open(settings.windowURL, settings.windowName, windowFeatures).focus();\n event.preventDefault();\n }\n });\n\n return $.mage.popupWindow;\n});\n","mage/loader_old.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'mage/template',\n 'jquery-ui-modules/widget',\n 'mage/translate'\n], function ($, mageTemplate) {\n 'use strict';\n\n $.widget('mage.loader', {\n loaderStarted: 0,\n spinner: $(undefined),\n options: {\n icon: '',\n texts: {\n loaderText: $.mage.__('Please wait...'),\n imgAlt: $.mage.__('Loading...')\n },\n template: '<div class=\"loading-mask\" data-role=\"loader\">' +\n '<div class=\"popup popup-loading\">' +\n '<div class=\"popup-inner\">' +\n '<% if (data.icon) { %>' +\n '<img ' +\n '<% if (data.texts.imgAlt) { %>alt=\"<%- data.texts.imgAlt %>\"<% } %> ' +\n 'src=\"<%- data.icon %>\"><% } %>' +\n '<% if (data.texts.loaderText) { %><%- data.texts.loaderText %><% } %>' +\n '</div>' +\n '</div>' +\n '</div>'\n },\n\n /**\n * Loader creation\n * @protected\n */\n _create: function () {\n this._bind();\n },\n\n /**\n * Bind on ajax events\n * @protected\n */\n _bind: function () {\n this._on({\n 'processStop': 'hide',\n 'processStart': 'show',\n 'show.loader': 'show',\n 'hide.loader': 'hide',\n 'contentUpdated.loader': '_contentUpdated'\n });\n },\n\n /**\n * Verify loader present after content updated\n *\n * This will be cleaned up by the task MAGETWO-11070\n *\n * @param {jQuery.Event} e\n * @private\n */\n _contentUpdated: function (e) {\n this.show(e);\n },\n\n /**\n * Show loader\n */\n show: function (e, ctx) {\n this._render();\n this.loaderStarted++;\n this.spinner.show();\n\n if (ctx) {\n this.spinner\n .css({\n width: ctx.outerWidth(),\n height: ctx.outerHeight(),\n position: 'absolute'\n })\n .position({\n my: 'top left',\n at: 'top left',\n of: ctx\n });\n }\n\n return false;\n },\n\n /**\n * Hide loader\n */\n hide: function () {\n if (this.loaderStarted > 0) {\n this.loaderStarted--;\n\n if (this.loaderStarted === 0) {\n this.spinner.hide();\n }\n }\n\n return false;\n },\n\n /**\n * Render loader\n * @protected\n */\n _render: function () {\n var tmpl;\n\n if (this.spinner.length === 0) {\n tmpl = mageTemplate(this.options.template, {\n data: this.options\n });\n\n this.spinner = $(tmpl);\n }\n\n this.element.prepend(this.spinner);\n },\n\n /**\n * Destroy loader\n */\n _destroy: function () {\n this.spinner.remove();\n }\n });\n\n /**\n * This widget takes care of registering the needed loader listeners on the body\n */\n $.widget('mage.loaderAjax', {\n options: {\n defaultContainer: '[data-container=body]'\n },\n\n /**\n * @private\n */\n _create: function () {\n this._bind();\n // There should only be one instance of this widget, and it should be attached\n // to the body only. Having it on the page twice will trigger multiple processStarts.\n if (window.console && !this.element.is(this.options.defaultContainer) && $.mage.isDevMode(undefined)) {\n console.warn('This widget is intended to be attached to the body, not below.');\n }\n },\n\n /**\n * @private\n */\n _bind: function () {\n $(document).on({\n 'ajaxSend': this._onAjaxSend.bind(this),\n 'ajaxComplete': this._onAjaxComplete.bind(this)\n });\n },\n\n /**\n * @param {Object} loaderContext\n * @return {*}\n * @private\n */\n _getJqueryObj: function (loaderContext) {\n var ctx;\n\n // Check to see if context is jQuery object or not.\n if (loaderContext) {\n if (loaderContext.jquery) {\n ctx = loaderContext;\n } else {\n ctx = $(loaderContext);\n }\n } else {\n ctx = $('[data-container=\"body\"]');\n }\n\n return ctx;\n },\n\n /**\n * @param {jQuery.Event} e\n * @param {Object} jqxhr\n * @param {Object} settings\n * @private\n */\n _onAjaxSend: function (e, jqxhr, settings) {\n var ctx;\n\n if (settings && settings.showLoader) {\n ctx = this._getJqueryObj(settings.loaderContext);\n ctx.trigger('processStart');\n\n // Check to make sure the loader is there on the page if not report it on the console.\n // NOTE that this check should be removed before going live. It is just an aid to help\n // in finding the uses of the loader that maybe broken.\n if (window.console && !ctx.parents('[data-role=\"loader\"]').length) {\n console.warn('Expected to start loader but did not find one in the dom');\n }\n }\n },\n\n /**\n * @param {jQuery.Event} e\n * @param {Object} jqxhr\n * @param {Object} settings\n * @private\n */\n _onAjaxComplete: function (e, jqxhr, settings) {\n if (settings && settings.showLoader && !settings.dontHide) {\n this._getJqueryObj(settings.loaderContext).trigger('processStop');\n }\n }\n });\n\n return {\n loader: $.mage.loader,\n loaderAjax: $.mage.loaderAjax\n };\n});\n","mage/validation/url.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n 'use strict';\n\n return {\n\n /**\n * Redirects to the url if it is considered safe\n *\n * @param {String} path - url to be redirected to\n */\n redirect: function (path) {\n path = this.sanitize(path);\n\n if (this.validate(path)) {\n window.location.href = path;\n }\n },\n\n /**\n * Validates url\n *\n * @param {Object} path - url to be validated\n * @returns {Boolean}\n */\n validate: function (path) {\n var hostname = window.location.hostname;\n\n if (path.indexOf(hostname) === -1 ||\n path.indexOf('javascript:') !== -1 ||\n path.indexOf('vbscript:') !== -1) {\n return false;\n }\n\n return true;\n },\n\n /**\n * Sanitize url, replacing disallowed chars\n *\n * @param {String} path - url to be normalized\n * @returns {String}\n */\n sanitize: function (path) {\n return path.replace('[^-A-Za-z0-9+&@#/%?=~_|!:,.;\\(\\)]', '');\n }\n };\n});\n","mage/adminhtml/globals.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global setLocation */\ndefine([\n 'Magento_Ui/js/modal/confirm',\n 'mage/dataPost'\n], function (confirm, dataPost) {\n 'use strict';\n\n /**\n * Set of a temporary methods used to provide\n * backward compatibility with a legacy code.\n */\n window.setLocation = function (url) {\n window.location.href = url;\n };\n\n /**\n * Helper for onclick action.\n * @param {String} message\n * @param {String} url\n * @param {Object} postData\n * @returns {Boolean}\n */\n window.deleteConfirm = function (message, url, postData) {\n confirm({\n content: message,\n actions: {\n /**\n * Confirm action.\n */\n confirm: function () {\n if (postData !== undefined) {\n postData.action = url;\n dataPost().postData(postData);\n } else {\n setLocation(url);\n }\n }\n }\n });\n\n return false;\n };\n\n /**\n * Helper for onclick action.\n * @param {String} message\n * @param {String} url\n * @returns {Boolean}\n */\n window.confirmSetLocation = window.deleteConfirm;\n});\n","mage/adminhtml/form.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global varienGlobalEvents, varienWindowOnloadCache, RegionUpdater, FormElementDependenceController */\n/* eslint-disable strict */\ndefine([\n 'jquery',\n 'prototype',\n 'mage/adminhtml/events'\n], function (jQuery) {\n var varienElementMethods;\n\n /*\n * @TODO Need to be removed after refactoring all dependent of the form the components\n */\n (function ($) {\n $(function () {\n $(document).on('beforeSubmit', function (e) { //eslint-disable-line max-nested-callbacks\n if (typeof varienGlobalEvents !== 'undefined') {\n varienGlobalEvents.fireEvent('formSubmit', $(e.target).attr('id'));\n }\n });\n });\n })(jQuery);\n\n /**\n * Additional elements methods\n */\n varienElementMethods = {\n /**\n * @param {HTMLElement} element\n */\n setHasChanges: function (element) {\n var elm;\n\n if ($(element) && $(element).hasClassName('no-changes')) {\n return;\n }\n elm = element;\n\n while (elm && elm.tagName != 'BODY') { //eslint-disable-line eqeqeq\n if (elm.statusBar) {\n Element.addClassName($(elm.statusBar), 'changed');\n }\n elm = elm.parentNode;\n }\n },\n\n /**\n * @param {HTMLElement} element\n * @param {*} flag\n * @param {Object} form\n */\n setHasError: function (element, flag, form) {\n var elm = element;\n\n while (elm && elm.tagName != 'BODY') { //eslint-disable-line eqeqeq\n if (elm.statusBar) {\n /* eslint-disable max-depth */\n if (form.errorSections.keys().indexOf(elm.statusBar.id) < 0) {\n form.errorSections.set(elm.statusBar.id, flag);\n }\n\n if (flag) {\n Element.addClassName($(elm.statusBar), 'error');\n\n if (form.canShowError && $(elm.statusBar).show) {\n form.canShowError = false;\n $(elm.statusBar).show();\n }\n form.errorSections.set(elm.statusBar.id, flag);\n } else if (!form.errorSections.get(elm.statusBar.id)) {\n Element.removeClassName($(elm.statusBar), 'error');\n }\n\n /* eslint-enable max-depth */\n }\n elm = elm.parentNode;\n }\n this.canShowElement = false;\n }\n };\n\n Element.addMethods(varienElementMethods);\n\n // Global bind changes\n window.varienWindowOnloadCache = {};\n\n /**\n * @param {*} useCache\n */\n function varienWindowOnload(useCache) {\n var dataElements = $$('input', 'select', 'textarea'),\n i;\n\n for (i = 0; i < dataElements.length; i++) {\n if (dataElements[i] && dataElements[i].id) {\n\n /* eslint-disable max-depth */\n if (!useCache || !varienWindowOnloadCache[dataElements[i].id]) {\n Event.observe(dataElements[i], 'change', dataElements[i].setHasChanges.bind(dataElements[i]));\n\n if (useCache) {\n varienWindowOnloadCache[dataElements[i].id] = true;\n }\n }\n\n /* eslint-disable max-depth */\n }\n }\n }\n Event.observe(window, 'load', varienWindowOnload);\n\n window.RegionUpdater = Class.create();\n RegionUpdater.prototype = {\n /**\n * @param {HTMLElement} countryEl\n * @param {HTMLElement} regionTextEl\n * @param {HTMLElement}regionSelectEl\n * @param {Object} regions\n * @param {*} disableAction\n * @param {*} clearRegionValueOnDisable\n */\n initialize: function (\n countryEl, regionTextEl, regionSelectEl, regions, disableAction, clearRegionValueOnDisable\n ) {\n this.isRegionRequired = true;\n this.countryEl = $(countryEl);\n this.regionTextEl = $(regionTextEl);\n this.regionSelectEl = $(regionSelectEl);\n this.config = regions.config;\n delete regions.config;\n this.regions = regions;\n this.sortedRegions = this.getSortedRegions();\n this.disableAction = typeof disableAction === 'undefined' ? 'hide' : disableAction;\n this.clearRegionValueOnDisable = typeof clearRegionValueOnDisable === 'undefined' ?\n false : clearRegionValueOnDisable;\n\n if (this.regionSelectEl.options.length <= 1) {\n this.update();\n } else {\n this.lastCountryId = this.countryEl.value;\n }\n\n this.countryEl.changeUpdater = this.update.bind(this);\n\n Event.observe(this.countryEl, 'change', this.update.bind(this));\n },\n\n /**\n * @private\n */\n _checkRegionRequired: function () {\n var label, wildCard, elements, that, regionRequired;\n\n if (!this.isRegionRequired) {\n return;\n }\n\n elements = [this.regionTextEl, this.regionSelectEl];\n that = this;\n\n if (typeof this.config == 'undefined') {\n return;\n }\n regionRequired = this.config['regions_required'].indexOf(this.countryEl.value) >= 0;\n\n elements.each(function (currentElement) {\n var form, validationInstance, field, topElement;\n\n if (!currentElement) {\n return;\n }\n form = currentElement.form;\n validationInstance = form ? jQuery(form).data('validation') : null;\n field = currentElement.up('.field') || new Element('div');\n\n if (validationInstance) {\n validationInstance.clearError(currentElement);\n }\n label = $$('label[for=\"' + currentElement.id + '\"]')[0];\n\n if (label) {\n wildCard = label.down('em') || label.down('span.required');\n topElement = label.up('tr') || label.up('li');\n\n if (!that.config['show_all_regions'] && topElement) {\n if (regionRequired) {\n topElement.show();\n } else {\n topElement.hide();\n }\n }\n }\n\n if (label && wildCard) {\n if (!regionRequired) {\n wildCard.hide();\n } else {\n wildCard.show();\n }\n }\n\n //compute the need for the required fields\n if (!regionRequired || !currentElement.visible()) {\n if (field.hasClassName('required')) {\n field.removeClassName('required');\n }\n\n if (currentElement.hasClassName('required-entry')) {\n currentElement.removeClassName('required-entry');\n }\n\n if (currentElement.tagName.toLowerCase() == 'select' && //eslint-disable-line eqeqeq\n currentElement.hasClassName('validate-select')\n ) {\n currentElement.removeClassName('validate-select');\n }\n } else {\n if (!field.hasClassName('required')) {\n field.addClassName('required');\n }\n\n if (!currentElement.hasClassName('required-entry')) {\n currentElement.addClassName('required-entry');\n }\n\n if (currentElement.tagName.toLowerCase() == 'select' && //eslint-disable-line eqeqeq\n !currentElement.hasClassName('validate-select')\n ) {\n currentElement.addClassName('validate-select');\n }\n }\n });\n },\n\n /**\n * Disable region validation.\n */\n disableRegionValidation: function () {\n this.isRegionRequired = false;\n },\n\n /**\n * Update.\n */\n update: function () {\n var option, selectElement, def, regionId, region;\n\n selectElement = this.regionSelectEl;\n\n if (this.sortedRegions[this.countryEl.value]) {\n if (this.lastCountryId != this.countryEl.value) { //eslint-disable-line eqeqeq\n def = selectElement.getAttribute('defaultValue');\n\n if (this.regionTextEl) {\n if (!def) {\n def = this.regionTextEl.value.toLowerCase();\n }\n this.regionTextEl.value = '';\n }\n\n selectElement.options.length = 1;\n\n this.sortedRegions[this.countryEl.value].forEach(function (item) {\n regionId = item[0];\n region = item[1];\n\n option = document.createElement('OPTION');\n option.value = regionId;\n option.text = region.name.stripTags();\n option.title = region.name;\n\n if (selectElement.options.add) {\n selectElement.options.add(option);\n } else {\n selectElement.appendChild(option);\n }\n\n if (regionId == def || region.name.toLowerCase() == def || region.code.toLowerCase() == def) { //eslint-disable-line\n selectElement.value = regionId;\n }\n });\n }\n\n if (this.disableAction == 'hide') { //eslint-disable-line eqeqeq\n if (this.regionTextEl) {\n this.regionTextEl.style.display = 'none';\n this.regionTextEl.style.disabled = true;\n }\n this.regionSelectEl.style.display = '';\n this.regionSelectEl.disabled = false;\n } else if (this.disableAction == 'disable') { //eslint-disable-line eqeqeq\n if (this.regionTextEl) {\n this.regionTextEl.disabled = true;\n }\n this.regionSelectEl.disabled = false;\n }\n this.setMarkDisplay(this.regionSelectEl, true);\n\n this.lastCountryId = this.countryEl.value;\n } else {\n if (this.disableAction == 'hide') { //eslint-disable-line eqeqeq\n if (this.regionTextEl) {\n this.regionTextEl.style.display = '';\n this.regionTextEl.style.disabled = false;\n }\n this.regionSelectEl.style.display = 'none';\n this.regionSelectEl.disabled = true;\n } else if (this.disableAction == 'disable') { //eslint-disable-line eqeqeq\n if (this.regionTextEl) {\n this.regionTextEl.disabled = false;\n }\n this.regionSelectEl.disabled = true;\n\n if (this.clearRegionValueOnDisable) {\n this.regionSelectEl.value = '';\n }\n } else if (this.disableAction == 'nullify') { //eslint-disable-line eqeqeq\n this.regionSelectEl.options.length = 1;\n this.regionSelectEl.value = '';\n this.regionSelectEl.selectedIndex = 0;\n this.lastCountryId = '';\n }\n this.setMarkDisplay(this.regionSelectEl, false);\n }\n varienGlobalEvents.fireEvent('address_country_changed', this.countryEl);\n this._checkRegionRequired();\n },\n\n /**\n * @param {HTMLElement} elem\n * @param {*} display\n */\n setMarkDisplay: function (elem, display) {\n var marks;\n\n if (elem.parentNode.parentNode) {\n marks = Element.select(elem.parentNode.parentNode, '.required');\n\n if (marks[0]) {\n display ? marks[0].show() : marks[0].hide();\n }\n }\n },\n\n /**\n * Sort regions from JSON by name\n *\n * @returns {*[]}\n */\n getSortedRegions: function () {\n var country, regionsEntries, regionsByCountry;\n\n regionsByCountry = [];\n\n for (country in this.regions) { //eslint-disable-line guard-for-in\n regionsEntries = Object.entries(this.regions[country]);\n regionsEntries.sort(function (a, b) {\n return a[1].name > b[1].name ? 1 : -1;\n });\n\n regionsByCountry[country] = regionsEntries;\n }\n\n return regionsByCountry;\n }\n };\n\n window.regionUpdater = RegionUpdater;\n\n /**\n * Fix errorrs in IE\n */\n Event.pointerX = function (event) {\n try {\n return event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)); //eslint-disable-line\n }\n catch (e) {}\n };\n\n /**\n * @param {jQuery.Event} event\n * @return {*}\n */\n Event.pointerY = function (event) {\n try {\n return event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop)); //eslint-disable-line\n }\n catch (e) {}\n };\n\n /**\n * Observer that watches for dependent form elements\n * If an element depends on 1 or more of other elements,\n * it should show up only when all of them gain specified values\n */\n window.FormElementDependenceController = Class.create();\n FormElementDependenceController.prototype = {\n /**\n * Structure of elements: {\n * 'id_of_dependent_element' : {\n * 'id_of_master_element_1' : 'reference_value',\n * 'id_of_master_element_2' : 'reference_value'\n * 'id_of_master_element_3' : ['reference_value1', 'reference_value2']\n * ...\n * }\n * }\n * @param {Object} elementsMap\n * @param {Object} config\n */\n initialize: function (elementsMap, config) {\n var idTo, idFrom, values, fromId, radioFrom;\n\n if (config) {\n this._config = jQuery.extend(this._config, config);\n }\n\n for (idTo in elementsMap) { //eslint-disable-line guard-for-in\n for (idFrom in elementsMap[idTo]) { //eslint-disable-line guard-for-in\n if ($(idFrom)) {\n Event.observe(\n $(idFrom),\n 'change',\n this.trackChange.bindAsEventListener(this, idTo, elementsMap[idTo])\n );\n } else {\n // Check if radio button\n values = elementsMap[idTo][idFrom].values;\n fromId = $(idFrom + values[0]);\n radioFrom = fromId ? $$('[name=\"' + fromId.name + '\"]') : false;\n\n if (radioFrom) {\n radioFrom.invoke(\n 'on',\n 'change',\n this.trackChange.bindAsEventListener(this, idTo, elementsMap[idTo])\n );\n }\n }\n this.trackChange(null, idTo, elementsMap[idTo]);\n }\n }\n },\n\n /**\n * Misc. config options\n * Keys are underscored intentionally\n */\n _config: {\n 'levels_up': 1 // how many levels up to travel when toggling element\n },\n\n /**\n * Define whether target element should be toggled and show/hide its row\n *\n * @param {Object} e - event\n * @param {String} idTo - id of target element\n * @param {Object} valuesFrom - ids of master elements and reference values\n * @return\n */\n trackChange: function (e, idTo, valuesFrom) {\n // define whether the target should show up\n var shouldShowUp = true,\n idFrom, from, values, isInArray, isNegative, headElement, isInheritCheckboxChecked, target, inputs,\n isAnInputOrSelect, currentConfig, rowElement, fromId, radioFrom, targetArray, isChooser;\n\n for (idFrom in valuesFrom) { //eslint-disable-line guard-for-in\n from = $(idFrom);\n\n if (from) {\n values = valuesFrom[idFrom].values;\n isInArray = values.indexOf(from.value) != -1; //eslint-disable-line\n isNegative = valuesFrom[idFrom].negative;\n\n if (!from || isInArray && isNegative || !isInArray && !isNegative) {\n shouldShowUp = false;\n }\n // Check if radio button\n } else {\n values = valuesFrom[idFrom].values;\n fromId = $(idFrom + values[0]);\n\n if (fromId) {\n radioFrom = $$('[name=\"' + fromId.name + '\"]:checked');\n isInArray = radioFrom.length > 0 && values.indexOf(radioFrom[0].value) !== -1;\n isNegative = valuesFrom[idFrom].negative;\n\n if (!radioFrom || isInArray && isNegative || !isInArray && !isNegative) {\n shouldShowUp = false;\n }\n }\n }\n }\n\n // toggle target row\n headElement = jQuery('#' + idTo + '-head');\n isInheritCheckboxChecked = $(idTo + '_inherit') && $(idTo + '_inherit').checked;\n target = $(idTo);\n\n // Account for the chooser style parameters.\n if (target === null && headElement.length === 0 && idTo.substring(0, 16) === 'options_fieldset') {\n targetArray = $$('input[id*=\"' + idTo + '\"]');\n isChooser = true;\n\n if (targetArray !== null && targetArray.length > 0) {\n target = targetArray[0];\n }\n headElement = jQuery('.field-' + idTo).add('.field-chooser' + idTo);\n }\n\n // Target won't always exist (for example, if field type is \"label\")\n if (target) {\n inputs = target.up(this._config['levels_up']).select('input', 'select', 'td');\n isAnInputOrSelect = ['input', 'select'].indexOf(target.tagName.toLowerCase()) != -1; //eslint-disable-line\n\n if (target.type === 'fieldset') {\n inputs = target.select('input', 'select', 'td');\n }\n } else {\n inputs = false;\n isAnInputOrSelect = false;\n }\n\n if (shouldShowUp) {\n currentConfig = this._config;\n\n if (inputs) {\n inputs.each(function (item) {\n // don't touch hidden inputs (and Use Default inputs too), bc they may have custom logic\n if ((!item.type || item.type != 'hidden') && !($(item.id + '_inherit') && $(item.id + '_inherit').checked) && //eslint-disable-line\n !(currentConfig['can_edit_price'] != undefined && !currentConfig['can_edit_price']) && //eslint-disable-line\n !item.getAttribute('readonly') || isChooser //eslint-disable-line\n ) {\n item.disabled = false;\n jQuery(item).removeClass('ignore-validate');\n }\n });\n }\n\n if (headElement.length > 0) {\n headElement.show();\n\n if (headElement.hasClass('open') && target) {\n target.show();\n } else if (target) {\n target.hide();\n }\n } else {\n if (target) {\n target.show();\n headElement = jQuery('.field-' + idTo).add('.field-chooser' + idTo);\n headElement.show();\n }\n\n if (isAnInputOrSelect && !isInheritCheckboxChecked) {\n if (target) {\n if (target.getAttribute('readonly')) {\n target.disabled = true;\n } else {\n target.disabled = false;\n }\n }\n\n jQuery('#' + idTo).removeClass('ignore-validate');\n }\n }\n } else {\n if (inputs) {\n inputs.each(function (item) {\n // don't touch hidden inputs (and Use Default inputs too), bc they may have custom logic\n if ((!item.type || item.type != 'hidden') && //eslint-disable-line eqeqeq\n !($(item.id + '_inherit') && $(item.id + '_inherit').checked)\n ) {\n item.disabled = true;\n jQuery(item).addClass('ignore-validate');\n }\n });\n }\n\n if (headElement.length > 0) {\n headElement.hide();\n } else {\n headElement = jQuery('.field-' + idTo).add('.field-chooser' + idTo);\n headElement.hide();\n }\n\n if (target) {\n target.hide();\n }\n\n if (isAnInputOrSelect && !isInheritCheckboxChecked) {\n if (target) {\n target.disabled = true;\n }\n jQuery('#' + idTo).addClass('ignore-validate');\n }\n\n }\n rowElement = $('row_' + idTo);\n\n if (rowElement == undefined && target) { //eslint-disable-line eqeqeq\n rowElement = target.up(this._config['levels_up']);\n\n if (target.type === 'fieldset') {\n rowElement = target;\n }\n }\n\n if (rowElement) {\n if (shouldShowUp) {\n rowElement.show();\n } else {\n rowElement.hide();\n }\n }\n }\n };\n\n window.varienWindowOnload = varienWindowOnload;\n window.varienElementMethods = varienElementMethods;\n});\n","mage/adminhtml/events.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global varienEvents */\n/* eslint-disable strict */\ndefine([\n 'Magento_Ui/js/modal/alert',\n 'prototype'\n], function (alert) {\n // from http://www.someelement.com/2007/03/eventpublisher-custom-events-la-pubsub.html\n window.varienEvents = Class.create();\n\n varienEvents.prototype = {\n /**\n * Initialize.\n */\n initialize: function () {\n this.arrEvents = {};\n this.eventPrefix = '';\n },\n\n /**\n * Attaches a {handler} function to the publisher's {eventName} event for execution upon the event firing\n * @param {String} eventName\n * @param {Function} handler\n * @param {Boolean} [asynchFlag] - Defaults to false if omitted.\n * Indicates whether to execute {handler} asynchronously (true) or not (false).\n */\n attachEventHandler: function (eventName, handler) {\n var asynchVar, handlerObj;\n\n if (typeof handler == 'undefined' || handler == null) {\n return;\n }\n eventName += this.eventPrefix;\n // using an event cache array to track all handlers for proper cleanup\n if (this.arrEvents[eventName] == null) {\n this.arrEvents[eventName] = [];\n }\n //create a custom object containing the handler method and the asynch flag\n asynchVar = arguments.length > 2 ? arguments[2] : false;\n handlerObj = {\n method: handler,\n asynch: asynchVar\n };\n this.arrEvents[eventName].push(handlerObj);\n },\n\n /**\n * Removes a single handler from a specific event\n * @param {String} eventName - The event name to clear the handler from\n * @param {Function} handler - A reference to the handler function to un-register from the event\n */\n removeEventHandler: function (eventName, handler) {\n eventName += this.eventPrefix;\n\n if (this.arrEvents[eventName] != null) {\n this.arrEvents[eventName] = this.arrEvents[eventName].reject(function (obj) {\n return obj.method == handler; //eslint-disable-line eqeqeq\n });\n }\n },\n\n /**\n * Removes all handlers from a single event\n * @param {String} eventName - The event name to clear handlers from\n */\n clearEventHandlers: function (eventName) {\n eventName += this.eventPrefix;\n this.arrEvents[eventName] = null;\n },\n\n /**\n * Removes all handlers from ALL events\n */\n clearAllEventHandlers: function () {\n this.arrEvents = {};\n },\n\n /**\n * Collect and modify value of arg synchronously in succession and return its new value.\n * In order to use, call attachEventHandler and add function handlers with eventName.\n * Then call fireEventReducer with eventName and any argument to have its value accumulatively modified.\n * Event handlers will be applied to argument in order of first attached to last attached.\n * @param {String} eventName\n * @param {*} arg\n */\n fireEventReducer: function (eventName, arg) {\n var evtName = eventName + this.eventPrefix,\n result = arg,\n len,\n i;\n\n if (!this.arrEvents[evtName]) {\n return result;\n }\n\n len = this.arrEvents[evtName].length; //optimization\n\n for (i = 0; i < len; i++) {\n /* eslint-disable max-depth */\n try {\n result = this.arrEvents[evtName][i].method(result);\n } catch (e) {\n if (this.id) {\n alert({\n content: 'error: error in ' + this.id + '.fireEventReducer():\\n\\nevent name: ' +\n eventName + '\\n\\nerror message: ' + e.message\n });\n } else {\n alert({\n content: 'error: error in [unknown object].fireEventReducer():\\n\\nevent name: ' +\n eventName + '\\n\\nerror message: ' + e.message\n });\n }\n }\n /* eslint-disable max-depth */\n }\n\n return result;\n },\n\n /**\n * Fires the event {eventName}, resulting in all registered handlers to be executed.\n * It also collects and returns results of all non-asynchronous handlers\n * @param {String} eventName - The name of the event to fire\n * @param {Object} [args] - Any object, will be passed into the handler function as the only argument\n * @return {Array}\n */\n fireEvent: function (eventName) {\n var evtName = eventName + this.eventPrefix,\n results = [],\n result, len, i, eventArgs, method, eventHandler;\n\n if (this.arrEvents[evtName] != null) {\n len = this.arrEvents[evtName].length; //optimization\n\n for (i = 0; i < len; i++) {\n /* eslint-disable max-depth */\n try {\n if (arguments.length > 1) {\n if (this.arrEvents[evtName][i].asynch) {\n eventArgs = arguments[1];\n method = this.arrEvents[evtName][i].method.bind(this);\n setTimeout(function () { //eslint-disable-line no-loop-func\n method(eventArgs);\n }, 10);\n } else {\n result = this.arrEvents[evtName][i].method(arguments[1]);\n }\n } else {\n if (this.arrEvents[evtName][i].asynch) { //eslint-disable-line no-lonely-if\n eventHandler = this.arrEvents[evtName][i].method;\n setTimeout(eventHandler, 1);\n } else if (\n this.arrEvents &&\n this.arrEvents[evtName] &&\n this.arrEvents[evtName][i] &&\n this.arrEvents[evtName][i].method\n ) {\n result = this.arrEvents[evtName][i].method();\n }\n }\n results.push(result);\n }\n catch (e) {\n if (this.id) {\n alert({\n content: 'error: error in ' + this.id + '.fireEvent():\\n\\nevent name: ' +\n eventName + '\\n\\nerror message: ' + e.message\n });\n } else {\n alert({\n content: 'error: error in [unknown object].fireEvent():\\n\\nevent name: ' +\n eventName + '\\n\\nerror message: ' + e.message\n });\n }\n }\n\n /* eslint-enable max-depth */\n }\n }\n\n return results;\n }\n };\n\n window.varienGlobalEvents = new varienEvents(); //jscs:ignore requireCapitalizedConstructors\n\n return window.varienGlobalEvents;\n});\n","mage/adminhtml/backup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @deprecated since version 2.2.0\n */\n/* global AdminBackup, setLocation */\n/* eslint-disable strict */\ndefine([\n 'jquery',\n 'Magento_Ui/js/modal/modal',\n 'mage/mage',\n 'prototype'\n], function (jQuery) {\n window.AdminBackup = new Class.create();\n\n AdminBackup.prototype = {\n /**\n * Initialize.\n */\n initialize: function () {\n this.reset();\n this.rollbackUrl = this.backupUrl = '';\n },\n\n /**\n * reset.\n */\n reset: function () {\n this.time = 0;\n this.type = '';\n },\n\n /**\n * @param {*} type\n * @return {Boolean}\n */\n backup: function (type) {\n this.reset();\n this.type = type;\n this.requestBackupOptions();\n\n return false;\n },\n\n /**\n * @param {*} type\n * @param {*} time\n * @return {Boolean}\n */\n rollback: function (type, time) {\n this.reset();\n this.time = time;\n this.type = type;\n this.showRollbackWarning();\n\n return false;\n },\n\n /**\n * Show rollback warning.\n */\n showRollbackWarning: function () {\n this.showPopup('rollback-warning');\n },\n\n /**\n * request backup options.\n */\n requestBackupOptions: function () {\n this.hidePopups();\n this.showPopup('backup-options');\n\n if (this.type === 'snapshot') {\n jQuery('#exclude-media-checkbox-container').removeClass('no-display');\n }\n },\n\n /**\n * Request password.\n */\n requestPassword: function () {\n this.hidePopups();\n\n this.showPopup('rollback-request-password');\n\n this.type != 'db' ? //eslint-disable-line eqeqeq\n $('use-ftp-checkbox-row').show() :\n $('use-ftp-checkbox-row').hide();\n },\n\n /**\n * Toggle Ftp Credentials Form.\n */\n toggleFtpCredentialsForm: function () {\n $('use_ftp').checked ? $('ftp-credentials-container').show()\n : $('ftp-credentials-container').hide();\n\n $$('#ftp-credentials-container input').each(function (item) {\n if (item.name == 'ftp_path') { //eslint-disable-line eqeqeq\n return;\n }\n $('use_ftp').checked ? item.addClassName('required-entry') : item.removeClassName('required-entry');\n });\n },\n\n /**\n * Submit backup.\n */\n submitBackup: function () {\n var data = {\n 'type': this.type,\n 'maintenance_mode': $('backup_maintenance_mode').checked ? 1 : 0,\n 'backup_name': $('backup_name').value,\n 'exclude_media': $('exclude_media').checked ? 1 : 0\n };\n\n new Ajax.Request(this.backupUrl, {\n onSuccess: function (transport) {\n this.processResponse(transport, 'backup-options');\n }.bind(this),\n method: 'post',\n parameters: data\n });\n\n this.modal.modal('closeModal');\n },\n\n /**\n * Submit rollback.\n */\n submitRollback: function () {\n var data = this.getPostData();\n\n new Ajax.Request(this.rollbackUrl, {\n onSuccess: function (transport) {\n this.processResponse(transport, 'rollback-request-password');\n }.bind(this),\n method: 'post',\n parameters: data\n });\n\n this.modal.modal('closeModal');\n },\n\n /**\n * @param {Object} transport\n * @param {*} popupId\n */\n processResponse: function (transport, popupId) {\n var json;\n\n if (!transport.responseText.isJSON()) {\n return;\n }\n\n json = transport.responseText.evalJSON();\n\n if (json.error) {\n this.showPopup(popupId);\n this.displayError(popupId, json.error);\n\n return;\n }\n\n if (json['redirect_url']) {\n setLocation(json['redirect_url']);\n }\n },\n\n /**\n * @param {*} parentContainer\n * @param {*} message\n */\n displayError: function (parentContainer, message) {\n var messageHtml = this.getErrorMessageHtml(message);\n\n $$('#' + parentContainer + ' .backup-messages .messages').invoke('update', messageHtml);\n $$('#' + parentContainer + ' .backup-messages').invoke('show');\n },\n\n /**\n * @param {*} message\n * @return {String}\n */\n getErrorMessageHtml: function (message) {\n return '<div class=\"message message-error error\"><div>' + message + '</div></div>';\n },\n\n /**\n * @return {*|jQuery}\n */\n getPostData: function () {\n var data = $('rollback-form').serialize(true);\n\n data.time = this.time;\n data.type = this.type;\n\n return data;\n },\n backupConfig: {\n 'backup-options': {\n title: jQuery.mage.__('Backup options'),\n\n /**\n * @return {String}\n */\n content: function () {\n return document.getElementById('backup-options-template').textContent;\n },\n\n /**\n * Action Ok.\n */\n actionOk: function () {\n this.modal.find('#backup-form').validation({\n submitHandler: jQuery.proxy(this.submitBackup, this)\n });\n this.modal.find('#backup-form').submit();\n }\n },\n 'rollback-warning': {\n title: jQuery.mage.__('Warning'),\n\n /**\n * @return {String}\n */\n content: function () {\n return document.getElementById('rollback-warning-template').textContent;\n },\n\n /**\n * Action Ok.\n */\n actionOk: function () {\n this.modal.modal('closeModal');\n this.requestPassword();\n }\n },\n 'rollback-request-password': {\n title: jQuery.mage.__('Backup options'),\n\n /**\n * @return {String}\n */\n content: function () {\n return document.getElementById('rollback-request-password-template').textContent;\n },\n\n /**\n * Action Ok.\n */\n actionOk: function () {\n this.modal.find('#rollback-form').validation({\n submitHandler: jQuery.proxy(this.submitRollback, this)\n });\n this.modal.find('#rollback-form').submit();\n },\n\n /**\n * Opened.\n */\n opened: function () {\n this.toggleFtpCredentialsForm();\n }\n }\n },\n\n /**\n * @param {*} divId\n */\n showPopup: function (divId) {\n var self = this;\n\n this.modal = jQuery('<div></div>').attr({\n id: divId\n }).html(this.backupConfig[divId].content()).modal({\n modalClass: 'magento',\n title: this.backupConfig[divId].title,\n type: 'slide',\n\n /**\n * @param {juery.Event} e\n * @param {Object} modal\n */\n closed: function (e, modal) {\n modal.modal.remove();\n },\n\n /**\n * Opened.\n */\n opened: function () {\n if (self.backupConfig[divId].opened) {\n self.backupConfig[divId].opened.call(self);\n }\n },\n buttons: [{\n text: jQuery.mage.__('Cancel'),\n 'class': 'action cancel',\n\n /**\n * Click action.\n */\n click: function () {\n this.closeModal();\n }\n }, {\n text: jQuery.mage.__('Ok'),\n 'class': 'action primary',\n\n /**\n * Click action.\n */\n click: function () {\n self.backupConfig[divId].actionOk.call(self);\n }\n }]\n });\n this.modal.modal('openModal');\n },\n\n /**\n * Hide Popups.\n */\n hidePopups: function () {\n var mask;\n\n $$('.backup-dialog').each(Element.hide);\n mask = $('popup-window-mask');\n\n if (mask) {\n mask.hide();\n }\n }\n };\n});\n","mage/adminhtml/grid.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n// also depends on a mage/adminhtml/tools.js for Base64 encoding\n/* global varienGrid, setLocation, varienGlobalEvents, FORM_KEY,\n BASE_URL, Base64, varienGridMassaction, varienStringArray, serializerController\n*/\n/* eslint-disable strict */\ndefine([\n 'jquery',\n 'mage/template',\n 'Magento_Ui/js/modal/alert',\n 'Magento_Ui/js/modal/confirm',\n 'mage/mage',\n 'prototype',\n 'mage/adminhtml/form',\n 'mage/adminhtml/events'\n], function (jQuery, mageTemplate, alert, confirm) {\n /**\n * @param {*} grid\n * @param {*} event\n */\n function openGridRow(grid, event) {\n var element = Event.findElement(event, 'tr');\n\n if (['a', 'input', 'select', 'option'].indexOf(Event.element(event).tagName.toLowerCase()) !== -1) {\n return;\n }\n\n if (element.title) {\n setLocation(element.title);\n }\n }\n window.openGridRow = openGridRow;\n\n window.varienGrid = new Class.create();\n\n varienGrid.prototype = {\n /**\n * @param {String} containerId\n * @param {String} url\n * @param {*} pageVar\n * @param {*} sortVar\n * @param {*} dirVar\n * @param {*} filterVar\n */\n initialize: function (containerId, url, pageVar, sortVar, dirVar, filterVar) {\n this.containerId = containerId;\n jQuery('#' + containerId).data('gridObject', this);\n this.url = url;\n this.pageVar = pageVar || false;\n this.sortVar = sortVar || false;\n this.dirVar = dirVar || false;\n this.filterVar = filterVar || false;\n this.tableSufix = '_table';\n this.useAjax = false;\n this.rowClickCallback = false;\n this.checkboxCheckCallback = false;\n this.preInitCallback = false;\n this.initCallback = false;\n this.initRowCallback = false;\n this.doFilterCallback = false;\n this.sortableUpdateCallback = false;\n this.targetElement = undefined;\n this.filterKeyPressCallback = false;\n\n this.reloadParams = false;\n\n this.trOnMouseOver = this.rowMouseOver.bindAsEventListener(this);\n this.trOnMouseOut = this.rowMouseOut.bindAsEventListener(this);\n this.trOnMouseDown = this.rowMouseDown.bindAsEventListener(this);\n this.trOnClick = this.rowMouseClick.bindAsEventListener(this);\n this.trOnDblClick = this.rowMouseDblClick.bindAsEventListener(this);\n this.trOnKeyPress = this.keyPress.bindAsEventListener(this);\n\n this.thLinkOnClick = this.doSort.bindAsEventListener(this);\n this.initGrid();\n },\n\n /**\n * Init grid.\n */\n initGrid: function () {\n var row, columns, col;\n\n if (this.preInitCallback) {\n this.preInitCallback(this);\n }\n\n if ($(this.containerId + this.tableSufix)) {\n this.rows = $$('#' + this.containerId + this.tableSufix + ' tbody tr');\n\n for (row = 0; row < this.rows.length; row++) {\n if (row % 2 == 0) { //eslint-disable-line eqeqeq, max-depth\n Element.addClassName(this.rows[row], 'even');\n }\n\n Event.observe(this.rows[row], 'mouseover', this.trOnMouseOver);\n Event.observe(this.rows[row], 'mouseout', this.trOnMouseOut);\n Event.observe(this.rows[row], 'mousedown', this.trOnMouseDown);\n Event.observe(this.rows[row], 'click', this.trOnClick);\n Event.observe(this.rows[row], 'dblclick', this.trOnDblClick);\n }\n }\n\n if (this.sortVar && this.dirVar) {\n columns = $$('#' + this.containerId + this.tableSufix + ' thead [data-sort]');\n\n for (col = 0; col < columns.length; col++) {\n Event.observe(columns[col], 'click', this.thLinkOnClick);\n }\n }\n this.bindFilterFields();\n this.bindFieldsChange();\n\n if (this.initCallback) {\n try {\n this.initCallback(this);\n } catch (e) {\n if (window.console) { //eslint-disable-line max-depth\n console.log(e);\n }\n }\n }\n jQuery('#' + this.containerId).trigger('gridinit', this);\n },\n\n /**\n * Init grid ajax.\n */\n initGridAjax: function () {\n this.initGrid();\n this.initGridRows();\n },\n\n /**\n * Init grid rows.\n */\n initGridRows: function () {\n var row;\n\n if (this.initRowCallback) {\n for (row = 0; row < this.rows.length; row++) {\n try { //eslint-disable-line max-depth\n this.initRowCallback(this, this.rows[row]);\n } catch (e) {\n if (window.console) { //eslint-disable-line max-depth\n console.log(e);\n }\n }\n }\n }\n },\n\n /**\n * @param {*} event\n */\n rowMouseOver: function (event) {\n var element = Event.findElement(event, 'tr');\n\n if (!element.title) {\n return;\n }\n\n Element.addClassName(element, 'on-mouse');\n\n if (!Element.hasClassName('_clickable') && (this.rowClickCallback !== openGridRow || element.title)) {\n if (element.title) {\n Element.addClassName(element, '_clickable');\n }\n }\n },\n\n /**\n * @param {*} event\n */\n rowMouseOut: function (event) {\n var element = Event.findElement(event, 'tr');\n\n Element.removeClassName(element, 'on-mouse');\n },\n\n /**\n * @param {*} event\n */\n rowMouseDown: function (event) {\n this.targetElement = event.target;\n },\n\n /**\n * @param {*} event\n */\n rowMouseClick: function (event) {\n if (this.rowClickCallback) {\n try {\n this.rowClickCallback(this, event);\n } catch (e) {\n }\n }\n varienGlobalEvents.fireEvent('gridRowClick', event);\n this.targetElement = undefined;\n },\n\n /**\n * @param {*} event\n */\n rowMouseDblClick: function (event) {\n varienGlobalEvents.fireEvent('gridRowDblClick', event);\n },\n\n /**\n * Key press.\n */\n keyPress: function () {\n },\n\n /**\n * @param {*} event\n * @return {Boolean}\n */\n doSort: function (event) {\n var element = Event.findElement(event, 'th');\n\n if (element.readAttribute('data-sort') && element.readAttribute('data-direction')) {\n this.addVarToUrl(this.sortVar, element.readAttribute('data-sort'));\n this.addVarToUrl(this.dirVar, element.readAttribute('data-direction'));\n this.reload(this.url);\n }\n Event.stop(event);\n\n return false;\n },\n\n /**\n * @param {Object} element\n */\n loadByElement: function (element) {\n if (element && element.name) {\n this.reload(this.addVarToUrl(element.name, element.value));\n }\n },\n\n /**\n * @param {*} data\n * @param {*} textStatus\n * @param {*} transport\n * @private\n */\n _onAjaxSeccess: function (data, textStatus, transport) {\n var responseText, response, divId;\n\n /* eslint-disable max-depth */\n try {\n responseText = transport.responseText;\n\n if (transport.responseText.isJSON()) {\n response = transport.responseText.evalJSON();\n\n if (response.error) {\n alert({\n content: response.message\n });\n }\n\n if (response.ajaxExpired && response.ajaxRedirect) {\n setLocation(response.ajaxRedirect);\n }\n } else {\n\n /*eslint-disable max-len*/\n /**\n * For IE <= 7.\n * If there are two elements, and first has name, that equals id of second.\n * In this case, IE will choose one that is above\n *\n * @see https://prototype.lighthouseapp.com/projects/8886/tickets/994-id-selector-finds-elements-by-name-attribute-in-ie7\n */\n\n /*eslint-enable max-len*/\n divId = $(this.containerId);\n\n if (divId.id == this.containerId) { //eslint-disable-line eqeqeq\n divId.update(responseText);\n } else {\n $$('div[id=\"' + this.containerId + '\"]')[0].update(responseText);\n }\n }\n } catch (e) {\n divId = $(this.containerId);\n\n if (divId.id == this.containerId) { //eslint-disable-line eqeqeq\n divId.update(responseText);\n } else {\n $$('div[id=\"' + this.containerId + '\"]')[0].update(responseText);\n }\n }\n\n /* eslint-enable max-depth */\n jQuery('#' + this.containerId).trigger('contentUpdated');\n },\n\n /**\n * @param {*} url\n * @param {Function} onSuccessCallback\n * @return {*}\n */\n reload: function (url, onSuccessCallback) {\n var ajaxSettings, ajaxRequest;\n\n this.reloadParams = this.reloadParams || {};\n this.reloadParams['form_key'] = FORM_KEY;\n url = url || this.url;\n\n if (this.useAjax) {\n ajaxSettings = {\n url: url + (url.match(new RegExp('\\\\?')) ? '&ajax=true' : '?ajax=true'),\n showLoader: true,\n method: 'post',\n context: jQuery('#' + this.containerId),\n data: this.reloadParams,\n error: this._processFailure.bind(this),\n complete: this.initGridAjax.bind(this),\n dataType: 'html',\n\n /**\n * Success callback.\n */\n success: function (data, textStatus, transport) {\n this._onAjaxSeccess(data, textStatus, transport);\n\n if (onSuccessCallback && typeof onSuccessCallback === 'function') {\n // execute the callback, passing parameters as necessary\n onSuccessCallback();\n }\n }.bind(this)\n };\n jQuery('#' + this.containerId).trigger('gridajaxsettings', ajaxSettings);\n ajaxRequest = jQuery.ajax(ajaxSettings);\n jQuery('#' + this.containerId).trigger('gridajax', ajaxRequest);\n\n return ajaxRequest;\n }\n\n if (this.reloadParams) {\n $H(this.reloadParams).each(function (pair) {\n url = this.addVarToUrl(pair.key, pair.value);\n }.bind(this));\n }\n location.href = url;\n },\n\n /**\n * @private\n */\n _processFailure: function () {\n location.href = BASE_URL;\n },\n\n /**\n * @param {*} url\n * @param {*} varName\n * @param {*} varValue\n * @return {String|*}\n * @private\n */\n _addVarToUrl: function (url, varName, varValue) {\n var re = new RegExp('\\/(' + varName + '\\/.*?\\/)'),\n parts = url.split(new RegExp('\\\\?'));\n\n url = parts[0].replace(re, '/');\n url += varName + '/' + varValue + '/';\n\n if (parts.size() > 1) {\n url += '?' + parts[1];\n }\n\n return url;\n },\n\n /**\n * Builds the form with fields containing the and submits\n *\n * @param {String} url\n * @param {String} varName\n * @param {String} varValue\n * @private\n */\n _buildFormAndSubmit: function (url, varName, varValue) {\n var re = new RegExp('\\/(' + varName + '\\/.*?\\/)'),\n parts = url.split(new RegExp('\\\\?')),\n form = jQuery('<form></form>'),\n inputProps = [\n {\n name: varName,\n value: varValue\n },\n {\n name: 'form_key',\n value: window.FORM_KEY\n }\n ],\n input;\n\n url = parts[0].replace(re, '/');\n\n if (parts.size() > 1) {\n url += '?' + parts[1];\n }\n\n form.attr('action', url);\n form.attr('method', 'POST');\n\n inputProps.forEach(function (item) {\n input = jQuery('<input/>');\n input.attr('name', item.name);\n input.attr('type', 'hidden');\n input.val(item.value);\n form.append(input);\n });\n jQuery('[data-container=\"body\"]').append(form);\n form.submit();\n form.remove();\n },\n\n /**\n * @param {*} varName\n * @param {*} varValue\n * @return {*|String}\n */\n addVarToUrl: function (varName, varValue) {\n this.url = this._addVarToUrl(this.url, varName, varValue);\n\n return this.url;\n },\n\n /**\n * Do export.\n */\n doExport: function () {\n var exportUrl;\n\n if ($(this.containerId + '_export')) {\n exportUrl = $(this.containerId + '_export').value;\n\n if (this.massaction && this.massaction.checkedString) {\n this._buildFormAndSubmit(\n exportUrl,\n this.massaction.formFieldNameInternal,\n this.massaction.checkedString\n );\n } else {\n location.href = exportUrl;\n }\n }\n },\n\n /**\n * Bind filter fields.\n */\n bindFilterFields: function () {\n var filters = $$(\n '#' + this.containerId + ' [data-role=\"filter-form\"] input',\n '#' + this.containerId + ' [data-role=\"filter-form\"] select'\n ),\n i;\n\n for (i = 0; i < filters.length; i++) {\n Event.observe(filters[i], 'keypress', this.filterKeyPress.bind(this));\n }\n },\n\n /**\n * Bind field change.\n */\n bindFieldsChange: function () {\n var dataElements, i;\n\n if (!$(this.containerId)) {\n return;\n }\n //var dataElements = $(this.containerId+this.tableSufix).down('.data tbody').select('input', 'select');\n // eslint-disable-next-line jquery-no-input-event-shorthand\n dataElements = $(this.containerId + this.tableSufix).down('tbody').select('input', 'select');\n\n for (i = 0; i < dataElements.length; i++) {\n Event.observe(dataElements[i], 'change', dataElements[i].setHasChanges.bind(dataElements[i]));\n }\n },\n\n /**\n * Bind sortable.\n */\n bindSortable: function () {\n if (jQuery('#' + this.containerId).find('.draggable-handle').length) {\n jQuery('#' + this.containerId).find('tbody').sortable({\n axis: 'y',\n handle: '.draggable-handle',\n\n /**\n * @param {*} event\n * @param {*} ui\n * @return {*}\n */\n helper: function (event, ui) {\n ui.children().each(function () {\n jQuery(this).width(jQuery(this).width());\n });\n\n return ui;\n },\n update: this.sortableUpdateCallback ? this.sortableUpdateCallback : function () {\n },\n tolerance: 'pointer'\n });\n }\n },\n\n /**\n * @param {Object} event\n */\n filterKeyPress: function (event) {\n if (event.keyCode == Event.KEY_RETURN) { //eslint-disable-line eqeqeq\n this.doFilter();\n }\n\n if (this.filterKeyPressCallback) {\n this.filterKeyPressCallback(this, event);\n }\n },\n\n /**\n * @param {Function} callback\n */\n doFilter: function (callback) {\n var filters = $$(\n '#' + this.containerId + ' [data-role=\"filter-form\"] input',\n '#' + this.containerId + ' [data-role=\"filter-form\"] select'\n ),\n elements = [],\n i;\n\n for (i in filters) {\n if (filters[i].value && filters[i].value.length) {\n elements.push(filters[i]);\n }\n }\n\n if (!this.doFilterCallback || this.doFilterCallback && this.doFilterCallback()) {\n this.reload(\n this.addVarToUrl(this.filterVar, Base64.encode(Form.serializeElements(elements))),\n callback\n );\n }\n },\n\n /**\n * @param {Function} callback\n */\n resetFilter: function (callback) {\n this.reload(this.addVarToUrl(this.filterVar, ''), callback);\n },\n\n /**\n * @param {Object} element\n */\n checkCheckboxes: function (element) {\n var elements = Element.select($(this.containerId), 'input[name=\"' + element.name + '\"]'),\n i;\n\n for (i = 0; i < elements.length; i++) {\n this.setCheckboxChecked(elements[i], element.checked);\n }\n\n /*eslint-enable no-undef*/\n },\n\n /**\n *\n * @param {HTMLElement} element\n * @param {*} checked\n */\n setCheckboxChecked: function (element, checked) {\n element.checked = checked;\n jQuery(element).trigger('change');\n element.setHasChanges({});\n\n if (this.checkboxCheckCallback) {\n this.checkboxCheckCallback(this, element, checked);\n }\n },\n\n /**\n * @param {Object} event\n * @param {*} lastId\n */\n inputPage: function (event, lastId) {\n var element = Event.element(event),\n keyCode = event.keyCode || event.which,\n enteredValue = parseInt(element.value, 10),\n pageId = parseInt(lastId, 10);\n\n if (keyCode == Event.KEY_RETURN) { //eslint-disable-line eqeqeq\n if (enteredValue > pageId) {\n this.setPage(pageId);\n } else {\n this.setPage(enteredValue);\n }\n }\n\n /*if(keyCode>47 && keyCode<58){\n\n }\n else{\n Event.stop(event);\n }*/\n },\n\n /**\n * @param {*} pageNumber\n */\n setPage: function (pageNumber) {\n this.reload(this.addVarToUrl(this.pageVar, pageNumber));\n }\n };\n\n window.varienGridMassaction = Class.create();\n varienGridMassaction.prototype = {\n /* Predefined vars */\n checkedValues: $H({}),\n checkedString: '',\n oldCallbacks: {},\n errorText: '',\n items: {},\n gridIds: [],\n useSelectAll: false,\n currentItem: false,\n lastChecked: {\n left: false,\n top: false,\n checkbox: false\n },\n fieldTemplate: mageTemplate('<input type=\"hidden\" name=\"<%- name %>\" value=\"<%- value %>\" />'),\n\n /**\n * @param {*} containerId\n * @param {*} grid\n * @param {*} checkedValues\n * @param {*} formFieldNameInternal\n * @param {*} formFieldName\n */\n initialize: function (containerId, grid, checkedValues, formFieldNameInternal, formFieldName) {\n this.setOldCallback('row_click', grid.rowClickCallback);\n this.setOldCallback('init', grid.initCallback);\n this.setOldCallback('init_row', grid.initRowCallback);\n this.setOldCallback('pre_init', grid.preInitCallback);\n\n this.useAjax = false;\n this.grid = grid;\n this.grid.massaction = this;\n this.containerId = containerId;\n this.initMassactionElements();\n\n this.checkedString = checkedValues;\n this.formFieldName = formFieldName;\n this.formFieldNameInternal = formFieldNameInternal;\n\n this.grid.initCallback = this.onGridInit.bind(this);\n this.grid.preInitCallback = this.onGridPreInit.bind(this);\n this.grid.initRowCallback = this.onGridRowInit.bind(this);\n this.grid.rowClickCallback = this.onGridRowClick.bind(this);\n this.initCheckboxes();\n this.checkCheckboxes();\n },\n\n /**\n * @param {*} flag\n */\n setUseAjax: function (flag) {\n this.useAjax = flag;\n },\n\n /**\n * @param {*} flag\n */\n setUseSelectAll: function (flag) {\n this.useSelectAll = flag;\n },\n\n /**\n * Init massaction elements.\n */\n initMassactionElements: function () {\n this.container = $(this.containerId);\n this.multiselect = $(this.containerId + '-mass-select');\n this.count = $(this.containerId + '-count');\n this.formHiddens = $(this.containerId + '-form-hiddens');\n this.formAdditional = $(this.containerId + '-form-additional');\n this.select = $(this.containerId + '-select');\n this.form = this.prepareForm();\n jQuery(this.form).mage('validation');\n this.select.observe('change', this.onSelectChange.bindAsEventListener(this));\n this.lastChecked = {\n left: false,\n top: false,\n checkbox: false\n };\n this.select.addClassName(this.select.value ? '_selected' : '');\n this.initMassSelect();\n },\n\n /**\n * @return {jQuery|*|HTMLElement}\n */\n prepareForm: function () {\n var form = $(this.containerId + '-form'),\n formPlace = null,\n formElement = this.formHiddens || this.formAdditional;\n\n if (!formElement) {\n formElement = this.container.getElementsByTagName('button')[0];\n formElement && formElement.parentNode;\n }\n\n if (!form && formElement) {\n /* fix problem with rendering form in FF through innerHTML property */\n form = document.createElement('form');\n form.setAttribute('method', 'post');\n form.setAttribute('action', '');\n form.id = this.containerId + '-form';\n formPlace = formElement.parentNode;\n formPlace.parentNode.appendChild(form);\n form.appendChild(formPlace);\n }\n\n return form;\n },\n\n /**\n * @param {Array} gridIds\n */\n setGridIds: function (gridIds) {\n this.gridIds = gridIds;\n this.updateCount();\n },\n\n /**\n * @return {Array}\n */\n getGridIds: function () {\n return this.gridIds;\n },\n\n /**\n * @param {*} items\n */\n setItems: function (items) {\n this.items = items;\n this.updateCount();\n },\n\n /**\n * @return {Object}\n */\n getItems: function () {\n return this.items;\n },\n\n /**\n * @param {*} itemId\n * @return {*}\n */\n getItem: function (itemId) {\n if (this.items[itemId]) {\n return this.items[itemId];\n }\n\n return false;\n },\n\n /**\n * @param {String} callbackName\n * @return {Function}\n */\n getOldCallback: function (callbackName) {\n return this.oldCallbacks[callbackName] ? this.oldCallbacks[callbackName] : Prototype.emptyFunction;\n },\n\n /**\n * @param {String} callbackName\n * @param {Function} callback\n */\n setOldCallback: function (callbackName, callback) {\n this.oldCallbacks[callbackName] = callback;\n },\n\n /**\n * @param {*} grid\n */\n onGridPreInit: function (grid) {\n this.initMassactionElements();\n this.getOldCallback('pre_init')(grid);\n },\n\n /**\n * @param {*} grid\n */\n onGridInit: function (grid) {\n this.initCheckboxes();\n this.checkCheckboxes();\n this.updateCount();\n this.getOldCallback('init')(grid);\n },\n\n /**\n * @param {*} grid\n * @param {*} row\n */\n onGridRowInit: function (grid, row) {\n this.getOldCallback('init_row')(grid, row);\n },\n\n /**\n * @param {Object} evt\n */\n isDisabled: function (evt) {\n var target = jQuery(evt.target),\n tr,\n checkbox;\n\n tr = target.is('tr') ? target : target.closest('tr');\n checkbox = tr.find('input[type=\"checkbox\"]');\n\n return checkbox.is(':disabled');\n },\n\n /**\n * @param {*} grid\n * @param {*} evt\n * @return {*}\n */\n onGridRowClick: function (grid, evt) {\n var tdElement = Event.findElement(evt, 'td'),\n trElement = Event.findElement(evt, 'tr'),\n checkbox, isInput, checked;\n\n if (this.isDisabled(evt)) {\n return false;\n }\n\n if (!$(tdElement).down('input')) {\n if ($(tdElement).down('a') || $(tdElement).down('select')) {\n return; //eslint-disable-line\n }\n\n if (trElement.title && trElement.title.strip() != '#') { //eslint-disable-line eqeqeq\n this.getOldCallback('row_click')(grid, evt);\n } else {\n checkbox = Element.select(trElement, 'input');\n isInput = Event.element(evt).tagName == 'input'; //eslint-disable-line eqeqeq\n checked = isInput ? checkbox[0].checked : !checkbox[0].checked;\n\n if (checked) { //eslint-disable-line max-depth\n this.checkedString = varienStringArray.add(checkbox[0].value, this.checkedString);\n } else {\n this.checkedString = varienStringArray.remove(checkbox[0].value, this.checkedString);\n }\n this.grid.setCheckboxChecked(checkbox[0], checked);\n this.updateCount();\n }\n\n return; //eslint-disable-line\n }\n\n if (Event.element(evt).isMassactionCheckbox) {\n this.setCheckbox(Event.element(evt));\n } else if (checkbox = this.findCheckbox(evt)) { //eslint-disable-line no-cond-assign\n checkbox.checked = !checkbox.checked;\n jQuery(checkbox).trigger('change');\n this.setCheckbox(checkbox);\n }\n },\n\n /**\n * @param {Object} evt\n */\n onSelectChange: function (evt) {\n var item = this.getSelectedItem();\n\n if (item) {\n this.formAdditional.update($(this.containerId + '-item-' + item.id + '-block').innerHTML);\n evt.target.addClassName('_selected');\n } else {\n this.formAdditional.update('');\n evt.target.removeClassName('_selected');\n }\n jQuery(this.form).data('validator').resetForm();\n },\n\n /**\n * @param {Object} evt\n * @return {*}\n */\n findCheckbox: function (evt) {\n if (['a', 'input', 'select'].indexOf(Event.element(evt).tagName.toLowerCase()) !== -1) {\n return false;\n }\n checkbox = false; //eslint-disable-line no-undef\n Event.findElement(evt, 'tr').select('[data-role=\"select-row\"]').each(function (element) { //eslint-disable-line\n if (element.isMassactionCheckbox) {\n checkbox = element; //eslint-disable-line no-undef\n }\n });\n\n return checkbox; //eslint-disable-line no-undef\n },\n\n /**\n * Init checkobox.\n */\n initCheckboxes: function () {\n this.getCheckboxes().each(function (checkbox) { //eslint-disable-line no-extra-bind\n checkbox.isMassactionCheckbox = true; //eslint-disable-line no-undef\n });\n },\n\n /**\n * Check checkbox.\n */\n checkCheckboxes: function () {\n this.getCheckboxes().each(function (checkbox) {\n checkbox.checked = varienStringArray.has(checkbox.value, this.checkedString);\n jQuery(checkbox).trigger('change');\n }.bind(this));\n },\n\n /**\n * @return {Boolean}\n */\n selectAll: function () {\n this.setCheckedValues(this.useSelectAll ? this.getGridIds() : this.getCheckboxesValuesAsString());\n this.checkCheckboxes();\n this.updateCount();\n this.clearLastChecked();\n\n return false;\n },\n\n /**\n * @return {Boolean}\n */\n unselectAll: function () {\n this.setCheckedValues('');\n this.checkCheckboxes();\n this.updateCount();\n this.clearLastChecked();\n\n return false;\n },\n\n /**\n * @return {Boolean}\n */\n selectVisible: function () {\n this.setCheckedValues(this.getCheckboxesValuesAsString());\n this.checkCheckboxes();\n this.updateCount();\n this.clearLastChecked();\n\n return false;\n },\n\n /**\n * @return {Boolean}\n */\n unselectVisible: function () {\n this.getCheckboxesValues().each(function (key) {\n this.checkedString = varienStringArray.remove(key, this.checkedString);\n }.bind(this));\n this.checkCheckboxes();\n this.updateCount();\n this.clearLastChecked();\n\n return false;\n },\n\n /**\n * @param {*} values\n */\n setCheckedValues: function (values) {\n this.checkedString = values;\n },\n\n /**\n * @return {String}\n */\n getCheckedValues: function () {\n return this.checkedString;\n },\n\n /**\n * @return {Array}\n */\n getCheckboxes: function () {\n var result = [];\n\n this.grid.rows.each(function (row) {\n var checkboxes = row.select('[data-role=\"select-row\"]');\n\n checkboxes.each(function (checkbox) {\n result.push(checkbox);\n });\n });\n\n return result;\n },\n\n /**\n * @return {Array}\n */\n getCheckboxesValues: function () {\n var result = [];\n\n this.getCheckboxes().each(function (checkbox) { //eslint-disable-line no-extra-bind\n result.push(checkbox.value);\n });\n\n return result;\n },\n\n /**\n * @return {String}\n */\n getCheckboxesValuesAsString: function () {\n return this.getCheckboxesValues().join(',');\n },\n\n /**\n * @param {Object} checkbox\n */\n setCheckbox: function (checkbox) {\n if (checkbox.checked) {\n this.checkedString = varienStringArray.add(checkbox.value, this.checkedString);\n } else {\n this.checkedString = varienStringArray.remove(checkbox.value, this.checkedString);\n }\n this.updateCount();\n },\n\n /**\n * Update count.\n */\n updateCount: function () {\n var checkboxesTotal = varienStringArray.count(\n this.useSelectAll ? this.getGridIds() : this.getCheckboxesValuesAsString()\n ),\n checkboxesChecked = varienStringArray.count(this.checkedString);\n\n jQuery('[data-role=\"counter\"]', this.count).html(checkboxesChecked);\n\n if (!checkboxesTotal) {\n this.multiselect.addClassName('_disabled');\n } else {\n this.multiselect.removeClassName('_disabled');\n }\n\n if (checkboxesChecked == checkboxesTotal && checkboxesTotal != 0) { //eslint-disable-line eqeqeq\n this.count.removeClassName('_empty');\n this.multiselect.addClassName('_checked').removeClassName('_indeterminate');\n } else if (checkboxesChecked == 0) { //eslint-disable-line eqeqeq\n this.count.addClassName('_empty');\n this.multiselect.removeClassName('_checked').removeClassName('_indeterminate');\n } else {\n this.count.removeClassName('_empty');\n this.multiselect.addClassName('_checked').addClassName('_indeterminate');\n }\n\n if (!this.grid.reloadParams) {\n this.grid.reloadParams = {};\n }\n this.grid.reloadParams[this.formFieldNameInternal] = this.checkedString;\n },\n\n /**\n * @return {*}\n */\n getSelectedItem: function () {\n if (this.getItem(this.select.value)) {\n return this.getItem(this.select.value);\n }\n\n return false;\n },\n\n /**\n * Apply.\n */\n apply: function () {\n var item, fieldName;\n\n if (varienStringArray.count(this.checkedString) == 0) { //eslint-disable-line eqeqeq\n alert({\n content: this.errorText\n });\n\n return;\n }\n\n item = this.getSelectedItem();\n\n if (!item) {\n jQuery(this.form).valid();\n\n return;\n }\n this.currentItem = item;\n fieldName = item.field ? item.field : this.formFieldName;\n\n if (this.currentItem.confirm) {\n confirm({\n content: this.currentItem.confirm,\n actions: {\n confirm: this.onConfirm.bind(this, fieldName, item)\n }\n });\n } else {\n this.onConfirm(fieldName, item);\n }\n },\n\n /**\n * @param {*} fieldName\n * @param {*} item\n */\n onConfirm: function (fieldName, item) {\n this.formHiddens.update('');\n new Insertion.Bottom(this.formHiddens, this.fieldTemplate({\n name: fieldName,\n value: this.checkedString\n }));\n new Insertion.Bottom(this.formHiddens, this.fieldTemplate({\n name: 'massaction_prepare_key',\n value: fieldName\n }));\n\n if (!jQuery(this.form).valid()) {\n return;\n }\n\n if (this.useAjax && item.url) {\n new Ajax.Request(item.url, {\n 'method': 'post',\n 'parameters': this.form.serialize(true),\n 'onComplete': this.onMassactionComplete.bind(this)\n });\n } else if (item.url) {\n this.form.action = item.url;\n this.form.submit();\n }\n },\n\n /**\n * @param {*} transport\n */\n onMassactionComplete: function (transport) {\n var listener;\n\n if (this.currentItem.complete) {\n try {\n listener = this.getListener(this.currentItem.complete) || Prototype.emptyFunction;\n listener(this.grid, this, transport);\n } catch (e) {\n }\n }\n },\n\n /**\n * @param {*} strValue\n * @return {Object}\n */\n getListener: function (strValue) {\n return eval(strValue); //eslint-disable-line no-eval\n },\n\n /**\n * Init mass select.\n */\n initMassSelect: function () {\n $$('input[data-role=\"select-row\"]').each(function (element) {\n element.observe('click', this.massSelect.bind(this));\n }.bind(this));\n },\n\n /**\n * Clear last checked.\n */\n clearLastChecked: function () {\n this.lastChecked = {\n left: false,\n top: false,\n checkbox: false\n };\n },\n\n /**\n * @param {Object} evt\n */\n massSelect: function (evt) {\n var currentCheckbox, lastCheckbox, start, finish;\n\n if (this.lastChecked.left !== false &&\n this.lastChecked.top !== false &&\n evt.button === 0 &&\n evt.shiftKey === true\n ) {\n currentCheckbox = Event.element(evt);\n lastCheckbox = this.lastChecked.checkbox;\n\n if (lastCheckbox != currentCheckbox) { //eslint-disable-line eqeqeq\n start = this.getCheckboxOrder(lastCheckbox);\n finish = this.getCheckboxOrder(currentCheckbox);\n\n if (start !== false && finish !== false) { //eslint-disable-line max-depth\n this.selectCheckboxRange(\n Math.min(start, finish),\n Math.max(start, finish),\n currentCheckbox.checked\n );\n }\n }\n }\n\n this.lastChecked = {\n left: Event.element(evt).viewportOffset().left,\n top: Event.element(evt).viewportOffset().top,\n checkbox: Event.element(evt) // \"boundary\" checkbox\n };\n },\n\n /**\n * @param {*} curCheckbox\n * @return {Boolean}\n */\n getCheckboxOrder: function (curCheckbox) {\n var order = false;\n\n this.getCheckboxes().each(function (checkbox, key) {\n if (curCheckbox == checkbox) { //eslint-disable-line eqeqeq\n order = key;\n }\n });\n\n return order;\n },\n\n /**\n * @param {*} start\n * @param {*} finish\n * @param {*} isChecked\n */\n selectCheckboxRange: function (start, finish, isChecked) {\n this.getCheckboxes().each(function (checkbox, key) {\n if (key >= start && key <= finish) {\n checkbox.checked = isChecked;\n this.setCheckbox(checkbox);\n }\n }.bind(this));\n }\n };\n\n window.varienGridAction = {\n /**\n * @param {Object} select\n */\n execute: function (select) {\n var config, win;\n\n if (!select.value || !select.value.isJSON()) {\n return;\n }\n\n config = select.value.evalJSON();\n\n if (config.confirm && !window.confirm(config.confirm)) { //eslint-disable-line no-alert\n select.options[0].selected = true;\n\n return;\n }\n\n if (config.popup) {\n win = window.open(config.href, 'action_window', 'width=500,height=600,resizable=1,scrollbars=1');\n win.focus();\n select.options[0].selected = true;\n } else {\n setLocation(config.href);\n }\n }\n };\n\n window.varienStringArray = {\n /**\n * @param {*} str\n * @param {*} haystack\n * @return {*}\n */\n remove: function (str, haystack) {\n haystack = ',' + haystack + ',';\n haystack = haystack.replace(new RegExp(',' + str + ',', 'g'), ',');\n\n return this.trimComma(haystack);\n },\n\n /**\n * @param {*} str\n * @param {*} haystack\n * @return {*}\n */\n add: function (str, haystack) {\n haystack = ',' + haystack + ',';\n\n if (haystack.search(new RegExp(',' + str + ',', 'g'), haystack) === -1) {\n haystack += str + ',';\n }\n\n return this.trimComma(haystack);\n },\n\n /**\n * @param {*} str\n * @param {*} haystack\n * @return {Boolean}\n */\n has: function (str, haystack) {\n haystack = ',' + haystack + ',';\n\n if (haystack.search(new RegExp(',' + str + ',', 'g'), haystack) === -1) {\n return false;\n }\n\n return true;\n },\n\n /**\n * @param {*} haystack\n * @return {*}\n */\n count: function (haystack) {\n var match;\n\n if (typeof haystack != 'string') {\n return 0;\n }\n\n /* eslint-disable no-undef, no-cond-assign, eqeqeq */\n if (match = haystack.match(new RegExp(',', 'g'))) {\n return match.length + 1;\n } else if (haystack.length != 0) {\n return 1;\n }\n\n /* eslint-enable no-undef, no-cond-assign, eqeqeq */\n return 0;\n },\n\n /**\n * @param {*} haystack\n * @param {*} fnc\n */\n each: function (haystack, fnc) {\n var i;\n\n haystack = haystack.split(',');\n\n for (i = 0; i < haystack.length; i++) {\n fnc(haystack[i]);\n }\n },\n\n /**\n * @param {String} string\n * @return {String}\n */\n trimComma: function (string) {\n string = string.replace(new RegExp('^(,+)', 'i'), '');\n string = string.replace(new RegExp('(,+)$', 'i'), '');\n\n return string;\n }\n };\n\n window.serializerController = Class.create();\n serializerController.prototype = {\n oldCallbacks: {},\n\n /**\n * @param {*} hiddenDataHolder\n * @param {*} predefinedData\n * @param {*} inputsToManage\n * @param {*} grid\n * @param {*} reloadParamName\n */\n initialize: function (hiddenDataHolder, predefinedData, inputsToManage, grid, reloadParamName) {\n //Grid inputs\n this.tabIndex = 1000;\n this.inputsToManage = inputsToManage;\n this.multidimensionalMode = inputsToManage.length > 0;\n\n //Hash with grid data\n this.gridData = this.getGridDataHash(predefinedData);\n\n //Hidden input data holder\n this.hiddenDataHolder = $(hiddenDataHolder);\n this.hiddenDataHolder.value = this.serializeObject();\n\n this.grid = grid;\n\n // Set old callbacks\n this.setOldCallback('row_click', this.grid.rowClickCallback);\n this.setOldCallback('init_row', this.grid.initRowCallback);\n this.setOldCallback('checkbox_check', this.grid.checkboxCheckCallback);\n\n //Grid\n this.reloadParamName = reloadParamName;\n this.grid.reloadParams = {};\n this.grid.reloadParams[this.reloadParamName + '[]'] = this.getDataForReloadParam();\n this.grid.rowClickCallback = this.rowClick.bind(this);\n this.grid.initRowCallback = this.rowInit.bind(this);\n this.grid.checkboxCheckCallback = this.registerData.bind(this);\n this.grid.rows.each(this.eachRow.bind(this));\n },\n\n /**\n * @param {String} callbackName\n * @param {Function} callback\n */\n setOldCallback: function (callbackName, callback) {\n this.oldCallbacks[callbackName] = callback;\n },\n\n /**\n * @param {String} callbackName\n * @return {Prototype.emptyFunction}\n */\n getOldCallback: function (callbackName) {\n return this.oldCallbacks[callbackName] ? this.oldCallbacks[callbackName] : Prototype.emptyFunction;\n },\n\n /**\n * @param {*} grid\n * @param {*} element\n * @param {*} checked\n */\n registerData: function (grid, element, checked) {\n var i;\n\n if (this.multidimensionalMode) {\n if (checked) {\n /*eslint-disable max-depth*/\n if (element.inputElements) {\n this.gridData.set(element.value, {});\n\n for (i = 0; i < element.inputElements.length; i++) {\n element.inputElements[i].disabled = false;\n this.gridData.get(element.value)[element.inputElements[i].name] =\n element.inputElements[i].value;\n }\n }\n } else {\n if (element.inputElements) {\n for (i = 0; i < element.inputElements.length; i++) {\n element.inputElements[i].disabled = true;\n }\n }\n this.gridData.unset(element.value);\n }\n } else {\n if (checked) { //eslint-disable-line no-lonely-if\n this.gridData.set(element.value, element.value);\n } else {\n this.gridData.unset(element.value);\n }\n }\n\n this.hiddenDataHolder.value = this.serializeObject();\n this.grid.reloadParams = {};\n this.grid.reloadParams[this.reloadParamName + '[]'] = this.getDataForReloadParam();\n this.getOldCallback('checkbox_check')(grid, element, checked);\n\n /*eslint-enable max-depth*/\n },\n\n /**\n * @param {*} row\n */\n eachRow: function (row) {\n this.rowInit(this.grid, row);\n },\n\n /**\n * @param {*} grid\n * @param {*} event\n */\n rowClick: function (grid, event) {\n var trElement = Event.findElement(event, 'tr'),\n isInput = Event.element(event).tagName == 'INPUT', //eslint-disable-line eqeqeq\n checkbox, checked;\n\n if (trElement) {\n // eslint-disable-next-line jquery-no-input-event-shorthand\n checkbox = Element.select(trElement, 'input');\n\n if (checkbox[0] && !checkbox[0].disabled) {\n checked = isInput ? checkbox[0].checked : !checkbox[0].checked;\n this.grid.setCheckboxChecked(checkbox[0], checked);\n }\n }\n this.getOldCallback('row_click')(grid, event);\n },\n\n /**\n * @param {*} event\n */\n inputChange: function (event) {\n var element = Event.element(event);\n\n if (element && element.checkboxElement && element.checkboxElement.checked) {\n this.gridData.get(element.checkboxElement.value)[element.name] = element.value;\n this.hiddenDataHolder.value = this.serializeObject();\n }\n },\n\n /**\n * @param {*} grid\n * @param {*} row\n */\n rowInit: function (grid, row) {\n var checkbox, selectors, inputs, i;\n\n if (this.multidimensionalMode) {\n // eslint-disable-next-line jquery-no-input-event-shorthand\n checkbox = $(row).select('.checkbox')[0];\n selectors = this.inputsToManage.map(function (name) {\n return ['input[name=\"' + name + '\"]', 'select[name=\"' + name + '\"]'];\n });\n inputs = $(row).select.apply($(row), selectors.flatten());\n\n if (checkbox && inputs.length > 0) {\n checkbox.inputElements = inputs;\n\n /* eslint-disable max-depth */\n for (i = 0; i < inputs.length; i++) {\n inputs[i].checkboxElement = checkbox;\n\n if (this.gridData.get(checkbox.value) && this.gridData.get(checkbox.value)[inputs[i].name]) {\n inputs[i].value = this.gridData.get(checkbox.value)[inputs[i].name];\n }\n inputs[i].disabled = !checkbox.checked;\n inputs[i].tabIndex = this.tabIndex++;\n Event.observe(inputs[i], 'keyup', this.inputChange.bind(this));\n Event.observe(inputs[i], 'change', this.inputChange.bind(this));\n }\n }\n }\n\n /* eslint-enable max-depth */\n this.getOldCallback('init_row')(grid, row);\n },\n\n /**\n * Stuff methods.\n *\n * @param {*} _object\n * @return {*}\n */\n getGridDataHash: function (_object) {\n return $H(this.multidimensionalMode ? _object : this.convertArrayToObject(_object));\n },\n\n /**\n * @return {*}\n */\n getDataForReloadParam: function () {\n return this.multidimensionalMode ? this.gridData.keys() : this.gridData.values();\n },\n\n /**\n * @return {*}\n */\n serializeObject: function () {\n var clone;\n\n if (this.multidimensionalMode) {\n clone = this.gridData.clone();\n clone.each(function (pair) {\n clone.set(pair.key, Base64.encode(Object.toQueryString(pair.value)));\n });\n\n return clone.toQueryString();\n }\n\n return this.gridData.values().join('&');\n },\n\n /**\n * @param {Array} _array\n * @return {Object}\n */\n convertArrayToObject: function (_array) {\n var _object = {},\n i, l;\n\n for (i = 0, l = _array.length; i < l; i++) {\n _object[_array[i]] = _array[i];\n }\n\n return _object;\n }\n };\n});\n","mage/adminhtml/accordion.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global varienAccordion, varienLoader, Cookie */\n/* eslint-disable strict */\ndefine([\n 'prototype'\n], function () {\n window.varienAccordion = new Class.create(); //eslint-disable-line\n varienAccordion.prototype = {\n /**\n * @param {*} containerId\n * @param {*} activeOnlyOne\n */\n initialize: function (containerId, activeOnlyOne) {\n var links, i;\n\n this.containerId = containerId;\n this.activeOnlyOne = activeOnlyOne || false;\n this.container = $(this.containerId);\n this.items = $$('#' + this.containerId + ' dt');\n this.loader = new varienLoader(true); //jscs:ignore requireCapitalizedConstructors\n\n links = $$('#' + this.containerId + ' dt a');\n\n for (i in links) {\n if (links[i].href) {\n Event.observe(links[i], 'click', this.clickItem.bind(this));\n this.items[i].dd = this.items[i].next('dd');\n this.items[i].link = links[i];\n }\n }\n\n this.initFromCookie();\n },\n\n /**\n * Init from cookie.\n */\n initFromCookie: function () {\n var activeItemId, visibility;\n\n if (this.activeOnlyOne &&\n (activeItemId = Cookie.read(this.cookiePrefix() + 'active-item')) !== null) {\n this.hideAllItems();\n this.showItem(this.getItemById(activeItemId));\n } else if (!this.activeOnlyOne) {\n this.items.each(function (item) {\n if ((visibility = Cookie.read(this.cookiePrefix() + item.id)) !== null) {\n if (visibility == 0) { //eslint-disable-line eqeqeq\n this.hideItem(item);\n } else {\n this.showItem(item);\n }\n }\n }.bind(this));\n }\n },\n\n /**\n * @return {String}\n */\n cookiePrefix: function () {\n return 'accordion-' + this.containerId + '-';\n },\n\n /**\n * @param {*} itemId\n * @return {*}\n */\n getItemById: function (itemId) {\n var result = null;\n\n this.items.each(function (item) {\n if (item.id == itemId) { //eslint-disable-line\n result = item;\n throw $break;\n }\n });\n\n return result;\n },\n\n /**\n * @param {*} event\n */\n clickItem: function (event) {\n var item = Event.findElement(event, 'dt');\n\n if (this.activeOnlyOne) {\n this.hideAllItems();\n this.showItem(item);\n Cookie.write(this.cookiePrefix() + 'active-item', item.id, 30 * 24 * 60 * 60);\n } else {\n if (this.isItemVisible(item)) { //eslint-disable-line no-lonely-if\n this.hideItem(item);\n Cookie.write(this.cookiePrefix() + item.id, 0, 30 * 24 * 60 * 60);\n } else {\n this.showItem(item);\n Cookie.write(this.cookiePrefix() + item.id, 1, 30 * 24 * 60 * 60);\n }\n }\n Event.stop(event);\n },\n\n /**\n * @param {Object} item\n */\n showItem: function (item) {\n if (item && item.link) {\n if (item.link.href) {\n this.loadContent(item);\n }\n\n Element.addClassName(item, 'open');\n Element.addClassName(item.dd, 'open');\n }\n },\n\n /**\n * @param {Object} item\n */\n hideItem: function (item) {\n Element.removeClassName(item, 'open');\n Element.removeClassName(item.dd, 'open');\n },\n\n /**\n * @param {*} item\n * @return {*}\n */\n isItemVisible: function (item) {\n return Element.hasClassName(item, 'open');\n },\n\n /**\n * @param {*} item\n */\n loadContent: function (item) {\n if (item.link.href.indexOf('#') == item.link.href.length - 1) { //eslint-disable-line eqeqeq\n return;\n }\n\n if (Element.hasClassName(item.link, 'ajax')) {\n this.loadingItem = item;\n this.loader.load(item.link.href, {\n updaterId: this.loadingItem.dd.id\n }, this.setItemContent.bind(this));\n\n return;\n }\n location.href = item.link.href;\n },\n\n /**\n * @param {Object} content\n */\n setItemContent: function (content) {\n if (content.isJSON) {\n return;\n }\n this.loadingItem.dd.innerHTML = content;\n },\n\n /**\n * Hide all items\n */\n hideAllItems: function () {\n var i;\n\n for (i in this.items) {\n if (this.items[i].id) {\n Element.removeClassName(this.items[i], 'open');\n Element.removeClassName(this.items[i].dd, 'open');\n }\n }\n }\n };\n});\n","mage/adminhtml/browser.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global MediabrowserUtility, FORM_KEY, tinyMceEditors */\n/* eslint-disable strict */\ndefine([\n 'jquery',\n 'wysiwygAdapter',\n 'Magento_Ui/js/modal/prompt',\n 'Magento_Ui/js/modal/confirm',\n 'Magento_Ui/js/modal/alert',\n 'underscore',\n 'Magento_Ui/js/modal/modal',\n 'jquery/ui',\n 'jquery/jstree/jquery.jstree',\n 'mage/mage'\n], function ($, wysiwyg, prompt, confirm, alert, _) {\n window.MediabrowserUtility = {\n windowId: 'modal_dialog_message',\n modalLoaded: false,\n targetElementId: false,\n pathId: '',\n\n /**\n * @return {Number}\n */\n getMaxZIndex: function () {\n var max = 0,\n cn = document.body.childNodes,\n i, el, zIndex;\n\n for (i = 0; i < cn.length; i++) {\n el = cn[i];\n zIndex = el.nodeType == 1 ? parseInt(el.style.zIndex, 10) || 0 : 0; //eslint-disable-line eqeqeq\n\n if (zIndex < 10000) {\n max = Math.max(max, zIndex);\n }\n }\n\n return max + 10;\n },\n\n /**\n * @param {*} url\n * @param {*} width\n * @param {*} height\n * @param {*} title\n * @param {Object} options\n */\n openDialog: function (url, width, height, title, options) {\n var windowId = this.windowId,\n content = '<div class=\"popup-window\" id=\"' + windowId + '\"></div>';\n\n if (this.modalLoaded) {\n\n if (!_.isUndefined(options)) {\n this.modal.modal('option', 'closed', options.closed);\n }\n\n this.modal.modal('openModal');\n this.setTargetElementId(options, url);\n this.setPathId(url);\n $(window).trigger('reload.MediaGallery');\n\n return;\n }\n\n this.modal = $(content).modal($.extend({\n title: title || 'Insert File...',\n modalClass: 'magento',\n type: 'slide',\n buttons: []\n }, options));\n\n this.modal.modal('openModal');\n\n $.ajax({\n url: url,\n type: 'get',\n context: $(this),\n showLoader: true\n\n }).done(function (data) {\n this.modal.html(data).trigger('contentUpdated');\n this.modalLoaded = true;\n this.setTargetElementId(options, url);\n this.setPathId(url);\n }.bind(this));\n\n },\n\n /**\n * Setter for endcoded path id\n */\n setPathId: function (url) {\n this.pathId = url.match(/(&|\\/|%26)current_tree_path(=|\\/)([\\s\\S].*?)(\\/|$)/)[3];\n },\n\n /**\n * Setter for targetElementId property\n *\n * @param {Object} options\n * @param {String} url\n */\n setTargetElementId: function (options, url) {\n this.targetElementId = options && options.targetElementId ?\n options.targetElementId\n : url.match(/\\/target_element_id\\/([\\s\\S].*?)\\//)[1];\n },\n\n /**\n * Close dialog.\n */\n closeDialog: function () {\n this.modal.modal('closeModal');\n }\n };\n\n $.widget('mage.mediabrowser', {\n eventPrefix: 'mediabrowser',\n options: {\n contentsUrl: null,\n onInsertUrl: null,\n newFolderUrl: null,\n deleteFolderUrl: null,\n deleteFilesUrl: null,\n headerText: null,\n tree: null,\n currentNode: null,\n storeId: null,\n showBreadcrumbs: null,\n hidden: 'no-display'\n },\n\n /**\n * Proxy creation\n * @protected\n */\n _create: function () {\n this._on({\n 'click [data-row=file]': 'selectFile',\n 'dblclick [data-row=file]': 'insert',\n 'click #new_folder': 'newFolder',\n 'click #delete_folder': 'deleteFolder',\n 'click #delete_files': 'deleteFiles',\n 'click #insert_files': 'insertSelectedFiles',\n 'fileuploaddone': '_uploadDone',\n 'click [data-row=breadcrumb]': 'selectFolder'\n });\n\n $(window).on('reload.MediaGallery', $.proxy(this.reload, this));\n this.activeNode = null;\n //tree dont use event bubbling\n this.tree = this.element.find('[data-role=tree]');\n this.tree.on('select_node.jstree', $.proxy(this._selectNode, this));\n },\n\n /**\n * @param {jQuery.Event} event\n * @param {Object} data\n * @private\n */\n _selectNode: function (event, data) {\n var node = data.node;\n\n this.activeNode = node;\n this.element.find('#delete_files, #insert_files').toggleClass(this.options.hidden, true);\n this.element.find('#contents').toggleClass(this.options.hidden, false);\n this.element.find('#delete_folder')\n .toggleClass(this.options.hidden, node.id === 'root'); //eslint-disable-line eqeqeq\n this.element.find('#content_header_text')\n .html(node.id === 'root' ? this.headerText : node.text); //eslint-disable-line eqeqeq\n\n this.drawBreadcrumbs(data);\n this.loadFileList(node);\n },\n\n /**\n * @return {*}\n */\n reload: function (uploaded) {\n return this.loadFileList(this.activeNode, uploaded);\n },\n\n /**\n * @param {Object} element\n * @param {*} value\n */\n insertAtCursor: function (element, value) {\n var sel, startPos, endPos, scrollTop;\n\n if ('selection' in document) {\n //For browsers like Internet Explorer\n element.focus();\n sel = document.selection.createRange();\n sel.text = value;\n element.focus();\n } else if (element.selectionStart || element.selectionStart == '0') { //eslint-disable-line eqeqeq\n //For browsers like Firefox and Webkit based\n startPos = element.selectionStart;\n endPos = element.selectionEnd;\n scrollTop = element.scrollTop;\n element.value = element.value.substring(0, startPos) + value +\n element.value.substring(startPos, endPos) + element.value.substring(endPos, element.value.length);\n element.focus();\n element.selectionStart = startPos + value.length;\n element.selectionEnd = startPos + value.length + element.value.substring(startPos, endPos).length;\n element.scrollTop = scrollTop;\n } else {\n element.value += value;\n element.focus();\n }\n },\n\n /**\n * @param {Object} node\n */\n loadFileList: function (node, uploaded) {\n var contentBlock = this.element.find('#contents');\n\n return $.ajax({\n url: this.options.contentsUrl,\n type: 'GET',\n dataType: 'html',\n data: {\n 'form_key': FORM_KEY,\n node: node ? node.id : null\n },\n context: contentBlock,\n showLoader: true\n }).done(function (data) {\n contentBlock.html(data).trigger('contentUpdated');\n\n if (uploaded) {\n contentBlock.find('.filecnt:last').trigger('click');\n }\n });\n },\n\n /**\n * @param {jQuery.Event} event\n */\n selectFolder: function (event) {\n this.element.find('[data-id=\"' + $(event.currentTarget).data('node').id + '\"]>a').trigger('click');\n },\n\n /**\n * Insert selected files.\n */\n insertSelectedFiles: function () {\n this.element.find('[data-row=file].selected').trigger('dblclick');\n },\n\n /**\n * @param {jQuery.Event} event\n */\n selectFile: function (event) {\n var fileRow = $(event.currentTarget);\n\n fileRow.toggleClass('selected');\n this.element.find('[data-row=file]').not(fileRow).removeClass('selected');\n this.element.find('#delete_files, #insert_files')\n .toggleClass(this.options.hidden, !fileRow.is('.selected'));\n fileRow.trigger('selectfile');\n },\n\n /**\n * @private\n */\n _uploadDone: function () {\n this.element.find('.file-row').remove();\n this.reload(true);\n },\n\n /**\n * @param {jQuery.Event} event\n * @return {Boolean}\n */\n insert: function (event) {\n var fileRow = $(event.currentTarget),\n targetEl;\n\n if (!fileRow.prop('id')) {\n return false;\n }\n targetEl = this.getTargetElement();\n\n if (!targetEl.length) {\n MediabrowserUtility.closeDialog();\n throw 'Target element not found for content update';\n }\n\n return $.ajax({\n url: this.options.onInsertUrl,\n data: {\n filename: fileRow.attr('id'),\n node: this.activeNode.id,\n store: this.options.storeId,\n 'as_is': typeof targetEl !== 'function' && targetEl.is('textarea') ? 1 : 0,\n 'force_static_path': typeof targetEl !== 'function' && targetEl.data('force_static_path') ? 1 : 0,\n 'form_key': FORM_KEY\n },\n context: this,\n showLoader: true\n }).done($.proxy(function (data) {\n if (typeof targetEl === 'function') {\n targetEl(data, {text: fileRow.find('img').attr('alt')});\n } else if (targetEl.is('textarea')) {\n this.insertAtCursor(targetEl.get(0), data);\n } else {\n targetEl\n .val(data)\n .data('size', fileRow.data('size'))\n .data('mime-type', fileRow.data('mime-type'));\n }\n MediabrowserUtility.closeDialog();\n\n if (typeof targetEl !== 'function') {\n targetEl.focus();\n jQuery(targetEl).trigger('change');\n }\n }, this));\n },\n\n /**\n * Find document target element in next order:\n * in acive file browser opener:\n * - input field with ID: \"src\" in opener window\n * - input field with ID: \"href\" in opener window\n * in document:\n * - element with target ID\n *\n * return {HTMLElement|null}\n */\n getTargetElement: function () {\n var mediaBrowser = window.MediabrowserUtility;\n\n if (!_.isUndefined(wysiwyg) && wysiwyg.get(mediaBrowser.targetElementId)) {\n return this.getMediaBrowserOpener() || window;\n }\n\n return $('#' + mediaBrowser.targetElementId);\n },\n\n /**\n * Return opener Window object if it exists, not closed and editor is active\n *\n * return {Object|null}\n */\n getMediaBrowserOpener: function () {\n var targetElementId = window.MediabrowserUtility.targetElementId;\n\n if (!_.isUndefined(wysiwyg) && wysiwyg.get(targetElementId) && !_.isUndefined(tinyMceEditors)) {\n return tinyMceEditors.get(targetElementId).getMediaBrowserOpener();\n }\n\n return null;\n },\n\n /**\n * New folder.\n */\n newFolder: function () {\n var self = this;\n\n prompt({\n title: this.options.newFolderPrompt,\n actions: {\n /**\n * @param {*} folderName\n */\n confirm: function (folderName) {\n $.ajax({\n url: self.options.newFolderUrl,\n dataType: 'json',\n data: {\n name: folderName,\n node: self.activeNode.id,\n store: self.options.storeId,\n 'form_key': FORM_KEY\n },\n context: self.element,\n showLoader: true\n }).done($.proxy(function (data) {\n if (data.error) {\n alert({\n content: data.message\n });\n } else {\n self.tree.jstree(\n 'refresh_node',\n self.element.find('[data-id=\"' + self.activeNode.id + '\"]')\n );\n }\n }, this));\n\n return true;\n }\n }\n });\n },\n\n /**\n * Delete folder.\n */\n deleteFolder: function () {\n var self = this;\n\n confirm({\n content: this.options.deleteFolderConfirmationMessage,\n actions: {\n /**\n * Confirm.\n */\n confirm: function () {\n return $.ajax({\n url: self.options.deleteFolderUrl,\n dataType: 'json',\n data: {\n node: self.activeNode.id,\n store: self.options.storeId,\n 'form_key': FORM_KEY\n },\n context: self.element,\n showLoader: true\n }).done($.proxy(function (data) {\n if (data.error) {\n alert({\n content: data.message\n });\n } else {\n self.tree.jstree('refresh', self.activeNode.id);\n self.reload();\n $(window).trigger('fileDeleted.mediabrowser', {\n ids: self.activeNode.id\n });\n }\n }, this));\n },\n\n /**\n * @return {Boolean}\n */\n cancel: function () {\n return false;\n }\n }\n });\n },\n\n /**\n * Delete files.\n */\n deleteFiles: function () {\n var self = this;\n\n confirm({\n content: this.options.deleteFileConfirmationMessage,\n actions: {\n /**\n * Confirm.\n */\n confirm: function () {\n var selectedFiles = self.element.find('[data-row=file].selected'),\n ids = selectedFiles.map(function () {\n return $(this).attr('id');\n }).toArray();\n\n return $.ajax({\n url: self.options.deleteFilesUrl,\n data: {\n files: ids,\n store: self.options.storeId,\n 'form_key': FORM_KEY\n },\n context: self.element,\n showLoader: true\n }).done($.proxy(function (data) {\n if (data.error) {\n alert({\n content: data.message\n });\n } else {\n self.reload();\n self.element.find('#delete_files, #insert_files').toggleClass(\n self.options.hidden, true\n );\n\n $(window).trigger('fileDeleted.mediabrowser', {\n ids: ids\n });\n }\n }, this));\n },\n\n /**\n * @return {Boolean}\n */\n cancel: function () {\n return false;\n }\n }\n });\n },\n\n /**\n * @param {Object} data\n */\n drawBreadcrumbs: function (data) {\n var node, breadcrumbs;\n\n if (this.element.find('#breadcrumbs').length) {\n this.element.find('#breadcrumbs').remove();\n }\n node = data.node;\n\n if (node.id === 'root') { //eslint-disable-line eqeqeq\n return;\n }\n breadcrumbs = $('<ul class=\"breadcrumbs\" id=\"breadcrumbs\"></ul>');\n // jscs:disable requireCamelCaseOrUpperCaseIdentifiers\n data.instance.get_path(node).each(function (name, index) {\n if (index > 0) {\n breadcrumbs.append($('<li>\\/</li>')); //eslint-disable-line\n }\n breadcrumbs.append($('<li />').attr('data-row', 'breadcrumb').text(name));\n\n });\n // jscs:enable requireCamelCaseOrUpperCaseIdentifiers\n\n breadcrumbs.insertAfter(this.element.find('#content_header'));\n }\n });\n\n return window.MediabrowserUtility;\n});\n","mage/adminhtml/wysiwyg/events.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n 'use strict';\n\n return {\n afterInitialization: 'afterInitialization',\n afterChangeContent: 'afterChangeContent',\n afterUndo: 'afterUndo',\n afterPaste: 'afterPaste',\n beforeSetContent: 'beforeSetContent',\n afterSetContent: 'afterSetContent',\n afterSave: 'afterSave',\n afterOpenFileBrowser: 'afterOpenFileBrowser',\n afterFormSubmit: 'afterFormSubmit',\n afterBlur: 'afterBlur',\n afterFocus: 'afterFocus'\n };\n});\n","mage/adminhtml/wysiwyg/widget.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global setLocation, Base64, updateElementAtCursor, varienGlobalEvents */\n/* eslint-disable strict */\ndefine([\n 'jquery',\n 'wysiwygAdapter',\n 'Magento_Ui/js/modal/alert',\n 'jquery/ui',\n 'mage/translate',\n 'mage/mage',\n 'mage/validation',\n 'mage/adminhtml/events',\n 'prototype',\n 'Magento_Ui/js/modal/modal'\n], function (jQuery, wysiwyg, alert) {\n var widgetTools = {\n\n /**\n * Sets the widget to be active and is the scope of the slide out if the value is set\n */\n activeSelectedNode: null,\n editMode: false,\n cursorLocation: 0,\n\n /**\n * Set active selected node.\n *\n * @param {Object} activeSelectedNode\n */\n setActiveSelectedNode: function (activeSelectedNode) {\n this.activeSelectedNode = activeSelectedNode;\n },\n\n /**\n * Get active selected node.\n *\n * @returns {null}\n */\n getActiveSelectedNode: function () {\n return this.activeSelectedNode;\n },\n\n /**\n *\n * @param {Boolean} editMode\n */\n setEditMode: function (editMode) {\n this.editMode = editMode;\n },\n\n /**\n * @param {*} id\n * @param {*} html\n * @return {String}\n */\n getDivHtml: function (id, html) {\n\n if (!html) {\n html = '';\n }\n\n return '<div id=\"' + id + '\">' + html + '</div>';\n },\n\n /**\n * @param {Object} transport\n */\n onAjaxSuccess: function (transport) {\n var response;\n\n if (transport.responseText.isJSON()) {\n response = transport.responseText.evalJSON();\n\n if (response.error) {\n throw response;\n } else if (response.ajaxExpired && response.ajaxRedirect) {\n setLocation(response.ajaxRedirect);\n }\n }\n },\n\n dialogOpened: false,\n\n /**\n * @return {Number}\n */\n getMaxZIndex: function () {\n var max = 0,\n cn = document.body.childNodes,\n i, el, zIndex;\n\n for (i = 0; i < cn.length; i++) {\n el = cn[i];\n zIndex = el.nodeType == 1 ? parseInt(el.style.zIndex, 10) || 0 : 0; //eslint-disable-line eqeqeq\n\n if (zIndex < 10000) {\n max = Math.max(max, zIndex);\n }\n }\n\n return max + 10;\n },\n\n /**\n * @param {String} widgetUrl\n */\n openDialog: function (widgetUrl) {\n var oThis = this,\n title = 'Insert Widget',\n mode = 'new',\n dialog;\n\n if (this.editMode) {\n title = 'Edit Widget';\n mode = 'edit';\n }\n\n if (this.dialogOpened) {\n return;\n }\n\n this.dialogWindow = jQuery('<div/>').modal({\n\n title: jQuery.mage.__(title),\n type: 'slide',\n buttons: [],\n\n /**\n * Opened.\n */\n opened: function () {\n dialog = jQuery(this).addClass('loading magento-message');\n\n widgetUrl += 'mode/' + mode;\n\n new Ajax.Updater($(this), widgetUrl, {\n evalScripts: true,\n\n /**\n * On complete.\n */\n onComplete: function () {\n dialog.removeClass('loading');\n }\n });\n },\n\n /**\n * @param {jQuery.Event} e\n * @param {Object} modal\n */\n closed: function (e, modal) {\n modal.modal.remove();\n oThis.dialogOpened = false;\n }\n });\n\n this.dialogOpened = true;\n this.dialogWindow.modal('openModal');\n }\n },\n WysiwygWidget = {};\n\n WysiwygWidget.Widget = Class.create();\n WysiwygWidget.Widget.prototype = {\n /**\n * @param {HTMLElement} formEl\n * @param {HTMLElement} widgetEl\n * @param {*} widgetOptionsEl\n * @param {*} optionsSourceUrl\n * @param {*} widgetTargetId\n */\n initialize: function (formEl, widgetEl, widgetOptionsEl, optionsSourceUrl, widgetTargetId) {\n $(formEl).insert({\n bottom: widgetTools.getDivHtml(widgetOptionsEl)\n });\n\n this.formEl = formEl;\n this.widgetEl = $(widgetEl);\n this.widgetOptionsEl = $(widgetOptionsEl);\n this.optionsUrl = optionsSourceUrl;\n this.optionValues = new Hash({});\n this.widgetTargetId = widgetTargetId;\n\n if (typeof wysiwyg != 'undefined' && wysiwyg.activeEditor()) { //eslint-disable-line eqeqeq\n this.bMark = wysiwyg.activeEditor().selection.getBookmark();\n }\n\n // disable -- Please Select -- option from being re-selected\n this.widgetEl.querySelector('option').setAttribute('disabled', 'disabled');\n\n Event.observe(this.widgetEl, 'change', this.loadOptions.bind(this));\n\n this.initOptionValues();\n },\n\n /**\n * @return {String}\n */\n getOptionsContainerId: function () {\n return this.widgetOptionsEl.id + '_' + this.widgetEl.value.gsub(/\\//, '_');\n },\n\n /**\n * @param {*} containerId\n */\n switchOptionsContainer: function (containerId) {\n $$('#' + this.widgetOptionsEl.id + ' div[id^=' + this.widgetOptionsEl.id + ']').each(function (e) {\n this.disableOptionsContainer(e.id);\n }.bind(this));\n\n if (containerId != undefined) { //eslint-disable-line eqeqeq\n this.enableOptionsContainer(containerId);\n }\n this._showWidgetDescription();\n },\n\n /**\n * @param {*} containerId\n */\n enableOptionsContainer: function (containerId) {\n var container = $(containerId);\n\n container.select('.widget-option').each(function (e) {\n e.removeClassName('skip-submit');\n\n if (e.hasClassName('obligatory')) {\n e.removeClassName('obligatory');\n e.addClassName('required-entry');\n }\n });\n container.removeClassName('no-display');\n },\n\n /**\n * @param {*} containerId\n */\n disableOptionsContainer: function (containerId) {\n var container = $(containerId);\n\n if (container.hasClassName('no-display')) {\n return;\n }\n container.select('.widget-option').each(function (e) {\n // Avoid submitting fields of unactive container\n if (!e.hasClassName('skip-submit')) {\n e.addClassName('skip-submit');\n }\n // Form validation workaround for unactive container\n if (e.hasClassName('required-entry')) {\n e.removeClassName('required-entry');\n e.addClassName('obligatory');\n }\n });\n container.addClassName('no-display');\n },\n\n /**\n * Assign widget options values when existing widget selected in WYSIWYG.\n *\n * @return {Boolean}\n */\n initOptionValues: function () {\n var e, widgetCode;\n\n if (!this.wysiwygExists()) {\n return false;\n }\n\n e = this.getWysiwygNode();\n\n if (e.localName === 'span') {\n e = e.firstElementChild;\n }\n\n if (e != undefined && e.id) { //eslint-disable-line eqeqeq\n // attempt to Base64-decode id on selected node; exception is thrown if it is in fact not a widget node\n try {\n widgetCode = Base64.idDecode(e.id);\n } catch (ex) {\n return false;\n }\n\n if (widgetCode.indexOf('{{widget') !== -1) {\n this.optionValues = new Hash({});\n widgetCode.gsub(/([a-z0-9\\_]+)\\s*\\=\\s*[\\\"]{1}([^\\\"]+)[\\\"]{1}/i, function (match) {\n\n if (match[1] == 'type') { //eslint-disable-line eqeqeq\n this.widgetEl.value = match[2];\n } else {\n this.optionValues.set(match[1], match[2]);\n }\n\n }.bind(this));\n\n this.loadOptions();\n }\n }\n },\n\n /**\n * Load options.\n */\n loadOptions: function () {\n var optionsContainerId,\n params,\n msg,\n msgTmpl,\n $wrapper,\n typeName = this.optionValues.get('type_name');\n\n if (!this.widgetEl.value) {\n if (typeName) {\n msgTmpl = jQuery.mage.__('The widget %1 is no longer available. Select a different widget.');\n msg = jQuery.mage.__(msgTmpl).replace('%1', typeName);\n\n jQuery('body').notification('clear').notification('add', {\n error: true,\n message: msg,\n\n /**\n * @param {String} message\n */\n insertMethod: function (message) {\n $wrapper = jQuery('<div/>').html(message);\n\n $wrapper.insertAfter('.modal-slide .page-main-actions');\n }\n });\n }\n this.switchOptionsContainer();\n\n return;\n }\n\n optionsContainerId = this.getOptionsContainerId();\n\n if ($(optionsContainerId) != undefined) { //eslint-disable-line eqeqeq\n this.switchOptionsContainer(optionsContainerId);\n\n return;\n }\n\n this._showWidgetDescription();\n\n params = {\n 'widget_type': this.widgetEl.value,\n values: this.optionValues\n };\n new Ajax.Request(this.optionsUrl, {\n parameters: {\n widget: Object.toJSON(params)\n },\n\n /**\n * On success.\n */\n onSuccess: function (transport) {\n try {\n widgetTools.onAjaxSuccess(transport);\n this.switchOptionsContainer();\n\n if ($(optionsContainerId) == undefined) { //eslint-disable-line eqeqeq\n this.widgetOptionsEl.insert({\n bottom: widgetTools.getDivHtml(optionsContainerId, transport.responseText)\n });\n } else {\n this.switchOptionsContainer(optionsContainerId);\n }\n } catch (e) {\n alert({\n content: e.message\n });\n }\n }.bind(this)\n });\n },\n\n /**\n * @private\n */\n _showWidgetDescription: function () {\n var noteCnt = this.widgetEl.next().down('small'),\n descrCnt = $('widget-description-' + this.widgetEl.selectedIndex),\n description;\n\n if (noteCnt != undefined) { //eslint-disable-line eqeqeq\n description = descrCnt != undefined ? descrCnt.innerHTML : ''; //eslint-disable-line eqeqeq\n noteCnt.update(description);\n }\n },\n\n /**\n * Validate field.\n */\n validateField: function () {\n jQuery(this.widgetEl).valid();\n jQuery('#insert_button').removeClass('disabled');\n },\n\n /**\n * Closes the modal\n */\n closeModal: function () {\n widgetTools.dialogWindow.modal('closeModal');\n },\n\n /* eslint-disable max-depth*/\n /**\n * Insert widget.\n */\n insertWidget: function () {\n var validationResult,\n $form = jQuery('#' + this.formEl),\n formElements,\n i,\n params,\n editor,\n activeNode;\n\n // remove cached validator instance, which caches elements to validate\n jQuery.data($form[0], 'validator', null);\n\n $form.validate({\n /**\n * Ignores elements with .skip-submit, .no-display ancestor elements\n */\n ignore: function () {\n return jQuery(this).closest('.skip-submit, .no-display').length;\n },\n errorClass: 'mage-error'\n });\n\n validationResult = $form.valid();\n\n if (validationResult) {\n formElements = [];\n i = 0;\n Form.getElements($(this.formEl)).each(function (e) {\n\n if (jQuery(e).closest('.skip-submit, .no-display').length === 0) {\n formElements[i] = e;\n i++;\n }\n });\n\n // Add as_is flag to parameters if wysiwyg editor doesn't exist\n params = Form.serializeElements(formElements);\n\n if (!this.wysiwygExists()) {\n params += '&as_is=1';\n }\n\n new Ajax.Request($(this.formEl).action, {\n parameters: params,\n onComplete: function (transport) {\n try {\n editor = wysiwyg.get(this.widgetTargetId);\n\n widgetTools.onAjaxSuccess(transport);\n widgetTools.dialogWindow.modal('closeModal');\n\n if (editor) {\n editor.focus();\n activeNode = widgetTools.getActiveSelectedNode();\n\n if (activeNode) {\n editor.selection.select(activeNode);\n editor.selection.setContent(transport.responseText);\n editor.fire('Change');\n } else if (this.bMark) {\n editor.selection.moveToBookmark(this.bMark);\n }\n }\n\n if (!activeNode) {\n this.updateContent(transport.responseText);\n }\n } catch (e) {\n alert({\n content: e.message\n });\n }\n }.bind(this)\n });\n }\n },\n\n /**\n * @param {Object} content\n */\n updateContent: function (content) {\n var textarea;\n\n if (this.wysiwygExists()) {\n wysiwyg.insertContent(content, false);\n } else {\n textarea = document.getElementById(this.widgetTargetId);\n updateElementAtCursor(textarea, content);\n varienGlobalEvents.fireEvent('tinymceChange');\n jQuery(textarea).trigger('change');\n }\n },\n\n /**\n * @return {Boolean}\n */\n wysiwygExists: function () {\n return typeof wysiwyg != 'undefined' && wysiwyg.get(this.widgetTargetId);\n },\n\n /**\n * @return {null|wysiwyg.Editor|*}\n */\n getWysiwyg: function () {\n return wysiwyg.get(this.widgetTargetId);\n },\n\n /**\n * @return {*|Element}\n */\n getWysiwygNode: function () {\n return widgetTools.getActiveSelectedNode() || wysiwyg.activeEditor().selection.getNode();\n }\n };\n\n WysiwygWidget.chooser = Class.create();\n WysiwygWidget.chooser.prototype = {\n\n // HTML element A, on which click event fired when choose a selection\n chooserId: null,\n\n // Source URL for Ajax requests\n chooserUrl: null,\n\n // Chooser config\n config: null,\n\n // Chooser dialog window\n dialogWindow: null,\n\n // Chooser content for dialog window\n dialogContent: null,\n\n overlayShowEffectOptions: null,\n overlayHideEffectOptions: null,\n\n /**\n * @param {*} chooserId\n * @param {*} chooserUrl\n * @param {*} config\n */\n initialize: function (chooserId, chooserUrl, config) {\n this.chooserId = chooserId;\n this.chooserUrl = chooserUrl;\n this.config = config;\n },\n\n /**\n * @return {String}\n */\n getResponseContainerId: function () {\n return 'responseCnt' + this.chooserId;\n },\n\n /**\n * @return {jQuery|*|HTMLElement}\n */\n getChooserControl: function () {\n return $(this.chooserId + 'control');\n },\n\n /**\n * @return {jQuery|*|HTMLElement}\n */\n getElement: function () {\n return $(this.chooserId + 'value');\n },\n\n /**\n * @return {jQuery|*|HTMLElement}\n */\n getElementLabel: function () {\n return $(this.chooserId + 'label');\n },\n\n /**\n * Open.\n */\n open: function () {\n $(this.getResponseContainerId()).show();\n },\n\n /**\n * Close.\n */\n close: function () {\n $(this.getResponseContainerId()).hide();\n this.closeDialogWindow();\n },\n\n /**\n * Choose.\n */\n choose: function () {\n // Open dialog window with previously loaded dialog content\n var responseContainerId;\n\n if (this.dialogContent) {\n this.openDialogWindow(this.dialogContent);\n\n return;\n }\n // Show or hide chooser content if it was already loaded\n responseContainerId = this.getResponseContainerId();\n\n // Otherwise load content from server\n new Ajax.Request(this.chooserUrl, {\n parameters: {\n 'element_value': this.getElementValue(),\n 'element_label': this.getElementLabelText()\n },\n\n /**\n * On success.\n */\n onSuccess: function (transport) {\n try {\n widgetTools.onAjaxSuccess(transport);\n this.dialogContent = widgetTools.getDivHtml(responseContainerId, transport.responseText);\n this.openDialogWindow(this.dialogContent);\n } catch (e) {\n alert({\n content: e.message\n });\n }\n }.bind(this)\n });\n },\n\n /**\n * Open dialog winodw.\n *\n * @param {*} content\n */\n openDialogWindow: function (content) {\n this.dialogWindow = jQuery('<div/>').modal({\n title: this.config.buttons.open,\n type: 'slide',\n buttons: [],\n\n /**\n * Opened.\n */\n opened: function () {\n jQuery(this).addClass('magento-message');\n },\n\n /**\n * @param {jQuery.Event} e\n * @param {Object} modal\n */\n closed: function (e, modal) {\n modal.modal.remove();\n this.dialogWindow = null;\n }\n });\n\n this.dialogWindow.modal('openModal').append(content);\n },\n\n /**\n * Close dialog window.\n */\n closeDialogWindow: function () {\n this.dialogWindow.modal('closeModal').remove();\n },\n\n /**\n * @return {*|Number}\n */\n getElementValue: function () {\n return this.getElement().value;\n },\n\n /**\n * @return {String}\n */\n getElementLabelText: function () {\n return this.getElementLabel().innerHTML;\n },\n\n /**\n * @param {*} value\n */\n setElementValue: function (value) {\n this.getElement().value = value;\n },\n\n /**\n * @param {*} value\n */\n setElementLabel: function (value) {\n this.getElementLabel().innerHTML = value;\n }\n };\n\n window.WysiwygWidget = WysiwygWidget;\n window.widgetTools = widgetTools;\n});\n","mage/adminhtml/wysiwyg/tiny_mce/tinymce5Adapter.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global popups, tinyMceEditors, MediabrowserUtility, Base64 */\n/* eslint-disable strict */\ndefine([\n 'jquery',\n 'underscore',\n 'tinymce',\n 'mage/adminhtml/events',\n 'mage/adminhtml/wysiwyg/events',\n 'mage/translate',\n 'prototype',\n 'jquery/ui'\n], function (jQuery, _, tinyMCE, varienGlobalEvents, wysiwygEvents) {\n 'use strict';\n\n var tinyMceWysiwyg = Class.create();\n\n tinyMceWysiwyg.prototype = {\n mediaBrowserOpener: null,\n mediaBrowserTargetElementId: null,\n magentoVariablesPlugin: null,\n mode: 'exact',\n\n /**\n * @param {*} htmlId\n * @param {Object} config\n */\n initialize: function (htmlId, config) {\n this.id = htmlId;\n this.config = config;\n\n _.bindAll(\n this,\n 'beforeSetContent',\n 'saveContent',\n 'onChangeContent',\n 'openFileBrowser',\n 'updateTextArea',\n 'onUndo',\n 'removeEvents'\n );\n\n varienGlobalEvents.attachEventHandler('tinymceChange', this.onChangeContent);\n varienGlobalEvents.attachEventHandler('tinymceBeforeSetContent', this.beforeSetContent);\n varienGlobalEvents.attachEventHandler('tinymceSetContent', this.updateTextArea);\n varienGlobalEvents.attachEventHandler('tinymceSaveContent', this.saveContent);\n varienGlobalEvents.attachEventHandler('tinymceUndo', this.onUndo);\n\n if (typeof tinyMceEditors === 'undefined') {\n window.tinyMceEditors = $H({});\n }\n\n tinyMceEditors.set(this.id, this);\n },\n\n /**\n * Ensures the undo operation works properly\n */\n onUndo: function () {\n this.addContentEditableAttributeBackToNonEditableNodes();\n },\n\n /**\n * Setup TinyMCE editor\n */\n setup: function (mode) {\n var deferreds = [],\n settings,\n self = this;\n\n this.turnOff();\n\n if (this.config.plugins) {\n this.config.plugins.forEach(function (plugin) {\n var deferred;\n\n self.addPluginToToolbar(plugin.name, '|');\n\n if (!plugin.src) {\n return;\n }\n\n deferred = jQuery.Deferred();\n deferreds.push(deferred);\n\n require([plugin.src], function (factoryFn) {\n if (typeof factoryFn === 'function') {\n factoryFn(plugin.options);\n }\n\n tinyMCE.PluginManager.load(plugin.name, plugin.src);\n deferred.resolve();\n });\n });\n }\n\n if (jQuery.isReady) {\n tinyMCE.dom.Event.domLoaded = true;\n }\n\n settings = this.getSettings();\n\n if (mode === 'inline') {\n settings.inline = true;\n\n if (!isNaN(settings.toolbarZIndex)) {\n tinyMCE.ui.FloatPanel.zIndex = settings.toolbarZIndex;\n }\n\n this.removeEvents(self.id);\n }\n\n jQuery.when.apply(jQuery, deferreds).done(function () {\n tinyMCE.init(settings);\n this.getPluginButtons().hide();\n varienGlobalEvents.clearEventHandlers('open_browser_callback');\n this.eventBus.clearEventHandlers('open_browser_callback');\n this.eventBus.attachEventHandler('open_browser_callback', tinyMceEditors.get(self.id).openFileBrowser);\n }.bind(this));\n },\n\n /**\n * Remove events from instance.\n *\n * @param {String} wysiwygId\n */\n removeEvents: function (wysiwygId) {\n var editor;\n\n if (typeof tinyMceEditors !== 'undefined' && tinyMceEditors.get(wysiwygId)) {\n editor = tinyMceEditors.get(wysiwygId);\n varienGlobalEvents.removeEventHandler('tinymceChange', editor.onChangeContent);\n }\n },\n\n /**\n * Add plugin to the toolbar if not added.\n *\n * @param {String} plugin\n * @param {String} separator\n */\n addPluginToToolbar: function (plugin, separator) {\n var plugins = this.config.tinymce.plugins.split(' '),\n toolbar = this.config.tinymce.toolbar.split(' ');\n\n if (plugins.indexOf(plugin) === -1) {\n plugins.push(plugin);\n }\n\n if (toolbar.indexOf(plugin) === -1) {\n toolbar.push(separator || '', plugin);\n }\n\n this.config.tinymce.plugins = plugins.join(' ');\n this.config.tinymce.toolbar = toolbar.join(' ');\n },\n\n /**\n * Set the status of the toolbar to disabled or enabled (true for enabled, false for disabled)\n * @param {Boolean} enabled\n */\n setToolbarStatus: function (enabled) {\n var controlIds = this.get(this.getId()).theme.panel.rootControl.controlIdLookup;\n\n _.each(controlIds, function (controlId) {\n controlId.disabled(!enabled);\n controlId.canFocus = enabled;\n\n if (controlId.tooltip) {\n controlId.tooltip().state.set('rendered', enabled);\n\n if (enabled) {\n jQuery(controlId.getEl()).children('button').addBack().removeAttr('style');\n } else {\n jQuery(controlId.getEl()).children('button').addBack().attr('style', 'color: inherit;' +\n 'background-color: inherit;' +\n 'border-color: transparent;'\n );\n }\n }\n });\n },\n\n /**\n * @return {Object}\n */\n getSettings: function () {\n var settings,\n eventBus = this.eventBus;\n\n settings = {\n selector: '#' + this.getId(),\n theme: 'silver',\n skin: 'oxide',\n 'toolbar_mode': 'wrap',\n 'entity_encoding': 'raw',\n 'convert_urls': false,\n 'content_css': this.config.tinymce['content_css'],\n 'relative_urls': true,\n 'valid_children': '+body[style]',\n menubar: false,\n plugins: this.config.tinymce.plugins,\n toolbar: this.config.tinymce.toolbar,\n adapter: this,\n 'body_id': 'html-body',\n\n /**\n * @param {Object} editor\n */\n setup: function (editor) {\n var onChange;\n\n editor.on('BeforeSetContent', function (evt) {\n varienGlobalEvents.fireEvent('tinymceBeforeSetContent', evt);\n eventBus.fireEvent(wysiwygEvents.beforeSetContent);\n });\n\n editor.on('SaveContent', function (evt) {\n varienGlobalEvents.fireEvent('tinymceSaveContent', evt);\n eventBus.fireEvent(wysiwygEvents.afterSave);\n });\n\n editor.on('paste', function (evt) {\n varienGlobalEvents.fireEvent('tinymcePaste', evt);\n eventBus.fireEvent(wysiwygEvents.afterPaste);\n });\n\n editor.on('PostProcess', function (evt) {\n varienGlobalEvents.fireEvent('tinymceSaveContent', evt);\n eventBus.fireEvent(wysiwygEvents.afterSave);\n });\n\n editor.on('undo', function (evt) {\n varienGlobalEvents.fireEvent('tinymceUndo', evt);\n eventBus.fireEvent(wysiwygEvents.afterUndo);\n });\n\n editor.on('focus', function () {\n eventBus.fireEvent(wysiwygEvents.afterFocus);\n });\n\n editor.on('blur', function () {\n eventBus.fireEvent(wysiwygEvents.afterBlur);\n });\n\n /**\n * @param {*} evt\n */\n onChange = function (evt) {\n varienGlobalEvents.fireEvent('tinymceChange', evt);\n eventBus.fireEvent(wysiwygEvents.afterChangeContent);\n };\n\n editor.on('Change', onChange);\n editor.on('keyup', onChange);\n\n editor.on('ExecCommand', function (cmd) {\n varienGlobalEvents.fireEvent('tinymceExecCommand', cmd);\n });\n\n editor.on('init', function (args) {\n varienGlobalEvents.fireEvent('wysiwygEditorInitialized', args.target);\n eventBus.fireEvent(wysiwygEvents.afterInitialization);\n });\n }\n };\n\n // Set default initial height\n settings['min_height'] = this.config.tinymce['min_height'] ? this.config.tinymce['min_height'] : 250;\n\n if (this.config.skin) {\n settings.skin = this.config.skin;\n }\n\n if (this.config['toolbar_mode']) {\n settings['toolbar_mode'] = this.config['toolbar_mode'];\n }\n\n if (this.config.baseStaticUrl && this.config.baseStaticDefaultUrl) {\n settings['document_base_url'] = this.config.baseStaticUrl;\n }\n // Set the document base URL\n if (this.config['document_base_url']) {\n settings['document_base_url'] = this.config['document_base_url'];\n }\n\n if (this.config['files_browser_window_url']) {\n settings['file_picker_callback_types'] = 'file image media';\n\n /**\n * @param {*} callback\n * @param {*} value\n * @param {*} meta\n */\n settings['file_picker_callback'] = function (callback, value, meta) {\n var payload = {\n callback: callback,\n value: value,\n meta: meta\n };\n\n varienGlobalEvents.fireEvent('open_browser_callback', payload);\n this.eventBus.fireEvent('open_browser_callback', payload);\n }.bind(this);\n }\n\n if (this.config.width) {\n settings.width = this.config.width;\n }\n\n if (this.config.height) {\n settings.height = this.config.height;\n }\n\n if (this.config.plugins) {\n settings.magentoPluginsOptions = {};\n\n _.each(this.config.plugins, function (plugin) {\n settings.magentoPluginsOptions[plugin.name] = plugin.options;\n });\n }\n\n if (this.config.settings) {\n Object.extend(settings, this.config.settings);\n }\n\n return settings;\n },\n\n /**\n * @param {String} id\n */\n get: function (id) {\n return tinyMCE.get(id);\n },\n\n /**\n * @return {String|null}\n */\n getId: function () {\n return this.id || (this.activeEditor() ? this.activeEditor().id : null) || tinyMceEditors.values()[0].id;\n },\n\n /**\n * @return {Object}\n */\n activeEditor: function () {\n return tinyMCE.activeEditor;\n },\n\n /**\n * Insert content to active editor.\n *\n * @param {String} content\n * @param {Boolean} ui\n */\n insertContent: function (content, ui) {\n this.activeEditor().execCommand('mceInsertContent', typeof ui !== 'undefined' ? ui : false, content);\n },\n\n /**\n * Replace entire contents of wysiwyg with string content parameter\n *\n * @param {String} content\n */\n setContent: function (content) {\n this.get(this.getId()).setContent(content);\n },\n\n /**\n * Set caret location in WYSIWYG editor.\n *\n * @param {Object} targetElement\n */\n setCaretOnElement: function (targetElement) {\n this.activeEditor().selection.select(targetElement);\n this.activeEditor().selection.collapse();\n },\n\n /**\n * @param {Object} o\n */\n openFileBrowser: function (o) {\n var typeTitle = this.translate('Select Images'),\n storeId = this.config['store_id'] ? this.config['store_id'] : 0,\n frameDialog = jQuery('div.mce-container[role=\"dialog\"]'),\n self = this,\n wUrl = this.config['files_browser_window_url'] +\n 'target_element_id/' + this.getId() + '/' +\n 'store/' + storeId + '/';\n\n this.mediaBrowserOpener = o.callback;\n\n if (typeof o.meta.filetype !== 'undefined' && o.meta.filetype !== '') { //eslint-disable-line eqeqeq\n wUrl = wUrl + 'type/' + o.meta.filetype + '/';\n }\n\n frameDialog.hide();\n jQuery('.tox-tinymce-aux').hide();\n\n require(['mage/adminhtml/browser'], function () {\n MediabrowserUtility.openDialog(wUrl, false, false, typeTitle, {\n /**\n * Closed.\n */\n closed: function () {\n frameDialog.show();\n jQuery('.tox-tinymce-aux').show();\n },\n\n targetElementId: self.activeEditor() ? self.activeEditor().id : null\n }\n );\n });\n },\n\n /**\n * @param {String} string\n * @return {String}\n */\n translate: function (string) {\n return jQuery.mage.__ ? jQuery.mage.__(string) : string;\n },\n\n /**\n * @return {null}\n */\n getMediaBrowserOpener: function () {\n return this.mediaBrowserOpener;\n },\n\n /**\n * @return {null}\n */\n getMediaBrowserTargetElementId: function () {\n return this.mediaBrowserTargetElementId;\n },\n\n /**\n * @return {jQuery|*|HTMLElement}\n */\n getToggleButton: function () {\n return $('toggle' + this.getId());\n },\n\n /**\n * Get plugins button.\n */\n getPluginButtons: function () {\n return jQuery('#buttons' + this.getId() + ' > button.plugin');\n },\n\n /**\n * @param {*} mode\n * @return {wysiwygSetup}\n */\n turnOn: function (mode) {\n this.closePopups();\n\n this.setup(mode);\n\n this.getPluginButtons().hide();\n\n tinyMCE.execCommand('mceAddControl', false, this.getId());\n\n return this;\n },\n\n /**\n * @param {String} name\n */\n closeEditorPopup: function (name) {\n if (typeof popups !== 'undefined' && popups[name] !== undefined && !popups[name].closed) {\n popups[name].close();\n }\n },\n\n /**\n * @return {wysiwygSetup}\n */\n turnOff: function () {\n this.closePopups();\n\n this.getPluginButtons().show();\n\n tinyMCE.execCommand('mceRemoveEditor', false, this.getId());\n\n return this;\n },\n\n /**\n * Close popups.\n */\n closePopups: function () {\n // close all popups to avoid problems with updating parent content area\n varienGlobalEvents.fireEvent('wysiwygClosePopups');\n this.closeEditorPopup('browser_window' + this.getId());\n },\n\n /**\n * @return {Boolean}\n */\n toggle: function () {\n var content;\n\n if (!tinyMCE.get(this.getId())) {\n this.turnOn();\n\n return true;\n }\n\n content = this.get(this.getId()) ? this.get(this.getId()).getContent() : this.getTextArea().val();\n\n this.turnOff();\n\n if (content.match(/{{.+?}}/g)) {\n this.getTextArea().val(content.replace(/"/g, '\"'));\n }\n\n return false;\n },\n\n /**\n * On form validation.\n */\n onFormValidation: function () {\n if (tinyMCE.get(this.getId())) {\n $(this.getId()).value = tinyMCE.get(this.getId()).getContent();\n }\n },\n\n /**\n * On change content.\n */\n onChangeContent: function () {\n // Add \"changed\" to tab class if it exists\n var tab;\n\n this.updateTextArea();\n\n if (this.config['tab_id']) {\n tab = $$('a[id$=' + this.config['tab_id'] + ']')[0];\n\n if ($(tab) != undefined && $(tab).hasClassName('tab-item-link')) { //eslint-disable-line eqeqeq\n $(tab).addClassName('changed');\n }\n }\n },\n\n /**\n * @param {Object} o\n */\n beforeSetContent: function (o) {\n o.content = this.encodeContent(o.content);\n },\n\n /**\n * @param {Object} o\n */\n saveContent: function (o) {\n o.content = this.decodeContent(o.content);\n },\n\n /**\n * Return the content stored in the WYSIWYG field\n * @param {String} id\n * @return {String}\n */\n getContent: function (id) {\n return id ? this.get(id).getContent() : this.get(this.getId()).getContent();\n },\n\n /**\n * @returns {Object}\n */\n getAdapterPrototype: function () {\n return tinyMceWysiwyg;\n },\n\n /**\n * Fix range selection placement when typing. This fixes MAGETWO-84769\n * @param {Object} editor\n */\n fixRangeSelection: function (editor) {\n var selection = editor.selection,\n dom = editor.dom,\n rng = dom.createRng(),\n doc = editor.getDoc(),\n markerHtml,\n marker;\n\n // Validate the range we're trying to fix is contained within the current editors document\n if (!selection.getContent().length && jQuery.contains(doc, selection.getRng().startContainer)) {\n markerHtml = '<span id=\"mce_marker\" data-mce-type=\"bookmark\">\\uFEFF</span>';\n selection.setContent(markerHtml);\n marker = dom.get('mce_marker');\n rng.setStartBefore(marker);\n rng.setEndBefore(marker);\n dom.remove(marker);\n selection.setRng(rng);\n }\n },\n\n /**\n * Update text area.\n */\n updateTextArea: function () {\n var editor = this.get(this.getId()),\n content;\n\n if (!editor || editor.id !== this.activeEditor().id) {\n return;\n }\n\n this.addContentEditableAttributeBackToNonEditableNodes();\n\n content = editor.getContent();\n content = this.decodeContent(content);\n\n this.getTextArea().val(content).trigger('change');\n },\n\n /**\n * @return {Object} jQuery textarea element\n */\n getTextArea: function () {\n return jQuery('#' + this.getId());\n },\n\n /**\n * Set the status of the editor and toolbar\n *\n * @param {Boolean} enabled\n */\n setEnabledStatus: function (enabled) {\n if (this.activeEditor()) {\n this.activeEditor().getBody().setAttribute('contenteditable', enabled);\n this.activeEditor().readonly = !enabled;\n this.setToolbarStatus(enabled);\n }\n\n if (enabled) {\n this.getTextArea().prop('disabled', false);\n } else {\n this.getTextArea().prop('disabled', 'disabled');\n }\n },\n\n /**\n * Retrieve directives URL with substituted directive value.\n *\n * @param {String} directive\n */\n makeDirectiveUrl: function (directive) {\n return this.config['directives_url']\n .replace(/directive/, 'directive/___directive/' + directive)\n .replace(/\\/$/, '');\n },\n\n /**\n * Convert {{directive}} style attributes syntax to absolute URLs\n * @param {Object} content\n * @return {*}\n */\n encodeDirectives: function (content) {\n // collect all HTML tags with attributes that contain directives\n return content.gsub(/<([a-z0-9\\-\\_]+[^>]+?)([a-z0-9\\-\\_]+=\"[^\"]*?\\{\\{.+?\\}\\}.*?\".*?)>/i, function (match) {\n var attributesString = match[2],\n decodedDirectiveString;\n\n // process tag attributes string\n attributesString = attributesString.gsub(/([a-z0-9\\-\\_]+)=\"(.*?)(\\{\\{.+?\\}\\})(.*?)\"/i, function (m) {\n decodedDirectiveString = encodeURIComponent(Base64.mageEncode(m[3].replace(/"/g, '\"') + m[4]));\n\n return m[1] + '=\"' + m[2] + this.makeDirectiveUrl(decodedDirectiveString) + '\"';\n }.bind(this));\n\n return '<' + match[1] + attributesString + '>';\n }.bind(this));\n },\n\n /**\n * Convert absolute URLs to {{directive}} style attributes syntax\n * @param {Object} content\n * @return {*}\n */\n decodeDirectives: function (content) {\n var directiveUrl = this.makeDirectiveUrl('%directive%').split('?')[0], // remove query string from directive\n // escape special chars in directives url to use in regular expression\n regexEscapedDirectiveUrl = directiveUrl.replace(/([$^.?*!+:=()\\[\\]{}|\\\\])/g, '\\\\$1'),\n regexDirectiveUrl = regexEscapedDirectiveUrl\n .replace(\n '%directive%',\n '([a-zA-Z0-9,_-]+(?:%2[A-Z]|)+\\/?)(?:(?!\").)*'\n ) + '/?(\\\\\\\\?[^\"]*)?', // allow optional query string\n reg = new RegExp(regexDirectiveUrl);\n\n return content.gsub(reg, function (match) {\n return Base64.mageDecode(decodeURIComponent(match[1]).replace(/\\/$/, '')).replace(/\"/g, '"');\n });\n },\n\n /**\n * @param {Object} attributes\n * @return {Object}\n */\n parseAttributesString: function (attributes) {\n var result = {};\n\n // Decode " entity, as regex below does not support encoded quote\n attributes = attributes.replace(/"/g, '\"');\n\n attributes.gsub(\n /(\\w+)(?:\\s*=\\s*(?:(?:\"((?:\\\\.|[^\"])*)\")|(?:'((?:\\\\.|[^'])*)')|([^>\\s]+)))?/,\n function (match) {\n result[match[1]] = match[2];\n }\n );\n\n return result;\n },\n\n /**\n * @param {Object} content\n * @return {*}\n */\n decodeContent: function (content) {\n if (this.config['add_directives']) {\n content = this.decodeDirectives(content);\n }\n\n content = varienGlobalEvents.fireEventReducer('wysiwygDecodeContent', content);\n\n return content;\n },\n\n /**\n * @param {Object} content\n * @return {*}\n */\n encodeContent: function (content) {\n if (this.config['add_directives']) {\n content = this.encodeDirectives(content);\n }\n\n content = varienGlobalEvents.fireEventReducer('wysiwygEncodeContent', content);\n\n return content;\n },\n\n /**\n * Reinstate contenteditable attributes on .mceNonEditable nodes\n */\n addContentEditableAttributeBackToNonEditableNodes: function () {\n jQuery('.mceNonEditable', this.activeEditor().getDoc()).attr('contenteditable', false);\n },\n\n /**\n * Calls the save method on all editor instances in the collection.\n */\n triggerSave: function () {\n tinyMCE.triggerSave();\n }\n };\n\n return tinyMceWysiwyg.prototype;\n});\n","mage/adminhtml/wysiwyg/tiny_mce/html5-schema.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore'\n], function (_) {\n 'use strict';\n\n /* eslint-disable max-len */\n\n var schema = {\n blockContent: [\n 'address', 'article', 'aside', 'blockquote', 'details', 'dialog', 'div', 'dl', 'fieldset',\n 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr',\n 'menu', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul'\n ],\n phrasingContent: [\n '#comment', '#text', 'a', 'abbr', 'audio', 'b', 'bdi', 'bdo', 'br', 'button', 'canvas',\n 'cite','code', 'command', 'datalist', 'del', 'dfn', 'em', 'embed', 'i', 'iframe', 'img',\n 'input', 'ins', 'kbd', 'keygen', 'label', 'map', 'mark', 'meter', 'noscript', 'object',\n 'output', 'picture', 'progress', 'q', 'ruby', 's', 'samp', 'script', 'select', 'small',\n 'span', 'strong', 'sub', 'sup', 'textarea', 'time', 'u', 'var', 'video', 'wbr'\n ],\n blockElements: [\n 'address', 'article', 'aside', 'blockquote', 'caption', 'center', 'datalist', 'dd', 'dir', 'div',\n 'dl', 'dt', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'header', 'hgroup', 'hr', 'isindex', 'li', 'menu', 'nav', 'noscript', 'ol', 'optgroup', 'option',\n 'p', 'pre', 'section', 'select', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'ul'\n ],\n boolAttrs: [\n 'autoplay', 'checked', 'compact', 'controls', 'declare', 'defer', 'disabled', 'ismap', 'loop',\n 'multiple', 'nohref', 'noresize', 'noshade', 'nowrap', 'readonly', 'selected'\n ],\n shortEnded: [\n 'area', 'base', 'basefont', 'br', 'col', 'embed', 'frame', 'hr', 'img', 'input', 'isindex',\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\n ],\n whiteSpace: [\n 'audio', 'iframe', 'noscript', 'object', 'pre', 'script', 'style', 'textarea', 'video'\n ],\n selfClosing: [\n 'colgroup', 'dd', 'dt', 'li', 'option', 'p', 'td', 'tfoot', 'th', 'thead', 'tr'\n ]\n };\n\n schema.flowContent = schema.blockContent.concat(schema.phrasingContent, ['style']);\n schema.nonEmpty = ['td', 'th', 'iframe', 'video', 'audio', 'object', 'script', 'i', 'em', 'span'].concat(schema.shortEnded);\n\n _.extend(schema, (function (phrasingContent, flowContent) {\n var validElements = [],\n validChildren = [],\n compiled = {},\n globalAttrs,\n rawData;\n\n globalAttrs = [\n 'id', 'dir', 'lang', 'class', 'style', 'title', 'hidden', 'onclick', 'onkeyup',\n 'tabindex', 'dropzone', 'accesskey', 'draggable', 'translate', 'onmouseup',\n 'onkeydown', 'spellcheck', 'ondblclick', 'onmouseout', 'onkeypress', 'contextmenu',\n 'onmousedown', 'onmouseover', 'onmousemove', 'contenteditable'\n ];\n\n rawData = [\n ['html', 'manifest', 'head body'],\n ['head', '', 'base command link meta noscript script style title'],\n ['title hr noscript br'],\n ['base', 'href target'],\n ['link', 'href rel media hreflang type sizes hreflang'],\n ['meta', 'name http-equiv content charset'],\n ['style', 'media type scoped'],\n ['script', 'src async defer type charset'],\n ['body', 'onafterprint onbeforeprint onbeforeunload onblur onerror onfocus ' +\n 'onhashchange onload onmessage onoffline ononline onpagehide onpageshow ' +\n 'onpopstate onresize onscroll onstorage onunload background bgcolor text link vlink alink', flowContent\n ],\n ['caption', '', _.without(flowContent, 'table')],\n ['address dt dd div', '', flowContent],\n ['h1 h2 h3 h4 h5 h6 pre p abbr code var samp kbd sub sup i b u bdo span legend em strong small s cite dfn', '', phrasingContent],\n ['blockquote', 'cite', flowContent],\n ['ol', 'reversed start type', 'li'],\n ['ul', 'type compact', 'li'],\n ['li', 'value type', flowContent],\n ['dl', '', 'dt dd'],\n ['a', 'href target rel media hreflang type charset name rev shape coords download', phrasingContent],\n ['q', 'cite', phrasingContent],\n ['ins del', 'cite datetime', flowContent],\n ['img', 'src sizes srcset alt usemap ismap width height name longdesc align border hspace vspace'],\n ['iframe', 'src name width height longdesc frameborder marginwidth marginheight scrolling align sandbox seamless allowfullscreen', flowContent],\n ['embed', 'src type width height'],\n ['object', 'data type typemustmatch name usemap form width height declare classid code codebase codetype archive standby align border hspace vspace', flowContent.concat(['param'])],\n ['param', 'name value valuetype type'],\n ['map', 'name', flowContent.concat(['area'])],\n ['area', 'alt coords shape href target rel media hreflang type nohref'],\n ['table', 'border summary width frame rules cellspacing cellpadding align bgcolor', 'caption colgroup thead tfoot tbody tr col'],\n ['colgroup', 'span width align char charoff valign', 'col'],\n ['col', 'span'],\n ['tbody thead tfoot', 'align char charoff valign', 'tr'],\n ['tr', 'align char charoff valign bgcolor', 'td th'],\n ['td', 'colspan rowspan headers abbr axis scope align char charoff valign nowrap bgcolor width height', flowContent],\n ['th', 'colspan rowspan headers scope abbr axis align char charoff valign nowrap bgcolor width height accept', flowContent],\n ['form', 'accept-charset action autocomplete enctype method name novalidate target onsubmit onreset', flowContent],\n ['fieldset', 'disabled form name', flowContent.concat(['legend'])],\n ['label', 'form for', phrasingContent],\n ['input', 'accept alt autocomplete checked dirname disabled form formaction formenctype formmethod formnovalidate ' +\n 'formtarget height list max maxlength min multiple name pattern readonly required size src step type value width usemap align'\n ],\n ['button', 'disabled form formaction formenctype formmethod formnovalidate formtarget name type value', phrasingContent],\n ['select', 'disabled form multiple name required size onfocus onblur onchange', 'option optgroup'],\n ['optgroup', 'disabled label', 'option'],\n ['option', 'disabled label selected value'],\n ['textarea', 'cols dirname disabled form maxlength name readonly required rows wrap'],\n ['menu', 'type label', flowContent.concat(['li'])],\n ['noscript', '', flowContent],\n ['wbr'],\n ['ruby', '', phrasingContent.concat(['rt', 'rp'])],\n ['figcaption', '', flowContent],\n ['mark rt rp summary bdi', '', phrasingContent],\n ['canvas', 'width height', flowContent],\n ['video', 'src crossorigin poster preload autoplay mediagroup loop muted controls width height buffered', flowContent.concat(['track', 'source'])],\n ['audio', 'src crossorigin preload autoplay mediagroup loop muted controls buffered volume', flowContent.concat(['track', 'source'])],\n ['picture', '', 'img source'],\n ['source', 'src srcset type media sizes'],\n ['track', 'kind src srclang label default'],\n ['datalist', '', phrasingContent.concat(['option'])],\n ['article section nav aside header footer', '', flowContent],\n ['hgroup', '', 'h1 h2 h3 h4 h5 h6'],\n ['figure', '', flowContent.concat(['figcaption'])],\n ['time', 'datetime', phrasingContent],\n ['dialog', 'open', flowContent],\n ['command', 'type label icon disabled checked radiogroup command'],\n ['output', 'for form name', phrasingContent],\n ['progress', 'value max', phrasingContent],\n ['meter', 'value min max low high optimum', phrasingContent],\n ['details', 'open', flowContent.concat(['summary'])],\n ['keygen', 'autofocus challenge disabled form keytype name'],\n ['script', 'language xml:space'],\n ['style', 'xml:space'],\n ['embed', 'align name hspace vspace'],\n ['br', 'clear'],\n ['applet', 'codebase archive code object alt name width height align hspace vspace'],\n ['font basefont', 'size color face'],\n ['h1 h2 h3 h4 h5 h6 div p legend caption', 'align'],\n ['ol dl menu dir', 'compact'],\n ['pre', 'width xml:space'],\n ['hr', 'align noshade size width'],\n ['isindex', 'prompt'],\n ['col', 'width align char charoff valign'],\n ['input button select textarea', 'autofocus'],\n ['input textarea', 'placeholder onselect onchange onfocus onblur'],\n ['link script img', 'crossorigin']\n ];\n\n rawData.forEach(function (data) {\n var nodes = data[0].split(' '),\n attributes = data[1] || [],\n children = data[2] || [],\n ni = nodes.length,\n nodeName,\n schemaData;\n\n if (typeof attributes === 'string') {\n attributes = attributes.split(' ');\n }\n\n if (typeof children === 'string') {\n children = children.split(' ');\n }\n\n while (ni--) {\n nodeName = nodes[ni];\n schemaData = compiled[nodeName] || {};\n\n compiled[nodeName] = {\n attributes: _.union(schemaData.attributes, globalAttrs, attributes),\n children: _.union(schemaData.children, children)\n };\n }\n });\n\n ['a', 'dfn', 'form', 'meter', 'progress'].forEach(function (nodeName) {\n var node = compiled[nodeName];\n\n node.children = _.without(node.children, nodeName);\n });\n\n _.each(compiled, function (node, nodeName) {\n var filteredAttributes = [];\n\n _.each(node.attributes, function (attribute) { //eslint-disable-line max-nested-callbacks\n // Disallowing usage of 'on*' attributes.\n if (!/^on/.test(attribute)) {\n filteredAttributes.push(attribute);\n }\n });\n\n node.attributes = filteredAttributes;\n\n validElements.push(nodeName + '[' + node.attributes.join('|') + ']');\n validChildren.push(nodeName + '[' + node.children.join('|') + ']');\n });\n\n return {\n nodes: compiled,\n validElements: validElements,\n validChildren: validChildren\n };\n })(schema.phrasingContent, schema.flowContent));\n\n return schema;\n});\n","mage/adminhtml/wysiwyg/tiny_mce/setup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* eslint-disable strict */\ndefine([\n 'jquery',\n 'underscore',\n 'wysiwygAdapter',\n 'module',\n 'mage/translate',\n 'prototype',\n 'mage/adminhtml/events',\n 'mage/adminhtml/browser'\n], function (jQuery, _, wysiwygAdapter, module) {\n var baseConfig = module.config().config || {},\n wysiwygSetup = Class.create({\n wysiwygInstance: null\n });\n\n wysiwygSetup.prototype = {\n\n /**\n * @param {*} htmlId\n * @param {Object} config\n */\n initialize: function (htmlId, config) {\n var WysiwygInstancePrototype = new wysiwygAdapter.getAdapterPrototype();\n\n _.bindAll(this, 'openFileBrowser');\n\n config = _.extend({}, baseConfig, config || {});\n this.wysiwygInstance = new WysiwygInstancePrototype(htmlId, config);\n this.wysiwygInstance.eventBus = this.eventBus = new window.varienEvents();\n },\n\n /**\n * @param {*} mode\n */\n setup: function (mode) {\n this.wysiwygInstance.setup(mode);\n },\n\n /**\n * @param {Object} o\n */\n openFileBrowser: function (o) {\n this.wysiwygInstance.openFileBrowser(o);\n },\n\n /**\n * @return {Boolean}\n */\n toggle: function () {\n return this.wysiwygInstance.toggle();\n },\n\n /**\n * On form validation.\n */\n onFormValidation: function () {\n this.wysiwygInstance.onFormValidation();\n },\n\n /**\n * Encodes the content so it can be inserted into the wysiwyg\n * @param {String} content - The content to be encoded\n *\n * @returns {*} - The encoded content\n */\n updateContent: function (content) {\n return this.wysiwygInstance.encodeContent(content);\n }\n\n };\n window.wysiwygSetup = wysiwygSetup;\n\n return wysiwygSetup;\n});\n","mage/adminhtml/wysiwyg/tiny_mce/plugins/magentowidget/editor_plugin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global tinymce, widgetTools, Base64 */\n/* eslint-disable strict */\ndefine([\n 'wysiwygAdapter',\n 'mage/adminhtml/events',\n 'mage/adminhtml/wysiwyg/widget'\n], function (wysiwyg, varienGlobalEvents) {\n return function (config) {\n tinymce.create('tinymce.plugins.magentowidget', {\n\n /**\n * @param {tinymce.Editor} editor - Editor instance that the plugin is initialized in.\n */\n init: function (editor) {\n var self = this;\n\n this.activePlaceholder = null;\n\n editor.addCommand('mceMagentowidget', function (img) {\n if (self.activePlaceholder) {\n img = self.activePlaceholder;\n }\n\n widgetTools.setActiveSelectedNode(img);\n widgetTools.openDialog(\n config['window_url'] + 'widget_target_id/' + editor.getElement().id + '/'\n );\n });\n\n // Register Widget plugin button\n editor.ui.registry.addIcon(\n 'magentowidget',\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 32.000000 32.000000\" ' +\n 'preserveAspectRatio=\"xMidYMid meet\"> <g transform=\"translate(0.000000,32.000000) ' +\n 'scale(0.100000,-0.100000)\" fill=\"#000000\" stroke=\"none\"> <path d=\"M130 290 c0 -5 13 -10 30 ' +\n '-10 22 0 28 -4 24 -15 -5 -11 2 -15 26 -15 21 0 30 -4 28 -12 -7 -20 -40 -22 -50 -4 -5 9 -14 16 ' +\n '-20 16 -6 0 -19 7 -28 15 -9 8 -25 12 -38 8 -33 -8 -27 -26 8 -21 34 5 40 -6 12 -21 -14 -7 -25 -6 ' +\n '-40 5 -12 8 -23 10 -27 5 -5 -8 88 -71 105 -71 3 0 29 14 58 31 l53 30 -23 18 c-13 10 -31 20 -40 ' +\n '24 -10 3 -18 11 -18 17 0 5 -13 10 -30 10 -16 0 -30 -4 -30 -10z m58 -82 c-3 -7 -15 -13 -28 -13 ' +\n '-13 0 -25 6 -27 13 -3 8 6 12 27 12 21 0 30 -4 28 -12z\"/> <path d=\"M30 151 l0 -60 61 -36 c33 ' +\n '-19 64 -35 69 -35 5 0 36 16 69 35 l61 36 0 60 0 61 -65 -37 -65 -36 -65 36 -65 37 0 -61z\"/> </g>' +\n '</svg>'\n );\n editor.ui.registry.addToggleButton('magentowidget', {\n icon: 'magentowidget',\n tooltip: jQuery.mage.__('Insert Widget'),\n\n /**\n * execute openVariablesSlideout for onAction callback\n */\n onAction: function () {\n editor.execCommand('mceMagentowidget');\n },\n\n /**\n * Add a node change handler, selects the button in the UI when a image is selected\n * @param {ToolbarToggleButtonInstanceApi} api\n */\n onSetup: function (api) {\n /**\n * NodeChange handler\n */\n editor.on('NodeChange', function (e) {\n var placeholder = e.element;\n\n if (self.isWidgetPlaceholderSelected(placeholder)) {\n widgetTools.setEditMode(true);\n api.setActive(true);\n } else {\n widgetTools.setEditMode(false);\n api.setActive(false);\n }\n });\n }\n });\n\n // Add a widget placeholder image double click callback\n editor.on('dblClick', function (e) {\n var placeholder = e.target;\n\n if (self.isWidgetPlaceholderSelected(placeholder)) {\n widgetTools.setEditMode(true);\n this.execCommand('mceMagentowidget', null);\n }\n });\n\n /**\n * Attach event handler for when wysiwyg editor is about to encode its content\n */\n varienGlobalEvents.attachEventHandler('wysiwygEncodeContent', function (content) {\n content = self.encodeWidgets(self.decodeWidgets(content));\n content = self.removeDuplicateAncestorWidgetSpanElement(content);\n\n return content;\n });\n\n /**\n * Attach event handler for when wysiwyg editor is about to decode its content\n */\n varienGlobalEvents.attachEventHandler('wysiwygDecodeContent', function (content) {\n content = self.decodeWidgets(content);\n\n return content;\n });\n\n /**\n * Attach event handler for when popups associated with wysiwyg are about to be closed\n */\n varienGlobalEvents.attachEventHandler('wysiwygClosePopups', function () {\n wysiwyg.closeEditorPopup('widget_window' + wysiwyg.getId());\n });\n },\n\n /**\n * @param {Object} placeholder - Contains the selected node\n * @returns {Boolean}\n */\n isWidgetPlaceholderSelected: function (placeholder) {\n var isSelected = false;\n\n if (placeholder.nodeName &&\n (placeholder.nodeName === 'SPAN' || placeholder.nodeName === 'IMG') &&\n placeholder.className && placeholder.className.indexOf('magento-widget') !== -1\n ) {\n this.activePlaceholder = placeholder;\n isSelected = true;\n } else {\n this.activePlaceholder = null;\n }\n\n return isSelected;\n },\n\n /**\n * Convert {{widget}} style syntax to image placeholder HTML\n * @param {String} content\n * @return {*}\n */\n encodeWidgets: function (content) {\n return content.gsub(/\\{\\{widget([\\S\\s]*?)\\}\\}/i, function (match) {\n var attributes = wysiwyg.parseAttributesString(match[1]),\n imageSrc,\n imageHtml = '';\n\n if (attributes.type) {\n attributes.type = attributes.type.replace(/\\\\\\\\/g, '\\\\');\n imageSrc = config.placeholders[attributes.type];\n\n if (imageSrc) {\n imageHtml += '<span class=\"magento-placeholder magento-widget mceNonEditable\" ' +\n 'contenteditable=\"false\">';\n } else {\n imageSrc = config['error_image_url'];\n imageHtml += '<span ' +\n 'class=\"magento-placeholder magento-placeholder-error magento-widget mceNonEditable\" ' +\n 'contenteditable=\"false\">';\n }\n\n imageHtml += '<img';\n imageHtml += ' id=\"' + Base64.idEncode(match[0]) + '\"';\n imageHtml += ' src=\"' + imageSrc + '\"';\n imageHtml += ' />';\n\n if (config.types[attributes.type]) {\n imageHtml += config.types[attributes.type];\n }\n\n imageHtml += '</span>';\n\n return imageHtml;\n }\n });\n },\n\n /**\n * Convert image placeholder HTML to {{widget}} style syntax\n * @param {String} content\n * @return {*}\n */\n decodeWidgets: function (content) {\n return content.gsub(\n /(<span class=\"[^\"]*magento-widget[^\"]*\"[^>]*>)?<img([^>]+id=\"[^>]+)>(([^>]*)<\\/span>)?/i,\n function (match) {\n var attributes = wysiwyg.parseAttributesString(match[2]),\n widgetCode,\n result = match[0];\n\n if (attributes.id) {\n try {\n widgetCode = Base64.idDecode(attributes.id);\n } catch (e) {\n // Ignore and continue.\n }\n\n if (widgetCode && widgetCode.indexOf('{{widget') !== -1) {\n result = widgetCode;\n }\n }\n\n return result;\n }\n );\n },\n\n /**\n * Tinymce has strange behavior with html and this removes one of its side-effects\n * @param {String} content\n * @return {String}\n */\n removeDuplicateAncestorWidgetSpanElement: function (content) {\n var parser, doc, returnval = '';\n\n if (!window.DOMParser) {\n return content;\n }\n\n parser = new DOMParser();\n doc = parser.parseFromString(content.replace(/"/g, '&quot;'), 'text/html');\n\n [].forEach.call(doc.querySelectorAll('.magento-widget'), function (widgetEl) {\n var widgetChildEl = widgetEl.querySelector('.magento-widget');\n\n if (!widgetChildEl) {\n return;\n }\n\n [].forEach.call(widgetEl.childNodes, function (el) {\n widgetEl.parentNode.insertBefore(el, widgetEl);\n });\n\n widgetEl.parentNode.removeChild(widgetEl);\n });\n\n returnval += doc.head ? doc.head.innerHTML.replace(/&quot;/g, '"') : '';\n returnval += doc.body ? doc.body.innerHTML.replace(/&quot;/g, '"') : '';\n\n return returnval ? returnval : content;\n },\n\n /**\n * @return {Object}\n */\n getInfo: function () {\n return {\n longname: 'Magento Widget Manager Plugin',\n author: 'Magento Core Team',\n authorurl: 'http://magentocommerce.com',\n infourl: 'http://magentocommerce.com',\n version: '1.0'\n };\n }\n });\n\n // Register plugin\n tinymce.PluginManager.add('magentowidget', tinymce.plugins.magentowidget);\n };\n});\n","mage/adminhtml/wysiwyg/tiny_mce/plugins/magentovariable/editor_plugin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global tinymce, MagentovariablePlugin, varienGlobalEvents, Base64 */\n/* eslint-disable strict */\ndefine([\n 'Magento_Variable/js/config-directive-generator',\n 'Magento_Variable/js/custom-directive-generator',\n 'wysiwygAdapter',\n 'jquery',\n 'mage/adminhtml/tools'\n], function (configDirectiveGenerator, customDirectiveGenerator, wysiwyg, jQuery) {\n return function (config) {\n tinymce.create('tinymce.plugins.magentovariable', {\n\n /**\n * Initialize editor plugin.\n *\n * @param {tinymce.editor} editor - Editor instance that the plugin is initialized in.\n */\n init: function (editor) {\n var self = this;\n\n /**\n * Add new command to open variables selector slideout.\n */\n editor.addCommand('openVariablesSlideout', function (commandConfig) {\n var selectedElement;\n\n if (commandConfig) {\n selectedElement = commandConfig.selectedElement;\n } else {\n selectedElement = tinymce.activeEditor.selection.getNode();\n }\n MagentovariablePlugin.setEditor(editor);\n MagentovariablePlugin.loadChooser(\n config.url,\n wysiwyg.getId(),\n selectedElement\n );\n });\n\n /**\n * Add button to the editor toolbar.\n */\n editor.ui.registry.addIcon(\n 'magentovariable',\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 32.000000 32.000000\" ' +\n 'preserveAspectRatio=\"xMidYMid meet\"><g transform=\"translate(0.000000,32.000000) ' +\n 'scale(0.100000,-0.100000)\" fill=\"#000000\" stroke=\"none\"><path d=\"M68 250 c-56 -44 -75 -136 -37 ' +\n '-184 27 -34 42 -33 23 2 -26 50 -9 129 38 179 26 28 10 30 -24 3z\"/><path d=\"M266 253 c5 -10 9 ' +\n '-41 9 -70 0 -42 -6 -60 -32 -97 -36 -51 -35 -56 7 -26 54 39 78 139 44 188 -18 26 -40 30 -28 5z\"/>' +\n '<path d=\"M128 223 c-15 -4 -15 -6 0 -33 16 -28 16 -30 -11 -58 -30 -31 -34 -42 -13 -42 8 0 17 11 ' +\n '20 25 4 14 11 25 16 25 5 0 12 -11 16 -25 6 -25 37 -35 49 -15 3 5 2 10 -3 10 -23 0 -20 44 5 76 ' +\n '25 34 25 34 4 34 -12 0 -20 -4 -17 -8 2 -4 0 -14 -5 -22 -7 -10 -12 -11 -15 -4 -10 25 -30 40 ' +\n '-46 37z\"/></g>' +\n '</svg>'\n );\n editor.ui.registry.addToggleButton('magentovariable', {\n icon: 'magentovariable',\n tooltip: jQuery.mage.__('Insert Variable'),\n\n /**\n * execute openVariablesSlideout for onAction callback\n */\n onAction: function () {\n editor.execCommand('openVariablesSlideout');\n },\n\n /**\n * Highlight or dismiss Insert Variable button when variable is selected or deselected.\n */\n onSetup: function (api) {\n /**\n * Toggle active state of Insert Variable button.\n *\n * @param {Object} e\n */\n var toggleVariableButton = function (e) {\n api.setActive(false);\n\n if (jQuery(e.target).hasClass('magento-variable')) {\n api.setActive(true);\n }\n };\n\n editor.on('click', toggleVariableButton);\n editor.on('change', toggleVariableButton);\n }\n });\n\n /**\n * Double click handler on the editor to handle dbl click on variable placeholder.\n */\n editor.on('dblclick', function (evt) {\n if (jQuery(evt.target).hasClass('magento-variable')) {\n editor.selection.collapse(false);\n editor.execCommand('openVariablesSlideout', {\n ui: true,\n selectedElement: evt.target\n });\n }\n });\n\n /**\n * Attach event handler for when wysiwyg editor is about to encode its content\n */\n varienGlobalEvents.attachEventHandler('wysiwygEncodeContent', function (content) {\n content = self.encodeVariables(content);\n\n return content;\n });\n\n /**\n * Attach event handler for when wysiwyg editor is about to decode its content\n */\n varienGlobalEvents.attachEventHandler('wysiwygDecodeContent', function (content) {\n content = self.decodeVariables(content);\n\n return content;\n });\n },\n\n /**\n * Encode variables in content\n *\n * @param {String} content\n * @returns {*}\n */\n encodeVariables: function (content) {\n content = content.gsub(/\\{\\{config path=\\\"([^\\\"]+)\\\"\\}\\}/i, function (match) {\n var path = match[1],\n magentoVariables,\n imageHtml;\n\n magentoVariables = JSON.parse(config.placeholders);\n\n if (magentoVariables[match[1]] && magentoVariables[match[1]]['variable_type'] === 'default') {\n imageHtml = '<span id=\"%id\" class=\"magento-variable magento-placeholder mceNonEditable\">' +\n '%s</span>';\n imageHtml = imageHtml.replace('%s', magentoVariables[match[1]]['variable_name']);\n } else {\n imageHtml = '<span id=\"%id\" class=\"' +\n 'magento-variable magento-placeholder magento-placeholder-error ' +\n 'mceNonEditable' +\n '\">' +\n 'Not found' +\n '</span>';\n }\n\n return imageHtml.replace('%id', Base64.idEncode(path));\n });\n\n content = content.gsub(/\\{\\{customVar code=([^\\}\\\"]+)\\}\\}/i, function (match) {\n var path = match[1],\n magentoVariables,\n imageHtml;\n\n magentoVariables = JSON.parse(config.placeholders);\n\n if (magentoVariables[match[1]] && magentoVariables[match[1]]['variable_type'] === 'custom') {\n imageHtml = '<span id=\"%id\" class=\"magento-variable magento-custom-var magento-placeholder ' +\n 'mceNonEditable\">%s</span>';\n imageHtml = imageHtml.replace('%s', magentoVariables[match[1]]['variable_name']);\n } else {\n imageHtml = '<span id=\"%id\" class=\"' +\n 'magento-variable magento-custom-var magento-placeholder ' +\n 'magento-placeholder-error mceNonEditable' +\n '\">' +\n match[1] +\n '</span>';\n }\n\n return imageHtml.replace('%id', Base64.idEncode(path));\n });\n\n return content;\n },\n\n /**\n * Decode variables in content.\n *\n * @param {String} content\n * @returns {String}\n */\n decodeVariables: function (content) {\n var doc = new DOMParser().parseFromString(content.replace(/"/g, '&quot;'), 'text/html'),\n returnval = '';\n\n [].forEach.call(doc.querySelectorAll('span.magento-variable'), function (el) {\n var $el = jQuery(el);\n\n if ($el.hasClass('magento-custom-var')) {\n $el.replaceWith(\n customDirectiveGenerator.processConfig(\n Base64.idDecode(\n $el.attr('id')\n )\n )\n );\n } else {\n $el.replaceWith(\n configDirectiveGenerator.processConfig(\n Base64.idDecode(\n $el.attr('id')\n )\n )\n );\n }\n });\n\n returnval += doc.head ? doc.head.innerHTML.replace(/&quot;/g, '"') : '';\n returnval += doc.body ? doc.body.innerHTML.replace(/&quot;/g, '"') : '';\n\n return returnval ? returnval : content;\n },\n\n /**\n * @return {Object}\n */\n getInfo: function () {\n return {\n longname: 'Magento Variable Manager Plugin',\n author: 'Magento Core Team',\n authorurl: 'http://magentocommerce.com',\n infourl: 'http://magentocommerce.com',\n version: '1.0'\n };\n }\n });\n\n /**\n * Register plugin\n */\n tinymce.PluginManager.add('magentovariable', tinymce.plugins.magentovariable);\n };\n});\n","mage/backend/action-link.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'jquery/ui'\n], function ($) {\n 'use strict';\n\n $.widget('mage.actionLink', {\n /**\n * Button creation\n * @protected\n */\n _create: function () {\n this._bind();\n },\n\n /**\n * Bind handler on button click\n * @protected\n */\n _bind: function () {\n var keyCode = $.ui.keyCode;\n\n this._on({\n /**\n * @param {jQuery.Event} e\n */\n mousedown: function (e) {\n this._stopPropogation(e);\n },\n\n /**\n * @param {jQuery.Event} e\n */\n mouseup: function (e) {\n this._stopPropogation(e);\n },\n\n /**\n * @param {jQuery.Event} e\n */\n click: function (e) {\n this._stopPropogation(e);\n this._triggerEvent();\n },\n\n /**\n * @param {jQuery.Event} e\n */\n keydown: function (e) {\n switch (e.keyCode) {\n case keyCode.ENTER:\n case keyCode.NUMPAD_ENTER:\n this._stopPropogation(e);\n this._triggerEvent();\n break;\n }\n },\n\n /**\n * @param {jQuery.Event} e\n */\n keyup: function (e) {\n switch (e.keyCode) {\n case keyCode.ENTER:\n case keyCode.NUMPAD_ENTER:\n this._stopPropogation(e);\n break;\n }\n }\n });\n },\n\n /**\n * @param {Object} e - event object\n * @private\n */\n _stopPropogation: function (e) {\n e.stopImmediatePropagation();\n e.preventDefault();\n },\n\n /**\n * @private\n */\n _triggerEvent: function () {\n $(this.options.related || this.element)\n .trigger(this.options.event, this.options.eventData ? [this.options.eventData] : [{}]);\n }\n });\n\n return $.mage.actionLink;\n});\n","mage/backend/menu.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'jquery/ui'\n], function ($) {\n 'use strict';\n\n $.widget('mage.menu', {\n widgetEventPrefix: 'menu',\n version: '1.10.1',\n defaultElement: '<ul>',\n delay: 300,\n options: {\n icons: {\n submenu: 'ui-icon-carat-1-e'\n },\n menus: 'ul',\n position: {\n my: 'left top',\n at: 'right top'\n },\n role: 'menu',\n\n // callbacks\n blur: null,\n focus: null,\n select: null\n },\n\n /**\n * @private\n */\n _create: function () {\n this.activeMenu = this.element;\n // flag used to prevent firing of the click handler\n // as the event bubbles up through nested menus\n this.mouseHandled = false;\n this.element\n .uniqueId()\n .addClass('ui-menu ui-widget ui-widget-content ui-corner-all')\n .toggleClass('ui-menu-icons', !!this.element.find('.ui-icon').length)\n .attr({\n role: this.options.role,\n tabIndex: 0\n })\n // need to catch all clicks on disabled menu\n // not possible through _on\n .on('click' + this.eventNamespace, $.proxy(function (event) {\n if (this.options.disabled) {\n event.preventDefault();\n }\n }, this));\n\n if (this.options.disabled) {\n this.element\n .addClass('ui-state-disabled')\n .attr('aria-disabled', 'true');\n }\n\n this._on({\n /**\n * Prevent focus from sticking to links inside menu after clicking\n * them (focus should always stay on UL during navigation).\n */\n 'mousedown .ui-menu-item > a': function (event) {\n event.preventDefault();\n },\n\n /**\n * Prevent focus from sticking to links inside menu after clicking\n * them (focus should always stay on UL during navigation).\n */\n 'click .ui-state-disabled > a': function (event) {\n event.preventDefault();\n },\n\n /**\n * @param {jQuery.Event} event\n */\n 'click .ui-menu-item:has(a)': function (event) {\n var target = $(event.target).closest('.ui-menu-item');\n\n if (!this.mouseHandled && target.not('.ui-state-disabled').length) {\n this.mouseHandled = true;\n\n this.select(event);\n // Open submenu on click\n if (target.has('.ui-menu').length) {\n this.expand(event);\n } else if (!this.element.is(':focus')) {\n // Redirect focus to the menu\n this.element.trigger('focus', [true]);\n\n // If the active item is on the top level, let it stay active.\n // Otherwise, blur the active item since it is no longer visible.\n if (this.active && this.active.parents('.ui-menu').length === 1) { //eslint-disable-line\n clearTimeout(this.timer);\n }\n }\n }\n },\n\n /**\n * @param {jQuery.Event} event\n */\n 'mouseenter .ui-menu-item': function (event) {\n var target = $(event.currentTarget);\n\n // Remove ui-state-active class from siblings of the newly focused menu item\n // to avoid a jump caused by adjacent elements both having a class with a border\n target.siblings().children('.ui-state-active').removeClass('ui-state-active');\n this.focus(event, target);\n },\n mouseleave: 'collapseAll',\n 'mouseleave .ui-menu': 'collapseAll',\n\n /**\n * @param {jQuery.Event} event\n * @param {*} keepActiveItem\n */\n focus: function (event, keepActiveItem) {\n // If there's already an active item, keep it active\n // If not, activate the first item\n var item = this.active || this.element.children('.ui-menu-item').eq(0);\n\n if (!keepActiveItem) {\n this.focus(event, item);\n }\n },\n\n /**\n * @param {jQuery.Event} event\n */\n blur: function (event) {\n this._delay(function () {\n if (!$.contains(this.element[0], this.document[0].activeElement)) {\n this.collapseAll(event);\n }\n });\n },\n keydown: '_keydown'\n });\n\n this.refresh();\n\n // Clicks outside of a menu collapse any open menus\n this._on(this.document, {\n /**\n * @param {jQuery.Event} event\n */\n click: function (event) {\n if (!$(event.target).closest('.ui-menu').length) {\n this.collapseAll(event);\n }\n\n // Reset the mouseHandled flag\n this.mouseHandled = false;\n }\n });\n },\n\n /**\n * @private\n */\n _destroy: function () {\n // Destroy (sub)menus\n this.element\n .removeAttr('aria-activedescendant')\n .find('.ui-menu').addBack()\n .removeClass('ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons')\n .removeAttr('role')\n .removeAttr('tabIndex')\n .removeAttr('aria-labelledby')\n .removeAttr('aria-expanded')\n .removeAttr('aria-hidden')\n .removeAttr('aria-disabled')\n .removeUniqueId()\n .show();\n\n // Destroy menu items\n this.element.find('.ui-menu-item')\n .removeClass('ui-menu-item')\n .removeAttr('role')\n .removeAttr('aria-disabled')\n .children('a')\n .removeUniqueId()\n .removeClass('ui-corner-all ui-state-hover')\n .removeAttr('tabIndex')\n .removeAttr('role')\n .removeAttr('aria-haspopup')\n .children().each(function () {\n var elem = $(this);\n\n if (elem.data('ui-menu-submenu-carat')) {\n elem.remove();\n }\n });\n\n // Destroy menu dividers\n this.element.find('.ui-menu-divider').removeClass('ui-menu-divider ui-widget-content');\n },\n\n /**\n * @param {jQuery.Event} event\n * @private\n */\n _keydown: function (event) {\n var match, prev, character, skip, regex,\n preventDefault = true;\n\n /**\n * @param {String} value\n */\n function escape(value) {\n return value.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, '\\\\$&');\n }\n\n switch (event.keyCode) {\n case $.ui.keyCode.PAGE_UP:\n this.previousPage(event);\n break;\n\n case $.ui.keyCode.PAGE_DOWN:\n this.nextPage(event);\n break;\n\n case $.ui.keyCode.HOME:\n this._move('first', 'first', event);\n break;\n\n case $.ui.keyCode.END:\n this._move('last', 'last', event);\n break;\n\n case $.ui.keyCode.UP:\n this.previous(event);\n break;\n\n case $.ui.keyCode.DOWN:\n this.next(event);\n break;\n\n case $.ui.keyCode.LEFT:\n this.collapse(event);\n break;\n\n case $.ui.keyCode.RIGHT:\n if (this.active && !this.active.is('.ui-state-disabled')) {\n this.expand(event);\n }\n break;\n\n case $.ui.keyCode.ENTER:\n case $.ui.keyCode.SPACE:\n this._activate(event);\n break;\n\n case $.ui.keyCode.ESCAPE:\n this.collapse(event);\n break;\n\n default:\n preventDefault = false;\n prev = this.previousFilter || '';\n character = String.fromCharCode(event.keyCode);\n skip = false;\n\n clearTimeout(this.filterTimer);\n\n if (character === prev) {\n skip = true;\n } else {\n character = prev + character;\n }\n\n regex = new RegExp('^' + escape(character), 'i');\n match = this.activeMenu.children('.ui-menu-item').filter(function () {\n return regex.test($(this).children('a').text());\n });\n match = skip && match.index(this.active.next()) !== -1 ?\n this.active.nextAll('.ui-menu-item') :\n match;\n\n // If no matches on the current filter, reset to the last character pressed\n // to move down the menu to the first item that starts with that character\n if (!match.length) {\n character = String.fromCharCode(event.keyCode);\n regex = new RegExp('^' + escape(character), 'i');\n match = this.activeMenu.children('.ui-menu-item').filter(function () {\n return regex.test($(this).children('a').text());\n });\n }\n\n if (match.length) {\n this.focus(event, match);\n\n if (match.length > 1) { //eslint-disable-line max-depth\n this.previousFilter = character;\n this.filterTimer = this._delay(function () {\n delete this.previousFilter;\n }, 1000);\n } else {\n delete this.previousFilter;\n }\n } else {\n delete this.previousFilter;\n }\n }\n\n if (preventDefault) {\n event.preventDefault();\n }\n },\n\n /**\n * @param {jQuery.Event} event\n * @private\n */\n _activate: function (event) {\n if (!this.active.is('.ui-state-disabled')) {\n if (this.active.children('a[aria-haspopup=\"true\"]').length) {\n this.expand(event);\n } else {\n this.select(event);\n }\n }\n },\n\n /**\n * Refresh.\n */\n refresh: function () {\n var menus,\n icon = this.options.icons.submenu,\n submenus = this.element.find(this.options.menus);\n\n // Initialize nested menus\n submenus.filter(':not(.ui-menu)')\n .addClass('ui-menu ui-widget ui-widget-content ui-corner-all')\n .hide()\n .attr({\n role: this.options.role,\n 'aria-hidden': 'true',\n 'aria-expanded': 'false'\n })\n .each(function () {\n var menu = $(this),\n item = menu.prev('a'),\n submenuCarat = $('<span>')\n .addClass('ui-menu-icon ui-icon ' + icon)\n .data('ui-menu-submenu-carat', true);\n\n item\n .attr('aria-haspopup', 'true')\n .prepend(submenuCarat);\n menu.attr('aria-labelledby', item.attr('id'));\n });\n\n menus = submenus.add(this.element);\n\n // Don't refresh list items that are already adapted\n menus.children(':not(.ui-menu-item):has(a)')\n .addClass('ui-menu-item')\n .attr('role', 'presentation')\n .children('a')\n .uniqueId()\n .addClass('ui-corner-all')\n .attr({\n tabIndex: -1,\n role: this._itemRole()\n });\n\n // Initialize unlinked menu-items containing spaces and/or dashes only as dividers\n menus.children(':not(.ui-menu-item)').each(function () {\n var item = $(this);\n\n // hyphen, em dash, en dash\n if (!/[^\\-\\u2014\\u2013\\s]/.test(item.text())) {\n item.addClass('ui-widget-content ui-menu-divider');\n }\n });\n\n // Add aria-disabled attribute to any disabled menu item\n menus.children('.ui-state-disabled').attr('aria-disabled', 'true');\n\n // If the active item has been removed, blur the menu\n if (this.active && !$.contains(this.element[0], this.active[0])) {\n this.blur();\n }\n },\n\n /**\n * @return {*}\n * @private\n */\n _itemRole: function () {\n return {\n menu: 'menuitem',\n listbox: 'option'\n }[this.options.role];\n },\n\n /**\n * @param {String} key\n * @param {*} value\n * @private\n */\n _setOption: function (key, value) {\n if (key === 'icons') {\n this.element.find('.ui-menu-icon')\n .removeClass(this.options.icons.submenu)\n .addClass(value.submenu);\n }\n this._super(key, value);\n },\n\n /**\n * @param {jQuery.Event} event\n * @param {Object} item\n */\n focus: function (event, item) {\n var nested, focused;\n\n this.blur(event, event && event.type === 'focus');\n\n this._scrollIntoView(item);\n\n this.active = item.first();\n focused = this.active.children('a').addClass('ui-state-focus');\n // Only update aria-activedescendant if there's a role\n // otherwise we assume focus is managed elsewhere\n if (this.options.role) {\n this.element.attr('aria-activedescendant', focused.attr('id'));\n }\n\n // Highlight active parent menu item, if any\n this.active\n .parent()\n .closest('.ui-menu-item')\n .children('a:first')\n .addClass('ui-state-active');\n\n if (event && event.type === 'keydown') {\n this._close();\n } else {\n this.timer = this._delay(function () {\n this._close();\n }, this.delay);\n }\n\n nested = item.children('.ui-menu');\n\n if (nested.length && /^mouse/.test(event.type)) {\n this._startOpening(nested);\n }\n this.activeMenu = item.parent();\n\n this._trigger('focus', event, {\n item: item\n });\n },\n\n /**\n * @param {Object} item\n * @private\n */\n _scrollIntoView: function (item) {\n var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;\n\n if (this._hasScroll()) {\n borderTop = parseFloat($.css(this.activeMenu[0], 'borderTopWidth')) || 0;\n paddingTop = parseFloat($.css(this.activeMenu[0], 'paddingTop')) || 0;\n offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;\n scroll = this.activeMenu.scrollTop();\n elementHeight = this.activeMenu.height();\n itemHeight = item.height();\n\n if (offset < 0) {\n this.activeMenu.scrollTop(scroll + offset);\n } else if (offset + itemHeight > elementHeight) {\n this.activeMenu.scrollTop(scroll + offset - elementHeight + itemHeight);\n }\n }\n },\n\n /**\n * @param {jQuery.Event} event\n * @param {*} fromFocus\n */\n blur: function (event, fromFocus) {\n if (!fromFocus) {\n clearTimeout(this.timer);\n }\n\n if (!this.active) {\n return;\n }\n\n this.active.children('a').removeClass('ui-state-focus');\n this.active = null;\n\n this._trigger('blur', event, {\n item: this.active\n });\n },\n\n /**\n * @param {*} submenu\n * @private\n */\n _startOpening: function (submenu) {\n clearTimeout(this.timer);\n\n // Don't open if already open fixes a Firefox bug that caused a .5 pixel\n // shift in the submenu position when mousing over the carat icon\n if (submenu.attr('aria-hidden') !== 'true') {\n return;\n }\n\n this.timer = this._delay(function () {\n this._close();\n this._open(submenu);\n }, this.delay);\n },\n\n /**\n * @param {*} submenu\n * @private\n */\n _open: function (submenu) {\n var position = $.extend({\n of: this.active\n }, this.options.position);\n\n clearTimeout(this.timer);\n this.element.find('.ui-menu').not(submenu.parents('.ui-menu'))\n .hide()\n .attr('aria-hidden', 'true');\n\n submenu\n .show()\n .removeAttr('aria-hidden')\n .attr('aria-expanded', 'true')\n .position(position);\n },\n\n /**\n * @param {jQuery.Event} event\n * @param {*} all\n */\n collapseAll: function (event, all) {\n clearTimeout(this.timer);\n this.timer = this._delay(function () {\n // If we were passed an event, look for the submenu that contains the event\n var currentMenu = all ? this.element :\n $(event && event.target).closest(this.element.find('.ui-menu'));\n\n // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway\n if (!currentMenu.length) {\n currentMenu = this.element;\n }\n\n this._close(currentMenu);\n\n this.blur(event);\n this.activeMenu = currentMenu;\n }, this.delay);\n },\n\n // With no arguments, closes the currently active menu - if nothing is active\n // it closes all menus. If passed an argument, it will search for menus BELOW\n /**\n * With no arguments, closes the currently active menu - if nothing is active\n * it closes all menus. If passed an argument, it will search for menus BELOW.\n *\n * @param {*} startMenu\n * @private\n */\n _close: function (startMenu) {\n if (!startMenu) {\n startMenu = this.active ? this.active.parent() : this.element;\n }\n\n startMenu\n .find('.ui-menu')\n .hide()\n .attr('aria-hidden', 'true')\n .attr('aria-expanded', 'false')\n .end()\n .find('a.ui-state-active')\n .removeClass('ui-state-active');\n },\n\n /**\n * @param {jQuery.Event} event\n */\n collapse: function (event) {\n var newItem = this.active &&\n this.active.parent().closest('.ui-menu-item', this.element);\n\n if (newItem && newItem.length) {\n this._close();\n this.focus(event, newItem);\n }\n },\n\n /**\n * @param {jQuery.Event} event\n */\n expand: function (event) {\n var newItem = this.active &&\n this.active\n .children('.ui-menu ')\n .children('.ui-menu-item')\n .first();\n\n if (newItem && newItem.length) {\n this._open(newItem.parent());\n\n // Delay so Firefox will not hide activedescendant change in expanding submenu from AT\n this._delay(function () {\n this.focus(event, newItem);\n });\n }\n },\n\n /**\n * @param {jQuery.Event} event\n */\n next: function (event) {\n this._move('next', 'first', event);\n },\n\n /**\n * @param {jQuery.Event} event\n */\n previous: function (event) {\n this._move('prev', 'last', event);\n },\n\n /**\n * @return {null|Boolean}\n */\n isFirstItem: function () {\n return this.active && !this.active.prevAll('.ui-menu-item').length;\n },\n\n /**\n * @return {null|Boolean}\n */\n isLastItem: function () {\n return this.active && !this.active.nextAll('.ui-menu-item').length;\n },\n\n /**\n * @param {*} direction\n * @param {*} filter\n * @param {jQuery.Event} event\n * @private\n */\n _move: function (direction, filter, event) {\n var next;\n\n if (this.active) {\n if (direction === 'first' || direction === 'last') {\n next = this.active\n [direction === 'first' ? 'prevAll' : 'nextAll']('.ui-menu-item')\n .eq(-1);\n } else {\n next = this.active\n [direction + 'All']('.ui-menu-item')\n .eq(0);\n }\n }\n\n if (!next || !next.length || !this.active) {\n next = this.activeMenu.children('.ui-menu-item')[filter]();\n }\n\n this.focus(event, next);\n },\n\n /**\n * @param {jQuery.Event} event\n */\n nextPage: function (event) {\n var item, base, height;\n\n if (!this.active) {\n this.next(event);\n\n return;\n }\n\n if (this.isLastItem()) {\n return;\n }\n\n if (this._hasScroll()) {\n base = this.active.offset().top;\n height = this.element.height();\n this.active.nextAll('.ui-menu-item').each(function () {\n item = $(this);\n\n return item.offset().top - base - height < 0;\n });\n\n this.focus(event, item);\n } else {\n this.focus(event, this.activeMenu.children('.ui-menu-item')\n [!this.active ? 'first' : 'last']());\n }\n },\n\n /**\n * @param {jQuery.Event} event\n */\n previousPage: function (event) {\n var item, base, height;\n\n if (!this.active) {\n this.next(event);\n\n return;\n }\n\n if (this.isFirstItem()) {\n return;\n }\n\n if (this._hasScroll()) {\n base = this.active.offset().top;\n height = this.element.height();\n this.active.prevAll('.ui-menu-item').each(function () {\n item = $(this);\n\n return item.offset().top - base + height > 0;\n });\n\n this.focus(event, item);\n } else {\n this.focus(event, this.activeMenu.children('.ui-menu-item').first());\n }\n },\n\n /**\n * @return {Boolean}\n * @private\n */\n _hasScroll: function () {\n return this.element.outerHeight() < this.element.prop('scrollHeight');\n },\n\n /**\n * @param {jQuery.Event} event\n */\n select: function (event) {\n // TODO: It should never be possible to not have an active item at this\n // point, but the tests don't trigger mouseenter before click.\n var ui;\n\n this.active = this.active || $(event.target).closest('.ui-menu-item');\n ui = {\n item: this.active\n };\n\n if (!this.active.has('.ui-menu').length) {\n this.collapseAll(event, true);\n }\n this._trigger('select', event, ui);\n }\n });\n\n return $.mage.menu;\n});\n","mage/backend/tree-suggest.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'jquery/ui',\n 'jquery/jstree/jquery.jstree',\n 'mage/backend/suggest'\n], function ($) {\n 'use strict';\n\n /* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */\n var hover_node, dehover_node, select_node, init;\n\n $.extend(true, $, {\n // @TODO: Move method 'treeToList' in file with utility functions\n mage: {\n /**\n * @param {Array} list\n * @param {Object} nodes\n * @param {*} level\n * @param {*} path\n * @return {*}\n */\n treeToList: function (list, nodes, level, path) {\n $.each(nodes, function () {\n if (typeof this === 'object') {\n list.push({\n label: this.label,\n id: this.id,\n level: level,\n item: this,\n path: path + this.label\n });\n\n if (this.children) {\n $.mage.treeToList(list, this.children, level + 1, path + this.label + ' / ');\n }\n }\n });\n\n return list;\n }\n }\n });\n\n hover_node = $.jstree.core.prototype.hover_node;\n dehover_node = $.jstree.core.prototype.dehover_node;\n select_node = $.jstree.core.prototype.select_node;\n init = $.jstree.core.prototype.init;\n\n $.extend(true, $.jstree.core.prototype, {\n /**\n * @override\n */\n init: function () {\n this.get_container()\n .show()\n .on('keydown', $.proxy(function (e) {\n var o;\n\n if (e.keyCode === $.ui.keyCode.ENTER) {\n o = this.data.ui.hovered || this.data.ui.last_selected || -1;\n this.select_node(o, true);\n }\n }, this));\n init.call(this);\n },\n\n /**\n * @override\n */\n hover_node: function (obj) {\n hover_node.apply(this, arguments);\n obj = this._get_node(obj);\n\n if (!obj.length) {\n return false;\n }\n this.get_container().trigger('hover_node', [{\n item: obj.find('a:first')\n }]);\n },\n\n /**\n * @override\n */\n dehover_node: function () {\n dehover_node.call(this);\n this.get_container().trigger('dehover_node');\n },\n\n /**\n * @override\n */\n select_node: function (o) {\n var node;\n\n select_node.apply(this, arguments);\n node = this._get_node(o);\n\n (node ? $(node) : this.data.ui.last_selected)\n .trigger('select_tree_node');\n }\n });\n\n $.widget('mage.treeSuggest', $.mage.suggest, {\n widgetEventPrefix: 'suggest',\n options: {\n template:\n '<% if (data.items.length) { %>' +\n '<% if (data.allShown()) { %>' +\n '<% if (typeof data.nested === \"undefined\") { %>' +\n '<div style=\"display:none;\" data-mage-init=\"{"jstree":{"plugins":["themes","html_data","ui","hotkeys"],"themes":{"theme":"default","dots":false,"icons":false}}}\">' + //eslint-disable-line max-len\n '<% } %>' +\n '<ul>' +\n '<% _.each(data.items, function(value) { %>' +\n '<li class=\"<% if (data.itemSelected(value)) { %>mage-suggest-selected<% } %>' +\n ' <% if (value.is_active == 0) { %> mage-suggest-not-active<% } %>\">' +\n '<a href=\"#\" <%= data.optionData(value) %>><%- value.label %></a>' +\n '<% if (value.children && value.children.length) { %>' +\n '<%= data.renderTreeLevel(value.children) %>' +\n '<% } %>' +\n '</li>' +\n '<% }); %>' +\n '</ul>' +\n '<% if (typeof data.nested === \"undefined\") { %>' +\n '</div>' +\n '<% } %>' +\n '<% } else { %>' +\n '<ul data-mage-init=\"{"menu":[]}\">' +\n '<% _.each(data.items, function(value) { %>' +\n '<% if (!data.itemSelected(value)) {%>' +\n '<li <%= data.optionData(value) %>>' +\n '<a href=\"#\">' +\n '<span class=\"category-label\"><%- value.label %></span>' +\n '<span class=\"category-path\"><%- value.path %></span>' +\n '</a>' +\n '</li>' +\n '<% } %>' +\n '<% }); %>' +\n '</ul>' +\n '<% } %>' +\n '<% } else { %>' +\n '<span class=\"mage-suggest-no-records\"><%- data.noRecordsText %></span>' +\n '<% } %>',\n controls: {\n selector: ':ui-menu, :mage-menu, .jstree',\n eventsMap: {\n focus: ['menufocus', 'hover_node'],\n blur: ['menublur', 'dehover_node'],\n select: ['menuselect', 'select_tree_node']\n }\n }\n },\n\n /**\n * @override\n */\n _bind: function () {\n this._super();\n this._on({\n /**\n * @param {jQuery.Event} event\n */\n keydown: function (event) {\n var keyCode = $.ui.keyCode;\n\n switch (event.keyCode) {\n case keyCode.LEFT:\n case keyCode.RIGHT:\n\n if (this.isDropdownShown()) {\n event.preventDefault();\n this._proxyEvents(event);\n }\n break;\n }\n }\n });\n },\n\n /**\n * @override\n */\n close: function (e) {\n var eType = e ? e.type : null;\n\n if (eType === 'select_tree_node') {\n this.element.focus();\n } else {\n this._superApply(arguments);\n }\n },\n\n /**\n * @override\n */\n _filterSelected: function (items, context) {\n if (context._allShown) {\n return items;\n }\n\n return this._superApply(arguments);\n },\n\n /**\n * @override\n */\n _prepareDropdownContext: function () {\n var context = this._superApply(arguments),\n optionData = context.optionData,\n templates = this.templates,\n tmplName = this.templateName;\n\n /**\n * @param {Object} item\n * @return {*|String}\n */\n context.optionData = function (item) {\n item = $.extend({}, item);\n delete item.children;\n\n return optionData(item);\n };\n\n return $.extend(context, {\n /**\n * @param {*} children\n * @return {*|jQuery}\n */\n renderTreeLevel: function (children) {\n var _context = $.extend({}, this, {\n items: children,\n nested: true\n }),\n tmpl = templates[tmplName];\n\n tmpl = tmpl({\n data: _context\n });\n\n return $('<div>').append($(tmpl)).html();\n }\n });\n },\n\n /**\n * @override\n */\n _processResponse: function (e, items, context) {\n var control;\n\n if (context && !context._allShown) {\n items = this.filter($.mage.treeToList([], items, 0, ''), this._term);\n }\n control = this.dropdown.find(this._control.selector);\n\n if (control.length && control.hasClass('jstree')) {\n control.jstree('destroy');\n }\n this._superApply([e, items, context]);\n }\n });\n\n return $.mage.treeSuggest;\n});\n","mage/backend/validation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global BASE_URL, alertAlreadyDisplayed */\ndefine([\n 'jquery',\n 'underscore',\n 'Magento_Ui/js/modal/alert',\n 'jquery/ui',\n 'jquery/validate',\n 'mage/translate',\n 'mage/validation'\n], function ($, _, alert) {\n 'use strict';\n\n $.extend(true, $.validator.prototype, {\n /**\n * Focus invalid fields\n */\n focusInvalid: function () {\n if (this.settings.focusInvalid) {\n try {\n $(this.errorList.length && this.errorList[0].element || [])\n .trigger('focus')\n .trigger('focusin');\n } catch (e) {\n // ignore IE throwing errors when focusing hidden elements\n }\n }\n },\n\n /**\n * Elements.\n */\n elements: function () {\n var validator = this,\n rulesCache = {};\n\n // select all valid inputs inside the form (no submit or reset buttons)\n return $(this.currentForm)\n .find('input, select, textarea')\n .not(this.settings.forceIgnore)\n .not(':submit, :reset, :image, [disabled]')\n .not(this.settings.ignore)\n .filter(function () {\n if (!this.name && validator.settings.debug && window.console) {\n console.error('%o has no name assigned', this);\n }\n\n // select only the first element for each name, and only those with rules specified\n if (this.name in rulesCache || !validator.objectLength($(this).rules())) {\n return false;\n }\n\n rulesCache[this.name] = true;\n\n return true;\n });\n }\n });\n\n $.extend($.fn, {\n /**\n * ValidationDelegate overridden for those cases where the form is located in another form,\n * to avoid not correct working of validate plug-in\n * @override\n * @param {String} delegate - selector, if event target matched against this selector,\n * then event will be delegated\n * @param {String} type - event type\n * @param {Function} handler - event handler\n * @return {Element}\n */\n validateDelegate: function (delegate, type, handler) {\n return this.on(type, $.proxy(function (event) {\n var target = $(event.target),\n form = target[0].form;\n\n if (form && $(form).is(this) && $.data(form, 'validator') && target.is(delegate)) {\n return handler.apply(target, arguments);\n }\n }, this));\n }\n });\n\n $.widget('mage.validation', $.mage.validation, {\n options: {\n messagesId: 'messages',\n forceIgnore: '',\n ignore: ':disabled, .ignore-validate, .no-display.template, ' +\n ':disabled input, .ignore-validate input, .no-display.template input, ' +\n ':disabled select, .ignore-validate select, .no-display.template select, ' +\n ':disabled textarea, .ignore-validate textarea, .no-display.template textarea',\n errorElement: 'label',\n errorUrl: typeof BASE_URL !== 'undefined' ? BASE_URL : null,\n\n /**\n * @param {HTMLElement} element\n */\n highlight: function (element) {\n if ($.validator.defaults.highlight && typeof $.validator.defaults.highlight === 'function') {\n $.validator.defaults.highlight.apply(this, arguments);\n }\n $(element).trigger('highlight.validate');\n },\n\n /**\n * @param {HTMLElement} element\n */\n unhighlight: function (element) {\n if ($.validator.defaults.unhighlight && typeof $.validator.defaults.unhighlight === 'function') {\n $.validator.defaults.unhighlight.apply(this, arguments);\n }\n $(element).trigger('unhighlight.validate');\n }\n },\n\n /**\n * Validation creation\n * @protected\n */\n _create: function () {\n if (!this.options.submitHandler && typeof this.options.submitHandler !== 'function') {\n if (!this.options.frontendOnly && this.options.validationUrl) {\n this.options.submitHandler = $.proxy(this._ajaxValidate, this);\n } else {\n this.options.submitHandler = $.proxy(this._submit, this);\n }\n }\n this.element.on('resetElement', function (e) {\n $(e.target).rules('remove');\n });\n this._super('_create');\n },\n\n /**\n * ajax validation\n * @protected\n */\n _ajaxValidate: function () {\n $.ajax({\n url: this.options.validationUrl,\n type: 'POST',\n dataType: 'json',\n data: this.element.serialize(),\n context: $('body'),\n success: $.proxy(this._onSuccess, this),\n error: $.proxy(this._onError, this),\n showLoader: true,\n dontHide: false\n });\n },\n\n /**\n * Process ajax success.\n *\n * @protected\n * @param {Object} response\n */\n _onSuccess: function (response) {\n if (!response.error) {\n this._submit();\n } else {\n this._showErrors(response);\n $(this.element[0]).trigger('afterValidate.error');\n $('body').trigger('processStop');\n }\n },\n\n /**\n * Submitting a form.\n * @private\n */\n _submit: function () {\n $(this.element[0]).trigger('afterValidate.beforeSubmit');\n this.element[0].submit();\n },\n\n /**\n * Displays errors after backend validation.\n *\n * @param {Object} data - Data that came from backend.\n */\n _showErrors: function (data) {\n $('body').notification('clear')\n .notification('add', {\n error: data.error,\n message: data.message,\n\n /**\n * @param {*} message\n */\n insertMethod: function (message) {\n $('.messages:first').html(message);\n }\n });\n },\n\n /**\n * Tries to retrieve element either by id or by inputs' name property.\n * @param {String} code - String to search by.\n * @returns {jQuery} jQuery element.\n */\n _getByCode: function (code) {\n var parent = this.element[0],\n element;\n\n element = parent.querySelector('#' + code) || parent.querySelector('input[name=' + code + ']');\n\n return $(element);\n },\n\n /**\n * Process ajax error\n * @protected\n */\n _onError: function () {\n $(this.element[0]).trigger('afterValidate.error');\n $('body').trigger('processStop');\n\n if (this.options.errorUrl) {\n location.href = this.options.errorUrl;\n }\n }\n });\n\n _.each({\n 'validate-greater-zero-based-on-option': [\n function (v, el) {\n var optionType = $(el)\n .closest('.form-list')\n .prev('.fieldset-alt')\n .find('select.select-product-option-type'),\n optionTypeVal = optionType.val();\n\n v = Number(v) || 0;\n\n if (optionType && (optionTypeVal == 'checkbox' || optionTypeVal == 'multi') && v <= 0) { //eslint-disable-line\n return false;\n }\n\n return true;\n },\n $.mage.__('Please enter a number greater 0 in this field.')\n ],\n 'validate-rating': [\n function () {\n var ratings = $('#detailed_rating').find('.field-rating'),\n noError = true;\n\n ratings.each(function (index, rating) {\n noError = noError && $(rating).find('input:checked').length > 0;\n });\n\n return noError;\n },\n $.mage.__('Please select one of each ratings above.')\n ],\n 'validate-downloadable-file': [\n function (v, element) {\n var elmParent = $(element).parent(),\n linkType = elmParent.find('input[value=\"file\"]'),\n newFileContainer;\n\n if (linkType.is(':checked') && (v === '' || v === '[]')) {\n newFileContainer = elmParent.find('.new-file');\n\n if (!alertAlreadyDisplayed && (newFileContainer.empty() || newFileContainer.is(':visible'))) {\n window.alertAlreadyDisplayed = true;\n alert({\n content: $.mage.__('There are files that were selected but not uploaded yet. ' +\n 'Please upload or remove them first')\n });\n }\n\n return false;\n }\n\n return true;\n },\n 'Please upload a file.'\n ],\n 'validate-downloadable-url': [\n function (v, element) {\n var linkType = $(element).parent().find('input[value=\"url\"]');\n\n if (linkType.is(':checked') && v === '') {\n return false;\n }\n\n return true;\n },\n $.mage.__('Please specify Url.')\n ]\n }, function (rule, i) {\n rule.unshift(i);\n $.validator.addMethod.apply($.validator, rule);\n });\n\n return $.mage.validation;\n});\n","mage/backend/form.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'jquery/ui'\n], function ($) {\n 'use strict';\n\n $.widget('mage.form', {\n options: {\n handlersData: {\n save: {},\n saveAndContinueEdit: {\n action: {\n args: {\n back: 'edit'\n }\n }\n },\n preview: {\n target: '_blank'\n }\n }\n },\n\n /**\n * Form creation\n * @protected\n */\n _create: function () {\n this._bind();\n },\n\n /**\n * Set form attributes to initial state\n * @protected\n */\n _rollback: function () {\n if (this.oldAttributes) {\n this.element.prop(this.oldAttributes);\n }\n },\n\n /**\n * Check if field value is changed\n * @protected\n * @param {Object} e - event object\n */\n _changesObserver: function (e) {\n var target = $(e.target),\n changed;\n\n if (e.type === 'focus' || e.type === 'focusin') {\n this.currentField = {\n statuses: {\n checked: target.is(':checked'),\n selected: target.is(':selected')\n },\n val: target.val()\n };\n\n } else {\n if (this.currentField) { //eslint-disable-line no-lonely-if\n changed = target.val() !== this.currentField.val ||\n target.is(':checked') !== this.currentField.statuses.checked ||\n target.is(':selected') !== this.currentField.statuses.selected;\n\n if (changed) { //eslint-disable-line max-depth\n target.trigger('changed');\n }\n }\n }\n },\n\n /**\n * Get array with handler names\n * @protected\n * @return {Array} Array of handler names\n */\n _getHandlers: function () {\n var handlers = [];\n\n $.each(this.options.handlersData, function (key) {\n handlers.push(key);\n });\n\n return handlers;\n },\n\n /**\n * Store initial value of form attribute\n * @param {String} attrName - name of attribute\n * @protected\n */\n _storeAttribute: function (attrName) {\n var prop;\n\n this.oldAttributes = this.oldAttributes || {};\n\n if (!this.oldAttributes[attrName]) {\n prop = this.element.attr(attrName);\n this.oldAttributes[attrName] = prop ? prop : '';\n }\n },\n\n /**\n * Bind handlers\n * @protected\n */\n _bind: function () {\n this.element\n .on(this._getHandlers().join(' '), $.proxy(this._submit, this))\n .on('focus blur focusin focusout', $.proxy(this._changesObserver, this));\n },\n\n /**\n * Get action url for form\n * @param {Object|String} data - object with parameters for action url or url string\n * @return {String} action url\n */\n _getActionUrl: function (data) {\n if (typeof data === 'object') {\n return this._buildURL(this.oldAttributes.action, data.args);\n }\n\n return typeof data === 'string' ? data : this.oldAttributes.action;\n },\n\n /**\n * Add additional parameters into URL\n * @param {String} url - original url\n * @param {Object} params - object with parameters for action url\n * @return {String} action url\n * @private\n */\n _buildURL: function (url, params) {\n var concat = /\\?/.test(url) ? ['&', '='] : ['/', '/'];\n\n url = url.replace(/[\\/&]+$/, '');\n $.each(params, function (key, value) {\n url += concat[0] + key + concat[1] + window.encodeURIComponent(value);\n });\n\n return url + (concat[0] === '/' ? '/' : '');\n },\n\n /**\n * Prepare data for form attributes\n * @protected\n * @param {Object} data\n * @return {Object}\n */\n _processData: function (data) {\n $.each(data, $.proxy(function (attrName, attrValue) {\n this._storeAttribute(attrName);\n\n if (attrName === 'action') {\n data[attrName] = this._getActionUrl(attrValue);\n }\n }, this));\n\n return data;\n },\n\n /**\n * Get additional data before form submit\n * @protected\n * @param {String} handlerName\n * @param {Object} data\n */\n _beforeSubmit: function (handlerName, data) {\n var submitData = {},\n event = new $.Event('beforeSubmit');\n\n this.element.trigger(event, [submitData, handlerName]);\n data = $.extend(\n true, {},\n this.options.handlersData[handlerName] || {},\n submitData,\n data\n );\n this.element.prop(this._processData(data));\n\n return !event.isDefaultPrevented();\n },\n\n /**\n * Submit the form\n * @param {Object} e - event object\n * @param {Object} data - event data object\n */\n _submit: function (e, data) {\n this._rollback();\n\n if (this._beforeSubmit(e.type, data) !== false) {\n this.element.trigger('submit', e);\n }\n }\n });\n\n return $.mage.form;\n});\n","mage/backend/button.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'jquery/ui'\n], function ($) {\n 'use strict';\n\n $.widget('ui.button', $.ui.button, {\n options: {\n eventData: {},\n waitTillResolved: true\n },\n\n /**\n * Button creation.\n * @protected\n */\n _create: function () {\n if (this.options.event) {\n this.options.target = this.options.target || this.element;\n this._bind();\n }\n\n this._super();\n },\n\n /**\n * Bind handler on button click.\n * @protected\n */\n _bind: function () {\n this.element\n .off('click.button')\n .on('click.button', $.proxy(this._click, this));\n },\n\n /**\n * Button click handler.\n * @protected\n */\n _click: function () {\n var options = this.options;\n\n $(options.target).trigger(options.event, [options.eventData]);\n }\n });\n\n return $.ui.button;\n});\n","mage/backend/editablemultiselect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @deprecated since version 2.2.0\n */\n/* global EditableMultiselect */\n/* eslint-disable strict */\ndefine([\n 'jquery',\n 'Magento_Ui/js/modal/alert',\n 'Magento_Ui/js/modal/confirm',\n 'jquery/editableMultiselect/js/jquery.editable',\n 'jquery/editableMultiselect/js/jquery.multiselect'\n], function ($, alert, confirm) {\n /**\n * Editable multiselect wrapper for multiselects\n * This class is defined in global scope ('var' is not needed).\n *\n * @param {Object} settings - settings object.\n * @param {String} settings.add_button_caption - caption of the 'Add New Value' button\n * @param {String} settings.new_url - URL to which new request has to be submitted\n * @param {String} settings.save_url - URL to which save request has to be submitted\n * @param {String} settings.delete_url - URL to which delete request has to be submitted\n * @param {String} settings.delete_confirm_message - confirmation message that is shown to user during\n * delete operation\n * @param {String} settings.target_select_id - HTML ID of target select element\n * @param {Hash} settings.submit_data - extra parameters to send with new/edit/delete requests\n * @param {String} settings.entity_value_name - name of the request parameter that represents select option text\n * @param {String} settings.entity_id_name - name of the request parameter that represents select option value\n * @param {Boolean} settings.is_entry_editable - flag that shows if user can add/edit/remove data\n *\n * @constructor\n */\n window.EditableMultiselect = function (settings) {\n\n this.settings = settings || {};\n this.addButtonCaption = this.settings['add_button_caption'] || 'Add new value';\n this.newUrl = this.settings['new_url'];\n this.saveUrl = this.settings['save_url'];\n this.deleteUrl = this.settings['delete_url'];\n this.deleteConfirmMessage = this.settings['delete_confirm_message'];\n this.targetSelectId = this.settings['target_select_id'];\n this.submitData = this.settings['submit_data'] || {};\n this.entityIdName = this.settings['entity_id_name'] || 'entity_id';\n this.entityValueName = this.settings['entity_value_name'] || 'entity_value';\n this.isEntityEditable = this.settings['is_entity_editable'] || false;\n\n /**\n * Initialize editable multiselect (make it visible in UI)\n */\n EditableMultiselect.prototype.init = function () {\n var self = this,\n mselectOptions = {\n addText: this.addButtonCaption,\n\n /**\n * @param {*} value\n * @param {*} options\n */\n mselectInputSubmitCallback: function (value, options) {\n self.createEntity(value, options);\n }\n },\n mselectList;\n\n if (!this.isEntityEditable) {\n // Override default layout of editable multiselect\n mselectOptions.layout = '<section class=\"block %mselectListClass%\">' +\n '<div class=\"block-content\"><div class=\"%mselectItemsWrapperClass%\">' +\n '%items%' +\n '</div></div>' +\n '<div class=\"%mselectInputContainerClass%\">' +\n '<input type=\"text\" class=\"%mselectInputClass%\" title=\"%inputTitle%\"/>' +\n '<span class=\"%mselectButtonCancelClass%\" title=\"%cancelText%\"></span>' +\n '<span class=\"%mselectButtonSaveClass%\" title=\"Add\"></span>' +\n '</div>' +\n '</section>';\n }\n\n $('#' + this.targetSelectId).multiselect(mselectOptions);\n\n // Make multiselect editable if needed\n if (this.isEntityEditable) {\n this.makeMultiselectEditable();\n\n // Root element of HTML markup that represents select element in UI\n mselectList = $('#' + this.targetSelectId).next();\n this.attachEventsToControls(mselectList);\n }\n };\n\n /**\n * Attach required event handlers to control elements of editable multiselect\n *\n * @param {Object} mselectList\n */\n EditableMultiselect.prototype.attachEventsToControls = function (mselectList) {\n mselectList.on('click.mselect-delete', '.mselect-delete', {\n container: this\n }, function (event) {\n // Pass the clicked button to container\n event.data.container.deleteEntity({\n 'delete_button': this\n });\n });\n\n mselectList.on('click.mselect-checked', '.mselect-list-item input', {\n container: this\n }, function (event) {\n var el = $(this),\n checkedClassName = 'mselect-checked';\n\n el[el.is(':checked') ? 'addClass' : 'removeClass'](checkedClassName);\n event.data.container.makeMultiselectEditable();\n });\n\n mselectList.on('click.mselect-edit', '.mselect-edit', {\n container: this\n }, function (event) {\n event.data.container.makeMultiselectEditable();\n $(this).parent().find('label span').trigger('dblclick');\n });\n };\n\n /**\n * Make multiselect editable\n */\n EditableMultiselect.prototype.makeMultiselectEditable = function () {\n var entityIdName = this.entityIdName,\n entityValueName = this.entityValueName,\n selectList = $('#' + this.targetSelectId).next();\n\n selectList.find('.mselect-list-item:not(.mselect-list-item-not-editable) label span').editable(this.saveUrl,\n {\n type: 'text',\n submit: '<button class=\"mselect-save\" title=\"Save\" type=\"submit\"></button>',\n cancel: '<span class=\"mselect-cancel\" title=\"Cancel\"></span>',\n event: 'dblclick',\n placeholder: '',\n\n /**\n * Is checked.\n */\n isChecked: function () {\n var that = $(this),\n checked;\n\n if (!that.closest('.mselect-list-item').hasClass('mselect-disabled')) {\n checked = that.parent().find('[type=checkbox]').prop('disabled');\n that.parent().find('[type=checkbox]').prop({\n disabled: !checked\n });\n }\n },\n\n /**\n * @param {*} value\n * @param {Object} sett\n * @return {*}\n */\n data: function (value, sett) {\n var retval;\n\n sett.isChecked.apply(this, [sett]);\n\n if (typeof value === 'string') {\n retval = value.unescapeHTML();\n\n return retval;\n }\n\n return value;\n },\n submitdata: this.submitData,\n onblur: 'cancel',\n name: entityValueName,\n ajaxoptions: {\n dataType: 'json'\n },\n\n /**\n * @param {Object} sett\n * @param {*} original\n */\n onsubmit: function (sett, original) {\n var select = $(original).closest('.mselect-list').prev(),\n current = $(original).closest('.mselect-list-item').index(),\n entityId = select.find('option').eq(current).val(),\n entityInfo = {};\n\n entityInfo[entityIdName] = entityId;\n sett.submitdata = $.extend(sett.submitdata || {}, entityInfo);\n },\n\n /**\n * @param {Object} result\n * @param {Object} sett\n */\n callback: function (result, sett) {\n var select, current;\n\n sett.isChecked.apply(this, [sett]);\n select = $(this).closest('.mselect-list').prev();\n current = $(this).closest('.mselect-list-item').index();\n\n if (result.success) {\n if (typeof result[entityValueName] === 'string') {\n select.find('option').eq(current).val(result[entityIdName]).text(result[entityValueName]);\n $(this).html(result[entityValueName].escapeHTML());\n }\n } else {\n alert({\n content: result['error_message']\n });\n }\n }\n });\n };\n\n /**\n * Callback function that is called when admin adds new value to select\n *\n * @param {*} value\n * @param {Object} options - list of settings of multiselect\n */\n EditableMultiselect.prototype.createEntity = function (value, options) {\n var select, entityIdName, entityValueName, entityInfo, postData, ajaxOptions;\n\n if (!value) {\n return;\n }\n\n select = $('#' + this.targetSelectId),\n entityIdName = this.entityIdName,\n entityValueName = this.entityValueName,\n entityInfo = {};\n entityInfo[entityIdName] = null;\n entityInfo[entityValueName] = value;\n\n postData = $.extend(entityInfo, this.submitData);\n\n ajaxOptions = {\n type: 'POST',\n data: postData,\n dataType: 'json',\n url: this.newUrl,\n\n /**\n * @param {Object} result\n */\n success: function (result) {\n var resultEntityValueName, mselectItemHtml, sectionBlock, itemsWrapper, inputSelector;\n\n if (result.success) {\n resultEntityValueName = '';\n\n if (typeof result[entityValueName] === 'string') {\n resultEntityValueName = result[entityValueName].escapeHTML();\n } else {\n resultEntityValueName = result[entityValueName];\n }\n // Add item to initial select element\n select.append('<option value=\"' + result[entityIdName] + '\" selected=\"selected\">' +\n resultEntityValueName + '</option>');\n // Add editable multiselect item\n mselectItemHtml = $(options.item.replace(/%value%|%label%/gi, resultEntityValueName)\n .replace(/%mselectDisabledClass%|%iseditable%|%isremovable%/gi, '')\n .replace(/%mselectListItemClass%/gi, options.mselectListItemClass))\n .find('[type=checkbox]')\n .addClass(options.mselectCheckedClass)\n .prop('checked', true)\n .end();\n sectionBlock = select.nextAll('section.block:first');\n itemsWrapper = sectionBlock.find('.' + options.mselectItemsWrapperClass + '');\n\n if (itemsWrapper.children('.' + options.mselectListItemClass + '').length) {\n itemsWrapper.children('.' + options.mselectListItemClass + ':last').after(mselectItemHtml);\n } else {\n itemsWrapper.prepend(mselectItemHtml);\n }\n // Trigger blur event on input field, that is used to add new value, to hide it\n inputSelector = '.' + options.mselectInputContainerClass + ' [type=text].' +\n options.mselectInputClass + '';\n sectionBlock.find(inputSelector).trigger('blur');\n } else {\n alert({\n content: result['error_message']\n });\n }\n }\n };\n $.ajax(ajaxOptions);\n };\n\n /**\n * Callback function that is called when user tries to delete value from select\n *\n * @param {Object} options\n */\n EditableMultiselect.prototype.deleteEntity = function (options) {\n var self = this;\n\n if (options['delete_button']) {\n confirm({\n content: this.deleteConfirmMessage,\n actions: {\n /**\n * Confirm.\n */\n confirm: function () {\n // Button that has been clicked\n var deleteButton = $(options['delete_button']),\n index = deleteButton.parent().index(),\n select = deleteButton.closest('.mselect-list').prev(),\n entityId = select.find('option').eq(index).val(),\n entityInfo = {},\n postData, ajaxOptions;\n\n entityInfo[self.entityIdName] = entityId;\n postData = $.extend(entityInfo, self.submitData);\n\n ajaxOptions = {\n type: 'POST',\n data: postData,\n dataType: 'json',\n url: self.deleteUrl,\n\n /**\n * @param {Object} result\n */\n success: function (result) {\n if (result.success) {\n deleteButton.parent().remove();\n select.find('option').eq(index).remove();\n } else {\n alert({\n content: result['error_message']\n });\n }\n }\n };\n $.ajax(ajaxOptions);\n }\n }\n });\n }\n };\n };\n});\n","mage/backend/suggest.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'mage/template',\n 'mage/mage',\n 'jquery/ui',\n 'mage/backend/menu',\n 'mage/translate'\n], function ($, mageTemplate) {\n 'use strict';\n\n /**\n * Implement base functionality\n */\n $.widget('mage.suggest', {\n widgetEventPrefix: 'suggest',\n options: {\n template: '<% if (data.items.length) { %>' +\n '<% if (!data.term && !data.allShown() && data.recentShown()) { %>' +\n '<h5 class=\"title\"><%- data.recentTitle %></h5>' +\n '<% } %>' +\n '<ul data-mage-init=\\'{\"menu\":[]}\\'>' +\n '<% _.each(data.items, function(value){ %>' +\n '<% if (!data.itemSelected(value)) { %><li <%= data.optionData(value) %>>' +\n '<a href=\"#\"><%- value.label %></a></li><% } %>' +\n '<% }); %>' +\n '<% if (!data.term && !data.allShown() && data.recentShown()) { %>' +\n '<li data-mage-init=\\'{\"actionLink\":{\"event\":\"showAll\"}}\\' class=\"show-all\">' +\n '<a href=\"#\"><%- data.showAllTitle %></a></li>' +\n '<% } %>' +\n '</ul><% } else { %><span class=\"mage-suggest-no-records\"><%- data.noRecordsText %></span><% } %>',\n minLength: 1,\n\n /**\n * @type {(String|Array)}\n */\n source: null,\n delay: 500,\n loadingClass: 'mage-suggest-state-loading',\n events: {},\n appendMethod: 'after',\n controls: {\n selector: ':ui-menu, :mage-menu',\n eventsMap: {\n focus: ['menufocus'],\n blur: ['menublur'],\n select: ['menuselect']\n }\n },\n termAjaxArgument: 'label_part',\n filterProperty: 'label',\n className: null,\n inputWrapper: '<div class=\"mage-suggest\"><div class=\"mage-suggest-inner\"></div></div>',\n dropdownWrapper: '<div class=\"mage-suggest-dropdown\"></div>',\n preventClickPropagation: true,\n currentlySelected: null,\n submitInputOnEnter: true\n },\n\n /**\n * Component's constructor\n * @private\n */\n _create: function () {\n this._term = null;\n this._nonSelectedItem = {\n id: '',\n label: ''\n };\n this.templates = {};\n this._renderedContext = null;\n this._selectedItem = this._nonSelectedItem;\n this._control = this.options.controls || {};\n this._setTemplate();\n this._prepareValueField();\n this._render();\n this._bind();\n },\n\n /**\n * Render base elements for suggest component\n * @private\n */\n _render: function () {\n var wrapper;\n\n this.dropdown = $(this.options.dropdownWrapper).hide();\n wrapper = this.options.className ?\n $(this.options.inputWrapper).addClass(this.options.className) :\n $(this.options.inputWrapper);\n this.element\n .wrap(wrapper)[this.options.appendMethod](this.dropdown)\n .attr('autocomplete', 'off');\n },\n\n /**\n * Define a field for storing item id (find in DOM or create a new one)\n * @private\n */\n _prepareValueField: function () {\n if (this.options.valueField) {\n this.valueField = $(this.options.valueField);\n } else {\n this.valueField = this._createValueField()\n .insertBefore(this.element)\n .attr('name', this.element.attr('name'));\n this.element.removeAttr('name');\n }\n },\n\n /**\n * Create value field which keeps a id for selected option\n * can be overridden in descendants\n * @return {jQuery}\n * @private\n */\n _createValueField: function () {\n return $('<input/>', {\n type: 'hidden'\n });\n },\n\n /**\n * Component's destructor\n * @private\n */\n _destroy: function () {\n this.element\n .unwrap()\n .removeAttr('autocomplete');\n\n if (!this.options.valueField) {\n this.element.attr('name', this.valueField.attr('name'));\n this.valueField.remove();\n }\n\n this.dropdown.remove();\n this._off(this.element, 'keydown keyup blur');\n },\n\n /**\n * Return actual value of an \"input\"-element\n * @return {String}\n * @private\n */\n _value: function () {\n return this.element[this.element.is(':input') ? 'val' : 'text']().trim();\n },\n\n /**\n * Pass original event to a control component for handling it as it's own event\n * @param {Object} event - event object\n * @private\n */\n _proxyEvents: function (event) {\n var fakeEvent = $.extend({}, $.Event(event.type), {\n ctrlKey: event.ctrlKey,\n keyCode: event.keyCode,\n which: event.keyCode\n }),\n target = this._control.selector ? this.dropdown.find(this._control.selector) : this.dropdown;\n\n target.trigger(fakeEvent);\n },\n\n /**\n * Bind handlers on specific events\n * @private\n */\n _bind: function () {\n this._on($.extend({\n /**\n * @param {jQuery.Event} event\n */\n keydown: function (event) {\n var keyCode = $.ui.keyCode,\n suggestList,\n hasSuggestedItems,\n hasSelectedItems,\n selectedItem;\n\n switch (event.keyCode) {\n case keyCode.PAGE_UP:\n case keyCode.UP:\n if (!event.shiftKey) {\n event.preventDefault();\n this._proxyEvents(event);\n }\n\n suggestList = event.currentTarget.parentNode.getElementsByTagName('ul')[0];\n hasSuggestedItems = event.currentTarget\n .parentNode.getElementsByTagName('ul')[0].children.length >= 0;\n\n if (hasSuggestedItems) {\n selectedItem = $(suggestList.getElementsByClassName('_active')[0])\n .removeClass('_active').prev().addClass('_active');\n event.currentTarget.value = selectedItem.find('a').text();\n }\n\n break;\n\n case keyCode.PAGE_DOWN:\n case keyCode.DOWN:\n if (!event.shiftKey) {\n event.preventDefault();\n this._proxyEvents(event);\n }\n\n suggestList = event.currentTarget.parentNode.getElementsByTagName('ul')[0];\n hasSuggestedItems = event.currentTarget\n .parentNode.getElementsByTagName('ul')[0].children.length >= 0;\n\n if (hasSuggestedItems) {\n hasSelectedItems = suggestList.getElementsByClassName('_active').length === 0;\n\n if (hasSelectedItems) { //eslint-disable-line max-depth\n selectedItem = $(suggestList.children[0]).addClass('_active');\n event.currentTarget.value = selectedItem.find('a').text();\n } else {\n selectedItem = $(suggestList.getElementsByClassName('_active')[0])\n .removeClass('_active').next().addClass('_active');\n event.currentTarget.value = selectedItem.find('a').text();\n }\n }\n break;\n\n case keyCode.TAB:\n if (this.isDropdownShown()) {\n this._onSelectItem(event, null);\n event.preventDefault();\n }\n break;\n\n case keyCode.ENTER:\n case keyCode.NUMPAD_ENTER:\n this._toggleEnter(event);\n\n if (this.isDropdownShown() && this._focused) {\n this._proxyEvents(event);\n event.preventDefault();\n }\n break;\n\n case keyCode.ESCAPE:\n if (this.isDropdownShown()) {\n event.stopPropagation();\n }\n this.close(event);\n this._blurItem();\n break;\n }\n },\n\n /**\n * @param {jQuery.Event} event\n */\n keyup: function (event) {\n var keyCode = $.ui.keyCode;\n\n switch (event.keyCode) {\n case keyCode.HOME:\n case keyCode.END:\n case keyCode.PAGE_UP:\n case keyCode.PAGE_DOWN:\n case keyCode.ESCAPE:\n case keyCode.UP:\n case keyCode.DOWN:\n case keyCode.LEFT:\n case keyCode.RIGHT:\n case keyCode.TAB:\n break;\n\n case keyCode.ENTER:\n case keyCode.NUMPAD_ENTER:\n if (this.isDropdownShown()) {\n event.preventDefault();\n }\n break;\n default:\n this.search(event);\n }\n },\n\n /**\n * @param {jQuery.Event} event\n */\n blur: function (event) {\n if (!this.preventBlur) {\n this._abortSearch();\n this.close(event);\n this._change(event);\n } else {\n this.element.trigger('focus');\n }\n },\n cut: this.search,\n paste: this.search,\n input: this.search,\n selectItem: this._onSelectItem,\n click: this.search\n }, this.options.events));\n\n this._bindSubmit();\n this._bindDropdown();\n },\n\n /**\n * @param {Object} event\n * @private\n */\n _toggleEnter: function (event) {\n var suggestList,\n activeItems,\n selectedItem;\n\n if (!this.options.submitInputOnEnter) {\n event.preventDefault();\n }\n\n suggestList = $(event.currentTarget.parentNode).find('ul').first();\n activeItems = suggestList.find('._active');\n\n if (activeItems.length >= 0) {\n selectedItem = activeItems.first();\n\n if (selectedItem.find('a') && selectedItem.find('a').attr('href') !== undefined) {\n window.location = selectedItem.find('a').attr('href');\n event.preventDefault();\n }\n }\n },\n\n /**\n * Bind handlers for submit on enter\n * @private\n */\n _bindSubmit: function () {\n this.element.parents('form').on('submit', function (event) {\n if (!this.submitInputOnEnter) {\n event.preventDefault();\n }\n });\n },\n\n /**\n * @param {Object} e - event object\n * @private\n */\n _change: function (e) {\n if (this._term !== this._value()) {\n this._trigger('change', e);\n }\n },\n\n /**\n * Bind handlers for dropdown element on specific events\n * @private\n */\n _bindDropdown: function () {\n var events = {\n /**\n * @param {jQuery.Event} e\n */\n click: function (e) {\n // prevent default browser's behavior of changing location by anchor href\n e.preventDefault();\n },\n\n /**\n * @param {jQuery.Event} e\n */\n mousedown: function (e) {\n e.preventDefault();\n }\n };\n\n $.each(this._control.eventsMap, $.proxy(function (suggestEvent, controlEvents) {\n $.each(controlEvents, $.proxy(function (i, handlerName) {\n switch (suggestEvent) {\n case 'select':\n events[handlerName] = this._onSelectItem;\n break;\n\n case 'focus':\n events[handlerName] = this._focusItem;\n break;\n\n case 'blur':\n events[handlerName] = this._blurItem;\n break;\n }\n }, this));\n }, this));\n\n if (this.options.preventClickPropagation) {\n this._on(this.dropdown, events);\n }\n // Fix for IE 8\n this._on(this.dropdown, {\n /**\n * Mousedown.\n */\n mousedown: function () {\n this.preventBlur = true;\n },\n\n /**\n * Mouseup.\n */\n mouseup: function () {\n this.preventBlur = false;\n }\n });\n },\n\n /**\n * @override\n */\n _trigger: function (type, event) {\n var result = this._superApply(arguments);\n\n if (result === false && event) {\n event.stopImmediatePropagation();\n event.preventDefault();\n }\n\n return result;\n },\n\n /**\n * Handle focus event of options item\n * @param {Object} e - event object\n * @param {Object} ui - object that can contain information about focused item\n * @private\n */\n _focusItem: function (e, ui) {\n if (ui && ui.item) {\n this._focused = $(ui.item).prop('tagName') ?\n this._readItemData(ui.item) :\n ui.item;\n\n this.element.val(this._focused.label);\n this._trigger('focus', e, {\n item: this._focused\n });\n }\n },\n\n /**\n * Handle blur event of options item\n * @private\n */\n _blurItem: function () {\n this._focused = null;\n this.element.val(this._term);\n },\n\n /**\n * @param {Object} e - event object\n * @param {Object} item\n * @private\n */\n _onSelectItem: function (e, item) {\n if (item && typeof item === 'object' && $(e.target).is(this.element)) {\n this._focusItem(e, {\n item: item\n });\n }\n\n if (this._trigger('beforeselect', e || null, {\n item: this._focused\n }) === false) {\n return;\n }\n this._selectItem(e);\n this._blurItem();\n this._trigger('select', e || null, {\n item: this._selectedItem\n });\n },\n\n /**\n * Save selected item and hide dropdown\n * @private\n * @param {Object} e - event object\n */\n _selectItem: function (e) {\n if (this._focused) {\n this._selectedItem = this._focused;\n\n if (this._selectedItem !== this._nonSelectedItem) {\n this._term = this._selectedItem.label;\n this.valueField.val(this._selectedItem.id);\n this.close(e);\n }\n }\n },\n\n /**\n * Read option data from item element\n * @param {Element} element\n * @return {Object}\n * @private\n */\n _readItemData: function (element) {\n return element.data('suggestOption') || this._nonSelectedItem;\n },\n\n /**\n * Check if dropdown is shown\n * @return {Boolean}\n */\n isDropdownShown: function () {\n return this.dropdown.is(':visible');\n },\n\n /**\n * Open dropdown\n * @private\n * @param {Object} e - event object\n */\n open: function (e) {\n if (!this.isDropdownShown()) {\n this.element.addClass('_suggest-dropdown-open');\n this.dropdown.show();\n this._trigger('open', e);\n }\n },\n\n /**\n * Close and clear dropdown content\n * @private\n * @param {Object} e - event object\n */\n close: function (e) {\n this._renderedContext = null;\n\n if (this.dropdown.length) {\n this.element.removeClass('_suggest-dropdown-open');\n this.dropdown.hide().empty();\n }\n\n this._trigger('close', e);\n },\n\n /**\n * Acquire content template\n * @private\n */\n _setTemplate: function () {\n this.templateName = 'suggest' + Math.random().toString(36).substr(2);\n\n this.templates[this.templateName] = mageTemplate(this.options.template);\n },\n\n /**\n * Execute search process\n * @public\n * @param {Object} e - event object\n */\n search: function (e) {\n var term = this._value();\n\n if ((this._term !== term || term.length === 0) && !this.preventBlur) {\n this._term = term;\n\n if (typeof term === 'string' && term.length >= this.options.minLength) {\n if (this._trigger('search', e) === false) { //eslint-disable-line max-depth\n return;\n }\n this._search(e, term, {});\n } else {\n this._selectedItem = this._nonSelectedItem;\n this._resetSuggestValue();\n }\n }\n },\n\n /**\n * Clear suggest hidden input\n * @private\n */\n _resetSuggestValue: function () {\n this.valueField.val(this._nonSelectedItem.id);\n },\n\n /**\n * Actual search method, can be overridden in descendants\n * @param {Object} e - event object\n * @param {String} term - search phrase\n * @param {Object} context - search context\n * @private\n */\n _search: function (e, term, context) {\n var response = $.proxy(function (items) {\n return this._processResponse(e, items, context || {});\n }, this);\n\n this.element.addClass(this.options.loadingClass);\n\n if (this.options.delay) {\n if (typeof this.options.data !== 'undefined') {\n response(this.filter(this.options.data, term));\n }\n clearTimeout(this._searchTimeout);\n this._searchTimeout = this._delay(function () {\n this._source(term, response);\n }, this.options.delay);\n } else {\n this._source(term, response);\n }\n },\n\n /**\n * Extend basic context with additional data (search results, search term)\n * @param {Object} context\n * @return {Object}\n * @private\n */\n _prepareDropdownContext: function (context) {\n return $.extend(context, {\n items: this._items,\n term: this._term,\n\n /**\n * @param {Object} item\n * @return {String}\n */\n optionData: function (item) {\n return 'data-suggest-option=\"' +\n $('<div>').text(JSON.stringify(item)).html().replace(/\"/g, '"') + '\"';\n },\n itemSelected: $.proxy(this._isItemSelected, this),\n noRecordsText: $.mage.__('No records found.')\n });\n },\n\n /**\n * @param {Object} item\n * @return {Boolean}\n * @private\n */\n _isItemSelected: function (item) {\n return item.id == (this._selectedItem && this._selectedItem.id ? //eslint-disable-line eqeqeq\n this._selectedItem.id :\n this.options.currentlySelected);\n },\n\n /**\n * Render content of suggest's dropdown\n * @param {Object} e - event object\n * @param {Array} items - list of label+id objects\n * @param {Object} context - template's context\n * @private\n */\n _renderDropdown: function (e, items, context) {\n var tmpl = this.templates[this.templateName];\n\n this._items = items;\n\n tmpl = tmpl({\n data: this._prepareDropdownContext(context)\n });\n\n $(tmpl).appendTo(this.dropdown.empty());\n\n this.dropdown.trigger('contentUpdated')\n .find(this._control.selector).on('focus', function (event) {\n event.preventDefault();\n });\n\n this._renderedContext = context;\n this.element.removeClass(this.options.loadingClass);\n this.open(e);\n },\n\n /**\n * @param {Object} e\n * @param {Object} items\n * @param {Object} context\n * @private\n */\n _processResponse: function (e, items, context) {\n var renderer = $.proxy(function (i) {\n return this._renderDropdown(e, i, context || {});\n }, this);\n\n if (this._trigger('response', e, [items, renderer]) === false) {\n return;\n }\n this._renderDropdown(e, items, context);\n },\n\n /**\n * Implement search process via spesific source\n * @param {String} term - search phrase\n * @param {Function} response - search results handler, process search result\n * @private\n */\n _source: function (term, response) {\n var o = this.options,\n ajaxData;\n\n if (Array.isArray(o.source)) {\n response(this.filter(o.source, term));\n } else if (typeof o.source === 'string') {\n ajaxData = {};\n ajaxData[this.options.termAjaxArgument] = term;\n\n this._xhr = $.ajax($.extend(true, {\n url: o.source,\n type: 'POST',\n dataType: 'json',\n data: ajaxData,\n success: $.proxy(function (items) {\n this.options.data = items;\n response.apply(response, arguments);\n }, this)\n }, o.ajaxOptions || {}));\n } else if (typeof o.source === 'function') {\n o.source.apply(o.source, arguments);\n }\n },\n\n /**\n * Abort search process\n * @private\n */\n _abortSearch: function () {\n this.element.removeClass(this.options.loadingClass);\n clearTimeout(this._searchTimeout);\n },\n\n /**\n * Perform filtering in advance loaded items and returns search result\n * @param {Array} items - all available items\n * @param {String} term - search phrase\n * @return {Object}\n */\n filter: function (items, term) {\n var matcher = new RegExp(term.replace(/[\\-\\/\\\\\\^$*+?.()|\\[\\]{}]/g, '\\\\$&'), 'i'),\n itemsArray = Array.isArray(items) ? items : $.map(items, function (element) {\n return element;\n }),\n property = this.options.filterProperty;\n\n return $.grep(\n itemsArray,\n function (value) {\n return matcher.test(value[property] || value.id || value);\n }\n );\n }\n });\n\n /**\n * Implement show all functionality and storing and display recent searches\n */\n $.widget('mage.suggest', $.mage.suggest, {\n options: {\n showRecent: false,\n showAll: false,\n storageKey: 'suggest',\n storageLimit: 10\n },\n\n /**\n * @override\n */\n _create: function () {\n var recentItems;\n\n if (this.options.showRecent && window.localStorage) {\n recentItems = JSON.parse(localStorage.getItem(this.options.storageKey));\n\n /**\n * @type {Array} - list of recently searched items\n * @private\n */\n this._recentItems = Array.isArray(recentItems) ? recentItems : [];\n }\n this._super();\n },\n\n /**\n * @override\n */\n _bind: function () {\n this._super();\n this._on(this.dropdown, {\n /**\n * @param {jQuery.Event} e\n */\n showAll: function (e) {\n e.stopImmediatePropagation();\n e.preventDefault();\n this.element.trigger('showAll');\n }\n });\n\n if (this.options.showRecent || this.options.showAll) {\n this._on({\n /**\n * @param {jQuery.Event} e\n */\n focus: function (e) {\n if (!this.isDropdownShown()) {\n this.search(e);\n }\n },\n showAll: this._showAll\n });\n }\n },\n\n /**\n * @private\n * @param {Object} e - event object\n */\n _showAll: function (e) {\n this._abortSearch();\n this._search(e, '', {\n _allShown: true\n });\n },\n\n /**\n * @override\n */\n search: function (e) {\n if (!this._value()) {\n\n if (this.options.showRecent) {\n\n if (this._recentItems.length) { //eslint-disable-line max-depth\n this._processResponse(e, this._recentItems, {});\n } else {\n this._showAll(e);\n }\n } else if (this.options.showAll) {\n this._showAll(e);\n }\n }\n this._superApply(arguments);\n },\n\n /**\n * @override\n */\n _selectItem: function () {\n this._superApply(arguments);\n\n if (this._selectedItem && this._selectedItem.id && this.options.showRecent) {\n this._addRecent(this._selectedItem);\n }\n },\n\n /**\n * @override\n */\n _prepareDropdownContext: function () {\n var context = this._superApply(arguments);\n\n return $.extend(context, {\n recentShown: $.proxy(function () {\n return this.options.showRecent;\n }, this),\n recentTitle: $.mage.__('Recent items'),\n showAllTitle: $.mage.__('Show all...'),\n\n /**\n * @return {Boolean}\n */\n allShown: function () {\n return !!context._allShown;\n }\n });\n },\n\n /**\n * Add selected item of search result into storage of recents\n * @param {Object} item - label+id object\n * @private\n */\n _addRecent: function (item) {\n this._recentItems = $.grep(this._recentItems, function (obj) {\n return obj.id !== item.id;\n });\n this._recentItems.unshift(item);\n this._recentItems = this._recentItems.slice(0, this.options.storageLimit);\n localStorage.setItem(this.options.storageKey, JSON.stringify(this._recentItems));\n }\n });\n\n /**\n * Implement multi suggest functionality\n */\n $.widget('mage.suggest', $.mage.suggest, {\n options: {\n multiSuggestWrapper: '<ul class=\"mage-suggest-choices\">' +\n '<li class=\"mage-suggest-search-field\" data-role=\"parent-choice-element\"><' +\n 'label class=\"mage-suggest-search-label\"></label></li></ul>',\n choiceTemplate: '<li class=\"mage-suggest-choice button\"><div><%- text %></div>' +\n '<span class=\"mage-suggest-choice-close\" tabindex=\"-1\" ' +\n 'data-mage-init=\\'{\"actionLink\":{\"event\":\"removeOption\"}}\\'></span></li>',\n selectedClass: 'mage-suggest-selected'\n },\n\n /**\n * @override\n */\n _create: function () {\n this.choiceTmpl = mageTemplate(this.options.choiceTemplate);\n\n this._super();\n\n if (this.options.multiselect) {\n this.valueField.hide();\n }\n },\n\n /**\n * @override\n */\n _render: function () {\n this._super();\n\n if (this.options.multiselect) {\n this._renderMultiselect();\n }\n },\n\n /**\n * Render selected options\n * @private\n */\n _renderMultiselect: function () {\n var that = this;\n\n this.element.wrap(this.options.multiSuggestWrapper);\n this.elementWrapper = this.element.closest('[data-role=\"parent-choice-element\"]');\n $(function () {\n that._getOptions()\n .each(function (i, option) {\n option = $(option);\n that._createOption({\n id: option.val(),\n label: option.text()\n });\n });\n });\n },\n\n /**\n * @return {Array} array of DOM-elements\n * @private\n */\n _getOptions: function () {\n return this.valueField.find('option');\n },\n\n /**\n * @override\n */\n _bind: function () {\n this._super();\n\n if (this.options.multiselect) {\n this._on({\n /**\n * @param {jQuery.Event} event\n */\n keydown: function (event) {\n if (event.keyCode === $.ui.keyCode.BACKSPACE) {\n if (!this._value()) {\n this._removeLastAdded(event);\n }\n }\n },\n removeOption: this.removeOption\n });\n }\n },\n\n /**\n * @param {Array} items\n * @return {Array}\n * @private\n */\n _filterSelected: function (items) {\n var options = this._getOptions();\n\n return $.grep(items, function (value) {\n var itemSelected = false;\n\n $.each(options, function () {\n if (value.id == $(this).val()) { //eslint-disable-line eqeqeq\n itemSelected = true;\n }\n });\n\n return !itemSelected;\n });\n },\n\n /**\n * @override\n */\n _processResponse: function (e, items, context) {\n if (this.options.multiselect) {\n items = this._filterSelected(items, context);\n }\n this._superApply([e, items, context]);\n },\n\n /**\n * @override\n */\n _prepareValueField: function () {\n this._super();\n\n if (this.options.multiselect && !this.options.valueField && this.options.selectedItems) {\n $.each(this.options.selectedItems, $.proxy(function (i, item) {\n this._addOption(item);\n }, this));\n }\n },\n\n /**\n * If \"multiselect\" option is set, then do not need to clear value for hidden select, to avoid losing of\n * previously selected items\n * @override\n */\n _resetSuggestValue: function () {\n if (!this.options.multiselect) {\n this._super();\n }\n },\n\n /**\n * @override\n */\n _createValueField: function () {\n if (this.options.multiselect) {\n return $('<select></select>', {\n type: 'hidden',\n multiple: 'multiple'\n });\n }\n\n return this._super();\n },\n\n /**\n * @override\n */\n _selectItem: function (e) {\n if (this.options.multiselect) {\n if (this._focused) {\n this._selectedItem = this._focused;\n\n /* eslint-disable max-depth */\n if (this._selectedItem !== this._nonSelectedItem) {\n this._term = '';\n this.element.val(this._term);\n\n if (this._isItemSelected(this._selectedItem)) {\n $(e.target).removeClass(this.options.selectedClass);\n this.removeOption(e, this._selectedItem);\n this._selectedItem = this._nonSelectedItem;\n } else {\n $(e.target).addClass(this.options.selectedClass);\n this._addOption(e, this._selectedItem);\n }\n }\n\n /* eslint-enable max-depth */\n }\n this.close(e);\n } else {\n this._superApply(arguments);\n }\n },\n\n /**\n * @override\n */\n _isItemSelected: function (item) {\n if (this.options.multiselect) {\n return this.valueField.find('option[value=' + item.id + ']').length > 0;\n }\n\n return this._superApply(arguments);\n },\n\n /**\n *\n * @param {Object} item\n * @return {Element}\n * @private\n */\n _createOption: function (item) {\n var option = this._getOption(item);\n\n if (!option.length) {\n option = $('<option>', {\n value: item.id,\n selected: true\n }).text(item.label);\n }\n\n return option.data('renderedOption', this._renderOption(item));\n },\n\n /**\n * Add selected item in to select options\n * @param {Object} e - event object\n * @param {*} item\n * @private\n */\n _addOption: function (e, item) {\n this.valueField.append(this._createOption(item).data('selectTarget', $(e.target)));\n },\n\n /**\n * @param {Object|Element} item\n * @return {Element}\n * @private\n */\n _getOption: function (item) {\n return $(item).prop('tagName') ?\n $(item) :\n this.valueField.find('option[value=' + item.id + ']');\n },\n\n /**\n * Remove last added option\n * @private\n * @param {Object} e - event object\n */\n _removeLastAdded: function (e) {\n var lastAdded = this._getOptions().last();\n\n if (lastAdded.length) {\n this.removeOption(e, lastAdded);\n }\n },\n\n /**\n * Remove item from select options\n * @param {Object} e - event object\n * @param {Object} item\n * @private\n */\n removeOption: function (e, item) {\n var option = this._getOption(item),\n selectTarget = option.data('selectTarget');\n\n if (selectTarget && selectTarget.length) {\n selectTarget.removeClass(this.options.selectedClass);\n }\n\n option.data('renderedOption').remove();\n option.remove();\n },\n\n /**\n * Render visual element of selected item\n * @param {Object} item - selected item\n * @private\n */\n _renderOption: function (item) {\n var tmpl = this.choiceTmpl({\n text: item.label\n });\n\n return $(tmpl)\n .insertBefore(this.elementWrapper)\n .trigger('contentUpdated')\n .on('removeOption', $.proxy(function (e) {\n this.removeOption(e, item);\n }, this));\n }\n });\n\n return $.mage.suggest;\n});\n","mage/backend/bootstrap.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global FORM_KEY */\ndefine([\n 'jquery',\n 'mage/apply/main',\n 'mage/backend/notification',\n 'Magento_Ui/js/lib/knockout/bootstrap',\n 'mage/mage',\n 'mage/translate'\n], function ($, mage, notification) {\n 'use strict';\n\n var bootstrap;\n\n $.ajaxSetup({\n /*\n * @type {string}\n */\n type: 'POST',\n\n /**\n * Ajax before send callback.\n *\n * @param {Object} jqXHR - The jQuery XMLHttpRequest object returned by $.ajax()\n * @param {Object} settings\n */\n beforeSend: function (jqXHR, settings) {\n var formKey = typeof FORM_KEY !== 'undefined' ? FORM_KEY : null;\n\n if (!settings.url.match(new RegExp('[?&]isAjax=true',''))) {\n settings.url = settings.url.match(\n new RegExp('\\\\?', 'g')) ?\n settings.url + '&isAjax=true' :\n settings.url + '?isAjax=true';\n }\n\n if (!settings.data) {\n settings.data = {\n 'form_key': formKey\n };\n } else if (typeof settings.data === 'string' &&\n settings.data.indexOf('form_key=') === -1) {\n settings.data += '&' + $.param({\n 'form_key': formKey\n });\n } else if ($.isPlainObject(settings.data) && !settings.data['form_key']) {\n settings.data['form_key'] = formKey;\n }\n },\n\n /**\n * Ajax complete callback.\n *\n * @param {Object} jqXHR - The jQuery XMLHttpRequest object returned by $.ajax()\n */\n complete: function (jqXHR) {\n var jsonObject;\n\n if (jqXHR.readyState === 4) {\n try {\n jsonObject = JSON.parse(jqXHR.responseText);\n\n if (jsonObject.ajaxExpired && jsonObject.ajaxRedirect) { //eslint-disable-line max-depth\n window.location.replace(jsonObject.ajaxRedirect);\n }\n } catch (e) {}\n }\n },\n\n /**\n * Error callback.\n */\n error: function () {\n $('body').notification('clear')\n .notification('add', {\n error: true,\n message: $.mage.__(\n 'A technical problem with the server created an error. ' +\n 'Try again to continue what you were doing. If the problem persists, try again later.'\n ),\n\n /**\n * @param {String} message\n */\n insertMethod: function (message) {\n var $wrapper = $('<div></div>').html(message);\n\n $('.page-main-actions').after($wrapper);\n }\n });\n }\n });\n\n /**\n * Bootstrap application.\n */\n bootstrap = function () {\n /**\n * Init all components defined via data-mage-init attribute\n * and subscribe init action on contentUpdated event\n */\n mage.apply();\n\n /*\n * Initialization of notification widget\n */\n notification({}, $('body'));\n };\n\n $(bootstrap);\n});\n","mage/backend/floating-header.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'jquery/ui'\n], function ($) {\n 'use strict';\n\n $.widget('mage.floatingHeader', {\n options: {\n placeholderAttrs: {\n 'class': 'page-actions-placeholder'\n },\n fixedClass: '_fixed',\n hiddenClass: '_hidden',\n title: '.page-title-wrapper .page-title',\n pageMainActions: '.page-main-actions',\n contains: '[data-role=modal]'\n },\n\n /**\n * Widget initialization\n * @private\n */\n _create: function () {\n var title = $(this.options.title).text(),\n wrapped = this.element.find('.page-actions-buttons').children();\n\n if (this.element.parents(this.options.contains).length) {\n return this;\n }\n\n this._setVars();\n this._bind();\n this.element.find('script').remove();\n\n if (wrapped.length) {\n wrapped\n .unwrap() // .page-actions-buttons\n .unwrap(); // .page-actions-inner\n }\n this.element.wrapInner($('<div></div>', {\n 'class': 'page-actions-buttons'\n }));\n this.element.wrapInner($('<div></div>', {\n 'class': 'page-actions-inner', 'data-title': title\n }));\n this.element.removeClass('floating-header');\n },\n\n /**\n * Set privat variables on load, for performance purposes\n * @private\n */\n _setVars: function () {\n this._placeholder = this.element.before($('<div/>', this.options.placeholderAttrs)).prev();\n this._offsetTop = this._placeholder.offset().top;\n this._height = this.element\n .parents(this.options.pageMainActions)\n .outerHeight();\n },\n\n /**\n * Event binding, will monitor scroll and resize events (resize events left for backward compat)\n * @private\n */\n _bind: function () {\n this._on(window, {\n scroll: this._handlePageScroll,\n resize: this._handlePageScroll\n });\n },\n\n /**\n * Event handler for setting fixed positioning\n * @private\n */\n _handlePageScroll: function () {\n var isActive = $(window).scrollTop() > this._offsetTop;\n\n if (isActive) {\n this.element\n .addClass(this.options.fixedClass)\n .parents(this.options.pageMainActions)\n .addClass(this.options.hiddenClass);\n } else {\n this.element\n .removeClass(this.options.fixedClass)\n .parents(this.options.pageMainActions)\n .removeClass(this.options.hiddenClass);\n }\n\n this._placeholder.height(isActive ? this._height : '');\n },\n\n /**\n * Widget destroy functionality\n * @private\n */\n _destroy: function () {\n if (this._placeholder) {\n this._placeholder.remove();\n }\n this._off($(window));\n }\n });\n\n return $.mage.floatingHeader;\n});\n","mage/backend/notification.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'mage/template',\n 'jquery/ui'\n], function ($, mageTemplate) {\n 'use strict';\n\n $.widget('mage.notification', {\n options: {\n templates: {\n global: '<div data-role=\"messages\" id=\"messages\">' +\n '<div class=\"message <% if (data.error) { %>error<% } %>\"><div><%- data.message %></div></div>' +\n '</div>',\n error: '<div data-role=\"messages\" id=\"messages\">' +\n '<div class=\"messages\"><div class=\"message message-error error\">' +\n '<div data-ui-id=\"messages-message-error\"><%- data.message %></div></div>' +\n '</div></div>'\n }\n },\n placeholder: '[data-role=messages]',\n\n /**\n * Notification creation\n * @protected\n */\n _create: function () {\n $(document).on('ajaxComplete ajaxError', $.proxy(this._add, this));\n },\n\n /**\n * Add new message\n * @protected\n * @param {Object} event - object\n * @param {Object} jqXHR - The jQuery XMLHttpRequest object returned by $.ajax()\n */\n _add: function (event, jqXHR) {\n var response;\n\n try {\n response = JSON.parse(jqXHR.responseText);\n\n if (response && response.error && response['html_message']) {\n $(this.placeholder).html(response['html_message']);\n }\n } catch (e) {}\n },\n\n /**\n * Adds new message.\n *\n * @param {Object} data - Data with a message to be displayed.\n */\n add: function (data) {\n var template = data.error ? this.options.templates.error : this.options.templates.global,\n message = mageTemplate(template, {\n data: data\n }),\n messageContainer;\n\n if (typeof data.insertMethod === 'function') {\n data.insertMethod(message);\n } else {\n messageContainer = data.messageContainer || this.placeholder;\n $(messageContainer).prepend(message);\n }\n\n return this;\n },\n\n /**\n * Removes error messages.\n */\n clear: function () {\n $(this.placeholder).html('');\n }\n });\n\n return $.mage.notification;\n});\n","mage/backend/tabs.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global FORM_KEY */\ndefine([\n 'jquery',\n 'jquery/ui',\n 'jquery/ui-modules/widgets/tabs'\n], function ($) {\n 'use strict';\n\n var rhash, isLocal;\n\n // mage.tabs base functionality\n $.widget('mage.tabs', $.ui.tabs, {\n options: {\n spinner: false,\n groups: null,\n tabPanelClass: '',\n excludedPanel: ''\n },\n\n /**\n * Tabs creation\n * @protected\n */\n _create: function () {\n var activeIndex = this._getTabIndex(this.options.active);\n\n this.options.active = activeIndex >= 0 ? activeIndex : 0;\n this._super();\n },\n\n /**\n * @override\n * @private\n * @return {Array} Array of DOM-elements\n */\n _getList: function () {\n if (this.options.groups) {\n return this.element.find(this.options.groups);\n }\n\n return this._super();\n },\n\n /**\n * Get active anchor\n * @return {Element}\n */\n activeAnchor: function () {\n return this.anchors.eq(this.option('active'));\n },\n\n /**\n * Get tab index by tab id\n * @protected\n * @param {String} id - id of tab\n * @return {Number}\n */\n _getTabIndex: function (id) {\n var anchors = this.anchors ?\n this.anchors :\n this._getList().find('> li > a[href]');\n\n return anchors.index($('#' + id));\n },\n\n /**\n * Switch between tabs\n * @protected\n * @param {Object} event - event object\n * @param {undefined|Object} eventData\n */\n _toggle: function (event, eventData) {\n var anchor = $(eventData.newTab).find('a');\n\n if ($(eventData.newTab).find('a').data().tabType === 'link') {\n location.href = anchor.prop('href');\n } else {\n this._superApply(arguments);\n }\n }\n });\n\n rhash = /#.*$/;\n\n /**\n * @param {*} anchor\n * @return {Boolean}\n */\n isLocal = function (anchor) {\n return anchor.hash.length > 1 &&\n anchor.href.replace(rhash, '') ===\n location.href.replace(rhash, '')\n // support: Safari 5.1\n // Safari 5.1 doesn't encode spaces in window.location\n // but it does encode spaces from anchors (#8777)\n .replace(/\\s/g, '%20');\n };\n\n // Extension for mage.tabs - Move panels in destination element\n $.widget('mage.tabs', $.mage.tabs, {\n /**\n * Move panels in destination element on creation\n * @protected\n * @override\n */\n _create: function () {\n this._super();\n this._movePanelsInDestination(this.panels);\n },\n\n /**\n * Get panel for tab. If panel no exist in tabs container, then find panel in destination element\n * @protected\n * @override\n * @param {Element} tab - tab \"li\" DOM-element\n * @return {Element}\n */\n _getPanelForTab: function (tab) {\n var panel = this._superApply(arguments),\n id;\n\n if (!panel.length) {\n id = $(tab).attr('aria-controls');\n panel = $(this.options.destination).find(this._sanitizeSelector('#' + id));\n }\n\n return panel;\n },\n\n /**\n * @private\n */\n _processTabs: function () {\n var that = this;\n\n this.tablist = this._getList()\n .addClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all')\n .attr('role', 'tablist');\n\n this.tabs = this.tablist.find('> li:has(a[href])')\n .addClass('ui-state-default ui-corner-top')\n .attr({\n role: 'tab',\n tabIndex: -1\n });\n\n this.anchors = this.tabs.map(function () {\n return $('a', this)[ 0 ];\n })\n .addClass('ui-tabs-anchor')\n .attr({\n role: 'presentation',\n tabIndex: -1\n });\n\n this.panels = $();\n\n this.anchors.each(function (i, anchor) {\n var selector, panel, panelId,\n anchorId = $(anchor).uniqueId().attr('id'),\n tab = $(anchor).closest('li'),\n originalAriaControls = tab.attr('aria-controls');\n\n // inline tab\n if (isLocal(anchor)) {\n selector = anchor.hash;\n panel = that.document.find(that._sanitizeSelector(selector));\n // remote tab\n } else {\n panelId = tab.attr('aria-controls') || $({}).uniqueId()[ 0 ].id;\n selector = '#' + panelId;\n panel = that.element.find(selector);\n\n if (!panel.length) {\n panel = that._createPanel(panelId);\n panel.insertAfter(that.panels[ i - 1 ] || that.tablist);\n }\n panel.attr('aria-live', 'polite');\n }\n\n if (panel.length) {\n that.panels = that.panels.add(panel);\n }\n\n if (originalAriaControls) {\n tab.data('ui-tabs-aria-controls', originalAriaControls);\n }\n tab.attr({\n 'aria-controls': selector.substring(1),\n 'aria-labelledby': anchorId\n });\n panel.attr('aria-labelledby', anchorId);\n\n if (that.options.excludedPanel.indexOf(anchorId + '_content') < 0) {\n panel.addClass(that.options.tabPanelClass);\n }\n });\n\n this.panels\n .addClass('ui-tabs-panel ui-widget-content ui-corner-bottom')\n .attr('role', 'tabpanel');\n },\n\n /**\n * Move panels in destination element\n * @protected\n * @override\n */\n _movePanelsInDestination: function (panels) {\n if (this.options.destination && !panels.parents(this.options.destination).length) {\n this.element.trigger('beforePanelsMove', panels);\n\n panels.find('script:not([type]), script[type=\"text/javascript\"]').remove();\n\n panels.appendTo(this.options.destination)\n .each($.proxy(function (i, panel) {\n $(panel).trigger('move.tabs', this.anchors.eq(i));\n }, this));\n }\n },\n\n /**\n * Move panels in destination element on tabs switching\n * @protected\n * @override\n * @param {Object} event - event object\n * @param {Object} eventData\n */\n _toggle: function (event, eventData) {\n this._movePanelsInDestination(eventData.newPanel);\n this._superApply(arguments);\n }\n });\n\n // Extension for mage.tabs - Ajax functionality for tabs\n $.widget('mage.tabs', $.mage.tabs, {\n options: {\n /**\n * Add form key to ajax call\n * @param {Object} event - event object\n * @param {Object} ui\n */\n beforeLoad: function (event, ui) {\n ui.ajaxSettings.type = 'POST';\n ui.ajaxSettings.hasContent = true;\n ui.jqXHR.setRequestHeader('Content-Type', ui.ajaxSettings.contentType);\n ui.ajaxSettings.data = jQuery.param(\n {\n isAjax: true,\n 'form_key': typeof FORM_KEY !== 'undefined' ? FORM_KEY : null\n },\n ui.ajaxSettings.traditional\n );\n },\n\n /**\n * Replacing href attribute with loaded panel id\n * @param {Object} event - event object\n * @param {Object} ui\n */\n load: function (event, ui) {\n var panel = $(ui.panel);\n\n $(ui.tab).prop('href', '#' + panel.prop('id'));\n panel.trigger('contentUpdated');\n }\n }\n });\n\n // Extension for mage.tabs - Attach event handlers to tabs\n $.widget('mage.tabs', $.mage.tabs, {\n options: {\n tabIdArgument: 'tab',\n tabsBlockPrefix: null\n },\n\n /**\n * Attach event handlers to tabs, on creation\n * @protected\n * @override\n */\n _refresh: function () {\n this._super();\n $.each(this.tabs, $.proxy(function (i, tab) {\n $(this._getPanelForTab(tab))\n .off('changed' + this.eventNamespace)\n .off('highlight.validate' + this.eventNamespace)\n .off('focusin' + this.eventNamespace)\n\n .on('changed' + this.eventNamespace, {\n index: i\n }, $.proxy(this._onContentChange, this))\n .on('highlight.validate' + this.eventNamespace, {\n index: i\n }, $.proxy(this._onInvalid, this))\n .on('focusin' + this.eventNamespace, {\n index: i\n }, $.proxy(this._onFocus, this));\n }, this));\n\n ($(this.options.destination).is('form') ?\n $(this.options.destination) :\n $(this.options.destination).closest('form'))\n .off('beforeSubmit' + this.eventNamespace)\n .on('beforeSubmit' + this.eventNamespace, $.proxy(this._onBeforeSubmit, this));\n },\n\n /**\n * Mark tab as changed if some field inside tab panel is changed\n * @protected\n * @param {Object} e - event object\n */\n _onContentChange: function (e) {\n var cssChanged = '_changed';\n\n this.anchors.eq(e.data.index).addClass(cssChanged);\n this._updateNavTitleMessages(e, cssChanged);\n },\n\n /**\n * Clone messages (tooltips) from anchor to parent element\n * @protected\n * @param {Object} e - event object\n * @param {String} messageType - changed or error\n */\n _updateNavTitleMessages: function (e, messageType) {\n var curAnchor = this.anchors.eq(e.data.index),\n curItem = curAnchor.parents('[data-role=\"container\"]').find('[data-role=\"title\"]'),\n curItemMessages = curItem.find('[data-role=\"title-messages\"]'),\n activeClass = '_active';\n\n if (curItemMessages.is(':empty')) {\n curAnchor\n .find('[data-role=\"item-messages\"]')\n .clone()\n .appendTo(curItemMessages);\n }\n\n curItemMessages.find('.' + messageType).addClass(activeClass);\n },\n\n /**\n * Mark tab as error if some field inside tab panel is not passed validation\n * @param {Object} e - event object\n * @protected\n */\n _onInvalid: function (e) {\n var cssError = '_error',\n fakeEvent = e;\n\n fakeEvent.currentTarget = $(this.anchors).eq(e.data.index);\n this._eventHandler(fakeEvent);\n this.anchors.eq(e.data.index).addClass(cssError).find('.' + cssError).show();\n this._updateNavTitleMessages(e, cssError);\n },\n\n /**\n * Show tab panel if focus event triggered of some field inside tab panel\n * @param {Object} e - event object\n * @protected\n */\n _onFocus: function (e) {\n this.option('_active', e.data.index);\n },\n\n /**\n * Add active tab id in data object when \"beforeSubmit\" event is triggered\n * @param {Object} e - event object\n * @param {Object} data - event data object\n * @protected\n */\n _onBeforeSubmit: function (e, data) { //eslint-disable-line no-unused-vars\n var activeAnchor = this.activeAnchor(),\n activeTabId = activeAnchor.prop('id'),\n options;\n\n if (this.options.tabsBlockPrefix) {\n if (activeAnchor.is('[id*=\"' + this.options.tabsBlockPrefix + '\"]')) {\n activeTabId = activeAnchor.prop('id').substr(this.options.tabsBlockPrefix.length);\n }\n }\n $(this.anchors).removeClass('error');\n options = {\n action: {\n args: {}\n }\n };\n options.action.args[this.options.tabIdArgument] = activeTabId;\n }\n });\n\n // Extension for mage.tabs - Shadow tabs functionality\n $.widget('mage.tabs', $.mage.tabs, {\n /**\n * Add shadow tabs functionality on creation\n * @protected\n * @override\n */\n _refresh: function () {\n var anchors, shadowTabs, tabs;\n\n this._super();\n anchors = this.anchors;\n shadowTabs = this.options.shadowTabs;\n tabs = this.tabs;\n\n if (shadowTabs) {\n anchors.each($.proxy(function (i, anchor) {\n var anchorId = $(anchor).prop('id');\n\n if (shadowTabs[anchorId]) {\n $(anchor).parents('li').on('click', $.proxy(function () {\n $.each(shadowTabs[anchorId], $.proxy(function (key, id) {\n this.load($(tabs).index($('#' + id).parents('li')), {});\n }, this));\n }, this));\n }\n }, this));\n }\n }\n });\n\n return $.mage.tabs;\n});\n","mage/utils/strings.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'underscore'\n], function (_) {\n 'use strict';\n\n var jsonRe = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/;\n\n return {\n\n /**\n * Attempts to convert string to one of the primitive values,\n * or to parse it as a valid json object.\n *\n * @param {String} str - String to be processed.\n * @returns {*}\n */\n castString: function (str) {\n try {\n str = str === 'true' ? true :\n str === 'false' ? false :\n str === 'null' ? null :\n +str + '' === str ? +str :\n jsonRe.test(str) ? JSON.parse(str) :\n str;\n } catch (e) {\n }\n\n return str;\n },\n\n /**\n * Splits string by separator if it's possible,\n * otherwise returns the incoming value.\n *\n * @param {(String|Array|*)} str - String to split.\n * @param {String} [separator=' '] - Seperator based on which to split the string.\n * @returns {Array|*} Splitted string or the incoming value.\n */\n stringToArray: function (str, separator) {\n separator = separator || ' ';\n\n return typeof str === 'string' ?\n str.split(separator) :\n str;\n },\n\n /**\n * Converts the incoming string which consists\n * of a specified delimiters into a format commonly used in form elements.\n *\n * @param {String} name - The incoming string.\n * @param {String} [separator='.']\n * @returns {String} Serialized string.\n *\n * @example\n * utils.serializeName('one.two.three');\n * => 'one[two][three]';\n */\n serializeName: function (name, separator) {\n var result;\n\n separator = separator || '.';\n name = name.split(separator);\n\n result = name.shift();\n\n name.forEach(function (part) {\n result += '[' + part + ']';\n });\n\n return result;\n },\n\n /**\n * Checks wether the incoming value is not empty,\n * e.g. not 'null' or 'undefined'\n *\n * @param {*} value - Value to check.\n * @returns {Boolean}\n */\n isEmpty: function (value) {\n return value === '' || _.isUndefined(value) || _.isNull(value);\n },\n\n /**\n * Adds 'prefix' to the 'part' value if it was provided.\n *\n * @param {String} prefix\n * @param {String} part\n * @returns {String}\n */\n fullPath: function (prefix, part) {\n return prefix ? prefix + '.' + part : part;\n },\n\n /**\n * Splits incoming string and returns its' part specified by offset.\n *\n * @param {String} parts\n * @param {Number} [offset]\n * @param {String} [delimiter=.]\n * @returns {String}\n */\n getPart: function (parts, offset, delimiter) {\n delimiter = delimiter || '.';\n parts = parts.split(delimiter);\n offset = this.formatOffset(parts, offset);\n\n parts.splice(offset, 1);\n\n return parts.join(delimiter) || '';\n },\n\n /**\n * Converts nameThroughCamelCase to name-through-minus\n *\n * @param {String} string\n * @returns {String}\n */\n camelCaseToMinus: function camelCaseToMinus(string) {\n return ('' + string)\n .split('')\n .map(function (symbol, index) {\n return index ?\n symbol.toUpperCase() === symbol ?\n '-' + symbol.toLowerCase() :\n symbol :\n symbol.toLowerCase();\n })\n .join('');\n },\n\n /**\n * Converts name-through-minus to nameThroughCamelCase\n *\n * @param {String} string\n * @returns {String}\n */\n minusToCamelCase: function minusToCamelCase(string) {\n return ('' + string)\n .split('-')\n .map(function (part, index) {\n return index ? part.charAt(0).toUpperCase() + part.slice(1) : part;\n })\n .join('');\n }\n };\n});\n","mage/utils/arrays.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n './strings'\n], function (_, utils) {\n 'use strict';\n\n /**\n * Defines index of an item in a specified container.\n *\n * @param {*} item - Item whose index should be defined.\n * @param {Array} container - Container upon which to perform search.\n * @returns {Number}\n */\n function getIndex(item, container) {\n var index = container.indexOf(item);\n\n if (~index) {\n return index;\n }\n\n return _.findIndex(container, function (value) {\n return value && value.name === item;\n });\n }\n\n return {\n /**\n * Facade method to remove/add value from/to array\n * without creating a new instance.\n *\n * @param {Array} arr - Array to be modified.\n * @param {*} value - Value to add/remove.\n * @param {Boolean} add - Flag that specfies operation.\n * @returns {Utils} Chainable.\n */\n toggle: function (arr, value, add) {\n return add ?\n this.add(arr, value) :\n this.remove(arr, value);\n },\n\n /**\n * Removes the incoming value from array in case\n * without creating a new instance of it.\n *\n * @param {Array} arr - Array to be modified.\n * @param {*} value - Value to be removed.\n * @returns {Utils} Chainable.\n */\n remove: function (arr, value) {\n var index = arr.indexOf(value);\n\n if (~index) {\n arr.splice(index, 1);\n }\n\n return this;\n },\n\n /**\n * Adds the incoming value to array if\n * it's not alredy present in there.\n *\n * @param {Array} arr - Array to be modifed.\n * @param {...*} arguments - Values to be added.\n * @returns {Utils} Chainable.\n */\n add: function (arr) {\n var values = _.toArray(arguments).slice(1);\n\n values.forEach(function (value) {\n if (!~arr.indexOf(value)) {\n arr.push(value);\n }\n });\n\n return this;\n },\n\n /**\n * Inserts specified item into container at a specified position.\n *\n * @param {*} item - Item to be inserted into container.\n * @param {Array} container - Container of items.\n * @param {*} [position=-1] - Position at which item should be inserted.\n * Position can represent:\n * - specific index in container\n * - item which might already be present in container\n * - structure with one of these properties: after, before\n * @returns {Boolean|*}\n * - true if element has changed its' position\n * - false if nothing has changed\n * - inserted value if it wasn't present in container\n */\n insert: function (item, container, position) {\n var currentIndex = getIndex(item, container),\n newIndex,\n target;\n\n if (typeof position === 'undefined') {\n position = -1;\n } else if (typeof position === 'string') {\n position = isNaN(+position) ? position : +position;\n }\n\n newIndex = position;\n\n if (~currentIndex) {\n target = container.splice(currentIndex, 1)[0];\n\n if (typeof item === 'string') {\n item = target;\n }\n }\n\n if (typeof position !== 'number') {\n target = position.after || position.before || position;\n\n newIndex = getIndex(target, container);\n\n if (~newIndex && (position.after || newIndex >= currentIndex)) {\n newIndex++;\n }\n }\n\n if (newIndex < 0) {\n newIndex += container.length + 1;\n }\n\n container[newIndex] ?\n container.splice(newIndex, 0, item) :\n container[newIndex] = item;\n\n return !~currentIndex ? item : currentIndex !== newIndex;\n },\n\n /**\n * @param {Array} elems\n * @param {Number} offset\n * @return {Number|*}\n */\n formatOffset: function (elems, offset) {\n if (utils.isEmpty(offset)) {\n offset = -1;\n }\n\n offset = +offset;\n\n if (offset < 0) {\n offset += elems.length + 1;\n }\n\n return offset;\n }\n };\n});\n","mage/utils/compare.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'underscore',\n 'mage/utils/objects'\n], function (_, utils) {\n 'use strict';\n\n var result = [];\n\n /**\n * Checks if all of the provided arrays contains equal values.\n *\n * @param {(Boolean|Array)} [keepOrder=false]\n * @param {Array} target\n * @returns {Boolean}\n */\n function equalArrays(keepOrder, target) {\n var args = _.toArray(arguments),\n arrays;\n\n if (!Array.isArray(keepOrder)) {\n arrays = args.slice(2);\n } else {\n target = keepOrder;\n keepOrder = false;\n arrays = args.slice(1);\n }\n\n if (!arrays.length) {\n return true;\n }\n\n return arrays.every(function (array) {\n if (array === target) {\n return true;\n } else if (array.length !== target.length) {\n return false;\n } else if (!keepOrder) {\n return !_.difference(target, array).length;\n }\n\n return array.every(function (value, index) {\n return target[index] === value;\n });\n });\n }\n\n /**\n * Checks if two values are different.\n *\n * @param {*} a - First value.\n * @param {*} b - Second value.\n * @returns {Boolean}\n */\n function isDifferent(a, b) {\n var oldIsPrimitive = utils.isPrimitive(a);\n\n if (Array.isArray(a) && Array.isArray(b)) {\n return !equalArrays(true, a, b);\n }\n\n return oldIsPrimitive ? a !== b : true;\n }\n\n /**\n * @param {String} prefix\n * @param {String} part\n */\n function getPath(prefix, part) {\n return prefix ? prefix + '.' + part : part;\n }\n\n /**\n * Checks if object has own specified property.\n *\n * @param {*} obj - Value to be checked.\n * @param {String} key - Key of the property.\n * @returns {Boolean}\n */\n function hasOwn(obj, key) {\n return Object.prototype.hasOwnProperty.call(obj, key);\n }\n\n /**\n * @param {Array} changes\n */\n function getContainers(changes) {\n var containers = {},\n indexed = _.indexBy(changes, 'path');\n\n _.each(indexed, function (change, name) {\n var path;\n\n name.split('.').forEach(function (part) {\n path = getPath(path, part);\n\n if (path in indexed) {\n return;\n }\n\n (containers[path] = containers[path] || []).push(change);\n });\n });\n\n return containers;\n }\n\n /**\n * @param {String} path\n * @param {String} name\n * @param {String} type\n * @param {String} newValue\n * @param {String} oldValue\n */\n function addChange(path, name, type, newValue, oldValue) {\n var data;\n\n data = {\n path: path,\n name: name,\n type: type\n };\n\n if (type !== 'remove') {\n data.value = newValue;\n data.oldValue = oldValue;\n } else {\n data.oldValue = newValue;\n }\n\n result.push(data);\n }\n\n /**\n * @param {String} ns\n * @param {String} name\n * @param {String} type\n * @param {String} iterator\n * @param {String} placeholder\n */\n function setAll(ns, name, type, iterator, placeholder) {\n var key;\n\n if (arguments.length > 4) {\n type === 'add' ?\n addChange(ns, name, 'update', iterator, placeholder) :\n addChange(ns, name, 'update', placeholder, iterator);\n } else {\n addChange(ns, name, type, iterator);\n }\n\n if (!utils.isObject(iterator)) {\n return;\n }\n\n for (key in iterator) {\n if (hasOwn(iterator, key)) {\n setAll(getPath(ns, key), key, type, iterator[key]);\n }\n }\n }\n\n /*eslint-disable max-depth*/\n /**\n * @param {Object} old\n * @param {Object} current\n * @param {String} ns\n * @param {String} name\n */\n function compare(old, current, ns, name) {\n var key,\n oldIsObj = utils.isObject(old),\n newIsObj = utils.isObject(current);\n\n if (oldIsObj && newIsObj) {\n for (key in old) {\n if (hasOwn(old, key) && !hasOwn(current, key)) {\n setAll(getPath(ns, key), key, 'remove', old[key]);\n }\n }\n\n for (key in current) {\n if (hasOwn(current, key)) {\n hasOwn(old, key) ?\n compare(old[key], current[key], getPath(ns, key), key) :\n setAll(getPath(ns, key), key, 'add', current[key]);\n }\n }\n } else if (oldIsObj) {\n setAll(ns, name, 'remove', old, current);\n } else if (newIsObj) {\n setAll(ns, name, 'add', current, old);\n } else if (isDifferent(old, current)) {\n addChange(ns, name, 'update', current, old);\n }\n }\n\n /*eslint-enable max-depth*/\n\n return {\n\n /**\n *\n * @returns {Object}\n */\n compare: function () {\n var changes;\n\n compare.apply(null, arguments);\n\n changes = result.splice(0);\n\n return {\n containers: getContainers(changes),\n changes: changes,\n equal: !changes.length\n };\n },\n\n equalArrays: equalArrays\n };\n});\n","mage/utils/misc.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'jquery',\n 'mage/utils/objects'\n], function (_, $, utils) {\n 'use strict';\n\n var defaultAttributes,\n ajaxSettings,\n map;\n\n defaultAttributes = {\n method: 'post',\n enctype: 'multipart/form-data'\n };\n\n ajaxSettings = {\n default: {\n method: 'POST',\n cache: false,\n processData: false,\n contentType: false\n },\n simple: {\n method: 'POST',\n dataType: 'json'\n }\n };\n\n map = {\n 'D': 'DDD',\n 'dd': 'DD',\n 'd': 'D',\n 'EEEE': 'dddd',\n 'EEE': 'ddd',\n 'e': 'd',\n 'yyyy': 'YYYY',\n 'yy': 'YY',\n 'y': 'YYYY',\n 'a': 'A'\n };\n\n return {\n\n /**\n * Generates a unique identifier.\n *\n * @param {Number} [size=7] - Length of a resulting identifier.\n * @returns {String}\n */\n uniqueid: function (size) {\n var code = Math.random() * 25 + 65 | 0,\n idstr = String.fromCharCode(code);\n\n size = size || 7;\n\n while (idstr.length < size) {\n code = Math.floor(Math.random() * 42 + 48);\n\n if (code < 58 || code > 64) {\n idstr += String.fromCharCode(code);\n }\n }\n\n return idstr;\n },\n\n /**\n * Limits function call.\n *\n * @param {Object} owner\n * @param {String} target\n * @param {Number} limit\n */\n limit: function (owner, target, limit) {\n var fn = owner[target];\n\n owner[target] = _.debounce(fn.bind(owner), limit);\n },\n\n /**\n * Converts mage date format to a moment.js format.\n *\n * @param {String} mageFormat\n * @returns {String}\n */\n normalizeDate: function (mageFormat) {\n var result = mageFormat;\n\n _.each(map, function (moment, mage) {\n result = result.replace(\n new RegExp(mage + '(?=([^\\u0027]*\\u0027[^\\u0027]*\\u0027)*[^\\u0027]*$)'),\n moment\n );\n });\n result = result.replace(/'(.*?)'/g, '[$1]');\n return result;\n },\n\n /**\n * Puts provided value in range of min and max parameters.\n *\n * @param {Number} value - Value to be located.\n * @param {Number} min - Min value.\n * @param {Number} max - Max value.\n * @returns {Number}\n */\n inRange: function (value, min, max) {\n return Math.min(Math.max(min, value), max);\n },\n\n /**\n * Serializes and sends data via POST request.\n *\n * @param {Object} options - Options object that consists of\n * a 'url' and 'data' properties.\n * @param {Object} attrs - Attributes that will be added to virtual form.\n */\n submit: function (options, attrs) {\n var form = document.createElement('form'),\n data = utils.serialize(options.data),\n attributes = _.extend({}, defaultAttributes, attrs || {});\n\n if (!attributes.action) {\n attributes.action = options.url;\n }\n\n data['form_key'] = window.FORM_KEY;\n\n _.each(attributes, function (value, name) {\n form.setAttribute(name, value);\n });\n\n data = _.map(\n data,\n function (value, name) {\n return '<input type=\"hidden\" ' +\n 'name=\"' + _.escape(name) + '\" ' +\n 'value=\"' + _.escape(value) + '\"' +\n ' />';\n }\n ).join('');\n\n form.insertAdjacentHTML('afterbegin', data);\n document.body.appendChild(form);\n\n form.submit();\n },\n\n /**\n * Serializes and sends data via AJAX POST request.\n *\n * @param {Object} options - Options object that consists of\n * a 'url' and 'data' properties.\n * @param {Object} config\n */\n ajaxSubmit: function (options, config) {\n var t = new Date().getTime(),\n settings;\n\n options.data['form_key'] = window.FORM_KEY;\n options.data = this.prepareFormData(options.data, config.ajaxSaveType);\n settings = _.extend({}, ajaxSettings[config.ajaxSaveType], options || {});\n\n if (!config.ignoreProcessEvents) {\n $('body').trigger('processStart');\n }\n\n return $.ajax(settings)\n .done(function (data) {\n if (config.response) {\n data.t = t;\n config.response.data(data);\n config.response.status(undefined);\n config.response.status(!data.error);\n }\n })\n .fail(function () {\n if (config.response) {\n config.response.status(undefined);\n config.response.status(false);\n config.response.data({\n error: true,\n messages: 'Something went wrong.',\n t: t\n });\n }\n })\n .always(function () {\n if (!config.ignoreProcessEvents) {\n $('body').trigger('processStop');\n }\n });\n },\n\n /**\n * Creates FormData object and append this data.\n *\n * @param {Object} data\n * @param {String} type\n * @returns {FormData}\n */\n prepareFormData: function (data, type) {\n var formData;\n\n if (type === 'default') {\n formData = new FormData();\n _.each(utils.serialize(data), function (val, name) {\n formData.append(name, val);\n });\n } else if (type === 'simple') {\n formData = utils.serialize(data);\n }\n\n return formData;\n },\n\n /**\n * Filters data object. Finds properties with suffix\n * and sets their values to properties with the same name without suffix.\n *\n * @param {Object} data - The data object that should be filtered\n * @param {String} suffix - The string by which data object should be filtered\n * @param {String} separator - The string that is separator between property and suffix\n *\n * @returns {Object} Filtered data object\n */\n filterFormData: function (data, suffix, separator) {\n data = data || {};\n suffix = suffix || 'prepared-for-send';\n separator = separator || '-';\n\n _.each(data, function (value, key) {\n if (_.isObject(value) && !Array.isArray(value)) {\n this.filterFormData(value, suffix, separator);\n } else if (_.isString(key) && ~key.indexOf(suffix)) {\n data[key.split(separator)[0]] = value;\n delete data[key];\n }\n }, this);\n\n return data;\n },\n\n /**\n * Replaces special characters with their corresponding HTML entities.\n *\n * @param {String} string - Text to escape.\n * @returns {String} Escaped text.\n */\n escape: function (string) {\n return string ? $('<p></p>').text(string).html().replace(/\"/g, '"') : string;\n },\n\n /**\n * Replaces symbol codes with their unescaped counterparts.\n *\n * @param {String} data\n *\n * @returns {String}\n */\n unescape: function (data) {\n var unescaped = _.unescape(data),\n mapCharacters = {\n ''': '\\''\n };\n\n _.each(mapCharacters, function (value, key) {\n unescaped = unescaped.replace(key, value);\n });\n\n return unescaped;\n },\n\n /**\n * Converts PHP IntlFormatter format to moment format.\n *\n * @param {String} format - PHP format\n * @returns {String} - moment compatible formatting\n */\n convertToMomentFormat: function (format) {\n var newFormat;\n\n newFormat = format.replace(/yyyy|yy|y/, 'YYYY'); // replace the year\n newFormat = newFormat.replace(/dd|d/g, 'DD'); // replace the date\n\n return newFormat;\n },\n\n /**\n * Get Url Parameters.\n *\n * @param {String} url - Url string\n * @returns {Object}\n */\n getUrlParameters: function (url) {\n var params = {},\n queries = url.split('?'),\n temp,\n i,\n l;\n\n if (!queries[1]) {\n return params;\n }\n\n queries = queries[1].split('&');\n\n for (i = 0, l = queries.length; i < l; i++) {\n temp = queries[i].split('=');\n\n if (temp[1]) {\n params[temp[0]] = decodeURIComponent(temp[1].replace(/\\+/g, '%20'));\n } else {\n params[temp[0]] = '';\n }\n }\n\n return params;\n }\n };\n});\n","mage/utils/objects.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n 'jquery',\n 'underscore',\n 'mage/utils/strings'\n], function (ko, $, _, stringUtils) {\n 'use strict';\n\n var primitives = [\n 'undefined',\n 'boolean',\n 'number',\n 'string'\n ];\n\n /**\n * Sets nested property of a specified object.\n * @private\n *\n * @param {Object} parent - Object to look inside for the properties.\n * @param {Array} path - Splitted path the property.\n * @param {*} value - Value of the last property in 'path' array.\n * returns {*} New value for the property.\n */\n function setNested(parent, path, value) {\n var last = path.pop(),\n len = path.length,\n pi = 0,\n part = path[pi];\n\n for (; pi < len; part = path[++pi]) {\n if (!_.isObject(parent[part])) {\n parent[part] = {};\n }\n\n parent = parent[part];\n }\n\n if (typeof parent[last] === 'function') {\n parent[last](value);\n } else {\n parent[last] = value;\n }\n\n return value;\n }\n\n /**\n * Retrieves value of a nested property.\n * @private\n *\n * @param {Object} parent - Object to look inside for the properties.\n * @param {Array} path - Splitted path the property.\n * @returns {*} Value of the property.\n */\n function getNested(parent, path) {\n var exists = true,\n len = path.length,\n pi = 0;\n\n for (; pi < len && exists; pi++) {\n parent = parent[path[pi]];\n\n if (typeof parent === 'undefined') {\n exists = false;\n }\n }\n\n if (exists) {\n if (ko.isObservable(parent)) {\n parent = parent();\n }\n\n return parent;\n }\n }\n\n /**\n * Removes property from a specified object.\n * @private\n *\n * @param {Object} parent - Object from which to remove property.\n * @param {Array} path - Splitted path to the property.\n */\n function removeNested(parent, path) {\n var field = path.pop();\n\n parent = getNested(parent, path);\n\n if (_.isObject(parent)) {\n delete parent[field];\n }\n }\n\n return {\n\n /**\n * Retrieves or defines objects' property by a composite path.\n *\n * @param {Object} data - Container for the properties specified in path.\n * @param {String} path - Objects' properties divided by dots.\n * @param {*} [value] - New value for the last property.\n * @returns {*} Returns value of the last property in chain.\n *\n * @example\n * utils.nested({}, 'one.two', 3);\n * => { one: {two: 3} }\n */\n nested: function (data, path, value) {\n var action = arguments.length > 2 ? setNested : getNested;\n\n path = path ? path.split('.') : [];\n\n return action(data, path, value);\n },\n\n /**\n * Removes nested property from an object.\n *\n * @param {Object} data - Data source.\n * @param {String} path - Path to the property e.g. 'one.two.three'\n */\n nestedRemove: function (data, path) {\n path = path.split('.');\n\n removeNested(data, path);\n },\n\n /**\n * Flattens objects' nested properties.\n *\n * @param {Object} data - Object to flatten.\n * @param {String} [separator='.'] - Objects' keys separator.\n * @returns {Object} Flattened object.\n *\n * @example Example with a default separator.\n * utils.flatten({one: { two: { three: 'value'} }});\n * => { 'one.two.three': 'value' };\n *\n * @example Example with a custom separator.\n * utils.flatten({one: { two: { three: 'value'} }}, '=>');\n * => {'one=>two=>three': 'value'};\n */\n flatten: function (data, separator, parent, result) {\n separator = separator || '.';\n result = result || {};\n\n if (!data) {\n return result;\n }\n\n // UnderscoreJS each breaks when an object has a length property so we use Object.keys\n _.each(Object.keys(data), function (name) {\n var node = data[name];\n\n if ({}.toString.call(node) === '[object Function]') {\n return;\n }\n\n if (parent) {\n name = parent + separator + name;\n }\n\n typeof node === 'object' ?\n this.flatten(node, separator, name, result) :\n result[name] = node;\n\n }, this);\n\n return result;\n },\n\n /**\n * Opposite operation of the 'flatten' method.\n *\n * @param {Object} data - Previously flattened object.\n * @param {String} [separator='.'] - Keys separator.\n * @returns {Object} Object with nested properties.\n *\n * @example Example using custom separator.\n * utils.unflatten({'one=>two': 'value'}, '=>');\n * => {\n * one: { two: 'value' }\n * };\n */\n unflatten: function (data, separator) {\n var result = {};\n\n separator = separator || '.';\n\n _.each(data, function (value, nodes) {\n nodes = nodes.split(separator);\n\n setNested(result, nodes, value);\n });\n\n return result;\n },\n\n /**\n * Same operation as 'flatten' method,\n * but returns objects' keys wrapped in '[]'.\n *\n * @param {Object} data - Object that should be serialized.\n * @returns {Object} Serialized data.\n *\n * @example\n * utils.serialize({one: { two: { three: 'value'} }});\n * => { 'one[two][three]': 'value' }\n */\n serialize: function (data) {\n var result = {};\n\n data = this.flatten(data);\n\n _.each(data, function (value, keys) {\n keys = stringUtils.serializeName(keys);\n value = _.isUndefined(value) ? '' : value;\n\n result[keys] = value;\n }, this);\n\n return result;\n },\n\n /**\n * Performs deep extend of specified objects.\n *\n * @returns {Object|Array} Extended object.\n */\n extend: function () {\n var args = _.toArray(arguments);\n\n args.unshift(true);\n\n return $.extend.apply($, args);\n },\n\n /**\n * Performs a deep clone of a specified object.\n *\n * @param {(Object|Array)} data - Data that should be copied.\n * @returns {Object|Array} Cloned object.\n */\n copy: function (data) {\n var result = data,\n isArray = Array.isArray(data),\n placeholder;\n\n if (this.isObject(data) || isArray) {\n placeholder = isArray ? [] : {};\n result = this.extend(placeholder, data);\n }\n\n return result;\n },\n\n /**\n * Performs a deep clone of a specified object.\n * Doesn't save links to original object.\n *\n * @param {*} original - Object to clone\n * @returns {*}\n */\n hardCopy: function (original) {\n if (original === null || typeof original !== 'object') {\n return original;\n }\n\n return JSON.parse(JSON.stringify(original));\n },\n\n /**\n * Removes specified nested properties from the target object.\n *\n * @param {Object} target - Object whose properties should be removed.\n * @param {(...String|Array|Object)} list - List that specifies properties to be removed.\n * @returns {Object} Modified object.\n *\n * @example Basic usage\n * var obj = {a: {b: 2}, c: 'a'};\n *\n * omit(obj, 'a.b');\n * => {'a.b': 2};\n * obj => {a: {}, c: 'a'};\n *\n * @example Various syntaxes that would return same result\n * omit(obj, ['a.b', 'c']);\n * omit(obj, 'a.b', 'c');\n * omit(obj, {'a.b': true, 'c': true});\n */\n omit: function (target, list) {\n var removed = {},\n ignored = list;\n\n if (this.isObject(list)) {\n ignored = [];\n\n _.each(list, function (value, key) {\n if (value) {\n ignored.push(key);\n }\n });\n } else if (_.isString(list)) {\n ignored = _.toArray(arguments).slice(1);\n }\n\n _.each(ignored, function (path) {\n var value = this.nested(target, path);\n\n if (!_.isUndefined(value)) {\n removed[path] = value;\n\n this.nestedRemove(target, path);\n }\n }, this);\n\n return removed;\n },\n\n /**\n * Checks if provided value is a plain object.\n *\n * @param {*} value - Value to be checked.\n * @returns {Boolean}\n */\n isObject: function (value) {\n var objProto = Object.prototype;\n\n return typeof value == 'object' ?\n objProto.toString.call(value) === '[object Object]' :\n false;\n },\n\n /**\n *\n * @param {*} value\n * @returns {Boolean}\n */\n isPrimitive: function (value) {\n return value === null || ~primitives.indexOf(typeof value);\n },\n\n /**\n * Iterates over obj props/array elems recursively, applying action to each one\n *\n * @param {Object|Array} data - Data to be iterated.\n * @param {Function} action - Callback to be called with each item as an argument.\n * @param {Number} [maxDepth=7] - Max recursion depth.\n */\n forEachRecursive: function (data, action, maxDepth) {\n maxDepth = typeof maxDepth === 'number' && !isNaN(maxDepth) ? maxDepth - 1 : 7;\n\n if (!_.isFunction(action) || _.isFunction(data) || maxDepth < 0) {\n return;\n }\n\n if (!_.isObject(data)) {\n action(data);\n\n return;\n }\n\n _.each(data, function (value) {\n this.forEachRecursive(value, action, maxDepth);\n }, this);\n\n action(data);\n },\n\n /**\n * Maps obj props/array elems recursively\n *\n * @param {Object|Array} data - Data to be iterated.\n * @param {Function} action - Callback to transform each item.\n * @param {Number} [maxDepth=7] - Max recursion depth.\n *\n * @returns {Object|Array}\n */\n mapRecursive: function (data, action, maxDepth) {\n var newData;\n\n maxDepth = typeof maxDepth === 'number' && !isNaN(maxDepth) ? maxDepth - 1 : 7;\n\n if (!_.isFunction(action) || _.isFunction(data) || maxDepth < 0) {\n return data;\n }\n\n if (!_.isObject(data)) {\n return action(data);\n }\n\n if (_.isArray(data)) {\n newData = _.map(data, function (item) {\n return this.mapRecursive(item, action, maxDepth);\n }, this);\n\n return action(newData);\n }\n\n newData = _.mapObject(data, function (val, key) {\n if (data.hasOwnProperty(key)) {\n return this.mapRecursive(val, action, maxDepth);\n }\n\n return val;\n }, this);\n\n return action(newData);\n },\n\n /**\n * Removes empty(in common sence) obj props/array elems\n *\n * @param {*} data - Data to be cleaned.\n * @returns {*}\n */\n removeEmptyValues: function (data) {\n if (!_.isObject(data)) {\n return data;\n }\n\n if (_.isArray(data)) {\n return data.filter(function (item) {\n return !this.isEmptyObj(item);\n }, this);\n }\n\n return _.omit(data, this.isEmptyObj.bind(this));\n },\n\n /**\n * Checks that argument of any type is empty in common sence:\n * empty string, string with spaces only, object without own props, empty array, null or undefined\n *\n * @param {*} val - Value to be checked.\n * @returns {Boolean}\n */\n isEmptyObj: function (val) {\n\n return _.isObject(val) && _.isEmpty(val) ||\n this.isEmpty(val) ||\n val && val.trim && this.isEmpty(val.trim());\n }\n };\n});\n\n","mage/utils/template.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* eslint-disable no-shadow */\n\ndefine([\n 'jquery',\n 'underscore',\n 'mage/utils/objects',\n 'mage/utils/strings'\n], function ($, _, utils, stringUtils) {\n 'use strict';\n\n var tmplSettings = _.templateSettings,\n interpolate = /\\$\\{([\\s\\S]+?)\\}/g,\n opener = '${',\n template,\n hasStringTmpls;\n\n /**\n * Identifies whether ES6 templates are supported.\n */\n hasStringTmpls = (function () {\n var testString = 'var foo = \"bar\"; return `${ foo }` === foo';\n\n try {\n return Function(testString)();\n } catch (e) {\n return false;\n }\n })();\n\n /**\n * Objects can specify how to use templating for their properties - getting that configuration.\n *\n * To disable rendering for all properties of your object add __disableTmpl: true.\n * To disable for specific property add __disableTmpl: {propertyName: true}.\n * To limit recursion for a specific property add __disableTmpl: {propertyName: numberOfCycles}.\n *\n * @param {String} tmpl\n * @param {Object | undefined} target\n * @returns {Boolean|Object}\n */\n function isTmplIgnored(tmpl, target) {\n var parsedTmpl;\n\n try {\n parsedTmpl = JSON.parse(tmpl);\n\n if (typeof parsedTmpl === 'object') {\n return tmpl.includes('__disableTmpl');\n }\n } catch (e) {\n }\n\n if (typeof target !== 'undefined') {\n if (typeof target === 'object' && target.hasOwnProperty('__disableTmpl')) {\n return target.__disableTmpl;\n }\n }\n\n return false;\n\n }\n\n if (hasStringTmpls) {\n\n /*eslint-disable no-unused-vars, no-eval*/\n /**\n * Evaluates template string using ES6 templates.\n *\n * @param {String} tmpl - Template string.\n * @param {Object} $ - Data object used in a template.\n * @returns {String} Compiled template.\n */\n template = function (tmpl, $) {\n return eval('`' + tmpl + '`');\n };\n\n /*eslint-enable no-unused-vars, no-eval*/\n } else {\n\n /**\n * Fallback function used when ES6 templates are not supported.\n * Uses underscore templates renderer.\n *\n * @param {String} tmpl - Template string.\n * @param {Object} data - Data object used in a template.\n * @returns {String} Compiled template.\n */\n template = function (tmpl, data) {\n var cached = tmplSettings.interpolate;\n\n tmplSettings.interpolate = interpolate;\n\n tmpl = _.template(tmpl, {\n variable: '$'\n })(data);\n\n tmplSettings.interpolate = cached;\n\n return tmpl;\n };\n }\n\n /**\n * Checks if provided value contains template syntax.\n *\n * @param {*} value - Value to be checked.\n * @returns {Boolean}\n */\n function isTemplate(value) {\n return typeof value === 'string' &&\n value.indexOf(opener) !== -1 &&\n // the below pattern almost always indicates an accident which should not cause template evaluation\n // refuse to evaluate\n value.indexOf('${{') === -1;\n }\n\n /**\n * Iteratively processes provided string\n * until no templates syntax will be found.\n *\n * @param {String} tmpl - Template string.\n * @param {Object} data - Data object used in a template.\n * @param {Boolean} [castString=false] - Flag that indicates whether template\n * should be casted after evaluation to a value of another type or\n * that it should be leaved as a string.\n * @param {Number|undefined} maxCycles - Maximum number of rendering cycles, can be 0.\n * @returns {*} Compiled template.\n */\n function render(tmpl, data, castString, maxCycles) {\n var last = tmpl,\n cycles = 0;\n\n while (~tmpl.indexOf(opener) && (typeof maxCycles === 'undefined' || cycles < maxCycles)) {\n if (!isTmplIgnored(tmpl)) {\n tmpl = template(tmpl, data);\n }\n\n if (tmpl === last) {\n break;\n }\n\n last = tmpl;\n cycles++;\n }\n\n return castString ?\n stringUtils.castString(tmpl) :\n tmpl;\n }\n\n return {\n\n /**\n * Applies provided data to the template.\n *\n * @param {Object|String} tmpl\n * @param {Object} [data] - Data object to match with template.\n * @param {Boolean} [castString=false] - Flag that indicates whether template\n * should be casted after evaluation to a value of another type or\n * that it should be leaved as a string.\n * @returns {*}\n *\n * @example Template defined as a string.\n * var source = { foo: 'Random Stuff', bar: 'Some' };\n *\n * utils.template('${ $.bar } ${ $.foo }', source);\n * => 'Some Random Stuff';\n *\n * @example Template defined as an object.\n * var tmpl = {\n * key: {'${ $.$data.bar }': '${ $.$data.foo }'},\n * foo: 'bar',\n * x1: 2, x2: 5,\n * delta: '${ $.x2 - $.x1 }',\n * baz: 'Upper ${ $.foo.toUpperCase() }'\n * };\n *\n * utils.template(tmpl, source);\n * => {\n * key: {'Some': 'Random Stuff'},\n * foo: 'bar',\n * x1: 2, x2: 5,\n * delta: 3,\n * baz: 'Upper BAR'\n * };\n */\n template: function (tmpl, data, castString, dontClone) {\n if (typeof tmpl === 'string') {\n return render(tmpl, data, castString);\n }\n\n if (!dontClone) {\n tmpl = utils.copy(tmpl);\n }\n\n tmpl.$data = data || {};\n\n /**\n * Template iterator function.\n */\n _.each(tmpl, function iterate(value, key, list) {\n var disabled,\n maxCycles;\n\n if (key === '$data') {\n return;\n }\n\n if (isTemplate(key)) {\n delete list[key];\n\n key = render(key, tmpl);\n list[key] = value;\n }\n\n if (isTemplate(value)) {\n //Getting template disabling settings, can be true for all disabled and separate settings\n //for each property.\n disabled = isTmplIgnored(value, list);\n\n if (typeof disabled === 'object' && disabled.hasOwnProperty(key) && disabled[key] !== false) {\n //Checking if specific settings for a property provided.\n maxCycles = disabled[key];\n }\n\n if (disabled === true || maxCycles === true) {\n //Rendering for all properties is disabled.\n maxCycles = 0;\n }\n\n list[key] = render(value, tmpl, castString, maxCycles);\n } else if ($.isPlainObject(value) || Array.isArray(value)) {\n _.each(value, iterate);\n }\n });\n\n delete tmpl.$data;\n\n return tmpl;\n }\n };\n});\n","mage/utils/wrapper.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * Utility methods used to wrap and extend functions.\n *\n * @example Usage of a 'wrap' method with arguments delegation.\n * var multiply = function (a, b) {\n * return a * b;\n * };\n *\n * multiply = module.wrap(multiply, function (orig) {\n * return 'Result is: ' + orig();\n * });\n *\n * multiply(2, 2);\n * => 'Result is: 4'\n *\n * @example Usage of 'wrapSuper' method.\n * var multiply = function (a, b) {\n * return a * b;\n * };\n *\n * var obj = {\n * multiply: module.wrapSuper(multiply, function () {\n * return 'Result is: ' + this._super();\n * });\n * };\n *\n * obj.multiply(2, 2);\n * => 'Result is: 4'\n */\ndefine([\n 'underscore'\n], function (_) {\n 'use strict';\n\n /**\n * Checks if string has a '_super' substring.\n */\n var superReg = /\\b_super\\b/;\n\n return {\n\n /**\n * Wraps target function with a specified wrapper, which will receive\n * reference to the original function as a first argument.\n *\n * @param {Function} target - Function to be wrapped.\n * @param {Function} wrapper - Wrapper function.\n * @returns {Function} Wrapper function.\n */\n wrap: function (target, wrapper) {\n if (!_.isFunction(target) || !_.isFunction(wrapper)) {\n return wrapper;\n }\n\n return function () {\n var args = _.toArray(arguments),\n ctx = this,\n _super;\n\n /**\n * Function that will be passed to the wrapper.\n * If no arguments will be passed to it, then the original\n * function will be called with an arguments of a wrapper function.\n */\n _super = function () {\n var superArgs = arguments.length ? arguments : args.slice(1);\n\n return target.apply(ctx, superArgs);\n };\n\n args.unshift(_super);\n\n return wrapper.apply(ctx, args);\n };\n },\n\n /**\n * Wraps the incoming function to implement support of the '_super' method.\n *\n * @param {Function} target - Function to be wrapped.\n * @param {Function} wrapper - Wrapper function.\n * @returns {Function} Wrapped function.\n */\n wrapSuper: function (target, wrapper) {\n if (!this.hasSuper(wrapper) || !_.isFunction(target)) {\n return wrapper;\n }\n\n return function () {\n var _super = this._super,\n args = arguments,\n result;\n\n /**\n * Temporary define '_super' method which\n * contains call to the original function.\n */\n this._super = function () {\n var superArgs = arguments.length ? arguments : args;\n\n return target.apply(this, superArgs);\n };\n\n result = wrapper.apply(this, args);\n\n this._super = _super;\n\n return result;\n };\n },\n\n /**\n * Checks wether the incoming method contains calls of the '_super' method.\n *\n * @param {Function} fn - Function to be checked.\n * @returns {Boolean}\n */\n hasSuper: function (fn) {\n return _.isFunction(fn) && superReg.test(fn);\n },\n\n /**\n * Extends target object with provided extenders.\n * If property in target and extender objects is a function,\n * then it will be wrapped using 'wrap' method.\n *\n * @param {Object} target - Object to be extended.\n * @param {...Object} extenders - Multiple extenders objects.\n * @returns {Object} Modified target object.\n */\n extend: function (target) {\n var extenders = _.toArray(arguments).slice(1),\n iterator = this._extend.bind(this, target);\n\n extenders.forEach(iterator);\n\n return target;\n },\n\n /**\n * Same as the 'extend' method, but operates only on one extender object.\n *\n * @private\n * @param {Object} target\n * @param {Object} extender\n */\n _extend: function (target, extender) {\n _.each(extender, function (value, key) {\n target[key] = this.wrap(target[key], extender[key]);\n }, this);\n }\n };\n});\n","mage/utils/main.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine(function (require) {\n 'use strict';\n\n var utils = {},\n _ = require('underscore'),\n root = typeof self == 'object' && self.self === self && self ||\n typeof global == 'object' && global.global === global && global ||\n Function('return this')() || {};\n\n root._ = _;\n\n return _.extend(\n utils,\n require('./arrays'),\n require('./compare'),\n require('./misc'),\n require('./objects'),\n require('./strings'),\n require('./template')\n );\n});\n","mage/apply/scripts.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'jquery'\n], function (_, $) {\n 'use strict';\n\n var scriptSelector = 'script[type=\"text/x-magento-init\"]',\n dataAttr = 'data-mage-init',\n virtuals = [];\n\n /**\n * Adds components to the virtual list.\n *\n * @param {Object} components\n */\n function addVirtual(components) {\n virtuals.push({\n el: false,\n data: components\n });\n }\n\n /**\n * Merges provided data with a current data\n * of a elements' \"data-mage-init\" attribute.\n *\n * @param {Object} components - Object with components and theirs configuration.\n * @param {HTMLElement} elem - Element whose data should be modified.\n */\n function setData(components, elem) {\n var data = elem.getAttribute(dataAttr);\n\n data = data ? JSON.parse(data) : {};\n _.each(components, function (obj, key) {\n if (_.has(obj, 'mixins')) {\n data[key] = data[key] || {};\n data[key].mixins = data[key].mixins || [];\n data[key].mixins = data[key].mixins.concat(obj.mixins);\n delete obj.mixins;\n }\n });\n\n data = $.extend(true, data, components);\n data = JSON.stringify(data);\n elem.setAttribute(dataAttr, data);\n }\n\n /**\n * Search for the elements by privded selector and extends theirs data.\n *\n * @param {Object} components - Object with components and theirs configuration.\n * @param {String} selector - Selector for the elements.\n */\n function processElems(components, selector) {\n var elems,\n iterator;\n\n if (selector === '*') {\n addVirtual(components);\n\n return;\n }\n\n elems = document.querySelectorAll(selector);\n iterator = setData.bind(null, components);\n\n _.toArray(elems).forEach(iterator);\n }\n\n /**\n * Parses content of a provided script node.\n * Note: node will be removed from DOM.\n *\n * @param {HTMLScriptElement} node - Node to be processed.\n * @returns {Object}\n */\n function getNodeData(node) {\n var data = node.textContent;\n\n node.parentNode.removeChild(node);\n\n return JSON.parse(data);\n }\n\n /**\n * Parses 'script' tags with a custom type attribute and moves it's data\n * to a 'data-mage-init' attribute of an element found by provided selector.\n * Note: All found script nodes will be removed from DOM.\n *\n * @returns {Array} An array of components not assigned to the specific element.\n *\n * @example Sample declaration.\n * <script type=\"text/x-magento-init\">\n * {\n * \"body\": {\n * \"path/to/component\": {\"foo\": \"bar\"}\n * }\n * }\n * </script>\n *\n * @example Providing data without selector.\n * {\n * \"*\": {\n * \"path/to/component\": {\"bar\": \"baz\"}\n * }\n * }\n */\n return function () {\n var nodes = document.querySelectorAll(scriptSelector);\n\n _.toArray(nodes)\n .map(getNodeData)\n .forEach(function (item) {\n _.each(item, processElems);\n });\n\n return virtuals.splice(0, virtuals.length);\n };\n});\n","mage/apply/main.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'jquery',\n './scripts'\n], function (_, $, processScripts) {\n 'use strict';\n\n var dataAttr = 'data-mage-init',\n nodeSelector = '[' + dataAttr + ']';\n\n /**\n * Initializes components assigned to a specified element via data-* attribute.\n *\n * @param {HTMLElement} el - Element to initialize components with.\n * @param {Object|String} config - Initial components' config.\n * @param {String} component - Components' path.\n */\n function init(el, config, component) {\n require([component], function (fn) {\n var $el;\n\n if (typeof fn === 'object') {\n fn = fn[component].bind(fn);\n }\n\n if (_.isFunction(fn)) {\n fn = fn.bind(null, config, el);\n } else {\n $el = $(el);\n\n if ($el[component]) {\n // eslint-disable-next-line jquery-no-bind-unbind\n fn = $el[component].bind($el, config);\n }\n }\n // Init module in separate task to prevent blocking main thread.\n setTimeout(fn);\n }, function (error) {\n if ('console' in window && typeof window.console.error === 'function') {\n console.error(error);\n }\n\n return true;\n });\n }\n\n /**\n * Parses elements 'data-mage-init' attribute as a valid JSON data.\n * Note: data-mage-init attribute will be removed.\n *\n * @param {HTMLElement} el - Element whose attribute should be parsed.\n * @returns {Object}\n */\n function getData(el) {\n var data = el.getAttribute(dataAttr);\n\n el.removeAttribute(dataAttr);\n\n return {\n el: el,\n data: JSON.parse(data)\n };\n }\n\n return {\n /**\n * Initializes components assigned to HTML elements via [data-mage-init].\n *\n * @example Sample 'data-mage-init' declaration.\n * data-mage-init='{\"path/to/component\": {\"foo\": \"bar\"}}'\n */\n apply: function (context) {\n var virtuals = processScripts(!context ? document : context),\n nodes = document.querySelectorAll(nodeSelector);\n\n _.toArray(nodes)\n .map(getData)\n .concat(virtuals)\n .forEach(function (itemContainer) {\n var element = itemContainer.el;\n\n _.each(itemContainer.data, function (obj, key) {\n if (obj.mixins) {\n require(obj.mixins, function () { //eslint-disable-line max-nested-callbacks\n var i, len;\n\n for (i = 0, len = arguments.length; i < len; i++) {\n $.extend(\n true,\n itemContainer.data[key],\n arguments[i](itemContainer.data[key], element)\n );\n }\n\n delete obj.mixins;\n init.call(null, element, obj, key);\n });\n } else {\n init.call(null, element, obj, key);\n }\n\n }\n );\n\n });\n },\n applyFor: init\n };\n});\n","mage/requirejs/text.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/* inspired by http://github.com/requirejs/text */\n/*global XDomainRequest */\n\ndefine(['module'], function (module) {\n 'use strict';\n\n var xmlRegExp = /^\\s*<\\?xml(\\s)+version=[\\'\\\"](\\d)*.(\\d)*[\\'\\\"](\\s)*\\?>/im,\n bodyRegExp = /<body[^>]*>\\s*([\\s\\S]+)\\s*<\\/body>/im,\n stripReg = /!strip$/i,\n defaultConfig = module.config && module.config() || {};\n\n /**\n * Strips <?xml ...?> declarations so that external SVG and XML documents can be\n * added to a document without worry.\n * Also, if the string is an HTML document, only the part inside the body tag is returned.\n *\n * @param {String} external\n * @returns {String}\n */\n function stripContent(external) {\n var matches;\n\n if (!external) {\n return '';\n }\n\n matches = external.match(bodyRegExp);\n external = matches ?\n matches[1] :\n external.replace(xmlRegExp, '');\n\n return external;\n }\n\n /**\n * Checks that url match current location\n *\n * @param {String} url\n * @returns {Boolean}\n */\n function sameDomain(url) {\n var uProtocol, uHostName, uPort,\n xdRegExp = /^([\\w:]+)?\\/\\/([^\\/\\\\]+)/i,\n location = window.location,\n match = xdRegExp.exec(url);\n\n if (!match) {\n return true;\n }\n uProtocol = match[1];\n uHostName = match[2];\n\n uHostName = uHostName.split(':');\n uPort = uHostName[1] || '';\n uHostName = uHostName[0];\n\n return (!uProtocol || uProtocol === location.protocol) &&\n (!uHostName || uHostName.toLowerCase() === location.hostname.toLowerCase()) &&\n (!uPort && !uHostName || uPort === location.port);\n }\n\n /**\n * @returns {XMLHttpRequest|XDomainRequest|null}\n */\n function createRequest(url) {\n var xhr = new XMLHttpRequest();\n\n if (!sameDomain(url) && typeof XDomainRequest !== 'undefined') {\n xhr = new XDomainRequest();\n }\n\n return xhr;\n }\n\n /**\n * XHR requester. Returns value to callback.\n *\n * @param {String} url\n * @param {Function} callback\n * @param {Function} fail\n * @param {Object} headers\n */\n function getContent(url, callback, fail, headers) {\n var xhr = createRequest(url),\n header;\n\n xhr.open('GET', url);\n\n /*eslint-disable max-depth */\n if ('setRequestHeader' in xhr && headers) {\n for (header in headers) {\n if (headers.hasOwnProperty(header)) {\n xhr.setRequestHeader(header.toLowerCase(), headers[header]);\n }\n }\n }\n\n /**\n * @inheritdoc\n */\n xhr.onreadystatechange = function () {\n var status, err;\n\n //Do not explicitly handle errors, those should be\n //visible via console output in the browser.\n if (xhr.readyState === 4) {\n status = xhr.status || 0;\n\n if (status > 399 && status < 600) {\n //An http 4xx or 5xx error. Signal an error.\n err = new Error(url + ' HTTP status: ' + status);\n err.xhr = xhr;\n\n if (fail) {\n fail(err);\n }\n } else {\n callback(xhr.responseText);\n\n if (defaultConfig.onXhrComplete) {\n defaultConfig.onXhrComplete(xhr, url);\n }\n }\n }\n };\n\n /*eslint-enable max-depth */\n\n if (defaultConfig.onXhr) {\n defaultConfig.onXhr(xhr, url);\n }\n\n xhr.send();\n }\n\n /**\n * Main method used by RequireJs.\n *\n * @param {String} name - has format: some.module.filext!strip\n * @param {Function} req\n * @param {Function|undefined} onLoad\n */\n function loadContent(name, req, onLoad) {\n\n var toStrip = stripReg.test(name),\n url = req.toUrl(name.replace(stripReg, '')),\n headers = defaultConfig.headers;\n\n getContent(url, function (content) {\n content = toStrip ? stripContent(content) : content;\n onLoad(content);\n }, onLoad.error, headers);\n }\n\n return {\n load: loadContent,\n get: getContent\n };\n});\n","mage/requirejs/baseUrlResolver.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * Sample configuration:\n *\n require.config({\n \"config\": {\n \"baseUrlInterceptor\": {\n \"Magento_Ui/js/lib/knockout/bindings/collapsible.js\": \"../../../../frontend/Magento/luma/en_US/\"\n }\n }\n });\n */\n\n/* global jsSuffixRegExp */\n/* eslint-disable max-depth */\ndefine('baseUrlInterceptor', [\n 'module'\n], function (module) {\n 'use strict';\n\n /**\n * RequireJS Context object\n */\n var ctx = require.s.contexts._,\n\n /**\n * Original function\n *\n * @type {Function}\n */\n origNameToUrl = ctx.nameToUrl,\n\n /**\n * Original function\n *\n * @type {Function}\n */\n newContextConstr = require.s.newContext;\n\n /**\n * Remove dots from URL\n *\n * @param {Array} ary\n */\n function trimDots(ary) {\n var i, part, length = ary.length;\n\n for (i = 0; i < length; i++) {\n part = ary[i];\n\n if (part === '.') {\n ary.splice(i, 1);\n i -= 1;\n } else if (part === '..') {\n if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {\n //End of the line. Keep at least one non-dot\n //path segment at the front so it can be mapped\n //correctly to disk. Otherwise, there is likely\n //no path mapping for a path starting with '..'.\n //This can still fail, but catches the most reasonable\n //uses of ..\n break;\n } else if (i > 0) {\n ary.splice(i - 1, 2);\n i -= 2;\n }\n }\n }\n }\n\n /**\n * Normalize URL string (remove '/../')\n *\n * @param {String} name\n * @param {String} baseName\n * @param {Object} applyMap\n * @param {Object} localContext\n * @returns {*}\n */\n function normalize(name, baseName, applyMap, localContext) {\n var lastIndex,\n baseParts = baseName && baseName.split('/'),\n normalizedBaseParts = baseParts;\n\n //Adjust any relative paths.\n if (name && name.charAt(0) === '.') {\n //If have a base name, try to normalize against it,\n //otherwise, assume it is a top-level require that will\n //be relative to baseUrl in the end.\n if (baseName) {\n //Convert baseName to array, and lop off the last part,\n //so that . matches that 'directory' and not name of the baseName's\n //module. For instance, baseName of 'one/two/three', maps to\n //'one/two/three.js', but we want the directory, 'one/two' for\n //this normalization.\n normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);\n name = name.split('/');\n lastIndex = name.length - 1;\n\n // If wanting node ID compatibility, strip .js from end\n // of IDs. Have to do this here, and not in nameToUrl\n // because node allows either .js or non .js to map\n // to same file.\n if (localContext.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {\n name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');\n }\n\n name = normalizedBaseParts.concat(name);\n trimDots(name);\n name = name.join('/');\n } else if (name.indexOf('./') === 0) {\n // No baseName, so this is ID is resolved relative\n // to baseUrl, pull off the leading dot.\n name = name.substring(2);\n }\n }\n\n return name;\n }\n\n /**\n * Get full url.\n *\n * @param {Object} context\n * @param {String} url\n * @return {String}\n */\n function getUrl(context, url) {\n var baseUrl = context.config.baseUrl,\n newConfig = context.config,\n modulePath = url.replace(baseUrl, ''),\n newBaseUrl,\n rewrite = module.config()[modulePath];\n\n if (!rewrite) {\n return url;\n }\n\n newBaseUrl = normalize(rewrite, baseUrl, undefined, newConfig);\n\n return newBaseUrl + modulePath;\n }\n\n /**\n * Replace original function.\n *\n * @returns {*}\n */\n ctx.nameToUrl = function () {\n return getUrl(ctx, origNameToUrl.apply(ctx, arguments));\n };\n\n /**\n * Replace original function.\n *\n * @return {*}\n */\n require.s.newContext = function () {\n var newCtx = newContextConstr.apply(require.s, arguments),\n newOrigNameToUrl = newCtx.nameToUrl;\n\n /**\n * New implementation of native function.\n *\n * @returns {String}\n */\n newCtx.nameToUrl = function () {\n return getUrl(newCtx, newOrigNameToUrl.apply(newCtx, arguments));\n };\n\n return newCtx;\n };\n});\n\nrequire(['baseUrlInterceptor'], function () {\n 'use strict';\n\n});\n","mage/requirejs/resolver.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'underscore',\n 'domReady!'\n], function (_) {\n 'use strict';\n\n var context = require.s.contexts._,\n execCb = context.execCb,\n registry = context.registry,\n callbacks = [],\n retries = 10,\n updateDelay = 1,\n ready,\n update;\n\n /**\n * Checks if provided callback already exists in the callbacks list.\n *\n * @param {Object} callback - Callback object to be checked.\n * @returns {Boolean}\n */\n function isSubscribed(callback) {\n return !!_.findWhere(callbacks, callback);\n }\n\n /**\n * Checks if provided module is rejected during load.\n *\n * @param {Object} module - Module to be checked.\n * @return {Boolean}\n */\n function isRejected(module) {\n return registry[module.id] && (registry[module.id].inited || registry[module.id].error);\n }\n\n /**\n * Checks if provided module had path fallback triggered.\n *\n * @param {Object} module - Module to be checked.\n * @return {Boolean}\n */\n function isPathFallback(module) {\n return registry[module.id] && registry[module.id].events.error;\n }\n\n /**\n * Checks if provided module has unresolved dependencies.\n *\n * @param {Object} module - Module to be checked.\n * @returns {Boolean}\n */\n function isPending(module) {\n if (!module.depCount) {\n return false;\n }\n\n return module.depCount >\n _.filter(module.depMaps, isRejected).length + _.filter(module.depMaps, isPathFallback).length;\n }\n\n /**\n * Checks if requirejs's registry object contains pending modules.\n *\n * @returns {Boolean}\n */\n function hasPending() {\n return _.some(registry, isPending);\n }\n\n /**\n * Checks if 'resolver' module is in ready\n * state and that there are no pending modules.\n *\n * @returns {Boolean}\n */\n function isReady() {\n return ready && !hasPending();\n }\n\n /**\n * Invokes provided callback handler.\n *\n * @param {Object} callback\n */\n function invoke(callback) {\n callback.handler.call(callback.ctx);\n }\n\n /**\n * Sets 'resolver' module to a ready state\n * and invokes pending callbacks.\n */\n function resolve() {\n ready = true;\n\n callbacks.splice(0).forEach(invoke);\n }\n\n /**\n * Drops 'ready' flag and runs the update process.\n */\n function tick() {\n ready = false;\n\n update(retries);\n }\n\n /**\n * Adds callback which will be invoked\n * when all of the pending modules are initiated.\n *\n * @param {Function} handler - 'Ready' event handler function.\n * @param {Object} [ctx] - Optional context with which handler\n * will be invoked.\n */\n function subscribe(handler, ctx) {\n var callback = {\n handler: handler,\n ctx: ctx\n };\n\n if (!isSubscribed(callback)) {\n callbacks.push(callback);\n\n if (isReady()) {\n _.defer(tick);\n }\n }\n }\n\n /**\n * Checks for all modules to be initiated\n * and invokes pending callbacks if it's so.\n *\n * @param {Number} [retry] - Number of retries\n * that will be used to repeat the 'update' function\n * invokation in case if there are no pending requests.\n */\n update = _.debounce(function (retry) {\n if (!hasPending()) {\n retry ? update(--retry) : resolve();\n }\n }, updateDelay);\n\n /**\n * Overrides requirejs's original 'execCb' method\n * in order to track pending modules.\n *\n * @returns {*} Result of original method call.\n */\n context.execCb = function () {\n var exported = execCb.apply(context, arguments);\n\n tick();\n\n return exported;\n };\n\n return subscribe;\n});\n","mage/msie/file-reader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery'\n], function ($) {\n 'use strict';\n\n /**\n * Init \"readAsBinaryString\" function for FileReader class.\n * It need for IE11\n * @param {Blob} fileData\n */\n var readAsBinaryStringIEFunc = function (fileData) {\n var binary = '',\n self = this,\n reader = new FileReader();\n\n /**\n * Read file as binary string\n */\n reader.onload = function () {\n var bytes, length, index;\n\n /* eslint-disable no-undef */\n bytes = new Uint8Array(reader.result);\n /* eslint-enable */\n length = bytes.length;\n\n for (index = 0; index < length; index++) {\n binary += String.fromCharCode(bytes[index]);\n }\n //self.result - readonly so assign binary\n self.content = binary;\n $(self).trigger('onload');\n };\n reader.readAsArrayBuffer(fileData);\n };\n\n if (typeof FileReader.prototype.readAsBinaryString === 'undefined') {\n FileReader.prototype.readAsBinaryString = readAsBinaryStringIEFunc;\n }\n});\n","chartjs/chartjs-adapter-moment.js":"/*!\n * chartjs-adapter-moment v1.0.0\n * https://www.chartjs.org\n * (c) 2021 chartjs-adapter-moment Contributors\n * Released under the MIT license\n */\n(function (global, factory) {\ntypeof exports === 'object' && typeof module !== 'undefined' ? factory(require('moment'), require('chart.js')) :\ntypeof define === 'function' && define.amd ? define(['moment', 'chart.js'], factory) :\n(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.moment, global.Chart));\n}(this, (function (moment, chart_js) { 'use strict';\n\nfunction _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }\n\nvar moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);\n\nconst FORMATS = {\n datetime: 'MMM D, YYYY, h:mm:ss a',\n millisecond: 'h:mm:ss.SSS a',\n second: 'h:mm:ss a',\n minute: 'h:mm a',\n hour: 'hA',\n day: 'MMM D',\n week: 'll',\n month: 'MMM YYYY',\n quarter: '[Q]Q - YYYY',\n year: 'YYYY'\n};\n\nchart_js._adapters._date.override(typeof moment__default['default'] === 'function' ? {\n _id: 'moment', // DEBUG ONLY\n\n formats: function() {\n return FORMATS;\n },\n\n parse: function(value, format) {\n if (typeof value === 'string' && typeof format === 'string') {\n value = moment__default['default'](value, format);\n } else if (!(value instanceof moment__default['default'])) {\n value = moment__default['default'](value);\n }\n return value.isValid() ? value.valueOf() : null;\n },\n\n format: function(time, format) {\n return moment__default['default'](time).format(format);\n },\n\n add: function(time, amount, unit) {\n return moment__default['default'](time).add(amount, unit).valueOf();\n },\n\n diff: function(max, min, unit) {\n return moment__default['default'](max).diff(moment__default['default'](min), unit);\n },\n\n startOf: function(time, unit, weekday) {\n time = moment__default['default'](time);\n if (unit === 'isoWeek') {\n weekday = Math.trunc(Math.min(Math.max(0, weekday), 6));\n return time.isoWeekday(weekday).startOf('day').valueOf();\n }\n return time.startOf(unit).valueOf();\n },\n\n endOf: function(time, unit) {\n return moment__default['default'](time).endOf(unit).valueOf();\n }\n} : {});\n\n})));\n","chartjs/Chart.min.js":"/*!\n * Chart.js v3.9.1\n * https://www.chartjs.org\n * (c) 2022 Chart.js Contributors\n * Released under the MIT License\n */\n!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define(e):(t=\"undefined\"!=typeof globalThis?globalThis:t||self).Chart=e()}(this,(function(){\"use strict\";function t(){}const e=function(){let t=0;return function(){return t++}}();function i(t){return null==t}function s(t){if(Array.isArray&&Array.isArray(t))return!0;const e=Object.prototype.toString.call(t);return\"[object\"===e.slice(0,7)&&\"Array]\"===e.slice(-6)}function n(t){return null!==t&&\"[object Object]\"===Object.prototype.toString.call(t)}const o=t=>(\"number\"==typeof t||t instanceof Number)&&isFinite(+t);function a(t,e){return o(t)?t:e}function r(t,e){return void 0===t?e:t}const l=(t,e)=>\"string\"==typeof t&&t.endsWith(\"%\")?parseFloat(t)/100:t/e,h=(t,e)=>\"string\"==typeof t&&t.endsWith(\"%\")?parseFloat(t)/100*e:+t;function c(t,e,i){if(t&&\"function\"==typeof t.call)return t.apply(i,e)}function d(t,e,i,o){let a,r,l;if(s(t))if(r=t.length,o)for(a=r-1;a>=0;a--)e.call(i,t[a],a);else for(a=0;a<r;a++)e.call(i,t[a],a);else if(n(t))for(l=Object.keys(t),r=l.length,a=0;a<r;a++)e.call(i,t[l[a]],l[a])}function u(t,e){let i,s,n,o;if(!t||!e||t.length!==e.length)return!1;for(i=0,s=t.length;i<s;++i)if(n=t[i],o=e[i],n.datasetIndex!==o.datasetIndex||n.index!==o.index)return!1;return!0}function f(t){if(s(t))return t.map(f);if(n(t)){const e=Object.create(null),i=Object.keys(t),s=i.length;let n=0;for(;n<s;++n)e[i[n]]=f(t[i[n]]);return e}return t}function g(t){return-1===[\"__proto__\",\"prototype\",\"constructor\"].indexOf(t)}function p(t,e,i,s){if(!g(t))return;const o=e[t],a=i[t];n(o)&&n(a)?m(o,a,s):e[t]=f(a)}function m(t,e,i){const o=s(e)?e:[e],a=o.length;if(!n(t))return t;const r=(i=i||{}).merger||p;for(let s=0;s<a;++s){if(!n(e=o[s]))continue;const a=Object.keys(e);for(let s=0,n=a.length;s<n;++s)r(a[s],t,e,i)}return t}function b(t,e){return m(t,e,{merger:x})}function x(t,e,i){if(!g(t))return;const s=e[t],o=i[t];n(s)&&n(o)?b(s,o):Object.prototype.hasOwnProperty.call(e,t)||(e[t]=f(o))}const _={\"\":t=>t,x:t=>t.x,y:t=>t.y};function y(t,e){const i=_[e]||(_[e]=function(t){const e=v(t);return t=>{for(const i of e){if(\"\"===i)break;t=t&&t[i]}return t}}(e));return i(t)}function v(t){const e=t.split(\".\"),i=[];let s=\"\";for(const t of e)s+=t,s.endsWith(\"\\\\\")?s=s.slice(0,-1)+\".\":(i.push(s),s=\"\");return i}function w(t){return t.charAt(0).toUpperCase()+t.slice(1)}const M=t=>void 0!==t,k=t=>\"function\"==typeof t,S=(t,e)=>{if(t.size!==e.size)return!1;for(const i of t)if(!e.has(i))return!1;return!0};function P(t){return\"mouseup\"===t.type||\"click\"===t.type||\"contextmenu\"===t.type}const D=Math.PI,O=2*D,C=O+D,A=Number.POSITIVE_INFINITY,T=D/180,L=D/2,E=D/4,R=2*D/3,I=Math.log10,z=Math.sign;function F(t){const e=Math.round(t);t=N(t,e,t/1e3)?e:t;const i=Math.pow(10,Math.floor(I(t))),s=t/i;return(s<=1?1:s<=2?2:s<=5?5:10)*i}function V(t){const e=[],i=Math.sqrt(t);let s;for(s=1;s<i;s++)t%s==0&&(e.push(s),e.push(t/s));return i===(0|i)&&e.push(i),e.sort(((t,e)=>t-e)).pop(),e}function B(t){return!isNaN(parseFloat(t))&&isFinite(t)}function N(t,e,i){return Math.abs(t-e)<i}function W(t,e){const i=Math.round(t);return i-e<=t&&i+e>=t}function j(t,e,i){let s,n,o;for(s=0,n=t.length;s<n;s++)o=t[s][i],isNaN(o)||(e.min=Math.min(e.min,o),e.max=Math.max(e.max,o))}function H(t){return t*(D/180)}function $(t){return t*(180/D)}function Y(t){if(!o(t))return;let e=1,i=0;for(;Math.round(t*e)/e!==t;)e*=10,i++;return i}function U(t,e){const i=e.x-t.x,s=e.y-t.y,n=Math.sqrt(i*i+s*s);let o=Math.atan2(s,i);return o<-.5*D&&(o+=O),{angle:o,distance:n}}function X(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function q(t,e){return(t-e+C)%O-D}function K(t){return(t%O+O)%O}function G(t,e,i,s){const n=K(t),o=K(e),a=K(i),r=K(o-n),l=K(a-n),h=K(n-o),c=K(n-a);return n===o||n===a||s&&o===a||r>l&&h<c}function Z(t,e,i){return Math.max(e,Math.min(i,t))}function J(t){return Z(t,-32768,32767)}function Q(t,e,i,s=1e-6){return t>=Math.min(e,i)-s&&t<=Math.max(e,i)+s}function tt(t,e,i){i=i||(i=>t[i]<e);let s,n=t.length-1,o=0;for(;n-o>1;)s=o+n>>1,i(s)?o=s:n=s;return{lo:o,hi:n}}const et=(t,e,i,s)=>tt(t,i,s?s=>t[s][e]<=i:s=>t[s][e]<i),it=(t,e,i)=>tt(t,i,(s=>t[s][e]>=i));function st(t,e,i){let s=0,n=t.length;for(;s<n&&t[s]<e;)s++;for(;n>s&&t[n-1]>i;)n--;return s>0||n<t.length?t.slice(s,n):t}const nt=[\"push\",\"pop\",\"shift\",\"splice\",\"unshift\"];function ot(t,e){t._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,\"_chartjs\",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),nt.forEach((e=>{const i=\"_onData\"+w(e),s=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value(...e){const n=s.apply(this,e);return t._chartjs.listeners.forEach((t=>{\"function\"==typeof t[i]&&t[i](...e)})),n}})})))}function at(t,e){const i=t._chartjs;if(!i)return;const s=i.listeners,n=s.indexOf(e);-1!==n&&s.splice(n,1),s.length>0||(nt.forEach((e=>{delete t[e]})),delete t._chartjs)}function rt(t){const e=new Set;let i,s;for(i=0,s=t.length;i<s;++i)e.add(t[i]);return e.size===s?t:Array.from(e)}const lt=\"undefined\"==typeof window?function(t){return t()}:window.requestAnimationFrame;function ht(t,e,i){const s=i||(t=>Array.prototype.slice.call(t));let n=!1,o=[];return function(...i){o=s(i),n||(n=!0,lt.call(window,(()=>{n=!1,t.apply(e,o)})))}}function ct(t,e){let i;return function(...s){return e?(clearTimeout(i),i=setTimeout(t,e,s)):t.apply(this,s),e}}const dt=t=>\"start\"===t?\"left\":\"end\"===t?\"right\":\"center\",ut=(t,e,i)=>\"start\"===t?e:\"end\"===t?i:(e+i)/2,ft=(t,e,i,s)=>t===(s?\"left\":\"right\")?i:\"center\"===t?(e+i)/2:e;function gt(t,e,i){const s=e.length;let n=0,o=s;if(t._sorted){const{iScale:a,_parsed:r}=t,l=a.axis,{min:h,max:c,minDefined:d,maxDefined:u}=a.getUserBounds();d&&(n=Z(Math.min(et(r,a.axis,h).lo,i?s:et(e,l,a.getPixelForValue(h)).lo),0,s-1)),o=u?Z(Math.max(et(r,a.axis,c,!0).hi+1,i?0:et(e,l,a.getPixelForValue(c),!0).hi+1),n,s)-n:s-n}return{start:n,count:o}}function pt(t){const{xScale:e,yScale:i,_scaleRanges:s}=t,n={xmin:e.min,xmax:e.max,ymin:i.min,ymax:i.max};if(!s)return t._scaleRanges=n,!0;const o=s.xmin!==e.min||s.xmax!==e.max||s.ymin!==i.min||s.ymax!==i.max;return Object.assign(s,n),o}var mt=new class{constructor(){this._request=null,this._charts=new Map,this._running=!1,this._lastDate=void 0}_notify(t,e,i,s){const n=e.listeners[s],o=e.duration;n.forEach((s=>s({chart:t,initial:e.initial,numSteps:o,currentStep:Math.min(i-e.start,o)})))}_refresh(){this._request||(this._running=!0,this._request=lt.call(window,(()=>{this._update(),this._request=null,this._running&&this._refresh()})))}_update(t=Date.now()){let e=0;this._charts.forEach(((i,s)=>{if(!i.running||!i.items.length)return;const n=i.items;let o,a=n.length-1,r=!1;for(;a>=0;--a)o=n[a],o._active?(o._total>i.duration&&(i.duration=o._total),o.tick(t),r=!0):(n[a]=n[n.length-1],n.pop());r&&(s.draw(),this._notify(s,i,t,\"progress\")),n.length||(i.running=!1,this._notify(s,i,t,\"complete\"),i.initial=!1),e+=n.length})),this._lastDate=t,0===e&&(this._running=!1)}_getAnims(t){const e=this._charts;let i=e.get(t);return i||(i={running:!1,initial:!0,items:[],listeners:{complete:[],progress:[]}},e.set(t,i)),i}listen(t,e,i){this._getAnims(t).listeners[e].push(i)}add(t,e){e&&e.length&&this._getAnims(t).items.push(...e)}has(t){return this._getAnims(t).items.length>0}start(t){const e=this._charts.get(t);e&&(e.running=!0,e.start=Date.now(),e.duration=e.items.reduce(((t,e)=>Math.max(t,e._duration)),0),this._refresh())}running(t){if(!this._running)return!1;const e=this._charts.get(t);return!!(e&&e.running&&e.items.length)}stop(t){const e=this._charts.get(t);if(!e||!e.items.length)return;const i=e.items;let s=i.length-1;for(;s>=0;--s)i[s].cancel();e.items=[],this._notify(t,e,Date.now(),\"complete\")}remove(t){return this._charts.delete(t)}};\n /*!\n * @kurkle/color v0.2.1\n * https://github.com/kurkle/color#readme\n * (c) 2022 Jukka Kurkela\n * Released under the MIT License\n */function bt(t){return t+.5|0}const xt=(t,e,i)=>Math.max(Math.min(t,i),e);function _t(t){return xt(bt(2.55*t),0,255)}function yt(t){return xt(bt(255*t),0,255)}function vt(t){return xt(bt(t/2.55)/100,0,1)}function wt(t){return xt(bt(100*t),0,100)}const Mt={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},kt=[...\"0123456789ABCDEF\"],St=t=>kt[15&t],Pt=t=>kt[(240&t)>>4]+kt[15&t],Dt=t=>(240&t)>>4==(15&t);function Ot(t){var e=(t=>Dt(t.r)&&Dt(t.g)&&Dt(t.b)&&Dt(t.a))(t)?St:Pt;return t?\"#\"+e(t.r)+e(t.g)+e(t.b)+((t,e)=>t<255?e(t):\"\")(t.a,e):void 0}const Ct=/^(hsla?|hwb|hsv)\\(\\s*([-+.e\\d]+)(?:deg)?[\\s,]+([-+.e\\d]+)%[\\s,]+([-+.e\\d]+)%(?:[\\s,]+([-+.e\\d]+)(%)?)?\\s*\\)$/;function At(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function Tt(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function Lt(t,e,i){const s=At(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function Et(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=function(t,e,i,s,n){return t===n?(e-i)/s+(e<i?6:0):e===n?(i-t)/s+2:(t-e)/s+4}(e,i,s,h,n),r=60*r+.5),[0|r,l||0,a]}function Rt(t,e,i,s){return(Array.isArray(e)?t(e[0],e[1],e[2]):t(e,i,s)).map(yt)}function It(t,e,i){return Rt(At,t,e,i)}function zt(t){return(t%360+360)%360}function Ft(t){const e=Ct.exec(t);let i,s=255;if(!e)return;e[5]!==i&&(s=e[6]?_t(+e[5]):yt(+e[5]));const n=zt(+e[2]),o=+e[3]/100,a=+e[4]/100;return i=\"hwb\"===e[1]?function(t,e,i){return Rt(Lt,t,e,i)}(n,o,a):\"hsv\"===e[1]?function(t,e,i){return Rt(Tt,t,e,i)}(n,o,a):It(n,o,a),{r:i[0],g:i[1],b:i[2],a:s}}const Vt={x:\"dark\",Z:\"light\",Y:\"re\",X:\"blu\",W:\"gr\",V:\"medium\",U:\"slate\",A:\"ee\",T:\"ol\",S:\"or\",B:\"ra\",C:\"lateg\",D:\"ights\",R:\"in\",Q:\"turquois\",E:\"hi\",P:\"ro\",O:\"al\",N:\"le\",M:\"de\",L:\"yello\",F:\"en\",K:\"ch\",G:\"arks\",H:\"ea\",I:\"ightg\",J:\"wh\"},Bt={OiceXe:\"f0f8ff\",antiquewEte:\"faebd7\",aqua:\"ffff\",aquamarRe:\"7fffd4\",azuY:\"f0ffff\",beige:\"f5f5dc\",bisque:\"ffe4c4\",black:\"0\",blanKedOmond:\"ffebcd\",Xe:\"ff\",XeviTet:\"8a2be2\",bPwn:\"a52a2a\",burlywood:\"deb887\",caMtXe:\"5f9ea0\",KartYuse:\"7fff00\",KocTate:\"d2691e\",cSO:\"ff7f50\",cSnflowerXe:\"6495ed\",cSnsilk:\"fff8dc\",crimson:\"dc143c\",cyan:\"ffff\",xXe:\"8b\",xcyan:\"8b8b\",xgTMnPd:\"b8860b\",xWay:\"a9a9a9\",xgYF:\"6400\",xgYy:\"a9a9a9\",xkhaki:\"bdb76b\",xmagFta:\"8b008b\",xTivegYF:\"556b2f\",xSange:\"ff8c00\",xScEd:\"9932cc\",xYd:\"8b0000\",xsOmon:\"e9967a\",xsHgYF:\"8fbc8f\",xUXe:\"483d8b\",xUWay:\"2f4f4f\",xUgYy:\"2f4f4f\",xQe:\"ced1\",xviTet:\"9400d3\",dAppRk:\"ff1493\",dApskyXe:\"bfff\",dimWay:\"696969\",dimgYy:\"696969\",dodgerXe:\"1e90ff\",fiYbrick:\"b22222\",flSOwEte:\"fffaf0\",foYstWAn:\"228b22\",fuKsia:\"ff00ff\",gaRsbSo:\"dcdcdc\",ghostwEte:\"f8f8ff\",gTd:\"ffd700\",gTMnPd:\"daa520\",Way:\"808080\",gYF:\"8000\",gYFLw:\"adff2f\",gYy:\"808080\",honeyMw:\"f0fff0\",hotpRk:\"ff69b4\",RdianYd:\"cd5c5c\",Rdigo:\"4b0082\",ivSy:\"fffff0\",khaki:\"f0e68c\",lavFMr:\"e6e6fa\",lavFMrXsh:\"fff0f5\",lawngYF:\"7cfc00\",NmoncEffon:\"fffacd\",ZXe:\"add8e6\",ZcSO:\"f08080\",Zcyan:\"e0ffff\",ZgTMnPdLw:\"fafad2\",ZWay:\"d3d3d3\",ZgYF:\"90ee90\",ZgYy:\"d3d3d3\",ZpRk:\"ffb6c1\",ZsOmon:\"ffa07a\",ZsHgYF:\"20b2aa\",ZskyXe:\"87cefa\",ZUWay:\"778899\",ZUgYy:\"778899\",ZstAlXe:\"b0c4de\",ZLw:\"ffffe0\",lime:\"ff00\",limegYF:\"32cd32\",lRF:\"faf0e6\",magFta:\"ff00ff\",maPon:\"800000\",VaquamarRe:\"66cdaa\",VXe:\"cd\",VScEd:\"ba55d3\",VpurpN:\"9370db\",VsHgYF:\"3cb371\",VUXe:\"7b68ee\",VsprRggYF:\"fa9a\",VQe:\"48d1cc\",VviTetYd:\"c71585\",midnightXe:\"191970\",mRtcYam:\"f5fffa\",mistyPse:\"ffe4e1\",moccasR:\"ffe4b5\",navajowEte:\"ffdead\",navy:\"80\",Tdlace:\"fdf5e6\",Tive:\"808000\",TivedBb:\"6b8e23\",Sange:\"ffa500\",SangeYd:\"ff4500\",ScEd:\"da70d6\",pOegTMnPd:\"eee8aa\",pOegYF:\"98fb98\",pOeQe:\"afeeee\",pOeviTetYd:\"db7093\",papayawEp:\"ffefd5\",pHKpuff:\"ffdab9\",peru:\"cd853f\",pRk:\"ffc0cb\",plum:\"dda0dd\",powMrXe:\"b0e0e6\",purpN:\"800080\",YbeccapurpN:\"663399\",Yd:\"ff0000\",Psybrown:\"bc8f8f\",PyOXe:\"4169e1\",saddNbPwn:\"8b4513\",sOmon:\"fa8072\",sandybPwn:\"f4a460\",sHgYF:\"2e8b57\",sHshell:\"fff5ee\",siFna:\"a0522d\",silver:\"c0c0c0\",skyXe:\"87ceeb\",UXe:\"6a5acd\",UWay:\"708090\",UgYy:\"708090\",snow:\"fffafa\",sprRggYF:\"ff7f\",stAlXe:\"4682b4\",tan:\"d2b48c\",teO:\"8080\",tEstN:\"d8bfd8\",tomato:\"ff6347\",Qe:\"40e0d0\",viTet:\"ee82ee\",JHt:\"f5deb3\",wEte:\"ffffff\",wEtesmoke:\"f5f5f5\",Lw:\"ffff00\",LwgYF:\"9acd32\"};let Nt;function Wt(t){Nt||(Nt=function(){const t={},e=Object.keys(Bt),i=Object.keys(Vt);let s,n,o,a,r;for(s=0;s<e.length;s++){for(a=r=e[s],n=0;n<i.length;n++)o=i[n],r=r.replace(o,Vt[o]);o=parseInt(Bt[a],16),t[r]=[o>>16&255,o>>8&255,255&o]}return t}(),Nt.transparent=[0,0,0,0]);const e=Nt[t.toLowerCase()];return e&&{r:e[0],g:e[1],b:e[2],a:4===e.length?e[3]:255}}const jt=/^rgba?\\(\\s*([-+.\\d]+)(%)?[\\s,]+([-+.e\\d]+)(%)?[\\s,]+([-+.e\\d]+)(%)?(?:[\\s,/]+([-+.e\\d]+)(%)?)?\\s*\\)$/;const Ht=t=>t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055,$t=t=>t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4);function Yt(t,e,i){if(t){let s=Et(t);s[e]=Math.max(0,Math.min(s[e]+s[e]*i,0===e?360:1)),s=It(s),t.r=s[0],t.g=s[1],t.b=s[2]}}function Ut(t,e){return t?Object.assign(e||{},t):t}function Xt(t){var e={r:0,g:0,b:0,a:255};return Array.isArray(t)?t.length>=3&&(e={r:t[0],g:t[1],b:t[2],a:255},t.length>3&&(e.a=yt(t[3]))):(e=Ut(t,{r:0,g:0,b:0,a:1})).a=yt(e.a),e}function qt(t){return\"r\"===t.charAt(0)?function(t){const e=jt.exec(t);let i,s,n,o=255;if(e){if(e[7]!==i){const t=+e[7];o=e[8]?_t(t):xt(255*t,0,255)}return i=+e[1],s=+e[3],n=+e[5],i=255&(e[2]?_t(i):xt(i,0,255)),s=255&(e[4]?_t(s):xt(s,0,255)),n=255&(e[6]?_t(n):xt(n,0,255)),{r:i,g:s,b:n,a:o}}}(t):Ft(t)}class Kt{constructor(t){if(t instanceof Kt)return t;const e=typeof t;let i;var s,n,o;\"object\"===e?i=Xt(t):\"string\"===e&&(o=(s=t).length,\"#\"===s[0]&&(4===o||5===o?n={r:255&17*Mt[s[1]],g:255&17*Mt[s[2]],b:255&17*Mt[s[3]],a:5===o?17*Mt[s[4]]:255}:7!==o&&9!==o||(n={r:Mt[s[1]]<<4|Mt[s[2]],g:Mt[s[3]]<<4|Mt[s[4]],b:Mt[s[5]]<<4|Mt[s[6]],a:9===o?Mt[s[7]]<<4|Mt[s[8]]:255})),i=n||Wt(t)||qt(t)),this._rgb=i,this._valid=!!i}get valid(){return this._valid}get rgb(){var t=Ut(this._rgb);return t&&(t.a=vt(t.a)),t}set rgb(t){this._rgb=Xt(t)}rgbString(){return this._valid?(t=this._rgb)&&(t.a<255?`rgba(${t.r}, ${t.g}, ${t.b}, ${vt(t.a)})`:`rgb(${t.r}, ${t.g}, ${t.b})`):void 0;var t}hexString(){return this._valid?Ot(this._rgb):void 0}hslString(){return this._valid?function(t){if(!t)return;const e=Et(t),i=e[0],s=wt(e[1]),n=wt(e[2]);return t.a<255?`hsla(${i}, ${s}%, ${n}%, ${vt(t.a)})`:`hsl(${i}, ${s}%, ${n}%)`}(this._rgb):void 0}mix(t,e){if(t){const i=this.rgb,s=t.rgb;let n;const o=e===n?.5:e,a=2*o-1,r=i.a-s.a,l=((a*r==-1?a:(a+r)/(1+a*r))+1)/2;n=1-l,i.r=255&l*i.r+n*s.r+.5,i.g=255&l*i.g+n*s.g+.5,i.b=255&l*i.b+n*s.b+.5,i.a=o*i.a+(1-o)*s.a,this.rgb=i}return this}interpolate(t,e){return t&&(this._rgb=function(t,e,i){const s=$t(vt(t.r)),n=$t(vt(t.g)),o=$t(vt(t.b));return{r:yt(Ht(s+i*($t(vt(e.r))-s))),g:yt(Ht(n+i*($t(vt(e.g))-n))),b:yt(Ht(o+i*($t(vt(e.b))-o))),a:t.a+i*(e.a-t.a)}}(this._rgb,t._rgb,e)),this}clone(){return new Kt(this.rgb)}alpha(t){return this._rgb.a=yt(t),this}clearer(t){return this._rgb.a*=1-t,this}greyscale(){const t=this._rgb,e=bt(.3*t.r+.59*t.g+.11*t.b);return t.r=t.g=t.b=e,this}opaquer(t){return this._rgb.a*=1+t,this}negate(){const t=this._rgb;return t.r=255-t.r,t.g=255-t.g,t.b=255-t.b,this}lighten(t){return Yt(this._rgb,2,t),this}darken(t){return Yt(this._rgb,2,-t),this}saturate(t){return Yt(this._rgb,1,t),this}desaturate(t){return Yt(this._rgb,1,-t),this}rotate(t){return function(t,e){var i=Et(t);i[0]=zt(i[0]+e),i=It(i),t.r=i[0],t.g=i[1],t.b=i[2]}(this._rgb,t),this}}function Gt(t){return new Kt(t)}function Zt(t){if(t&&\"object\"==typeof t){const e=t.toString();return\"[object CanvasPattern]\"===e||\"[object CanvasGradient]\"===e}return!1}function Jt(t){return Zt(t)?t:Gt(t)}function Qt(t){return Zt(t)?t:Gt(t).saturate(.5).darken(.1).hexString()}const te=Object.create(null),ee=Object.create(null);function ie(t,e){if(!e)return t;const i=e.split(\".\");for(let e=0,s=i.length;e<s;++e){const s=i[e];t=t[s]||(t[s]=Object.create(null))}return t}function se(t,e,i){return\"string\"==typeof e?m(ie(t,e),i):m(ie(t,\"\"),e)}var ne=new class{constructor(t){this.animation=void 0,this.backgroundColor=\"rgba(0,0,0,0.1)\",this.borderColor=\"rgba(0,0,0,0.1)\",this.color=\"#666\",this.datasets={},this.devicePixelRatio=t=>t.chart.platform.getDevicePixelRatio(),this.elements={},this.events=[\"mousemove\",\"mouseout\",\"click\",\"touchstart\",\"touchmove\"],this.font={family:\"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",size:12,style:\"normal\",lineHeight:1.2,weight:null},this.hover={},this.hoverBackgroundColor=(t,e)=>Qt(e.backgroundColor),this.hoverBorderColor=(t,e)=>Qt(e.borderColor),this.hoverColor=(t,e)=>Qt(e.color),this.indexAxis=\"x\",this.interaction={mode:\"nearest\",intersect:!0,includeInvisible:!1},this.maintainAspectRatio=!0,this.onHover=null,this.onClick=null,this.parsing=!0,this.plugins={},this.responsive=!0,this.scale=void 0,this.scales={},this.showLine=!0,this.drawActiveElementsOnTop=!0,this.describe(t)}set(t,e){return se(this,t,e)}get(t){return ie(this,t)}describe(t,e){return se(ee,t,e)}override(t,e){return se(te,t,e)}route(t,e,i,s){const o=ie(this,t),a=ie(this,i),l=\"_\"+e;Object.defineProperties(o,{[l]:{value:o[e],writable:!0},[e]:{enumerable:!0,get(){const t=this[l],e=a[s];return n(t)?Object.assign({},e,t):r(t,e)},set(t){this[l]=t}}})}}({_scriptable:t=>!t.startsWith(\"on\"),_indexable:t=>\"events\"!==t,hover:{_fallback:\"interaction\"},interaction:{_scriptable:!1,_indexable:!1}});function oe(){return\"undefined\"!=typeof window&&\"undefined\"!=typeof document}function ae(t){let e=t.parentNode;return e&&\"[object ShadowRoot]\"===e.toString()&&(e=e.host),e}function re(t,e,i){let s;return\"string\"==typeof t?(s=parseInt(t,10),-1!==t.indexOf(\"%\")&&(s=s/100*e.parentNode[i])):s=t,s}const le=t=>window.getComputedStyle(t,null);function he(t,e){return le(t).getPropertyValue(e)}const ce=[\"top\",\"right\",\"bottom\",\"left\"];function de(t,e,i){const s={};i=i?\"-\"+i:\"\";for(let n=0;n<4;n++){const o=ce[n];s[o]=parseFloat(t[e+\"-\"+o+i])||0}return s.width=s.left+s.right,s.height=s.top+s.bottom,s}function ue(t,e){if(\"native\"in t)return t;const{canvas:i,currentDevicePixelRatio:s}=e,n=le(i),o=\"border-box\"===n.boxSizing,a=de(n,\"padding\"),r=de(n,\"border\",\"width\"),{x:l,y:h,box:c}=function(t,e){const i=t.touches,s=i&&i.length?i[0]:t,{offsetX:n,offsetY:o}=s;let a,r,l=!1;if(((t,e,i)=>(t>0||e>0)&&(!i||!i.shadowRoot))(n,o,t.target))a=n,r=o;else{const t=e.getBoundingClientRect();a=s.clientX-t.left,r=s.clientY-t.top,l=!0}return{x:a,y:r,box:l}}(t,i),d=a.left+(c&&r.left),u=a.top+(c&&r.top);let{width:f,height:g}=e;return o&&(f-=a.width+r.width,g-=a.height+r.height),{x:Math.round((l-d)/f*i.width/s),y:Math.round((h-u)/g*i.height/s)}}const fe=t=>Math.round(10*t)/10;function ge(t,e,i,s){const n=le(t),o=de(n,\"margin\"),a=re(n.maxWidth,t,\"clientWidth\")||A,r=re(n.maxHeight,t,\"clientHeight\")||A,l=function(t,e,i){let s,n;if(void 0===e||void 0===i){const o=ae(t);if(o){const t=o.getBoundingClientRect(),a=le(o),r=de(a,\"border\",\"width\"),l=de(a,\"padding\");e=t.width-l.width-r.width,i=t.height-l.height-r.height,s=re(a.maxWidth,o,\"clientWidth\"),n=re(a.maxHeight,o,\"clientHeight\")}else e=t.clientWidth,i=t.clientHeight}return{width:e,height:i,maxWidth:s||A,maxHeight:n||A}}(t,e,i);let{width:h,height:c}=l;if(\"content-box\"===n.boxSizing){const t=de(n,\"border\",\"width\"),e=de(n,\"padding\");h-=e.width+t.width,c-=e.height+t.height}return h=Math.max(0,h-o.width),c=Math.max(0,s?Math.floor(h/s):c-o.height),h=fe(Math.min(h,a,l.maxWidth)),c=fe(Math.min(c,r,l.maxHeight)),h&&!c&&(c=fe(h/2)),{width:h,height:c}}function pe(t,e,i){const s=e||1,n=Math.floor(t.height*s),o=Math.floor(t.width*s);t.height=n/s,t.width=o/s;const a=t.canvas;return a.style&&(i||!a.style.height&&!a.style.width)&&(a.style.height=`${t.height}px`,a.style.width=`${t.width}px`),(t.currentDevicePixelRatio!==s||a.height!==n||a.width!==o)&&(t.currentDevicePixelRatio=s,a.height=n,a.width=o,t.ctx.setTransform(s,0,0,s,0,0),!0)}const me=function(){let t=!1;try{const e={get passive(){return t=!0,!1}};window.addEventListener(\"test\",null,e),window.removeEventListener(\"test\",null,e)}catch(t){}return t}();function be(t,e){const i=he(t,e),s=i&&i.match(/^(\\d+)(\\.\\d+)?px$/);return s?+s[1]:void 0}function xe(t){return!t||i(t.size)||i(t.family)?null:(t.style?t.style+\" \":\"\")+(t.weight?t.weight+\" \":\"\")+t.size+\"px \"+t.family}function _e(t,e,i,s,n){let o=e[n];return o||(o=e[n]=t.measureText(n).width,i.push(n)),o>s&&(s=o),s}function ye(t,e,i,n){let o=(n=n||{}).data=n.data||{},a=n.garbageCollect=n.garbageCollect||[];n.font!==e&&(o=n.data={},a=n.garbageCollect=[],n.font=e),t.save(),t.font=e;let r=0;const l=i.length;let h,c,d,u,f;for(h=0;h<l;h++)if(u=i[h],null!=u&&!0!==s(u))r=_e(t,o,a,r,u);else if(s(u))for(c=0,d=u.length;c<d;c++)f=u[c],null==f||s(f)||(r=_e(t,o,a,r,f));t.restore();const g=a.length/2;if(g>i.length){for(h=0;h<g;h++)delete o[a[h]];a.splice(0,g)}return r}function ve(t,e,i){const s=t.currentDevicePixelRatio,n=0!==i?Math.max(i/2,.5):0;return Math.round((e-n)*s)/s+n}function we(t,e){(e=e||t.getContext(\"2d\")).save(),e.resetTransform(),e.clearRect(0,0,t.width,t.height),e.restore()}function Me(t,e,i,s){ke(t,e,i,s,null)}function ke(t,e,i,s,n){let o,a,r,l,h,c;const d=e.pointStyle,u=e.rotation,f=e.radius;let g=(u||0)*T;if(d&&\"object\"==typeof d&&(o=d.toString(),\"[object HTMLImageElement]\"===o||\"[object HTMLCanvasElement]\"===o))return t.save(),t.translate(i,s),t.rotate(g),t.drawImage(d,-d.width/2,-d.height/2,d.width,d.height),void t.restore();if(!(isNaN(f)||f<=0)){switch(t.beginPath(),d){default:n?t.ellipse(i,s,n/2,f,0,0,O):t.arc(i,s,f,0,O),t.closePath();break;case\"triangle\":t.moveTo(i+Math.sin(g)*f,s-Math.cos(g)*f),g+=R,t.lineTo(i+Math.sin(g)*f,s-Math.cos(g)*f),g+=R,t.lineTo(i+Math.sin(g)*f,s-Math.cos(g)*f),t.closePath();break;case\"rectRounded\":h=.516*f,l=f-h,a=Math.cos(g+E)*l,r=Math.sin(g+E)*l,t.arc(i-a,s-r,h,g-D,g-L),t.arc(i+r,s-a,h,g-L,g),t.arc(i+a,s+r,h,g,g+L),t.arc(i-r,s+a,h,g+L,g+D),t.closePath();break;case\"rect\":if(!u){l=Math.SQRT1_2*f,c=n?n/2:l,t.rect(i-c,s-l,2*c,2*l);break}g+=E;case\"rectRot\":a=Math.cos(g)*f,r=Math.sin(g)*f,t.moveTo(i-a,s-r),t.lineTo(i+r,s-a),t.lineTo(i+a,s+r),t.lineTo(i-r,s+a),t.closePath();break;case\"crossRot\":g+=E;case\"cross\":a=Math.cos(g)*f,r=Math.sin(g)*f,t.moveTo(i-a,s-r),t.lineTo(i+a,s+r),t.moveTo(i+r,s-a),t.lineTo(i-r,s+a);break;case\"star\":a=Math.cos(g)*f,r=Math.sin(g)*f,t.moveTo(i-a,s-r),t.lineTo(i+a,s+r),t.moveTo(i+r,s-a),t.lineTo(i-r,s+a),g+=E,a=Math.cos(g)*f,r=Math.sin(g)*f,t.moveTo(i-a,s-r),t.lineTo(i+a,s+r),t.moveTo(i+r,s-a),t.lineTo(i-r,s+a);break;case\"line\":a=n?n/2:Math.cos(g)*f,r=Math.sin(g)*f,t.moveTo(i-a,s-r),t.lineTo(i+a,s+r);break;case\"dash\":t.moveTo(i,s),t.lineTo(i+Math.cos(g)*f,s+Math.sin(g)*f)}t.fill(),e.borderWidth>0&&t.stroke()}}function Se(t,e,i){return i=i||.5,!e||t&&t.x>e.left-i&&t.x<e.right+i&&t.y>e.top-i&&t.y<e.bottom+i}function Pe(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()}function De(t){t.restore()}function Oe(t,e,i,s,n){if(!e)return t.lineTo(i.x,i.y);if(\"middle\"===n){const s=(e.x+i.x)/2;t.lineTo(s,e.y),t.lineTo(s,i.y)}else\"after\"===n!=!!s?t.lineTo(e.x,i.y):t.lineTo(i.x,e.y);t.lineTo(i.x,i.y)}function Ce(t,e,i,s){if(!e)return t.lineTo(i.x,i.y);t.bezierCurveTo(s?e.cp1x:e.cp2x,s?e.cp1y:e.cp2y,s?i.cp2x:i.cp1x,s?i.cp2y:i.cp1y,i.x,i.y)}function Ae(t,e,n,o,a,r={}){const l=s(e)?e:[e],h=r.strokeWidth>0&&\"\"!==r.strokeColor;let c,d;for(t.save(),t.font=a.string,function(t,e){e.translation&&t.translate(e.translation[0],e.translation[1]);i(e.rotation)||t.rotate(e.rotation);e.color&&(t.fillStyle=e.color);e.textAlign&&(t.textAlign=e.textAlign);e.textBaseline&&(t.textBaseline=e.textBaseline)}(t,r),c=0;c<l.length;++c)d=l[c],h&&(r.strokeColor&&(t.strokeStyle=r.strokeColor),i(r.strokeWidth)||(t.lineWidth=r.strokeWidth),t.strokeText(d,n,o,r.maxWidth)),t.fillText(d,n,o,r.maxWidth),Te(t,n,o,d,r),o+=a.lineHeight;t.restore()}function Te(t,e,i,s,n){if(n.strikethrough||n.underline){const o=t.measureText(s),a=e-o.actualBoundingBoxLeft,r=e+o.actualBoundingBoxRight,l=i-o.actualBoundingBoxAscent,h=i+o.actualBoundingBoxDescent,c=n.strikethrough?(l+h)/2:h;t.strokeStyle=t.fillStyle,t.beginPath(),t.lineWidth=n.decorationWidth||2,t.moveTo(a,c),t.lineTo(r,c),t.stroke()}}function Le(t,e){const{x:i,y:s,w:n,h:o,radius:a}=e;t.arc(i+a.topLeft,s+a.topLeft,a.topLeft,-L,D,!0),t.lineTo(i,s+o-a.bottomLeft),t.arc(i+a.bottomLeft,s+o-a.bottomLeft,a.bottomLeft,D,L,!0),t.lineTo(i+n-a.bottomRight,s+o),t.arc(i+n-a.bottomRight,s+o-a.bottomRight,a.bottomRight,L,0,!0),t.lineTo(i+n,s+a.topRight),t.arc(i+n-a.topRight,s+a.topRight,a.topRight,0,-L,!0),t.lineTo(i+a.topLeft,s)}function Ee(t,e=[\"\"],i=t,s,n=(()=>t[0])){M(s)||(s=$e(\"_fallback\",t));const o={[Symbol.toStringTag]:\"Object\",_cacheable:!0,_scopes:t,_rootScopes:i,_fallback:s,_getTarget:n,override:n=>Ee([n,...t],e,i,s)};return new Proxy(o,{deleteProperty:(e,i)=>(delete e[i],delete e._keys,delete t[0][i],!0),get:(i,s)=>Ve(i,s,(()=>function(t,e,i,s){let n;for(const o of e)if(n=$e(ze(o,t),i),M(n))return Fe(t,n)?je(i,s,t,n):n}(s,e,t,i))),getOwnPropertyDescriptor:(t,e)=>Reflect.getOwnPropertyDescriptor(t._scopes[0],e),getPrototypeOf:()=>Reflect.getPrototypeOf(t[0]),has:(t,e)=>Ye(t).includes(e),ownKeys:t=>Ye(t),set(t,e,i){const s=t._storage||(t._storage=n());return t[e]=s[e]=i,delete t._keys,!0}})}function Re(t,e,i,o){const a={_cacheable:!1,_proxy:t,_context:e,_subProxy:i,_stack:new Set,_descriptors:Ie(t,o),setContext:e=>Re(t,e,i,o),override:s=>Re(t.override(s),e,i,o)};return new Proxy(a,{deleteProperty:(e,i)=>(delete e[i],delete t[i],!0),get:(t,e,i)=>Ve(t,e,(()=>function(t,e,i){const{_proxy:o,_context:a,_subProxy:r,_descriptors:l}=t;let h=o[e];k(h)&&l.isScriptable(e)&&(h=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_stack:r}=i;if(r.has(t))throw new Error(\"Recursion detected: \"+Array.from(r).join(\"->\")+\"->\"+t);r.add(t),e=e(o,a||s),r.delete(t),Fe(t,e)&&(e=je(n._scopes,n,t,e));return e}(e,h,t,i));s(h)&&h.length&&(h=function(t,e,i,s){const{_proxy:o,_context:a,_subProxy:r,_descriptors:l}=i;if(M(a.index)&&s(t))e=e[a.index%e.length];else if(n(e[0])){const i=e,s=o._scopes.filter((t=>t!==i));e=[];for(const n of i){const i=je(s,o,t,n);e.push(Re(i,a,r&&r[t],l))}}return e}(e,h,t,l.isIndexable));Fe(e,h)&&(h=Re(h,a,r&&r[e],l));return h}(t,e,i))),getOwnPropertyDescriptor:(e,i)=>e._descriptors.allKeys?Reflect.has(t,i)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(t,i),getPrototypeOf:()=>Reflect.getPrototypeOf(t),has:(e,i)=>Reflect.has(t,i),ownKeys:()=>Reflect.ownKeys(t),set:(e,i,s)=>(t[i]=s,delete e[i],!0)})}function Ie(t,e={scriptable:!0,indexable:!0}){const{_scriptable:i=e.scriptable,_indexable:s=e.indexable,_allKeys:n=e.allKeys}=t;return{allKeys:n,scriptable:i,indexable:s,isScriptable:k(i)?i:()=>i,isIndexable:k(s)?s:()=>s}}const ze=(t,e)=>t?t+w(e):e,Fe=(t,e)=>n(e)&&\"adapters\"!==t&&(null===Object.getPrototypeOf(e)||e.constructor===Object);function Ve(t,e,i){if(Object.prototype.hasOwnProperty.call(t,e))return t[e];const s=i();return t[e]=s,s}function Be(t,e,i){return k(t)?t(e,i):t}const Ne=(t,e)=>!0===t?e:\"string\"==typeof t?y(e,t):void 0;function We(t,e,i,s,n){for(const o of e){const e=Ne(i,o);if(e){t.add(e);const o=Be(e._fallback,i,n);if(M(o)&&o!==i&&o!==s)return o}else if(!1===e&&M(s)&&i!==s)return null}return!1}function je(t,e,i,o){const a=e._rootScopes,r=Be(e._fallback,i,o),l=[...t,...a],h=new Set;h.add(o);let c=He(h,l,i,r||i,o);return null!==c&&((!M(r)||r===i||(c=He(h,l,r,c,o),null!==c))&&Ee(Array.from(h),[\"\"],a,r,(()=>function(t,e,i){const o=t._getTarget();e in o||(o[e]={});const a=o[e];if(s(a)&&n(i))return i;return a}(e,i,o))))}function He(t,e,i,s,n){for(;i;)i=We(t,e,i,s,n);return i}function $e(t,e){for(const i of e){if(!i)continue;const e=i[t];if(M(e))return e}}function Ye(t){let e=t._keys;return e||(e=t._keys=function(t){const e=new Set;for(const i of t)for(const t of Object.keys(i).filter((t=>!t.startsWith(\"_\"))))e.add(t);return Array.from(e)}(t._scopes)),e}function Ue(t,e,i,s){const{iScale:n}=t,{key:o=\"r\"}=this._parsing,a=new Array(s);let r,l,h,c;for(r=0,l=s;r<l;++r)h=r+i,c=e[h],a[r]={r:n.parse(y(c,o),h)};return a}const Xe=Number.EPSILON||1e-14,qe=(t,e)=>e<t.length&&!t[e].skip&&t[e],Ke=t=>\"x\"===t?\"y\":\"x\";function Ge(t,e,i,s){const n=t.skip?e:t,o=e,a=i.skip?e:i,r=X(o,n),l=X(a,o);let h=r/(r+l),c=l/(r+l);h=isNaN(h)?0:h,c=isNaN(c)?0:c;const d=s*h,u=s*c;return{previous:{x:o.x-d*(a.x-n.x),y:o.y-d*(a.y-n.y)},next:{x:o.x+u*(a.x-n.x),y:o.y+u*(a.y-n.y)}}}function Ze(t,e=\"x\"){const i=Ke(e),s=t.length,n=Array(s).fill(0),o=Array(s);let a,r,l,h=qe(t,0);for(a=0;a<s;++a)if(r=l,l=h,h=qe(t,a+1),l){if(h){const t=h[e]-l[e];n[a]=0!==t?(h[i]-l[i])/t:0}o[a]=r?h?z(n[a-1])!==z(n[a])?0:(n[a-1]+n[a])/2:n[a-1]:n[a]}!function(t,e,i){const s=t.length;let n,o,a,r,l,h=qe(t,0);for(let c=0;c<s-1;++c)l=h,h=qe(t,c+1),l&&h&&(N(e[c],0,Xe)?i[c]=i[c+1]=0:(n=i[c]/e[c],o=i[c+1]/e[c],r=Math.pow(n,2)+Math.pow(o,2),r<=9||(a=3/Math.sqrt(r),i[c]=n*a*e[c],i[c+1]=o*a*e[c])))}(t,n,o),function(t,e,i=\"x\"){const s=Ke(i),n=t.length;let o,a,r,l=qe(t,0);for(let h=0;h<n;++h){if(a=r,r=l,l=qe(t,h+1),!r)continue;const n=r[i],c=r[s];a&&(o=(n-a[i])/3,r[`cp1${i}`]=n-o,r[`cp1${s}`]=c-o*e[h]),l&&(o=(l[i]-n)/3,r[`cp2${i}`]=n+o,r[`cp2${s}`]=c+o*e[h])}}(t,o,e)}function Je(t,e,i){return Math.max(Math.min(t,i),e)}function Qe(t,e,i,s,n){let o,a,r,l;if(e.spanGaps&&(t=t.filter((t=>!t.skip))),\"monotone\"===e.cubicInterpolationMode)Ze(t,n);else{let i=s?t[t.length-1]:t[0];for(o=0,a=t.length;o<a;++o)r=t[o],l=Ge(i,r,t[Math.min(o+1,a-(s?0:1))%a],e.tension),r.cp1x=l.previous.x,r.cp1y=l.previous.y,r.cp2x=l.next.x,r.cp2y=l.next.y,i=r}e.capBezierPoints&&function(t,e){let i,s,n,o,a,r=Se(t[0],e);for(i=0,s=t.length;i<s;++i)a=o,o=r,r=i<s-1&&Se(t[i+1],e),o&&(n=t[i],a&&(n.cp1x=Je(n.cp1x,e.left,e.right),n.cp1y=Je(n.cp1y,e.top,e.bottom)),r&&(n.cp2x=Je(n.cp2x,e.left,e.right),n.cp2y=Je(n.cp2y,e.top,e.bottom)))}(t,i)}const ti=t=>0===t||1===t,ei=(t,e,i)=>-Math.pow(2,10*(t-=1))*Math.sin((t-e)*O/i),ii=(t,e,i)=>Math.pow(2,-10*t)*Math.sin((t-e)*O/i)+1,si={linear:t=>t,easeInQuad:t=>t*t,easeOutQuad:t=>-t*(t-2),easeInOutQuad:t=>(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1),easeInCubic:t=>t*t*t,easeOutCubic:t=>(t-=1)*t*t+1,easeInOutCubic:t=>(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2),easeInQuart:t=>t*t*t*t,easeOutQuart:t=>-((t-=1)*t*t*t-1),easeInOutQuart:t=>(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2),easeInQuint:t=>t*t*t*t*t,easeOutQuint:t=>(t-=1)*t*t*t*t+1,easeInOutQuint:t=>(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2),easeInSine:t=>1-Math.cos(t*L),easeOutSine:t=>Math.sin(t*L),easeInOutSine:t=>-.5*(Math.cos(D*t)-1),easeInExpo:t=>0===t?0:Math.pow(2,10*(t-1)),easeOutExpo:t=>1===t?1:1-Math.pow(2,-10*t),easeInOutExpo:t=>ti(t)?t:t<.5?.5*Math.pow(2,10*(2*t-1)):.5*(2-Math.pow(2,-10*(2*t-1))),easeInCirc:t=>t>=1?t:-(Math.sqrt(1-t*t)-1),easeOutCirc:t=>Math.sqrt(1-(t-=1)*t),easeInOutCirc:t=>(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1),easeInElastic:t=>ti(t)?t:ei(t,.075,.3),easeOutElastic:t=>ti(t)?t:ii(t,.075,.3),easeInOutElastic(t){const e=.1125;return ti(t)?t:t<.5?.5*ei(2*t,e,.45):.5+.5*ii(2*t-1,e,.45)},easeInBack(t){const e=1.70158;return t*t*((e+1)*t-e)},easeOutBack(t){const e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack(t){let e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:t=>1-si.easeOutBounce(1-t),easeOutBounce(t){const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375},easeInOutBounce:t=>t<.5?.5*si.easeInBounce(2*t):.5*si.easeOutBounce(2*t-1)+.5};function ni(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:t.y+i*(e.y-t.y)}}function oi(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:\"middle\"===s?i<.5?t.y:e.y:\"after\"===s?i<1?t.y:e.y:i>0?e.y:t.y}}function ai(t,e,i,s){const n={x:t.cp2x,y:t.cp2y},o={x:e.cp1x,y:e.cp1y},a=ni(t,n,i),r=ni(n,o,i),l=ni(o,e,i),h=ni(a,r,i),c=ni(r,l,i);return ni(h,c,i)}const ri=new Map;function li(t,e,i){return function(t,e){e=e||{};const i=t+JSON.stringify(e);let s=ri.get(i);return s||(s=new Intl.NumberFormat(t,e),ri.set(i,s)),s}(e,i).format(t)}const hi=new RegExp(/^(normal|(\\d+(?:\\.\\d+)?)(px|em|%)?)$/),ci=new RegExp(/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/);function di(t,e){const i=(\"\"+t).match(hi);if(!i||\"normal\"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case\"px\":return t;case\"%\":t/=100}return e*t}function ui(t,e){const i={},s=n(e),o=s?Object.keys(e):e,a=n(t)?s?i=>r(t[i],t[e[i]]):e=>t[e]:()=>t;for(const t of o)i[t]=+a(t)||0;return i}function fi(t){return ui(t,{top:\"y\",right:\"x\",bottom:\"y\",left:\"x\"})}function gi(t){return ui(t,[\"topLeft\",\"topRight\",\"bottomLeft\",\"bottomRight\"])}function pi(t){const e=fi(t);return e.width=e.left+e.right,e.height=e.top+e.bottom,e}function mi(t,e){t=t||{},e=e||ne.font;let i=r(t.size,e.size);\"string\"==typeof i&&(i=parseInt(i,10));let s=r(t.style,e.style);s&&!(\"\"+s).match(ci)&&(console.warn('Invalid font style specified: \"'+s+'\"'),s=\"\");const n={family:r(t.family,e.family),lineHeight:di(r(t.lineHeight,e.lineHeight),i),size:i,style:s,weight:r(t.weight,e.weight),string:\"\"};return n.string=xe(n),n}function bi(t,e,i,n){let o,a,r,l=!0;for(o=0,a=t.length;o<a;++o)if(r=t[o],void 0!==r&&(void 0!==e&&\"function\"==typeof r&&(r=r(e),l=!1),void 0!==i&&s(r)&&(r=r[i%r.length],l=!1),void 0!==r))return n&&!l&&(n.cacheable=!1),r}function xi(t,e,i){const{min:s,max:n}=t,o=h(e,(n-s)/2),a=(t,e)=>i&&0===t?0:t+e;return{min:a(s,-Math.abs(o)),max:a(n,o)}}function _i(t,e){return Object.assign(Object.create(t),e)}function yi(t,e,i){return t?function(t,e){return{x:i=>t+t+e-i,setWidth(t){e=t},textAlign:t=>\"center\"===t?t:\"right\"===t?\"left\":\"right\",xPlus:(t,e)=>t-e,leftForLtr:(t,e)=>t-e}}(e,i):{x:t=>t,setWidth(t){},textAlign:t=>t,xPlus:(t,e)=>t+e,leftForLtr:(t,e)=>t}}function vi(t,e){let i,s;\"ltr\"!==e&&\"rtl\"!==e||(i=t.canvas.style,s=[i.getPropertyValue(\"direction\"),i.getPropertyPriority(\"direction\")],i.setProperty(\"direction\",e,\"important\"),t.prevTextDirection=s)}function wi(t,e){void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty(\"direction\",e[0],e[1]))}function Mi(t){return\"angle\"===t?{between:G,compare:q,normalize:K}:{between:Q,compare:(t,e)=>t-e,normalize:t=>t}}function ki({start:t,end:e,count:i,loop:s,style:n}){return{start:t%i,end:e%i,loop:s&&(e-t+1)%i==0,style:n}}function Si(t,e,i){if(!i)return[t];const{property:s,start:n,end:o}=i,a=e.length,{compare:r,between:l,normalize:h}=Mi(s),{start:c,end:d,loop:u,style:f}=function(t,e,i){const{property:s,start:n,end:o}=i,{between:a,normalize:r}=Mi(s),l=e.length;let h,c,{start:d,end:u,loop:f}=t;if(f){for(d+=l,u+=l,h=0,c=l;h<c&&a(r(e[d%l][s]),n,o);++h)d--,u--;d%=l,u%=l}return u<d&&(u+=l),{start:d,end:u,loop:f,style:t.style}}(t,e,i),g=[];let p,m,b,x=!1,_=null;const y=()=>x||l(n,b,p)&&0!==r(n,b),v=()=>!x||0===r(o,p)||l(o,b,p);for(let t=c,i=c;t<=d;++t)m=e[t%a],m.skip||(p=h(m[s]),p!==b&&(x=l(p,n,o),null===_&&y()&&(_=0===r(p,n)?t:i),null!==_&&v()&&(g.push(ki({start:_,end:t,loop:u,count:a,style:f})),_=null),i=t,b=p));return null!==_&&g.push(ki({start:_,end:d,loop:u,count:a,style:f})),g}function Pi(t,e){const i=[],s=t.segments;for(let n=0;n<s.length;n++){const o=Si(s[n],t.points,e);o.length&&i.push(...o)}return i}function Di(t,e){const i=t.points,s=t.options.spanGaps,n=i.length;if(!n)return[];const o=!!t._loop,{start:a,end:r}=function(t,e,i,s){let n=0,o=e-1;if(i&&!s)for(;n<e&&!t[n].skip;)n++;for(;n<e&&t[n].skip;)n++;for(n%=e,i&&(o+=n);o>n&&t[o%e].skip;)o--;return o%=e,{start:n,end:o}}(i,n,o,s);if(!0===s)return Oi(t,[{start:a,end:r,loop:o}],i,e);return Oi(t,function(t,e,i,s){const n=t.length,o=[];let a,r=e,l=t[e];for(a=e+1;a<=i;++a){const i=t[a%n];i.skip||i.stop?l.skip||(s=!1,o.push({start:e%n,end:(a-1)%n,loop:s}),e=r=i.stop?a:null):(r=a,l.skip&&(e=a)),l=i}return null!==r&&o.push({start:e%n,end:r%n,loop:s}),o}(i,a,r<a?r+n:r,!!t._fullLoop&&0===a&&r===n-1),i,e)}function Oi(t,e,i,s){return s&&s.setContext&&i?function(t,e,i,s){const n=t._chart.getContext(),o=Ci(t.options),{_datasetIndex:a,options:{spanGaps:r}}=t,l=i.length,h=[];let c=o,d=e[0].start,u=d;function f(t,e,s,n){const o=r?-1:1;if(t!==e){for(t+=l;i[t%l].skip;)t-=o;for(;i[e%l].skip;)e+=o;t%l!=e%l&&(h.push({start:t%l,end:e%l,loop:s,style:n}),c=n,d=e%l)}}for(const t of e){d=r?d:t.start;let e,o=i[d%l];for(u=d+1;u<=t.end;u++){const r=i[u%l];e=Ci(s.setContext(_i(n,{type:\"segment\",p0:o,p1:r,p0DataIndex:(u-1)%l,p1DataIndex:u%l,datasetIndex:a}))),Ai(e,c)&&f(d,u-1,t.loop,c),o=r,c=e}d<u-1&&f(d,u-1,t.loop,c)}return h}(t,e,i,s):e}function Ci(t){return{backgroundColor:t.backgroundColor,borderCapStyle:t.borderCapStyle,borderDash:t.borderDash,borderDashOffset:t.borderDashOffset,borderJoinStyle:t.borderJoinStyle,borderWidth:t.borderWidth,borderColor:t.borderColor}}function Ai(t,e){return e&&JSON.stringify(t)!==JSON.stringify(e)}var Ti=Object.freeze({__proto__:null,easingEffects:si,isPatternOrGradient:Zt,color:Jt,getHoverColor:Qt,noop:t,uid:e,isNullOrUndef:i,isArray:s,isObject:n,isFinite:o,finiteOrDefault:a,valueOrDefault:r,toPercentage:l,toDimension:h,callback:c,each:d,_elementsEqual:u,clone:f,_merger:p,merge:m,mergeIf:b,_mergerIf:x,_deprecated:function(t,e,i,s){void 0!==e&&console.warn(t+': \"'+i+'\" is deprecated. Please use \"'+s+'\" instead')},resolveObjectKey:y,_splitKey:v,_capitalize:w,defined:M,isFunction:k,setsEqual:S,_isClickEvent:P,toFontString:xe,_measureText:_e,_longestText:ye,_alignPixel:ve,clearCanvas:we,drawPoint:Me,drawPointLegend:ke,_isPointInArea:Se,clipArea:Pe,unclipArea:De,_steppedLineTo:Oe,_bezierCurveTo:Ce,renderText:Ae,addRoundedRectPath:Le,_lookup:tt,_lookupByKey:et,_rlookupByKey:it,_filterBetween:st,listenArrayEvents:ot,unlistenArrayEvents:at,_arrayUnique:rt,_createResolver:Ee,_attachContext:Re,_descriptors:Ie,_parseObjectDataRadialScale:Ue,splineCurve:Ge,splineCurveMonotone:Ze,_updateBezierControlPoints:Qe,_isDomSupported:oe,_getParentNode:ae,getStyle:he,getRelativePosition:ue,getMaximumSize:ge,retinaScale:pe,supportsEventListenerOptions:me,readUsedSize:be,fontString:function(t,e,i){return e+\" \"+t+\"px \"+i},requestAnimFrame:lt,throttled:ht,debounce:ct,_toLeftRightCenter:dt,_alignStartEnd:ut,_textX:ft,_getStartAndCountOfVisiblePoints:gt,_scaleRangesChanged:pt,_pointInLine:ni,_steppedInterpolation:oi,_bezierInterpolation:ai,formatNumber:li,toLineHeight:di,_readValueToProps:ui,toTRBL:fi,toTRBLCorners:gi,toPadding:pi,toFont:mi,resolve:bi,_addGrace:xi,createContext:_i,PI:D,TAU:O,PITAU:C,INFINITY:A,RAD_PER_DEG:T,HALF_PI:L,QUARTER_PI:E,TWO_THIRDS_PI:R,log10:I,sign:z,niceNum:F,_factorize:V,isNumber:B,almostEquals:N,almostWhole:W,_setMinAndMaxByKey:j,toRadians:H,toDegrees:$,_decimalPlaces:Y,getAngleFromPoint:U,distanceBetweenPoints:X,_angleDiff:q,_normalizeAngle:K,_angleBetween:G,_limitValue:Z,_int16Range:J,_isBetween:Q,getRtlAdapter:yi,overrideTextDirection:vi,restoreTextDirection:wi,_boundSegment:Si,_boundSegments:Pi,_computeSegments:Di});function Li(t,e,i,s){const{controller:n,data:o,_sorted:a}=t,r=n._cachedMeta.iScale;if(r&&e===r.axis&&\"r\"!==e&&a&&o.length){const t=r._reversePixels?it:et;if(!s)return t(o,e,i);if(n._sharedOptions){const s=o[0],n=\"function\"==typeof s.getRange&&s.getRange(e);if(n){const s=t(o,e,i-n),a=t(o,e,i+n);return{lo:s.lo,hi:a.hi}}}}return{lo:0,hi:o.length-1}}function Ei(t,e,i,s,n){const o=t.getSortedVisibleDatasetMetas(),a=i[e];for(let t=0,i=o.length;t<i;++t){const{index:i,data:r}=o[t],{lo:l,hi:h}=Li(o[t],e,a,n);for(let t=l;t<=h;++t){const e=r[t];e.skip||s(e,i,t)}}}function Ri(t,e,i,s,n){const o=[];if(!n&&!t.isPointInArea(e))return o;return Ei(t,i,e,(function(i,a,r){(n||Se(i,t.chartArea,0))&&i.inRange(e.x,e.y,s)&&o.push({element:i,datasetIndex:a,index:r})}),!0),o}function Ii(t,e,i,s,n,o){let a=[];const r=function(t){const e=-1!==t.indexOf(\"x\"),i=-1!==t.indexOf(\"y\");return function(t,s){const n=e?Math.abs(t.x-s.x):0,o=i?Math.abs(t.y-s.y):0;return Math.sqrt(Math.pow(n,2)+Math.pow(o,2))}}(i);let l=Number.POSITIVE_INFINITY;return Ei(t,i,e,(function(i,h,c){const d=i.inRange(e.x,e.y,n);if(s&&!d)return;const u=i.getCenterPoint(n);if(!(!!o||t.isPointInArea(u))&&!d)return;const f=r(e,u);f<l?(a=[{element:i,datasetIndex:h,index:c}],l=f):f===l&&a.push({element:i,datasetIndex:h,index:c})})),a}function zi(t,e,i,s,n,o){return o||t.isPointInArea(e)?\"r\"!==i||s?Ii(t,e,i,s,n,o):function(t,e,i,s){let n=[];return Ei(t,i,e,(function(t,i,o){const{startAngle:a,endAngle:r}=t.getProps([\"startAngle\",\"endAngle\"],s),{angle:l}=U(t,{x:e.x,y:e.y});G(l,a,r)&&n.push({element:t,datasetIndex:i,index:o})})),n}(t,e,i,n):[]}function Fi(t,e,i,s,n){const o=[],a=\"x\"===i?\"inXRange\":\"inYRange\";let r=!1;return Ei(t,i,e,((t,s,l)=>{t[a](e[i],n)&&(o.push({element:t,datasetIndex:s,index:l}),r=r||t.inRange(e.x,e.y,n))})),s&&!r?[]:o}var Vi={evaluateInteractionItems:Ei,modes:{index(t,e,i,s){const n=ue(e,t),o=i.axis||\"x\",a=i.includeInvisible||!1,r=i.intersect?Ri(t,n,o,s,a):zi(t,n,o,!1,s,a),l=[];return r.length?(t.getSortedVisibleDatasetMetas().forEach((t=>{const e=r[0].index,i=t.data[e];i&&!i.skip&&l.push({element:i,datasetIndex:t.index,index:e})})),l):[]},dataset(t,e,i,s){const n=ue(e,t),o=i.axis||\"xy\",a=i.includeInvisible||!1;let r=i.intersect?Ri(t,n,o,s,a):zi(t,n,o,!1,s,a);if(r.length>0){const e=r[0].datasetIndex,i=t.getDatasetMeta(e).data;r=[];for(let t=0;t<i.length;++t)r.push({element:i[t],datasetIndex:e,index:t})}return r},point:(t,e,i,s)=>Ri(t,ue(e,t),i.axis||\"xy\",s,i.includeInvisible||!1),nearest(t,e,i,s){const n=ue(e,t),o=i.axis||\"xy\",a=i.includeInvisible||!1;return zi(t,n,o,i.intersect,s,a)},x:(t,e,i,s)=>Fi(t,ue(e,t),\"x\",i.intersect,s),y:(t,e,i,s)=>Fi(t,ue(e,t),\"y\",i.intersect,s)}};const Bi=[\"left\",\"top\",\"right\",\"bottom\"];function Ni(t,e){return t.filter((t=>t.pos===e))}function Wi(t,e){return t.filter((t=>-1===Bi.indexOf(t.pos)&&t.box.axis===e))}function ji(t,e){return t.sort(((t,i)=>{const s=e?i:t,n=e?t:i;return s.weight===n.weight?s.index-n.index:s.weight-n.weight}))}function Hi(t,e){const i=function(t){const e={};for(const i of t){const{stack:t,pos:s,stackWeight:n}=i;if(!t||!Bi.includes(s))continue;const o=e[t]||(e[t]={count:0,placed:0,weight:0,size:0});o.count++,o.weight+=n}return e}(t),{vBoxMaxWidth:s,hBoxMaxHeight:n}=e;let o,a,r;for(o=0,a=t.length;o<a;++o){r=t[o];const{fullSize:a}=r.box,l=i[r.stack],h=l&&r.stackWeight/l.weight;r.horizontal?(r.width=h?h*s:a&&e.availableWidth,r.height=n):(r.width=s,r.height=h?h*n:a&&e.availableHeight)}return i}function $i(t,e,i,s){return Math.max(t[i],e[i])+Math.max(t[s],e[s])}function Yi(t,e){t.top=Math.max(t.top,e.top),t.left=Math.max(t.left,e.left),t.bottom=Math.max(t.bottom,e.bottom),t.right=Math.max(t.right,e.right)}function Ui(t,e,i,s){const{pos:o,box:a}=i,r=t.maxPadding;if(!n(o)){i.size&&(t[o]-=i.size);const e=s[i.stack]||{size:0,count:1};e.size=Math.max(e.size,i.horizontal?a.height:a.width),i.size=e.size/e.count,t[o]+=i.size}a.getPadding&&Yi(r,a.getPadding());const l=Math.max(0,e.outerWidth-$i(r,t,\"left\",\"right\")),h=Math.max(0,e.outerHeight-$i(r,t,\"top\",\"bottom\")),c=l!==t.w,d=h!==t.h;return t.w=l,t.h=h,i.horizontal?{same:c,other:d}:{same:d,other:c}}function Xi(t,e){const i=e.maxPadding;function s(t){const s={left:0,top:0,right:0,bottom:0};return t.forEach((t=>{s[t]=Math.max(e[t],i[t])})),s}return s(t?[\"left\",\"right\"]:[\"top\",\"bottom\"])}function qi(t,e,i,s){const n=[];let o,a,r,l,h,c;for(o=0,a=t.length,h=0;o<a;++o){r=t[o],l=r.box,l.update(r.width||e.w,r.height||e.h,Xi(r.horizontal,e));const{same:a,other:d}=Ui(e,i,r,s);h|=a&&n.length,c=c||d,l.fullSize||n.push(r)}return h&&qi(n,e,i,s)||c}function Ki(t,e,i,s,n){t.top=i,t.left=e,t.right=e+s,t.bottom=i+n,t.width=s,t.height=n}function Gi(t,e,i,s){const n=i.padding;let{x:o,y:a}=e;for(const r of t){const t=r.box,l=s[r.stack]||{count:1,placed:0,weight:1},h=r.stackWeight/l.weight||1;if(r.horizontal){const s=e.w*h,o=l.size||t.height;M(l.start)&&(a=l.start),t.fullSize?Ki(t,n.left,a,i.outerWidth-n.right-n.left,o):Ki(t,e.left+l.placed,a,s,o),l.start=a,l.placed+=s,a=t.bottom}else{const s=e.h*h,a=l.size||t.width;M(l.start)&&(o=l.start),t.fullSize?Ki(t,o,n.top,a,i.outerHeight-n.bottom-n.top):Ki(t,o,e.top+l.placed,a,s),l.start=o,l.placed+=s,o=t.right}}e.x=o,e.y=a}ne.set(\"layout\",{autoPadding:!0,padding:{top:0,right:0,bottom:0,left:0}});var Zi={addBox(t,e){t.boxes||(t.boxes=[]),e.fullSize=e.fullSize||!1,e.position=e.position||\"top\",e.weight=e.weight||0,e._layers=e._layers||function(){return[{z:0,draw(t){e.draw(t)}}]},t.boxes.push(e)},removeBox(t,e){const i=t.boxes?t.boxes.indexOf(e):-1;-1!==i&&t.boxes.splice(i,1)},configure(t,e,i){e.fullSize=i.fullSize,e.position=i.position,e.weight=i.weight},update(t,e,i,s){if(!t)return;const n=pi(t.options.layout.padding),o=Math.max(e-n.width,0),a=Math.max(i-n.height,0),r=function(t){const e=function(t){const e=[];let i,s,n,o,a,r;for(i=0,s=(t||[]).length;i<s;++i)n=t[i],({position:o,options:{stack:a,stackWeight:r=1}}=n),e.push({index:i,box:n,pos:o,horizontal:n.isHorizontal(),weight:n.weight,stack:a&&o+a,stackWeight:r});return e}(t),i=ji(e.filter((t=>t.box.fullSize)),!0),s=ji(Ni(e,\"left\"),!0),n=ji(Ni(e,\"right\")),o=ji(Ni(e,\"top\"),!0),a=ji(Ni(e,\"bottom\")),r=Wi(e,\"x\"),l=Wi(e,\"y\");return{fullSize:i,leftAndTop:s.concat(o),rightAndBottom:n.concat(l).concat(a).concat(r),chartArea:Ni(e,\"chartArea\"),vertical:s.concat(n).concat(l),horizontal:o.concat(a).concat(r)}}(t.boxes),l=r.vertical,h=r.horizontal;d(t.boxes,(t=>{\"function\"==typeof t.beforeLayout&&t.beforeLayout()}));const c=l.reduce(((t,e)=>e.box.options&&!1===e.box.options.display?t:t+1),0)||1,u=Object.freeze({outerWidth:e,outerHeight:i,padding:n,availableWidth:o,availableHeight:a,vBoxMaxWidth:o/2/c,hBoxMaxHeight:a/2}),f=Object.assign({},n);Yi(f,pi(s));const g=Object.assign({maxPadding:f,w:o,h:a,x:n.left,y:n.top},n),p=Hi(l.concat(h),u);qi(r.fullSize,g,u,p),qi(l,g,u,p),qi(h,g,u,p)&&qi(l,g,u,p),function(t){const e=t.maxPadding;function i(i){const s=Math.max(e[i]-t[i],0);return t[i]+=s,s}t.y+=i(\"top\"),t.x+=i(\"left\"),i(\"right\"),i(\"bottom\")}(g),Gi(r.leftAndTop,g,u,p),g.x+=g.w,g.y+=g.h,Gi(r.rightAndBottom,g,u,p),t.chartArea={left:g.left,top:g.top,right:g.left+g.w,bottom:g.top+g.h,height:g.h,width:g.w},d(r.chartArea,(e=>{const i=e.box;Object.assign(i,t.chartArea),i.update(g.w,g.h,{left:0,top:0,right:0,bottom:0})}))}};class Ji{acquireContext(t,e){}releaseContext(t){return!1}addEventListener(t,e,i){}removeEventListener(t,e,i){}getDevicePixelRatio(){return 1}getMaximumSize(t,e,i,s){return e=Math.max(0,e||t.width),i=i||t.height,{width:e,height:Math.max(0,s?Math.floor(e/s):i)}}isAttached(t){return!0}updateConfig(t){}}class Qi extends Ji{acquireContext(t){return t&&t.getContext&&t.getContext(\"2d\")||null}updateConfig(t){t.options.animation=!1}}const ts={touchstart:\"mousedown\",touchmove:\"mousemove\",touchend:\"mouseup\",pointerenter:\"mouseenter\",pointerdown:\"mousedown\",pointermove:\"mousemove\",pointerup:\"mouseup\",pointerleave:\"mouseout\",pointerout:\"mouseout\"},es=t=>null===t||\"\"===t;const is=!!me&&{passive:!0};function ss(t,e,i){t.canvas.removeEventListener(e,i,is)}function ns(t,e){for(const i of t)if(i===e||i.contains(e))return!0}function os(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||ns(i.addedNodes,s),e=e&&!ns(i.removedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}function as(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||ns(i.removedNodes,s),e=e&&!ns(i.addedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}const rs=new Map;let ls=0;function hs(){const t=window.devicePixelRatio;t!==ls&&(ls=t,rs.forEach(((e,i)=>{i.currentDevicePixelRatio!==t&&e()})))}function cs(t,e,i){const s=t.canvas,n=s&&ae(s);if(!n)return;const o=ht(((t,e)=>{const s=n.clientWidth;i(t,e),s<n.clientWidth&&i()}),window),a=new ResizeObserver((t=>{const e=t[0],i=e.contentRect.width,s=e.contentRect.height;0===i&&0===s||o(i,s)}));return a.observe(n),function(t,e){rs.size||window.addEventListener(\"resize\",hs),rs.set(t,e)}(t,o),a}function ds(t,e,i){i&&i.disconnect(),\"resize\"===e&&function(t){rs.delete(t),rs.size||window.removeEventListener(\"resize\",hs)}(t)}function us(t,e,i){const s=t.canvas,n=ht((e=>{null!==t.ctx&&i(function(t,e){const i=ts[t.type]||t.type,{x:s,y:n}=ue(t,e);return{type:i,chart:e,native:t,x:void 0!==s?s:null,y:void 0!==n?n:null}}(e,t))}),t,(t=>{const e=t[0];return[e,e.offsetX,e.offsetY]}));return function(t,e,i){t.addEventListener(e,i,is)}(s,e,n),n}class fs extends Ji{acquireContext(t,e){const i=t&&t.getContext&&t.getContext(\"2d\");return i&&i.canvas===t?(function(t,e){const i=t.style,s=t.getAttribute(\"height\"),n=t.getAttribute(\"width\");if(t.$chartjs={initial:{height:s,width:n,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||\"block\",i.boxSizing=i.boxSizing||\"border-box\",es(n)){const e=be(t,\"width\");void 0!==e&&(t.width=e)}if(es(s))if(\"\"===t.style.height)t.height=t.width/(e||2);else{const e=be(t,\"height\");void 0!==e&&(t.height=e)}}(t,e),i):null}releaseContext(t){const e=t.canvas;if(!e.$chartjs)return!1;const s=e.$chartjs.initial;[\"height\",\"width\"].forEach((t=>{const n=s[t];i(n)?e.removeAttribute(t):e.setAttribute(t,n)}));const n=s.style||{};return Object.keys(n).forEach((t=>{e.style[t]=n[t]})),e.width=e.width,delete e.$chartjs,!0}addEventListener(t,e,i){this.removeEventListener(t,e);const s=t.$proxies||(t.$proxies={}),n={attach:os,detach:as,resize:cs}[e]||us;s[e]=n(t,e,i)}removeEventListener(t,e){const i=t.$proxies||(t.$proxies={}),s=i[e];if(!s)return;({attach:ds,detach:ds,resize:ds}[e]||ss)(t,e,s),i[e]=void 0}getDevicePixelRatio(){return window.devicePixelRatio}getMaximumSize(t,e,i,s){return ge(t,e,i,s)}isAttached(t){const e=ae(t);return!(!e||!e.isConnected)}}function gs(t){return!oe()||\"undefined\"!=typeof OffscreenCanvas&&t instanceof OffscreenCanvas?Qi:fs}var ps=Object.freeze({__proto__:null,_detectPlatform:gs,BasePlatform:Ji,BasicPlatform:Qi,DomPlatform:fs});const ms=\"transparent\",bs={boolean:(t,e,i)=>i>.5?e:t,color(t,e,i){const s=Jt(t||ms),n=s.valid&&Jt(e||ms);return n&&n.valid?n.mix(s,i).hexString():e},number:(t,e,i)=>t+(e-t)*i};class xs{constructor(t,e,i,s){const n=e[i];s=bi([t.to,s,n,t.from]);const o=bi([t.from,n,s]);this._active=!0,this._fn=t.fn||bs[t.type||typeof o],this._easing=si[t.easing]||si.linear,this._start=Math.floor(Date.now()+(t.delay||0)),this._duration=this._total=Math.floor(t.duration),this._loop=!!t.loop,this._target=e,this._prop=i,this._from=o,this._to=s,this._promises=void 0}active(){return this._active}update(t,e,i){if(this._active){this._notify(!1);const s=this._target[this._prop],n=i-this._start,o=this._duration-n;this._start=i,this._duration=Math.floor(Math.max(o,t.duration)),this._total+=n,this._loop=!!t.loop,this._to=bi([t.to,e,s,t.from]),this._from=bi([t.from,s,e])}}cancel(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}tick(t){const e=t-this._start,i=this._duration,s=this._prop,n=this._from,o=this._loop,a=this._to;let r;if(this._active=n!==a&&(o||e<i),!this._active)return this._target[s]=a,void this._notify(!0);e<0?this._target[s]=n:(r=e/i%2,r=o&&r>1?2-r:r,r=this._easing(Math.min(1,Math.max(0,r))),this._target[s]=this._fn(n,a,r))}wait(){const t=this._promises||(this._promises=[]);return new Promise(((e,i)=>{t.push({res:e,rej:i})}))}_notify(t){const e=t?\"res\":\"rej\",i=this._promises||[];for(let t=0;t<i.length;t++)i[t][e]()}}ne.set(\"animation\",{delay:void 0,duration:1e3,easing:\"easeOutQuart\",fn:void 0,from:void 0,loop:void 0,to:void 0,type:void 0});const _s=Object.keys(ne.animation);ne.describe(\"animation\",{_fallback:!1,_indexable:!1,_scriptable:t=>\"onProgress\"!==t&&\"onComplete\"!==t&&\"fn\"!==t}),ne.set(\"animations\",{colors:{type:\"color\",properties:[\"color\",\"borderColor\",\"backgroundColor\"]},numbers:{type:\"number\",properties:[\"x\",\"y\",\"borderWidth\",\"radius\",\"tension\"]}}),ne.describe(\"animations\",{_fallback:\"animation\"}),ne.set(\"transitions\",{active:{animation:{duration:400}},resize:{animation:{duration:0}},show:{animations:{colors:{from:\"transparent\"},visible:{type:\"boolean\",duration:0}}},hide:{animations:{colors:{to:\"transparent\"},visible:{type:\"boolean\",easing:\"linear\",fn:t=>0|t}}}});class ys{constructor(t,e){this._chart=t,this._properties=new Map,this.configure(e)}configure(t){if(!n(t))return;const e=this._properties;Object.getOwnPropertyNames(t).forEach((i=>{const o=t[i];if(!n(o))return;const a={};for(const t of _s)a[t]=o[t];(s(o.properties)&&o.properties||[i]).forEach((t=>{t!==i&&e.has(t)||e.set(t,a)}))}))}_animateOptions(t,e){const i=e.options,s=function(t,e){if(!e)return;let i=t.options;if(!i)return void(t.options=e);i.$shared&&(t.options=i=Object.assign({},i,{$shared:!1,$animations:{}}));return i}(t,i);if(!s)return[];const n=this._createAnimations(s,i);return i.$shared&&function(t,e){const i=[],s=Object.keys(e);for(let e=0;e<s.length;e++){const n=t[s[e]];n&&n.active()&&i.push(n.wait())}return Promise.all(i)}(t.options.$animations,i).then((()=>{t.options=i}),(()=>{})),n}_createAnimations(t,e){const i=this._properties,s=[],n=t.$animations||(t.$animations={}),o=Object.keys(e),a=Date.now();let r;for(r=o.length-1;r>=0;--r){const l=o[r];if(\"$\"===l.charAt(0))continue;if(\"options\"===l){s.push(...this._animateOptions(t,e));continue}const h=e[l];let c=n[l];const d=i.get(l);if(c){if(d&&c.active()){c.update(d,h,a);continue}c.cancel()}d&&d.duration?(n[l]=c=new xs(d,t,l,h),s.push(c)):t[l]=h}return s}update(t,e){if(0===this._properties.size)return void Object.assign(t,e);const i=this._createAnimations(t,e);return i.length?(mt.add(this._chart,i),!0):void 0}}function vs(t,e){const i=t&&t.options||{},s=i.reverse,n=void 0===i.min?e:0,o=void 0===i.max?e:0;return{start:s?o:n,end:s?n:o}}function ws(t,e){const i=[],s=t._getSortedDatasetMetas(e);let n,o;for(n=0,o=s.length;n<o;++n)i.push(s[n].index);return i}function Ms(t,e,i,s={}){const n=t.keys,a=\"single\"===s.mode;let r,l,h,c;if(null!==e){for(r=0,l=n.length;r<l;++r){if(h=+n[r],h===i){if(s.all)continue;break}c=t.values[h],o(c)&&(a||0===e||z(e)===z(c))&&(e+=c)}return e}}function ks(t,e){const i=t&&t.options.stacked;return i||void 0===i&&void 0!==e.stack}function Ss(t,e,i){const s=t[e]||(t[e]={});return s[i]||(s[i]={})}function Ps(t,e,i,s){for(const n of e.getMatchingVisibleMetas(s).reverse()){const e=t[n.index];if(i&&e>0||!i&&e<0)return n.index}return null}function Ds(t,e){const{chart:i,_cachedMeta:s}=t,n=i._stacks||(i._stacks={}),{iScale:o,vScale:a,index:r}=s,l=o.axis,h=a.axis,c=function(t,e,i){return`${t.id}.${e.id}.${i.stack||i.type}`}(o,a,s),d=e.length;let u;for(let t=0;t<d;++t){const i=e[t],{[l]:o,[h]:d}=i;u=(i._stacks||(i._stacks={}))[h]=Ss(n,c,o),u[r]=d,u._top=Ps(u,a,!0,s.type),u._bottom=Ps(u,a,!1,s.type)}}function Os(t,e){const i=t.scales;return Object.keys(i).filter((t=>i[t].axis===e)).shift()}function Cs(t,e){const i=t.controller.index,s=t.vScale&&t.vScale.axis;if(s){e=e||t._parsed;for(const t of e){const e=t._stacks;if(!e||void 0===e[s]||void 0===e[s][i])return;delete e[s][i]}}}const As=t=>\"reset\"===t||\"none\"===t,Ts=(t,e)=>e?t:Object.assign({},t);class Ls{constructor(t,e){this.chart=t,this._ctx=t.ctx,this.index=e,this._cachedDataOpts={},this._cachedMeta=this.getMeta(),this._type=this._cachedMeta.type,this.options=void 0,this._parsing=!1,this._data=void 0,this._objectData=void 0,this._sharedOptions=void 0,this._drawStart=void 0,this._drawCount=void 0,this.enableOptionSharing=!1,this.supportsDecimation=!1,this.$context=void 0,this._syncList=[],this.initialize()}initialize(){const t=this._cachedMeta;this.configure(),this.linkScales(),t._stacked=ks(t.vScale,t),this.addElements()}updateIndex(t){this.index!==t&&Cs(this._cachedMeta),this.index=t}linkScales(){const t=this.chart,e=this._cachedMeta,i=this.getDataset(),s=(t,e,i,s)=>\"x\"===t?e:\"r\"===t?s:i,n=e.xAxisID=r(i.xAxisID,Os(t,\"x\")),o=e.yAxisID=r(i.yAxisID,Os(t,\"y\")),a=e.rAxisID=r(i.rAxisID,Os(t,\"r\")),l=e.indexAxis,h=e.iAxisID=s(l,n,o,a),c=e.vAxisID=s(l,o,n,a);e.xScale=this.getScaleForId(n),e.yScale=this.getScaleForId(o),e.rScale=this.getScaleForId(a),e.iScale=this.getScaleForId(h),e.vScale=this.getScaleForId(c)}getDataset(){return this.chart.data.datasets[this.index]}getMeta(){return this.chart.getDatasetMeta(this.index)}getScaleForId(t){return this.chart.scales[t]}_getOtherScale(t){const e=this._cachedMeta;return t===e.iScale?e.vScale:e.iScale}reset(){this._update(\"reset\")}_destroy(){const t=this._cachedMeta;this._data&&at(this._data,this),t._stacked&&Cs(t)}_dataCheck(){const t=this.getDataset(),e=t.data||(t.data=[]),i=this._data;if(n(e))this._data=function(t){const e=Object.keys(t),i=new Array(e.length);let s,n,o;for(s=0,n=e.length;s<n;++s)o=e[s],i[s]={x:o,y:t[o]};return i}(e);else if(i!==e){if(i){at(i,this);const t=this._cachedMeta;Cs(t),t._parsed=[]}e&&Object.isExtensible(e)&&ot(e,this),this._syncList=[],this._data=e}}addElements(){const t=this._cachedMeta;this._dataCheck(),this.datasetElementType&&(t.dataset=new this.datasetElementType)}buildOrUpdateElements(t){const e=this._cachedMeta,i=this.getDataset();let s=!1;this._dataCheck();const n=e._stacked;e._stacked=ks(e.vScale,e),e.stack!==i.stack&&(s=!0,Cs(e),e.stack=i.stack),this._resyncElements(t),(s||n!==e._stacked)&&Ds(this,e._parsed)}configure(){const t=this.chart.config,e=t.datasetScopeKeys(this._type),i=t.getOptionScopes(this.getDataset(),e,!0);this.options=t.createResolver(i,this.getContext()),this._parsing=this.options.parsing,this._cachedDataOpts={}}parse(t,e){const{_cachedMeta:i,_data:o}=this,{iScale:a,_stacked:r}=i,l=a.axis;let h,c,d,u=0===t&&e===o.length||i._sorted,f=t>0&&i._parsed[t-1];if(!1===this._parsing)i._parsed=o,i._sorted=!0,d=o;else{d=s(o[t])?this.parseArrayData(i,o,t,e):n(o[t])?this.parseObjectData(i,o,t,e):this.parsePrimitiveData(i,o,t,e);const a=()=>null===c[l]||f&&c[l]<f[l];for(h=0;h<e;++h)i._parsed[h+t]=c=d[h],u&&(a()&&(u=!1),f=c);i._sorted=u}r&&Ds(this,d)}parsePrimitiveData(t,e,i,s){const{iScale:n,vScale:o}=t,a=n.axis,r=o.axis,l=n.getLabels(),h=n===o,c=new Array(s);let d,u,f;for(d=0,u=s;d<u;++d)f=d+i,c[d]={[a]:h||n.parse(l[f],f),[r]:o.parse(e[f],f)};return c}parseArrayData(t,e,i,s){const{xScale:n,yScale:o}=t,a=new Array(s);let r,l,h,c;for(r=0,l=s;r<l;++r)h=r+i,c=e[h],a[r]={x:n.parse(c[0],h),y:o.parse(c[1],h)};return a}parseObjectData(t,e,i,s){const{xScale:n,yScale:o}=t,{xAxisKey:a=\"x\",yAxisKey:r=\"y\"}=this._parsing,l=new Array(s);let h,c,d,u;for(h=0,c=s;h<c;++h)d=h+i,u=e[d],l[h]={x:n.parse(y(u,a),d),y:o.parse(y(u,r),d)};return l}getParsed(t){return this._cachedMeta._parsed[t]}getDataElement(t){return this._cachedMeta.data[t]}applyStack(t,e,i){const s=this.chart,n=this._cachedMeta,o=e[t.axis];return Ms({keys:ws(s,!0),values:e._stacks[t.axis]},o,n.index,{mode:i})}updateRangeFromParsed(t,e,i,s){const n=i[e.axis];let o=null===n?NaN:n;const a=s&&i._stacks[e.axis];s&&a&&(s.values=a,o=Ms(s,n,this._cachedMeta.index)),t.min=Math.min(t.min,o),t.max=Math.max(t.max,o)}getMinMax(t,e){const i=this._cachedMeta,s=i._parsed,n=i._sorted&&t===i.iScale,a=s.length,r=this._getOtherScale(t),l=((t,e,i)=>t&&!e.hidden&&e._stacked&&{keys:ws(i,!0),values:null})(e,i,this.chart),h={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY},{min:c,max:d}=function(t){const{min:e,max:i,minDefined:s,maxDefined:n}=t.getUserBounds();return{min:s?e:Number.NEGATIVE_INFINITY,max:n?i:Number.POSITIVE_INFINITY}}(r);let u,f;function g(){f=s[u];const e=f[r.axis];return!o(f[t.axis])||c>e||d<e}for(u=0;u<a&&(g()||(this.updateRangeFromParsed(h,t,f,l),!n));++u);if(n)for(u=a-1;u>=0;--u)if(!g()){this.updateRangeFromParsed(h,t,f,l);break}return h}getAllParsedValues(t){const e=this._cachedMeta._parsed,i=[];let s,n,a;for(s=0,n=e.length;s<n;++s)a=e[s][t.axis],o(a)&&i.push(a);return i}getMaxOverflow(){return!1}getLabelAndValue(t){const e=this._cachedMeta,i=e.iScale,s=e.vScale,n=this.getParsed(t);return{label:i?\"\"+i.getLabelForValue(n[i.axis]):\"\",value:s?\"\"+s.getLabelForValue(n[s.axis]):\"\"}}_update(t){const e=this._cachedMeta;this.update(t||\"default\"),e._clip=function(t){let e,i,s,o;return n(t)?(e=t.top,i=t.right,s=t.bottom,o=t.left):e=i=s=o=t,{top:e,right:i,bottom:s,left:o,disabled:!1===t}}(r(this.options.clip,function(t,e,i){if(!1===i)return!1;const s=vs(t,i),n=vs(e,i);return{top:n.end,right:s.end,bottom:n.start,left:s.start}}(e.xScale,e.yScale,this.getMaxOverflow())))}update(t){}draw(){const t=this._ctx,e=this.chart,i=this._cachedMeta,s=i.data||[],n=e.chartArea,o=[],a=this._drawStart||0,r=this._drawCount||s.length-a,l=this.options.drawActiveElementsOnTop;let h;for(i.dataset&&i.dataset.draw(t,n,a,r),h=a;h<a+r;++h){const e=s[h];e.hidden||(e.active&&l?o.push(e):e.draw(t,n))}for(h=0;h<o.length;++h)o[h].draw(t,n)}getStyle(t,e){const i=e?\"active\":\"default\";return void 0===t&&this._cachedMeta.dataset?this.resolveDatasetElementOptions(i):this.resolveDataElementOptions(t||0,i)}getContext(t,e,i){const s=this.getDataset();let n;if(t>=0&&t<this._cachedMeta.data.length){const e=this._cachedMeta.data[t];n=e.$context||(e.$context=function(t,e,i){return _i(t,{active:!1,dataIndex:e,parsed:void 0,raw:void 0,element:i,index:e,mode:\"default\",type:\"data\"})}(this.getContext(),t,e)),n.parsed=this.getParsed(t),n.raw=s.data[t],n.index=n.dataIndex=t}else n=this.$context||(this.$context=function(t,e){return _i(t,{active:!1,dataset:void 0,datasetIndex:e,index:e,mode:\"default\",type:\"dataset\"})}(this.chart.getContext(),this.index)),n.dataset=s,n.index=n.datasetIndex=this.index;return n.active=!!e,n.mode=i,n}resolveDatasetElementOptions(t){return this._resolveElementOptions(this.datasetElementType.id,t)}resolveDataElementOptions(t,e){return this._resolveElementOptions(this.dataElementType.id,e,t)}_resolveElementOptions(t,e=\"default\",i){const s=\"active\"===e,n=this._cachedDataOpts,o=t+\"-\"+e,a=n[o],r=this.enableOptionSharing&&M(i);if(a)return Ts(a,r);const l=this.chart.config,h=l.datasetElementScopeKeys(this._type,t),c=s?[`${t}Hover`,\"hover\",t,\"\"]:[t,\"\"],d=l.getOptionScopes(this.getDataset(),h),u=Object.keys(ne.elements[t]),f=l.resolveNamedOptions(d,u,(()=>this.getContext(i,s)),c);return f.$shared&&(f.$shared=r,n[o]=Object.freeze(Ts(f,r))),f}_resolveAnimations(t,e,i){const s=this.chart,n=this._cachedDataOpts,o=`animation-${e}`,a=n[o];if(a)return a;let r;if(!1!==s.options.animation){const s=this.chart.config,n=s.datasetAnimationScopeKeys(this._type,e),o=s.getOptionScopes(this.getDataset(),n);r=s.createResolver(o,this.getContext(t,i,e))}const l=new ys(s,r&&r.animations);return r&&r._cacheable&&(n[o]=Object.freeze(l)),l}getSharedOptions(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}includeOptions(t,e){return!e||As(t)||this.chart._animationsDisabled}_getSharedOptions(t,e){const i=this.resolveDataElementOptions(t,e),s=this._sharedOptions,n=this.getSharedOptions(i),o=this.includeOptions(e,n)||n!==s;return this.updateSharedOptions(n,e,i),{sharedOptions:n,includeOptions:o}}updateElement(t,e,i,s){As(s)?Object.assign(t,i):this._resolveAnimations(e,s).update(t,i)}updateSharedOptions(t,e,i){t&&!As(e)&&this._resolveAnimations(void 0,e).update(t,i)}_setStyle(t,e,i,s){t.active=s;const n=this.getStyle(e,s);this._resolveAnimations(e,i,s).update(t,{options:!s&&this.getSharedOptions(n)||n})}removeHoverStyle(t,e,i){this._setStyle(t,i,\"active\",!1)}setHoverStyle(t,e,i){this._setStyle(t,i,\"active\",!0)}_removeDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,\"active\",!1)}_setDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,\"active\",!0)}_resyncElements(t){const e=this._data,i=this._cachedMeta.data;for(const[t,e,i]of this._syncList)this[t](e,i);this._syncList=[];const s=i.length,n=e.length,o=Math.min(n,s);o&&this.parse(0,o),n>s?this._insertElements(s,n-s,t):n<s&&this._removeElements(n,s-n)}_insertElements(t,e,i=!0){const s=this._cachedMeta,n=s.data,o=t+e;let a;const r=t=>{for(t.length+=e,a=t.length-1;a>=o;a--)t[a]=t[a-e]};for(r(n),a=t;a<o;++a)n[a]=new this.dataElementType;this._parsing&&r(s._parsed),this.parse(t,e),i&&this.updateElements(n,t,e,\"reset\")}updateElements(t,e,i,s){}_removeElements(t,e){const i=this._cachedMeta;if(this._parsing){const s=i._parsed.splice(t,e);i._stacked&&Cs(i,s)}i.data.splice(t,e)}_sync(t){if(this._parsing)this._syncList.push(t);else{const[e,i,s]=t;this[e](i,s)}this.chart._dataChanges.push([this.index,...t])}_onDataPush(){const t=arguments.length;this._sync([\"_insertElements\",this.getDataset().data.length-t,t])}_onDataPop(){this._sync([\"_removeElements\",this._cachedMeta.data.length-1,1])}_onDataShift(){this._sync([\"_removeElements\",0,1])}_onDataSplice(t,e){e&&this._sync([\"_removeElements\",t,e]);const i=arguments.length-2;i&&this._sync([\"_insertElements\",t,i])}_onDataUnshift(){this._sync([\"_insertElements\",0,arguments.length])}}Ls.defaults={},Ls.prototype.datasetElementType=null,Ls.prototype.dataElementType=null;class Es{constructor(){this.x=void 0,this.y=void 0,this.active=!1,this.options=void 0,this.$animations=void 0}tooltipPosition(t){const{x:e,y:i}=this.getProps([\"x\",\"y\"],t);return{x:e,y:i}}hasValue(){return B(this.x)&&B(this.y)}getProps(t,e){const i=this.$animations;if(!e||!i)return this;const s={};return t.forEach((t=>{s[t]=i[t]&&i[t].active()?i[t]._to:this[t]})),s}}Es.defaults={},Es.defaultRoutes=void 0;const Rs={values:t=>s(t)?t:\"\"+t,numeric(t,e,i){if(0===t)return\"0\";const s=this.chart.options.locale;let n,o=t;if(i.length>1){const e=Math.max(Math.abs(i[0].value),Math.abs(i[i.length-1].value));(e<1e-4||e>1e15)&&(n=\"scientific\"),o=function(t,e){let i=e.length>3?e[2].value-e[1].value:e[1].value-e[0].value;Math.abs(i)>=1&&t!==Math.floor(t)&&(i=t-Math.floor(t));return i}(t,i)}const a=I(Math.abs(o)),r=Math.max(Math.min(-1*Math.floor(a),20),0),l={notation:n,minimumFractionDigits:r,maximumFractionDigits:r};return Object.assign(l,this.options.ticks.format),li(t,s,l)},logarithmic(t,e,i){if(0===t)return\"0\";const s=t/Math.pow(10,Math.floor(I(t)));return 1===s||2===s||5===s?Rs.numeric.call(this,t,e,i):\"\"}};var Is={formatters:Rs};function zs(t,e){const s=t.options.ticks,n=s.maxTicksLimit||function(t){const e=t.options.offset,i=t._tickSize(),s=t._length/i+(e?0:1),n=t._maxLength/i;return Math.floor(Math.min(s,n))}(t),o=s.major.enabled?function(t){const e=[];let i,s;for(i=0,s=t.length;i<s;i++)t[i].major&&e.push(i);return e}(e):[],a=o.length,r=o[0],l=o[a-1],h=[];if(a>n)return function(t,e,i,s){let n,o=0,a=i[0];for(s=Math.ceil(s),n=0;n<t.length;n++)n===a&&(e.push(t[n]),o++,a=i[o*s])}(e,h,o,a/n),h;const c=function(t,e,i){const s=function(t){const e=t.length;let i,s;if(e<2)return!1;for(s=t[0],i=1;i<e;++i)if(t[i]-t[i-1]!==s)return!1;return s}(t),n=e.length/i;if(!s)return Math.max(n,1);const o=V(s);for(let t=0,e=o.length-1;t<e;t++){const e=o[t];if(e>n)return e}return Math.max(n,1)}(o,e,n);if(a>0){let t,s;const n=a>1?Math.round((l-r)/(a-1)):null;for(Fs(e,h,c,i(n)?0:r-n,r),t=0,s=a-1;t<s;t++)Fs(e,h,c,o[t],o[t+1]);return Fs(e,h,c,l,i(n)?e.length:l+n),h}return Fs(e,h,c),h}function Fs(t,e,i,s,n){const o=r(s,0),a=Math.min(r(n,t.length),t.length);let l,h,c,d=0;for(i=Math.ceil(i),n&&(l=n-s,i=l/Math.floor(l/i)),c=o;c<0;)d++,c=Math.round(o+d*i);for(h=Math.max(o,0);h<a;h++)h===c&&(e.push(t[h]),d++,c=Math.round(o+d*i))}ne.set(\"scale\",{display:!0,offset:!1,reverse:!1,beginAtZero:!1,bounds:\"ticks\",grace:0,grid:{display:!0,lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickLength:8,tickWidth:(t,e)=>e.lineWidth,tickColor:(t,e)=>e.color,offset:!1,borderDash:[],borderDashOffset:0,borderWidth:1},title:{display:!1,text:\"\",padding:{top:4,bottom:4}},ticks:{minRotation:0,maxRotation:50,mirror:!1,textStrokeWidth:0,textStrokeColor:\"\",padding:3,display:!0,autoSkip:!0,autoSkipPadding:3,labelOffset:0,callback:Is.formatters.values,minor:{},major:{},align:\"center\",crossAlign:\"near\",showLabelBackdrop:!1,backdropColor:\"rgba(255, 255, 255, 0.75)\",backdropPadding:2}}),ne.route(\"scale.ticks\",\"color\",\"\",\"color\"),ne.route(\"scale.grid\",\"color\",\"\",\"borderColor\"),ne.route(\"scale.grid\",\"borderColor\",\"\",\"borderColor\"),ne.route(\"scale.title\",\"color\",\"\",\"color\"),ne.describe(\"scale\",{_fallback:!1,_scriptable:t=>!t.startsWith(\"before\")&&!t.startsWith(\"after\")&&\"callback\"!==t&&\"parser\"!==t,_indexable:t=>\"borderDash\"!==t&&\"tickBorderDash\"!==t}),ne.describe(\"scales\",{_fallback:\"scale\"}),ne.describe(\"scale.ticks\",{_scriptable:t=>\"backdropPadding\"!==t&&\"callback\"!==t,_indexable:t=>\"backdropPadding\"!==t});const Vs=(t,e,i)=>\"top\"===e||\"left\"===e?t[e]+i:t[e]-i;function Bs(t,e){const i=[],s=t.length/e,n=t.length;let o=0;for(;o<n;o+=s)i.push(t[Math.floor(o)]);return i}function Ns(t,e,i){const s=t.ticks.length,n=Math.min(e,s-1),o=t._startPixel,a=t._endPixel,r=1e-6;let l,h=t.getPixelForTick(n);if(!(i&&(l=1===s?Math.max(h-o,a-h):0===e?(t.getPixelForTick(1)-h)/2:(h-t.getPixelForTick(n-1))/2,h+=n<e?l:-l,h<o-r||h>a+r)))return h}function Ws(t){return t.drawTicks?t.tickLength:0}function js(t,e){if(!t.display)return 0;const i=mi(t.font,e),n=pi(t.padding);return(s(t.text)?t.text.length:1)*i.lineHeight+n.height}function Hs(t,e,i){let s=dt(t);return(i&&\"right\"!==e||!i&&\"right\"===e)&&(s=(t=>\"left\"===t?\"right\":\"right\"===t?\"left\":t)(s)),s}class $s extends Es{constructor(t){super(),this.id=t.id,this.type=t.type,this.options=void 0,this.ctx=t.ctx,this.chart=t.chart,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this._margins={left:0,right:0,top:0,bottom:0},this.maxWidth=void 0,this.maxHeight=void 0,this.paddingTop=void 0,this.paddingBottom=void 0,this.paddingLeft=void 0,this.paddingRight=void 0,this.axis=void 0,this.labelRotation=void 0,this.min=void 0,this.max=void 0,this._range=void 0,this.ticks=[],this._gridLineItems=null,this._labelItems=null,this._labelSizes=null,this._length=0,this._maxLength=0,this._longestTextCache={},this._startPixel=void 0,this._endPixel=void 0,this._reversePixels=!1,this._userMax=void 0,this._userMin=void 0,this._suggestedMax=void 0,this._suggestedMin=void 0,this._ticksLength=0,this._borderValue=0,this._cache={},this._dataLimitsCached=!1,this.$context=void 0}init(t){this.options=t.setContext(this.getContext()),this.axis=t.axis,this._userMin=this.parse(t.min),this._userMax=this.parse(t.max),this._suggestedMin=this.parse(t.suggestedMin),this._suggestedMax=this.parse(t.suggestedMax)}parse(t,e){return t}getUserBounds(){let{_userMin:t,_userMax:e,_suggestedMin:i,_suggestedMax:s}=this;return t=a(t,Number.POSITIVE_INFINITY),e=a(e,Number.NEGATIVE_INFINITY),i=a(i,Number.POSITIVE_INFINITY),s=a(s,Number.NEGATIVE_INFINITY),{min:a(t,i),max:a(e,s),minDefined:o(t),maxDefined:o(e)}}getMinMax(t){let e,{min:i,max:s,minDefined:n,maxDefined:o}=this.getUserBounds();if(n&&o)return{min:i,max:s};const r=this.getMatchingVisibleMetas();for(let a=0,l=r.length;a<l;++a)e=r[a].controller.getMinMax(this,t),n||(i=Math.min(i,e.min)),o||(s=Math.max(s,e.max));return i=o&&i>s?s:i,s=n&&i>s?i:s,{min:a(i,a(s,i)),max:a(s,a(i,s))}}getPadding(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}getTicks(){return this.ticks}getLabels(){const t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}beforeLayout(){this._cache={},this._dataLimitsCached=!1}beforeUpdate(){c(this.options.beforeUpdate,[this])}update(t,e,i){const{beginAtZero:s,grace:n,ticks:o}=this.options,a=o.sampleSize;this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this._margins=i=Object.assign({left:0,right:0,top:0,bottom:0},i),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+i.left+i.right:this.height+i.top+i.bottom,this._dataLimitsCached||(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=xi(this,n,s),this._dataLimitsCached=!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();const r=a<this.ticks.length;this._convertTicksToLabels(r?Bs(this.ticks,a):this.ticks),this.configure(),this.beforeCalculateLabelRotation(),this.calculateLabelRotation(),this.afterCalculateLabelRotation(),o.display&&(o.autoSkip||\"auto\"===o.source)&&(this.ticks=zs(this,this.ticks),this._labelSizes=null,this.afterAutoSkip()),r&&this._convertTicksToLabels(this.ticks),this.beforeFit(),this.fit(),this.afterFit(),this.afterUpdate()}configure(){let t,e,i=this.options.reverse;this.isHorizontal()?(t=this.left,e=this.right):(t=this.top,e=this.bottom,i=!i),this._startPixel=t,this._endPixel=e,this._reversePixels=i,this._length=e-t,this._alignToPixels=this.options.alignToPixels}afterUpdate(){c(this.options.afterUpdate,[this])}beforeSetDimensions(){c(this.options.beforeSetDimensions,[this])}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=0,this.right=this.width):(this.height=this.maxHeight,this.top=0,this.bottom=this.height),this.paddingLeft=0,this.paddingTop=0,this.paddingRight=0,this.paddingBottom=0}afterSetDimensions(){c(this.options.afterSetDimensions,[this])}_callHooks(t){this.chart.notifyPlugins(t,this.getContext()),c(this.options[t],[this])}beforeDataLimits(){this._callHooks(\"beforeDataLimits\")}determineDataLimits(){}afterDataLimits(){this._callHooks(\"afterDataLimits\")}beforeBuildTicks(){this._callHooks(\"beforeBuildTicks\")}buildTicks(){return[]}afterBuildTicks(){this._callHooks(\"afterBuildTicks\")}beforeTickToLabelConversion(){c(this.options.beforeTickToLabelConversion,[this])}generateTickLabels(t){const e=this.options.ticks;let i,s,n;for(i=0,s=t.length;i<s;i++)n=t[i],n.label=c(e.callback,[n.value,i,t],this)}afterTickToLabelConversion(){c(this.options.afterTickToLabelConversion,[this])}beforeCalculateLabelRotation(){c(this.options.beforeCalculateLabelRotation,[this])}calculateLabelRotation(){const t=this.options,e=t.ticks,i=this.ticks.length,s=e.minRotation||0,n=e.maxRotation;let o,a,r,l=s;if(!this._isVisible()||!e.display||s>=n||i<=1||!this.isHorizontal())return void(this.labelRotation=s);const h=this._getLabelSizes(),c=h.widest.width,d=h.highest.height,u=Z(this.chart.width-c,0,this.maxWidth);o=t.offset?this.maxWidth/i:u/(i-1),c+6>o&&(o=u/(i-(t.offset?.5:1)),a=this.maxHeight-Ws(t.grid)-e.padding-js(t.title,this.chart.options.font),r=Math.sqrt(c*c+d*d),l=$(Math.min(Math.asin(Z((h.highest.height+6)/o,-1,1)),Math.asin(Z(a/r,-1,1))-Math.asin(Z(d/r,-1,1)))),l=Math.max(s,Math.min(n,l))),this.labelRotation=l}afterCalculateLabelRotation(){c(this.options.afterCalculateLabelRotation,[this])}afterAutoSkip(){}beforeFit(){c(this.options.beforeFit,[this])}fit(){const t={width:0,height:0},{chart:e,options:{ticks:i,title:s,grid:n}}=this,o=this._isVisible(),a=this.isHorizontal();if(o){const o=js(s,e.options.font);if(a?(t.width=this.maxWidth,t.height=Ws(n)+o):(t.height=this.maxHeight,t.width=Ws(n)+o),i.display&&this.ticks.length){const{first:e,last:s,widest:n,highest:o}=this._getLabelSizes(),r=2*i.padding,l=H(this.labelRotation),h=Math.cos(l),c=Math.sin(l);if(a){const e=i.mirror?0:c*n.width+h*o.height;t.height=Math.min(this.maxHeight,t.height+e+r)}else{const e=i.mirror?0:h*n.width+c*o.height;t.width=Math.min(this.maxWidth,t.width+e+r)}this._calculatePadding(e,s,c,h)}}this._handleMargins(),a?(this.width=this._length=e.width-this._margins.left-this._margins.right,this.height=t.height):(this.width=t.width,this.height=this._length=e.height-this._margins.top-this._margins.bottom)}_calculatePadding(t,e,i,s){const{ticks:{align:n,padding:o},position:a}=this.options,r=0!==this.labelRotation,l=\"top\"!==a&&\"x\"===this.axis;if(this.isHorizontal()){const a=this.getPixelForTick(0)-this.left,h=this.right-this.getPixelForTick(this.ticks.length-1);let c=0,d=0;r?l?(c=s*t.width,d=i*e.height):(c=i*t.height,d=s*e.width):\"start\"===n?d=e.width:\"end\"===n?c=t.width:\"inner\"!==n&&(c=t.width/2,d=e.width/2),this.paddingLeft=Math.max((c-a+o)*this.width/(this.width-a),0),this.paddingRight=Math.max((d-h+o)*this.width/(this.width-h),0)}else{let i=e.height/2,s=t.height/2;\"start\"===n?(i=0,s=t.height):\"end\"===n&&(i=e.height,s=0),this.paddingTop=i+o,this.paddingBottom=s+o}}_handleMargins(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}afterFit(){c(this.options.afterFit,[this])}isHorizontal(){const{axis:t,position:e}=this.options;return\"top\"===e||\"bottom\"===e||\"x\"===t}isFullSize(){return this.options.fullSize}_convertTicksToLabels(t){let e,s;for(this.beforeTickToLabelConversion(),this.generateTickLabels(t),e=0,s=t.length;e<s;e++)i(t[e].label)&&(t.splice(e,1),s--,e--);this.afterTickToLabelConversion()}_getLabelSizes(){let t=this._labelSizes;if(!t){const e=this.options.ticks.sampleSize;let i=this.ticks;e<i.length&&(i=Bs(i,e)),this._labelSizes=t=this._computeLabelSizes(i,i.length)}return t}_computeLabelSizes(t,e){const{ctx:n,_longestTextCache:o}=this,a=[],r=[];let l,h,c,u,f,g,p,m,b,x,_,y=0,v=0;for(l=0;l<e;++l){if(u=t[l].label,f=this._resolveTickFontOptions(l),n.font=g=f.string,p=o[g]=o[g]||{data:{},gc:[]},m=f.lineHeight,b=x=0,i(u)||s(u)){if(s(u))for(h=0,c=u.length;h<c;++h)_=u[h],i(_)||s(_)||(b=_e(n,p.data,p.gc,b,_),x+=m)}else b=_e(n,p.data,p.gc,b,u),x=m;a.push(b),r.push(x),y=Math.max(b,y),v=Math.max(x,v)}!function(t,e){d(t,(t=>{const i=t.gc,s=i.length/2;let n;if(s>e){for(n=0;n<s;++n)delete t.data[i[n]];i.splice(0,s)}}))}(o,e);const w=a.indexOf(y),M=r.indexOf(v),k=t=>({width:a[t]||0,height:r[t]||0});return{first:k(0),last:k(e-1),widest:k(w),highest:k(M),widths:a,heights:r}}getLabelForValue(t){return t}getPixelForValue(t,e){return NaN}getValueForPixel(t){}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getPixelForDecimal(t){this._reversePixels&&(t=1-t);const e=this._startPixel+t*this._length;return J(this._alignToPixels?ve(this.chart,e,0):e)}getDecimalForPixel(t){const e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){const{min:t,max:e}=this;return t<0&&e<0?e:t>0&&e>0?t:0}getContext(t){const e=this.ticks||[];if(t>=0&&t<e.length){const i=e[t];return i.$context||(i.$context=function(t,e,i){return _i(t,{tick:i,index:e,type:\"tick\"})}(this.getContext(),t,i))}return this.$context||(this.$context=_i(this.chart.getContext(),{scale:this,type:\"scale\"}))}_tickSize(){const t=this.options.ticks,e=H(this.labelRotation),i=Math.abs(Math.cos(e)),s=Math.abs(Math.sin(e)),n=this._getLabelSizes(),o=t.autoSkipPadding||0,a=n?n.widest.width+o:0,r=n?n.highest.height+o:0;return this.isHorizontal()?r*i>a*s?a/i:r/s:r*s<a*i?r/i:a/s}_isVisible(){const t=this.options.display;return\"auto\"!==t?!!t:this.getMatchingVisibleMetas().length>0}_computeGridLineItems(t){const e=this.axis,i=this.chart,s=this.options,{grid:o,position:a}=s,l=o.offset,h=this.isHorizontal(),c=this.ticks.length+(l?1:0),d=Ws(o),u=[],f=o.setContext(this.getContext()),g=f.drawBorder?f.borderWidth:0,p=g/2,m=function(t){return ve(i,t,g)};let b,x,_,y,v,w,M,k,S,P,D,O;if(\"top\"===a)b=m(this.bottom),w=this.bottom-d,k=b-p,P=m(t.top)+p,O=t.bottom;else if(\"bottom\"===a)b=m(this.top),P=t.top,O=m(t.bottom)-p,w=b+p,k=this.top+d;else if(\"left\"===a)b=m(this.right),v=this.right-d,M=b-p,S=m(t.left)+p,D=t.right;else if(\"right\"===a)b=m(this.left),S=t.left,D=m(t.right)-p,v=b+p,M=this.left+d;else if(\"x\"===e){if(\"center\"===a)b=m((t.top+t.bottom)/2+.5);else if(n(a)){const t=Object.keys(a)[0],e=a[t];b=m(this.chart.scales[t].getPixelForValue(e))}P=t.top,O=t.bottom,w=b+p,k=w+d}else if(\"y\"===e){if(\"center\"===a)b=m((t.left+t.right)/2);else if(n(a)){const t=Object.keys(a)[0],e=a[t];b=m(this.chart.scales[t].getPixelForValue(e))}v=b-p,M=v-d,S=t.left,D=t.right}const C=r(s.ticks.maxTicksLimit,c),A=Math.max(1,Math.ceil(c/C));for(x=0;x<c;x+=A){const t=o.setContext(this.getContext(x)),e=t.lineWidth,s=t.color,n=t.borderDash||[],a=t.borderDashOffset,r=t.tickWidth,c=t.tickColor,d=t.tickBorderDash||[],f=t.tickBorderDashOffset;_=Ns(this,x,l),void 0!==_&&(y=ve(i,_,e),h?v=M=S=D=y:w=k=P=O=y,u.push({tx1:v,ty1:w,tx2:M,ty2:k,x1:S,y1:P,x2:D,y2:O,width:e,color:s,borderDash:n,borderDashOffset:a,tickWidth:r,tickColor:c,tickBorderDash:d,tickBorderDashOffset:f}))}return this._ticksLength=c,this._borderValue=b,u}_computeLabelItems(t){const e=this.axis,i=this.options,{position:o,ticks:a}=i,r=this.isHorizontal(),l=this.ticks,{align:h,crossAlign:c,padding:d,mirror:u}=a,f=Ws(i.grid),g=f+d,p=u?-d:g,m=-H(this.labelRotation),b=[];let x,_,y,v,w,M,k,S,P,D,O,C,A=\"middle\";if(\"top\"===o)M=this.bottom-p,k=this._getXAxisLabelAlignment();else if(\"bottom\"===o)M=this.top+p,k=this._getXAxisLabelAlignment();else if(\"left\"===o){const t=this._getYAxisLabelAlignment(f);k=t.textAlign,w=t.x}else if(\"right\"===o){const t=this._getYAxisLabelAlignment(f);k=t.textAlign,w=t.x}else if(\"x\"===e){if(\"center\"===o)M=(t.top+t.bottom)/2+g;else if(n(o)){const t=Object.keys(o)[0],e=o[t];M=this.chart.scales[t].getPixelForValue(e)+g}k=this._getXAxisLabelAlignment()}else if(\"y\"===e){if(\"center\"===o)w=(t.left+t.right)/2-g;else if(n(o)){const t=Object.keys(o)[0],e=o[t];w=this.chart.scales[t].getPixelForValue(e)}k=this._getYAxisLabelAlignment(f).textAlign}\"y\"===e&&(\"start\"===h?A=\"top\":\"end\"===h&&(A=\"bottom\"));const T=this._getLabelSizes();for(x=0,_=l.length;x<_;++x){y=l[x],v=y.label;const t=a.setContext(this.getContext(x));S=this.getPixelForTick(x)+a.labelOffset,P=this._resolveTickFontOptions(x),D=P.lineHeight,O=s(v)?v.length:1;const e=O/2,i=t.color,n=t.textStrokeColor,h=t.textStrokeWidth;let d,f=k;if(r?(w=S,\"inner\"===k&&(f=x===_-1?this.options.reverse?\"left\":\"right\":0===x?this.options.reverse?\"right\":\"left\":\"center\"),C=\"top\"===o?\"near\"===c||0!==m?-O*D+D/2:\"center\"===c?-T.highest.height/2-e*D+D:-T.highest.height+D/2:\"near\"===c||0!==m?D/2:\"center\"===c?T.highest.height/2-e*D:T.highest.height-O*D,u&&(C*=-1)):(M=S,C=(1-O)*D/2),t.showLabelBackdrop){const e=pi(t.backdropPadding),i=T.heights[x],s=T.widths[x];let n=M+C-e.top,o=w-e.left;switch(A){case\"middle\":n-=i/2;break;case\"bottom\":n-=i}switch(k){case\"center\":o-=s/2;break;case\"right\":o-=s}d={left:o,top:n,width:s+e.width,height:i+e.height,color:t.backdropColor}}b.push({rotation:m,label:v,font:P,color:i,strokeColor:n,strokeWidth:h,textOffset:C,textAlign:f,textBaseline:A,translation:[w,M],backdrop:d})}return b}_getXAxisLabelAlignment(){const{position:t,ticks:e}=this.options;if(-H(this.labelRotation))return\"top\"===t?\"left\":\"right\";let i=\"center\";return\"start\"===e.align?i=\"left\":\"end\"===e.align?i=\"right\":\"inner\"===e.align&&(i=\"inner\"),i}_getYAxisLabelAlignment(t){const{position:e,ticks:{crossAlign:i,mirror:s,padding:n}}=this.options,o=t+n,a=this._getLabelSizes().widest.width;let r,l;return\"left\"===e?s?(l=this.right+n,\"near\"===i?r=\"left\":\"center\"===i?(r=\"center\",l+=a/2):(r=\"right\",l+=a)):(l=this.right-o,\"near\"===i?r=\"right\":\"center\"===i?(r=\"center\",l-=a/2):(r=\"left\",l=this.left)):\"right\"===e?s?(l=this.left+n,\"near\"===i?r=\"right\":\"center\"===i?(r=\"center\",l-=a/2):(r=\"left\",l-=a)):(l=this.left+o,\"near\"===i?r=\"left\":\"center\"===i?(r=\"center\",l+=a/2):(r=\"right\",l=this.right)):r=\"right\",{textAlign:r,x:l}}_computeLabelArea(){if(this.options.ticks.mirror)return;const t=this.chart,e=this.options.position;return\"left\"===e||\"right\"===e?{top:0,left:this.left,bottom:t.height,right:this.right}:\"top\"===e||\"bottom\"===e?{top:this.top,left:0,bottom:this.bottom,right:t.width}:void 0}drawBackground(){const{ctx:t,options:{backgroundColor:e},left:i,top:s,width:n,height:o}=this;e&&(t.save(),t.fillStyle=e,t.fillRect(i,s,n,o),t.restore())}getLineWidthForValue(t){const e=this.options.grid;if(!this._isVisible()||!e.display)return 0;const i=this.ticks.findIndex((e=>e.value===t));if(i>=0){return e.setContext(this.getContext(i)).lineWidth}return 0}drawGrid(t){const e=this.options.grid,i=this.ctx,s=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(t));let n,o;const a=(t,e,s)=>{s.width&&s.color&&(i.save(),i.lineWidth=s.width,i.strokeStyle=s.color,i.setLineDash(s.borderDash||[]),i.lineDashOffset=s.borderDashOffset,i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(e.x,e.y),i.stroke(),i.restore())};if(e.display)for(n=0,o=s.length;n<o;++n){const t=s[n];e.drawOnChartArea&&a({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},t),e.drawTicks&&a({x:t.tx1,y:t.ty1},{x:t.tx2,y:t.ty2},{color:t.tickColor,width:t.tickWidth,borderDash:t.tickBorderDash,borderDashOffset:t.tickBorderDashOffset})}}drawBorder(){const{chart:t,ctx:e,options:{grid:i}}=this,s=i.setContext(this.getContext()),n=i.drawBorder?s.borderWidth:0;if(!n)return;const o=i.setContext(this.getContext(0)).lineWidth,a=this._borderValue;let r,l,h,c;this.isHorizontal()?(r=ve(t,this.left,n)-n/2,l=ve(t,this.right,o)+o/2,h=c=a):(h=ve(t,this.top,n)-n/2,c=ve(t,this.bottom,o)+o/2,r=l=a),e.save(),e.lineWidth=s.borderWidth,e.strokeStyle=s.borderColor,e.beginPath(),e.moveTo(r,h),e.lineTo(l,c),e.stroke(),e.restore()}drawLabels(t){if(!this.options.ticks.display)return;const e=this.ctx,i=this._computeLabelArea();i&&Pe(e,i);const s=this._labelItems||(this._labelItems=this._computeLabelItems(t));let n,o;for(n=0,o=s.length;n<o;++n){const t=s[n],i=t.font,o=t.label;t.backdrop&&(e.fillStyle=t.backdrop.color,e.fillRect(t.backdrop.left,t.backdrop.top,t.backdrop.width,t.backdrop.height)),Ae(e,o,0,t.textOffset,i,t)}i&&De(e)}drawTitle(){const{ctx:t,options:{position:e,title:i,reverse:o}}=this;if(!i.display)return;const a=mi(i.font),r=pi(i.padding),l=i.align;let h=a.lineHeight/2;\"bottom\"===e||\"center\"===e||n(e)?(h+=r.bottom,s(i.text)&&(h+=a.lineHeight*(i.text.length-1))):h+=r.top;const{titleX:c,titleY:d,maxWidth:u,rotation:f}=function(t,e,i,s){const{top:o,left:a,bottom:r,right:l,chart:h}=t,{chartArea:c,scales:d}=h;let u,f,g,p=0;const m=r-o,b=l-a;if(t.isHorizontal()){if(f=ut(s,a,l),n(i)){const t=Object.keys(i)[0],s=i[t];g=d[t].getPixelForValue(s)+m-e}else g=\"center\"===i?(c.bottom+c.top)/2+m-e:Vs(t,i,e);u=l-a}else{if(n(i)){const t=Object.keys(i)[0],s=i[t];f=d[t].getPixelForValue(s)-b+e}else f=\"center\"===i?(c.left+c.right)/2-b+e:Vs(t,i,e);g=ut(s,r,o),p=\"left\"===i?-L:L}return{titleX:f,titleY:g,maxWidth:u,rotation:p}}(this,h,e,l);Ae(t,i.text,0,0,a,{color:i.color,maxWidth:u,rotation:f,textAlign:Hs(l,e,o),textBaseline:\"middle\",translation:[c,d]})}draw(t){this._isVisible()&&(this.drawBackground(),this.drawGrid(t),this.drawBorder(),this.drawTitle(),this.drawLabels(t))}_layers(){const t=this.options,e=t.ticks&&t.ticks.z||0,i=r(t.grid&&t.grid.z,-1);return this._isVisible()&&this.draw===$s.prototype.draw?[{z:i,draw:t=>{this.drawBackground(),this.drawGrid(t),this.drawTitle()}},{z:i+1,draw:()=>{this.drawBorder()}},{z:e,draw:t=>{this.drawLabels(t)}}]:[{z:e,draw:t=>{this.draw(t)}}]}getMatchingVisibleMetas(t){const e=this.chart.getSortedVisibleDatasetMetas(),i=this.axis+\"AxisID\",s=[];let n,o;for(n=0,o=e.length;n<o;++n){const o=e[n];o[i]!==this.id||t&&o.type!==t||s.push(o)}return s}_resolveTickFontOptions(t){return mi(this.options.ticks.setContext(this.getContext(t)).font)}_maxDigits(){const t=this._resolveTickFontOptions(0).lineHeight;return(this.isHorizontal()?this.width:this.height)/t}}class Ys{constructor(t,e,i){this.type=t,this.scope=e,this.override=i,this.items=Object.create(null)}isForType(t){return Object.prototype.isPrototypeOf.call(this.type.prototype,t.prototype)}register(t){const e=Object.getPrototypeOf(t);let i;(function(t){return\"id\"in t&&\"defaults\"in t})(e)&&(i=this.register(e));const s=this.items,n=t.id,o=this.scope+\".\"+n;if(!n)throw new Error(\"class does not have id: \"+t);return n in s||(s[n]=t,function(t,e,i){const s=m(Object.create(null),[i?ne.get(i):{},ne.get(e),t.defaults]);ne.set(e,s),t.defaultRoutes&&function(t,e){Object.keys(e).forEach((i=>{const s=i.split(\".\"),n=s.pop(),o=[t].concat(s).join(\".\"),a=e[i].split(\".\"),r=a.pop(),l=a.join(\".\");ne.route(o,n,l,r)}))}(e,t.defaultRoutes);t.descriptors&&ne.describe(e,t.descriptors)}(t,o,i),this.override&&ne.override(t.id,t.overrides)),o}get(t){return this.items[t]}unregister(t){const e=this.items,i=t.id,s=this.scope;i in e&&delete e[i],s&&i in ne[s]&&(delete ne[s][i],this.override&&delete te[i])}}var Us=new class{constructor(){this.controllers=new Ys(Ls,\"datasets\",!0),this.elements=new Ys(Es,\"elements\"),this.plugins=new Ys(Object,\"plugins\"),this.scales=new Ys($s,\"scales\"),this._typedRegistries=[this.controllers,this.scales,this.elements]}add(...t){this._each(\"register\",t)}remove(...t){this._each(\"unregister\",t)}addControllers(...t){this._each(\"register\",t,this.controllers)}addElements(...t){this._each(\"register\",t,this.elements)}addPlugins(...t){this._each(\"register\",t,this.plugins)}addScales(...t){this._each(\"register\",t,this.scales)}getController(t){return this._get(t,this.controllers,\"controller\")}getElement(t){return this._get(t,this.elements,\"element\")}getPlugin(t){return this._get(t,this.plugins,\"plugin\")}getScale(t){return this._get(t,this.scales,\"scale\")}removeControllers(...t){this._each(\"unregister\",t,this.controllers)}removeElements(...t){this._each(\"unregister\",t,this.elements)}removePlugins(...t){this._each(\"unregister\",t,this.plugins)}removeScales(...t){this._each(\"unregister\",t,this.scales)}_each(t,e,i){[...e].forEach((e=>{const s=i||this._getRegistryForType(e);i||s.isForType(e)||s===this.plugins&&e.id?this._exec(t,s,e):d(e,(e=>{const s=i||this._getRegistryForType(e);this._exec(t,s,e)}))}))}_exec(t,e,i){const s=w(t);c(i[\"before\"+s],[],i),e[t](i),c(i[\"after\"+s],[],i)}_getRegistryForType(t){for(let e=0;e<this._typedRegistries.length;e++){const i=this._typedRegistries[e];if(i.isForType(t))return i}return this.plugins}_get(t,e,i){const s=e.get(t);if(void 0===s)throw new Error('\"'+t+'\" is not a registered '+i+\".\");return s}};class Xs{constructor(){this._init=[]}notify(t,e,i,s){\"beforeInit\"===e&&(this._init=this._createDescriptors(t,!0),this._notify(this._init,t,\"install\"));const n=s?this._descriptors(t).filter(s):this._descriptors(t),o=this._notify(n,t,e,i);return\"afterDestroy\"===e&&(this._notify(n,t,\"stop\"),this._notify(this._init,t,\"uninstall\")),o}_notify(t,e,i,s){s=s||{};for(const n of t){const t=n.plugin;if(!1===c(t[i],[e,s,n.options],t)&&s.cancelable)return!1}return!0}invalidate(){i(this._cache)||(this._oldCache=this._cache,this._cache=void 0)}_descriptors(t){if(this._cache)return this._cache;const e=this._cache=this._createDescriptors(t);return this._notifyStateChanges(t),e}_createDescriptors(t,e){const i=t&&t.config,s=r(i.options&&i.options.plugins,{}),n=function(t){const e={},i=[],s=Object.keys(Us.plugins.items);for(let t=0;t<s.length;t++)i.push(Us.getPlugin(s[t]));const n=t.plugins||[];for(let t=0;t<n.length;t++){const s=n[t];-1===i.indexOf(s)&&(i.push(s),e[s.id]=!0)}return{plugins:i,localIds:e}}(i);return!1!==s||e?function(t,{plugins:e,localIds:i},s,n){const o=[],a=t.getContext();for(const r of e){const e=r.id,l=qs(s[e],n);null!==l&&o.push({plugin:r,options:Ks(t.config,{plugin:r,local:i[e]},l,a)})}return o}(t,n,s,e):[]}_notifyStateChanges(t){const e=this._oldCache||[],i=this._cache,s=(t,e)=>t.filter((t=>!e.some((e=>t.plugin.id===e.plugin.id))));this._notify(s(e,i),t,\"stop\"),this._notify(s(i,e),t,\"start\")}}function qs(t,e){return e||!1!==t?!0===t?{}:t:null}function Ks(t,{plugin:e,local:i},s,n){const o=t.pluginScopeKeys(e),a=t.getOptionScopes(s,o);return i&&e.defaults&&a.push(e.defaults),t.createResolver(a,n,[\"\"],{scriptable:!1,indexable:!1,allKeys:!0})}function Gs(t,e){const i=ne.datasets[t]||{};return((e.datasets||{})[t]||{}).indexAxis||e.indexAxis||i.indexAxis||\"x\"}function Zs(t,e){return\"x\"===t||\"y\"===t?t:e.axis||(\"top\"===(i=e.position)||\"bottom\"===i?\"x\":\"left\"===i||\"right\"===i?\"y\":void 0)||t.charAt(0).toLowerCase();var i}function Js(t){const e=t.options||(t.options={});e.plugins=r(e.plugins,{}),e.scales=function(t,e){const i=te[t.type]||{scales:{}},s=e.scales||{},o=Gs(t.type,e),a=Object.create(null),r=Object.create(null);return Object.keys(s).forEach((t=>{const e=s[t];if(!n(e))return console.error(`Invalid scale configuration for scale: ${t}`);if(e._proxy)return console.warn(`Ignoring resolver passed as options for scale: ${t}`);const l=Zs(t,e),h=function(t,e){return t===e?\"_index_\":\"_value_\"}(l,o),c=i.scales||{};a[l]=a[l]||t,r[t]=b(Object.create(null),[{axis:l},e,c[l],c[h]])})),t.data.datasets.forEach((i=>{const n=i.type||t.type,o=i.indexAxis||Gs(n,e),l=(te[n]||{}).scales||{};Object.keys(l).forEach((t=>{const e=function(t,e){let i=t;return\"_index_\"===t?i=e:\"_value_\"===t&&(i=\"x\"===e?\"y\":\"x\"),i}(t,o),n=i[e+\"AxisID\"]||a[e]||e;r[n]=r[n]||Object.create(null),b(r[n],[{axis:e},s[n],l[t]])}))})),Object.keys(r).forEach((t=>{const e=r[t];b(e,[ne.scales[e.type],ne.scale])})),r}(t,e)}function Qs(t){return(t=t||{}).datasets=t.datasets||[],t.labels=t.labels||[],t}const tn=new Map,en=new Set;function sn(t,e){let i=tn.get(t);return i||(i=e(),tn.set(t,i),en.add(i)),i}const nn=(t,e,i)=>{const s=y(e,i);void 0!==s&&t.add(s)};class on{constructor(t){this._config=function(t){return(t=t||{}).data=Qs(t.data),Js(t),t}(t),this._scopeCache=new Map,this._resolverCache=new Map}get platform(){return this._config.platform}get type(){return this._config.type}set type(t){this._config.type=t}get data(){return this._config.data}set data(t){this._config.data=Qs(t)}get options(){return this._config.options}set options(t){this._config.options=t}get plugins(){return this._config.plugins}update(){const t=this._config;this.clearCache(),Js(t)}clearCache(){this._scopeCache.clear(),this._resolverCache.clear()}datasetScopeKeys(t){return sn(t,(()=>[[`datasets.${t}`,\"\"]]))}datasetAnimationScopeKeys(t,e){return sn(`${t}.transition.${e}`,(()=>[[`datasets.${t}.transitions.${e}`,`transitions.${e}`],[`datasets.${t}`,\"\"]]))}datasetElementScopeKeys(t,e){return sn(`${t}-${e}`,(()=>[[`datasets.${t}.elements.${e}`,`datasets.${t}`,`elements.${e}`,\"\"]]))}pluginScopeKeys(t){const e=t.id;return sn(`${this.type}-plugin-${e}`,(()=>[[`plugins.${e}`,...t.additionalOptionScopes||[]]]))}_cachedScopes(t,e){const i=this._scopeCache;let s=i.get(t);return s&&!e||(s=new Map,i.set(t,s)),s}getOptionScopes(t,e,i){const{options:s,type:n}=this,o=this._cachedScopes(t,i),a=o.get(e);if(a)return a;const r=new Set;e.forEach((e=>{t&&(r.add(t),e.forEach((e=>nn(r,t,e)))),e.forEach((t=>nn(r,s,t))),e.forEach((t=>nn(r,te[n]||{},t))),e.forEach((t=>nn(r,ne,t))),e.forEach((t=>nn(r,ee,t)))}));const l=Array.from(r);return 0===l.length&&l.push(Object.create(null)),en.has(e)&&o.set(e,l),l}chartOptionScopes(){const{options:t,type:e}=this;return[t,te[e]||{},ne.datasets[e]||{},{type:e},ne,ee]}resolveNamedOptions(t,e,i,n=[\"\"]){const o={$shared:!0},{resolver:a,subPrefixes:r}=an(this._resolverCache,t,n);let l=a;if(function(t,e){const{isScriptable:i,isIndexable:n}=Ie(t);for(const o of e){const e=i(o),a=n(o),r=(a||e)&&t[o];if(e&&(k(r)||rn(r))||a&&s(r))return!0}return!1}(a,e)){o.$shared=!1;l=Re(a,i=k(i)?i():i,this.createResolver(t,i,r))}for(const t of e)o[t]=l[t];return o}createResolver(t,e,i=[\"\"],s){const{resolver:o}=an(this._resolverCache,t,i);return n(e)?Re(o,e,void 0,s):o}}function an(t,e,i){let s=t.get(e);s||(s=new Map,t.set(e,s));const n=i.join();let o=s.get(n);if(!o){o={resolver:Ee(e,i),subPrefixes:i.filter((t=>!t.toLowerCase().includes(\"hover\")))},s.set(n,o)}return o}const rn=t=>n(t)&&Object.getOwnPropertyNames(t).reduce(((e,i)=>e||k(t[i])),!1);const ln=[\"top\",\"bottom\",\"left\",\"right\",\"chartArea\"];function hn(t,e){return\"top\"===t||\"bottom\"===t||-1===ln.indexOf(t)&&\"x\"===e}function cn(t,e){return function(i,s){return i[t]===s[t]?i[e]-s[e]:i[t]-s[t]}}function dn(t){const e=t.chart,i=e.options.animation;e.notifyPlugins(\"afterRender\"),c(i&&i.onComplete,[t],e)}function un(t){const e=t.chart,i=e.options.animation;c(i&&i.onProgress,[t],e)}function fn(t){return oe()&&\"string\"==typeof t?t=document.getElementById(t):t&&t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t}const gn={},pn=t=>{const e=fn(t);return Object.values(gn).filter((t=>t.canvas===e)).pop()};function mn(t,e,i){const s=Object.keys(t);for(const n of s){const s=+n;if(s>=e){const o=t[n];delete t[n],(i>0||s>e)&&(t[s+i]=o)}}}class bn{constructor(t,i){const s=this.config=new on(i),n=fn(t),o=pn(n);if(o)throw new Error(\"Canvas is already in use. Chart with ID '\"+o.id+\"' must be destroyed before the canvas with ID '\"+o.canvas.id+\"' can be reused.\");const a=s.createResolver(s.chartOptionScopes(),this.getContext());this.platform=new(s.platform||gs(n)),this.platform.updateConfig(s);const r=this.platform.acquireContext(n,a.aspectRatio),l=r&&r.canvas,h=l&&l.height,c=l&&l.width;this.id=e(),this.ctx=r,this.canvas=l,this.width=c,this.height=h,this._options=a,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new Xs,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=ct((t=>this.update(t)),a.resizeDelay||0),this._dataChanges=[],gn[this.id]=this,r&&l?(mt.listen(this,\"complete\",dn),mt.listen(this,\"progress\",un),this._initialize(),this.attached&&this.update()):console.error(\"Failed to create chart: can't acquire context from the given item\")}get aspectRatio(){const{options:{aspectRatio:t,maintainAspectRatio:e},width:s,height:n,_aspectRatio:o}=this;return i(t)?e&&o?o:n?s/n:null:t}get data(){return this.config.data}set data(t){this.config.data=t}get options(){return this._options}set options(t){this.config.options=t}_initialize(){return this.notifyPlugins(\"beforeInit\"),this.options.responsive?this.resize():pe(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins(\"afterInit\"),this}clear(){return we(this.canvas,this.ctx),this}stop(){return mt.stop(this),this}resize(t,e){mt.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}_resize(t,e){const i=this.options,s=this.canvas,n=i.maintainAspectRatio&&this.aspectRatio,o=this.platform.getMaximumSize(s,t,e,n),a=i.devicePixelRatio||this.platform.getDevicePixelRatio(),r=this.width?\"resize\":\"attach\";this.width=o.width,this.height=o.height,this._aspectRatio=this.aspectRatio,pe(this,a,!0)&&(this.notifyPlugins(\"resize\",{size:o}),c(i.onResize,[this,o],this),this.attached&&this._doResize(r)&&this.render())}ensureScalesHaveIDs(){d(this.options.scales||{},((t,e)=>{t.id=e}))}buildOrUpdateScales(){const t=this.options,e=t.scales,i=this.scales,s=Object.keys(i).reduce(((t,e)=>(t[e]=!1,t)),{});let n=[];e&&(n=n.concat(Object.keys(e).map((t=>{const i=e[t],s=Zs(t,i),n=\"r\"===s,o=\"x\"===s;return{options:i,dposition:n?\"chartArea\":o?\"bottom\":\"left\",dtype:n?\"radialLinear\":o?\"category\":\"linear\"}})))),d(n,(e=>{const n=e.options,o=n.id,a=Zs(o,n),l=r(n.type,e.dtype);void 0!==n.position&&hn(n.position,a)===hn(e.dposition)||(n.position=e.dposition),s[o]=!0;let h=null;if(o in i&&i[o].type===l)h=i[o];else{h=new(Us.getScale(l))({id:o,type:l,ctx:this.ctx,chart:this}),i[h.id]=h}h.init(n,t)})),d(s,((t,e)=>{t||delete i[e]})),d(i,(t=>{Zi.configure(this,t,t.options),Zi.addBox(this,t)}))}_updateMetasets(){const t=this._metasets,e=this.data.datasets.length,i=t.length;if(t.sort(((t,e)=>t.index-e.index)),i>e){for(let t=e;t<i;++t)this._destroyDatasetMeta(t);t.splice(e,i-e)}this._sortedMetasets=t.slice(0).sort(cn(\"order\",\"index\"))}_removeUnreferencedMetasets(){const{_metasets:t,data:{datasets:e}}=this;t.length>e.length&&delete this._stacks,t.forEach(((t,i)=>{0===e.filter((e=>e===t._dataset)).length&&this._destroyDatasetMeta(i)}))}buildOrUpdateControllers(){const t=[],e=this.data.datasets;let i,s;for(this._removeUnreferencedMetasets(),i=0,s=e.length;i<s;i++){const s=e[i];let n=this.getDatasetMeta(i);const o=s.type||this.config.type;if(n.type&&n.type!==o&&(this._destroyDatasetMeta(i),n=this.getDatasetMeta(i)),n.type=o,n.indexAxis=s.indexAxis||Gs(o,this.options),n.order=s.order||0,n.index=i,n.label=\"\"+s.label,n.visible=this.isDatasetVisible(i),n.controller)n.controller.updateIndex(i),n.controller.linkScales();else{const e=Us.getController(o),{datasetElementType:s,dataElementType:a}=ne.datasets[o];Object.assign(e.prototype,{dataElementType:Us.getElement(a),datasetElementType:s&&Us.getElement(s)}),n.controller=new e(this,i),t.push(n.controller)}}return this._updateMetasets(),t}_resetElements(){d(this.data.datasets,((t,e)=>{this.getDatasetMeta(e).controller.reset()}),this)}reset(){this._resetElements(),this.notifyPlugins(\"reset\")}update(t){const e=this.config;e.update();const i=this._options=e.createResolver(e.chartOptionScopes(),this.getContext()),s=this._animationsDisabled=!i.animation;if(this._updateScales(),this._checkEventBindings(),this._updateHiddenIndices(),this._plugins.invalidate(),!1===this.notifyPlugins(\"beforeUpdate\",{mode:t,cancelable:!0}))return;const n=this.buildOrUpdateControllers();this.notifyPlugins(\"beforeElementsUpdate\");let o=0;for(let t=0,e=this.data.datasets.length;t<e;t++){const{controller:e}=this.getDatasetMeta(t),i=!s&&-1===n.indexOf(e);e.buildOrUpdateElements(i),o=Math.max(+e.getMaxOverflow(),o)}o=this._minPadding=i.layout.autoPadding?o:0,this._updateLayout(o),s||d(n,(t=>{t.reset()})),this._updateDatasets(t),this.notifyPlugins(\"afterUpdate\",{mode:t}),this._layers.sort(cn(\"z\",\"_idx\"));const{_active:a,_lastEvent:r}=this;r?this._eventHandler(r,!0):a.length&&this._updateHoverStyles(a,a,!0),this.render()}_updateScales(){d(this.scales,(t=>{Zi.removeBox(this,t)})),this.ensureScalesHaveIDs(),this.buildOrUpdateScales()}_checkEventBindings(){const t=this.options,e=new Set(Object.keys(this._listeners)),i=new Set(t.events);S(e,i)&&!!this._responsiveListeners===t.responsive||(this.unbindEvents(),this.bindEvents())}_updateHiddenIndices(){const{_hiddenIndices:t}=this,e=this._getUniformDataChanges()||[];for(const{method:i,start:s,count:n}of e){mn(t,s,\"_removeElements\"===i?-n:n)}}_getUniformDataChanges(){const t=this._dataChanges;if(!t||!t.length)return;this._dataChanges=[];const e=this.data.datasets.length,i=e=>new Set(t.filter((t=>t[0]===e)).map(((t,e)=>e+\",\"+t.splice(1).join(\",\")))),s=i(0);for(let t=1;t<e;t++)if(!S(s,i(t)))return;return Array.from(s).map((t=>t.split(\",\"))).map((t=>({method:t[1],start:+t[2],count:+t[3]})))}_updateLayout(t){if(!1===this.notifyPlugins(\"beforeLayout\",{cancelable:!0}))return;Zi.update(this,this.width,this.height,t);const e=this.chartArea,i=e.width<=0||e.height<=0;this._layers=[],d(this.boxes,(t=>{i&&\"chartArea\"===t.position||(t.configure&&t.configure(),this._layers.push(...t._layers()))}),this),this._layers.forEach(((t,e)=>{t._idx=e})),this.notifyPlugins(\"afterLayout\")}_updateDatasets(t){if(!1!==this.notifyPlugins(\"beforeDatasetsUpdate\",{mode:t,cancelable:!0})){for(let t=0,e=this.data.datasets.length;t<e;++t)this.getDatasetMeta(t).controller.configure();for(let e=0,i=this.data.datasets.length;e<i;++e)this._updateDataset(e,k(t)?t({datasetIndex:e}):t);this.notifyPlugins(\"afterDatasetsUpdate\",{mode:t})}}_updateDataset(t,e){const i=this.getDatasetMeta(t),s={meta:i,index:t,mode:e,cancelable:!0};!1!==this.notifyPlugins(\"beforeDatasetUpdate\",s)&&(i.controller._update(e),s.cancelable=!1,this.notifyPlugins(\"afterDatasetUpdate\",s))}render(){!1!==this.notifyPlugins(\"beforeRender\",{cancelable:!0})&&(mt.has(this)?this.attached&&!mt.running(this)&&mt.start(this):(this.draw(),dn({chart:this})))}draw(){let t;if(this._resizeBeforeDraw){const{width:t,height:e}=this._resizeBeforeDraw;this._resize(t,e),this._resizeBeforeDraw=null}if(this.clear(),this.width<=0||this.height<=0)return;if(!1===this.notifyPlugins(\"beforeDraw\",{cancelable:!0}))return;const e=this._layers;for(t=0;t<e.length&&e[t].z<=0;++t)e[t].draw(this.chartArea);for(this._drawDatasets();t<e.length;++t)e[t].draw(this.chartArea);this.notifyPlugins(\"afterDraw\")}_getSortedDatasetMetas(t){const e=this._sortedMetasets,i=[];let s,n;for(s=0,n=e.length;s<n;++s){const n=e[s];t&&!n.visible||i.push(n)}return i}getSortedVisibleDatasetMetas(){return this._getSortedDatasetMetas(!0)}_drawDatasets(){if(!1===this.notifyPlugins(\"beforeDatasetsDraw\",{cancelable:!0}))return;const t=this.getSortedVisibleDatasetMetas();for(let e=t.length-1;e>=0;--e)this._drawDataset(t[e]);this.notifyPlugins(\"afterDatasetsDraw\")}_drawDataset(t){const e=this.ctx,i=t._clip,s=!i.disabled,n=this.chartArea,o={meta:t,index:t.index,cancelable:!0};!1!==this.notifyPlugins(\"beforeDatasetDraw\",o)&&(s&&Pe(e,{left:!1===i.left?0:n.left-i.left,right:!1===i.right?this.width:n.right+i.right,top:!1===i.top?0:n.top-i.top,bottom:!1===i.bottom?this.height:n.bottom+i.bottom}),t.controller.draw(),s&&De(e),o.cancelable=!1,this.notifyPlugins(\"afterDatasetDraw\",o))}isPointInArea(t){return Se(t,this.chartArea,this._minPadding)}getElementsAtEventForMode(t,e,i,s){const n=Vi.modes[e];return\"function\"==typeof n?n(this,t,i,s):[]}getDatasetMeta(t){const e=this.data.datasets[t],i=this._metasets;let s=i.filter((t=>t&&t._dataset===e)).pop();return s||(s={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},i.push(s)),s}getContext(){return this.$context||(this.$context=_i(null,{chart:this,type:\"chart\"}))}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(t){const e=this.data.datasets[t];if(!e)return!1;const i=this.getDatasetMeta(t);return\"boolean\"==typeof i.hidden?!i.hidden:!e.hidden}setDatasetVisibility(t,e){this.getDatasetMeta(t).hidden=!e}toggleDataVisibility(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}getDataVisibility(t){return!this._hiddenIndices[t]}_updateVisibility(t,e,i){const s=i?\"show\":\"hide\",n=this.getDatasetMeta(t),o=n.controller._resolveAnimations(void 0,s);M(e)?(n.data[e].hidden=!i,this.update()):(this.setDatasetVisibility(t,i),o.update(n,{visible:i}),this.update((e=>e.datasetIndex===t?s:void 0)))}hide(t,e){this._updateVisibility(t,e,!1)}show(t,e){this._updateVisibility(t,e,!0)}_destroyDatasetMeta(t){const e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}_stop(){let t,e;for(this.stop(),mt.remove(this),t=0,e=this.data.datasets.length;t<e;++t)this._destroyDatasetMeta(t)}destroy(){this.notifyPlugins(\"beforeDestroy\");const{canvas:t,ctx:e}=this;this._stop(),this.config.clearCache(),t&&(this.unbindEvents(),we(t,e),this.platform.releaseContext(e),this.canvas=null,this.ctx=null),this.notifyPlugins(\"destroy\"),delete gn[this.id],this.notifyPlugins(\"afterDestroy\")}toBase64Image(...t){return this.canvas.toDataURL(...t)}bindEvents(){this.bindUserEvents(),this.options.responsive?this.bindResponsiveEvents():this.attached=!0}bindUserEvents(){const t=this._listeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(t,e,i)=>{t.offsetX=e,t.offsetY=i,this._eventHandler(t)};d(this.options.events,(t=>i(t,s)))}bindResponsiveEvents(){this._responsiveListeners||(this._responsiveListeners={});const t=this._responsiveListeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(i,s)=>{t[i]&&(e.removeEventListener(this,i,s),delete t[i])},n=(t,e)=>{this.canvas&&this.resize(t,e)};let o;const a=()=>{s(\"attach\",a),this.attached=!0,this.resize(),i(\"resize\",n),i(\"detach\",o)};o=()=>{this.attached=!1,s(\"resize\",n),this._stop(),this._resize(0,0),i(\"attach\",a)},e.isAttached(this.canvas)?a():o()}unbindEvents(){d(this._listeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._listeners={},d(this._responsiveListeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._responsiveListeners=void 0}updateHoverStyle(t,e,i){const s=i?\"set\":\"remove\";let n,o,a,r;for(\"dataset\"===e&&(n=this.getDatasetMeta(t[0].datasetIndex),n.controller[\"_\"+s+\"DatasetHoverStyle\"]()),a=0,r=t.length;a<r;++a){o=t[a];const e=o&&this.getDatasetMeta(o.datasetIndex).controller;e&&e[s+\"HoverStyle\"](o.element,o.datasetIndex,o.index)}}getActiveElements(){return this._active||[]}setActiveElements(t){const e=this._active||[],i=t.map((({datasetIndex:t,index:e})=>{const i=this.getDatasetMeta(t);if(!i)throw new Error(\"No dataset found at index \"+t);return{datasetIndex:t,element:i.data[e],index:e}}));!u(i,e)&&(this._active=i,this._lastEvent=null,this._updateHoverStyles(i,e))}notifyPlugins(t,e,i){return this._plugins.notify(this,t,e,i)}_updateHoverStyles(t,e,i){const s=this.options.hover,n=(t,e)=>t.filter((t=>!e.some((e=>t.datasetIndex===e.datasetIndex&&t.index===e.index)))),o=n(e,t),a=i?t:n(t,e);o.length&&this.updateHoverStyle(o,s.mode,!1),a.length&&s.mode&&this.updateHoverStyle(a,s.mode,!0)}_eventHandler(t,e){const i={event:t,replay:e,cancelable:!0,inChartArea:this.isPointInArea(t)},s=e=>(e.options.events||this.options.events).includes(t.native.type);if(!1===this.notifyPlugins(\"beforeEvent\",i,s))return;const n=this._handleEvent(t,e,i.inChartArea);return i.cancelable=!1,this.notifyPlugins(\"afterEvent\",i,s),(n||i.changed)&&this.render(),this}_handleEvent(t,e,i){const{_active:s=[],options:n}=this,o=e,a=this._getActiveElements(t,s,i,o),r=P(t),l=function(t,e,i,s){return i&&\"mouseout\"!==t.type?s?e:t:null}(t,this._lastEvent,i,r);i&&(this._lastEvent=null,c(n.onHover,[t,a,this],this),r&&c(n.onClick,[t,a,this],this));const h=!u(a,s);return(h||e)&&(this._active=a,this._updateHoverStyles(a,s,e)),this._lastEvent=l,h}_getActiveElements(t,e,i,s){if(\"mouseout\"===t.type)return[];if(!i)return e;const n=this.options.hover;return this.getElementsAtEventForMode(t,n.mode,n,s)}}const xn=()=>d(bn.instances,(t=>t._plugins.invalidate())),_n=!0;function yn(){throw new Error(\"This method is not implemented: Check that a complete date adapter is provided.\")}Object.defineProperties(bn,{defaults:{enumerable:_n,value:ne},instances:{enumerable:_n,value:gn},overrides:{enumerable:_n,value:te},registry:{enumerable:_n,value:Us},version:{enumerable:_n,value:\"3.9.1\"},getChart:{enumerable:_n,value:pn},register:{enumerable:_n,value:(...t)=>{Us.add(...t),xn()}},unregister:{enumerable:_n,value:(...t)=>{Us.remove(...t),xn()}}});class vn{constructor(t){this.options=t||{}}init(t){}formats(){return yn()}parse(t,e){return yn()}format(t,e){return yn()}add(t,e,i){return yn()}diff(t,e,i){return yn()}startOf(t,e,i){return yn()}endOf(t,e){return yn()}}vn.override=function(t){Object.assign(vn.prototype,t)};var wn={_date:vn};function Mn(t){const e=t.iScale,i=function(t,e){if(!t._cache.$bar){const i=t.getMatchingVisibleMetas(e);let s=[];for(let e=0,n=i.length;e<n;e++)s=s.concat(i[e].controller.getAllParsedValues(t));t._cache.$bar=rt(s.sort(((t,e)=>t-e)))}return t._cache.$bar}(e,t.type);let s,n,o,a,r=e._length;const l=()=>{32767!==o&&-32768!==o&&(M(a)&&(r=Math.min(r,Math.abs(o-a)||r)),a=o)};for(s=0,n=i.length;s<n;++s)o=e.getPixelForValue(i[s]),l();for(a=void 0,s=0,n=e.ticks.length;s<n;++s)o=e.getPixelForTick(s),l();return r}function kn(t,e,i,n){return s(t)?function(t,e,i,s){const n=i.parse(t[0],s),o=i.parse(t[1],s),a=Math.min(n,o),r=Math.max(n,o);let l=a,h=r;Math.abs(a)>Math.abs(r)&&(l=r,h=a),e[i.axis]=h,e._custom={barStart:l,barEnd:h,start:n,end:o,min:a,max:r}}(t,e,i,n):e[i.axis]=i.parse(t,n),e}function Sn(t,e,i,s){const n=t.iScale,o=t.vScale,a=n.getLabels(),r=n===o,l=[];let h,c,d,u;for(h=i,c=i+s;h<c;++h)u=e[h],d={},d[n.axis]=r||n.parse(a[h],h),l.push(kn(u,d,o,h));return l}function Pn(t){return t&&void 0!==t.barStart&&void 0!==t.barEnd}function Dn(t,e,i,s){let n=e.borderSkipped;const o={};if(!n)return void(t.borderSkipped=o);if(!0===n)return void(t.borderSkipped={top:!0,right:!0,bottom:!0,left:!0});const{start:a,end:r,reverse:l,top:h,bottom:c}=function(t){let e,i,s,n,o;return t.horizontal?(e=t.base>t.x,i=\"left\",s=\"right\"):(e=t.base<t.y,i=\"bottom\",s=\"top\"),e?(n=\"end\",o=\"start\"):(n=\"start\",o=\"end\"),{start:i,end:s,reverse:e,top:n,bottom:o}}(t);\"middle\"===n&&i&&(t.enableBorderRadius=!0,(i._top||0)===s?n=h:(i._bottom||0)===s?n=c:(o[On(c,a,r,l)]=!0,n=h)),o[On(n,a,r,l)]=!0,t.borderSkipped=o}function On(t,e,i,s){var n,o,a;return s?(a=i,t=Cn(t=(n=t)===(o=e)?a:n===a?o:n,i,e)):t=Cn(t,e,i),t}function Cn(t,e,i){return\"start\"===t?e:\"end\"===t?i:t}function An(t,{inflateAmount:e},i){t.inflateAmount=\"auto\"===e?1===i?.33:0:e}class Tn extends Ls{parsePrimitiveData(t,e,i,s){return Sn(t,e,i,s)}parseArrayData(t,e,i,s){return Sn(t,e,i,s)}parseObjectData(t,e,i,s){const{iScale:n,vScale:o}=t,{xAxisKey:a=\"x\",yAxisKey:r=\"y\"}=this._parsing,l=\"x\"===n.axis?a:r,h=\"x\"===o.axis?a:r,c=[];let d,u,f,g;for(d=i,u=i+s;d<u;++d)g=e[d],f={},f[n.axis]=n.parse(y(g,l),d),c.push(kn(y(g,h),f,o,d));return c}updateRangeFromParsed(t,e,i,s){super.updateRangeFromParsed(t,e,i,s);const n=i._custom;n&&e===this._cachedMeta.vScale&&(t.min=Math.min(t.min,n.min),t.max=Math.max(t.max,n.max))}getMaxOverflow(){return 0}getLabelAndValue(t){const e=this._cachedMeta,{iScale:i,vScale:s}=e,n=this.getParsed(t),o=n._custom,a=Pn(o)?\"[\"+o.start+\", \"+o.end+\"]\":\"\"+s.getLabelForValue(n[s.axis]);return{label:\"\"+i.getLabelForValue(n[i.axis]),value:a}}initialize(){this.enableOptionSharing=!0,super.initialize();this._cachedMeta.stack=this.getDataset().stack}update(t){const e=this._cachedMeta;this.updateElements(e.data,0,e.data.length,t)}updateElements(t,e,s,n){const o=\"reset\"===n,{index:a,_cachedMeta:{vScale:r}}=this,l=r.getBasePixel(),h=r.isHorizontal(),c=this._getRuler(),{sharedOptions:d,includeOptions:u}=this._getSharedOptions(e,n);for(let f=e;f<e+s;f++){const e=this.getParsed(f),s=o||i(e[r.axis])?{base:l,head:l}:this._calculateBarValuePixels(f),g=this._calculateBarIndexPixels(f,c),p=(e._stacks||{})[r.axis],m={horizontal:h,base:s.base,enableBorderRadius:!p||Pn(e._custom)||a===p._top||a===p._bottom,x:h?s.head:g.center,y:h?g.center:s.head,height:h?g.size:Math.abs(s.size),width:h?Math.abs(s.size):g.size};u&&(m.options=d||this.resolveDataElementOptions(f,t[f].active?\"active\":n));const b=m.options||t[f].options;Dn(m,b,p,a),An(m,b,c.ratio),this.updateElement(t[f],f,m,n)}}_getStacks(t,e){const{iScale:s}=this._cachedMeta,n=s.getMatchingVisibleMetas(this._type).filter((t=>t.controller.options.grouped)),o=s.options.stacked,a=[],r=t=>{const s=t.controller.getParsed(e),n=s&&s[t.vScale.axis];if(i(n)||isNaN(n))return!0};for(const i of n)if((void 0===e||!r(i))&&((!1===o||-1===a.indexOf(i.stack)||void 0===o&&void 0===i.stack)&&a.push(i.stack),i.index===t))break;return a.length||a.push(void 0),a}_getStackCount(t){return this._getStacks(void 0,t).length}_getStackIndex(t,e,i){const s=this._getStacks(t,i),n=void 0!==e?s.indexOf(e):-1;return-1===n?s.length-1:n}_getRuler(){const t=this.options,e=this._cachedMeta,i=e.iScale,s=[];let n,o;for(n=0,o=e.data.length;n<o;++n)s.push(i.getPixelForValue(this.getParsed(n)[i.axis],n));const a=t.barThickness;return{min:a||Mn(e),pixels:s,start:i._startPixel,end:i._endPixel,stackCount:this._getStackCount(),scale:i,grouped:t.grouped,ratio:a?1:t.categoryPercentage*t.barPercentage}}_calculateBarValuePixels(t){const{_cachedMeta:{vScale:e,_stacked:s},options:{base:n,minBarLength:o}}=this,a=n||0,r=this.getParsed(t),l=r._custom,h=Pn(l);let c,d,u=r[e.axis],f=0,g=s?this.applyStack(e,r,s):u;g!==u&&(f=g-u,g=u),h&&(u=l.barStart,g=l.barEnd-l.barStart,0!==u&&z(u)!==z(l.barEnd)&&(f=0),f+=u);const p=i(n)||h?f:n;let m=e.getPixelForValue(p);if(c=this.chart.getDataVisibility(t)?e.getPixelForValue(f+g):m,d=c-m,Math.abs(d)<o){d=function(t,e,i){return 0!==t?z(t):(e.isHorizontal()?1:-1)*(e.min>=i?1:-1)}(d,e,a)*o,u===a&&(m-=d/2);const t=e.getPixelForDecimal(0),i=e.getPixelForDecimal(1),s=Math.min(t,i),n=Math.max(t,i);m=Math.max(Math.min(m,n),s),c=m+d}if(m===e.getPixelForValue(a)){const t=z(d)*e.getLineWidthForValue(a)/2;m+=t,d-=t}return{size:d,base:m,head:c,center:c+d/2}}_calculateBarIndexPixels(t,e){const s=e.scale,n=this.options,o=n.skipNull,a=r(n.maxBarThickness,1/0);let l,h;if(e.grouped){const s=o?this._getStackCount(t):e.stackCount,r=\"flex\"===n.barThickness?function(t,e,i,s){const n=e.pixels,o=n[t];let a=t>0?n[t-1]:null,r=t<n.length-1?n[t+1]:null;const l=i.categoryPercentage;null===a&&(a=o-(null===r?e.end-e.start:r-o)),null===r&&(r=o+o-a);const h=o-(o-Math.min(a,r))/2*l;return{chunk:Math.abs(r-a)/2*l/s,ratio:i.barPercentage,start:h}}(t,e,n,s):function(t,e,s,n){const o=s.barThickness;let a,r;return i(o)?(a=e.min*s.categoryPercentage,r=s.barPercentage):(a=o*n,r=1),{chunk:a/n,ratio:r,start:e.pixels[t]-a/2}}(t,e,n,s),c=this._getStackIndex(this.index,this._cachedMeta.stack,o?t:void 0);l=r.start+r.chunk*c+r.chunk/2,h=Math.min(a,r.chunk*r.ratio)}else l=s.getPixelForValue(this.getParsed(t)[s.axis],t),h=Math.min(a,e.min*e.ratio);return{base:l-h/2,head:l+h/2,center:l,size:h}}draw(){const t=this._cachedMeta,e=t.vScale,i=t.data,s=i.length;let n=0;for(;n<s;++n)null!==this.getParsed(n)[e.axis]&&i[n].draw(this._ctx)}}Tn.id=\"bar\",Tn.defaults={datasetElementType:!1,dataElementType:\"bar\",categoryPercentage:.8,barPercentage:.9,grouped:!0,animations:{numbers:{type:\"number\",properties:[\"x\",\"y\",\"base\",\"width\",\"height\"]}}},Tn.overrides={scales:{_index_:{type:\"category\",offset:!0,grid:{offset:!0}},_value_:{type:\"linear\",beginAtZero:!0}}};class Ln extends Ls{initialize(){this.enableOptionSharing=!0,super.initialize()}parsePrimitiveData(t,e,i,s){const n=super.parsePrimitiveData(t,e,i,s);for(let t=0;t<n.length;t++)n[t]._custom=this.resolveDataElementOptions(t+i).radius;return n}parseArrayData(t,e,i,s){const n=super.parseArrayData(t,e,i,s);for(let t=0;t<n.length;t++){const s=e[i+t];n[t]._custom=r(s[2],this.resolveDataElementOptions(t+i).radius)}return n}parseObjectData(t,e,i,s){const n=super.parseObjectData(t,e,i,s);for(let t=0;t<n.length;t++){const s=e[i+t];n[t]._custom=r(s&&s.r&&+s.r,this.resolveDataElementOptions(t+i).radius)}return n}getMaxOverflow(){const t=this._cachedMeta.data;let e=0;for(let i=t.length-1;i>=0;--i)e=Math.max(e,t[i].size(this.resolveDataElementOptions(i))/2);return e>0&&e}getLabelAndValue(t){const e=this._cachedMeta,{xScale:i,yScale:s}=e,n=this.getParsed(t),o=i.getLabelForValue(n.x),a=s.getLabelForValue(n.y),r=n._custom;return{label:e.label,value:\"(\"+o+\", \"+a+(r?\", \"+r:\"\")+\")\"}}update(t){const e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}updateElements(t,e,i,s){const n=\"reset\"===s,{iScale:o,vScale:a}=this._cachedMeta,{sharedOptions:r,includeOptions:l}=this._getSharedOptions(e,s),h=o.axis,c=a.axis;for(let d=e;d<e+i;d++){const e=t[d],i=!n&&this.getParsed(d),u={},f=u[h]=n?o.getPixelForDecimal(.5):o.getPixelForValue(i[h]),g=u[c]=n?a.getBasePixel():a.getPixelForValue(i[c]);u.skip=isNaN(f)||isNaN(g),l&&(u.options=r||this.resolveDataElementOptions(d,e.active?\"active\":s),n&&(u.options.radius=0)),this.updateElement(e,d,u,s)}}resolveDataElementOptions(t,e){const i=this.getParsed(t);let s=super.resolveDataElementOptions(t,e);s.$shared&&(s=Object.assign({},s,{$shared:!1}));const n=s.radius;return\"active\"!==e&&(s.radius=0),s.radius+=r(i&&i._custom,n),s}}Ln.id=\"bubble\",Ln.defaults={datasetElementType:!1,dataElementType:\"point\",animations:{numbers:{type:\"number\",properties:[\"x\",\"y\",\"borderWidth\",\"radius\"]}}},Ln.overrides={scales:{x:{type:\"linear\"},y:{type:\"linear\"}},plugins:{tooltip:{callbacks:{title:()=>\"\"}}}};class En extends Ls{constructor(t,e){super(t,e),this.enableOptionSharing=!0,this.innerRadius=void 0,this.outerRadius=void 0,this.offsetX=void 0,this.offsetY=void 0}linkScales(){}parse(t,e){const i=this.getDataset().data,s=this._cachedMeta;if(!1===this._parsing)s._parsed=i;else{let o,a,r=t=>+i[t];if(n(i[t])){const{key:t=\"value\"}=this._parsing;r=e=>+y(i[e],t)}for(o=t,a=t+e;o<a;++o)s._parsed[o]=r(o)}}_getRotation(){return H(this.options.rotation-90)}_getCircumference(){return H(this.options.circumference)}_getRotationExtents(){let t=O,e=-O;for(let i=0;i<this.chart.data.datasets.length;++i)if(this.chart.isDatasetVisible(i)){const s=this.chart.getDatasetMeta(i).controller,n=s._getRotation(),o=s._getCircumference();t=Math.min(t,n),e=Math.max(e,n+o)}return{rotation:t,circumference:e-t}}update(t){const e=this.chart,{chartArea:i}=e,s=this._cachedMeta,n=s.data,o=this.getMaxBorderWidth()+this.getMaxOffset(n)+this.options.spacing,a=Math.max((Math.min(i.width,i.height)-o)/2,0),r=Math.min(l(this.options.cutout,a),1),c=this._getRingWeight(this.index),{circumference:d,rotation:u}=this._getRotationExtents(),{ratioX:f,ratioY:g,offsetX:p,offsetY:m}=function(t,e,i){let s=1,n=1,o=0,a=0;if(e<O){const r=t,l=r+e,h=Math.cos(r),c=Math.sin(r),d=Math.cos(l),u=Math.sin(l),f=(t,e,s)=>G(t,r,l,!0)?1:Math.max(e,e*i,s,s*i),g=(t,e,s)=>G(t,r,l,!0)?-1:Math.min(e,e*i,s,s*i),p=f(0,h,d),m=f(L,c,u),b=g(D,h,d),x=g(D+L,c,u);s=(p-b)/2,n=(m-x)/2,o=-(p+b)/2,a=-(m+x)/2}return{ratioX:s,ratioY:n,offsetX:o,offsetY:a}}(u,d,r),b=(i.width-o)/f,x=(i.height-o)/g,_=Math.max(Math.min(b,x)/2,0),y=h(this.options.radius,_),v=(y-Math.max(y*r,0))/this._getVisibleDatasetWeightTotal();this.offsetX=p*y,this.offsetY=m*y,s.total=this.calculateTotal(),this.outerRadius=y-v*this._getRingWeightOffset(this.index),this.innerRadius=Math.max(this.outerRadius-v*c,0),this.updateElements(n,0,n.length,t)}_circumference(t,e){const i=this.options,s=this._cachedMeta,n=this._getCircumference();return e&&i.animation.animateRotate||!this.chart.getDataVisibility(t)||null===s._parsed[t]||s.data[t].hidden?0:this.calculateCircumference(s._parsed[t]*n/O)}updateElements(t,e,i,s){const n=\"reset\"===s,o=this.chart,a=o.chartArea,r=o.options.animation,l=(a.left+a.right)/2,h=(a.top+a.bottom)/2,c=n&&r.animateScale,d=c?0:this.innerRadius,u=c?0:this.outerRadius,{sharedOptions:f,includeOptions:g}=this._getSharedOptions(e,s);let p,m=this._getRotation();for(p=0;p<e;++p)m+=this._circumference(p,n);for(p=e;p<e+i;++p){const e=this._circumference(p,n),i=t[p],o={x:l+this.offsetX,y:h+this.offsetY,startAngle:m,endAngle:m+e,circumference:e,outerRadius:u,innerRadius:d};g&&(o.options=f||this.resolveDataElementOptions(p,i.active?\"active\":s)),m+=e,this.updateElement(i,p,o,s)}}calculateTotal(){const t=this._cachedMeta,e=t.data;let i,s=0;for(i=0;i<e.length;i++){const n=t._parsed[i];null===n||isNaN(n)||!this.chart.getDataVisibility(i)||e[i].hidden||(s+=Math.abs(n))}return s}calculateCircumference(t){const e=this._cachedMeta.total;return e>0&&!isNaN(t)?O*(Math.abs(t)/e):0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=li(e._parsed[t],i.options.locale);return{label:s[t]||\"\",value:n}}getMaxBorderWidth(t){let e=0;const i=this.chart;let s,n,o,a,r;if(!t)for(s=0,n=i.data.datasets.length;s<n;++s)if(i.isDatasetVisible(s)){o=i.getDatasetMeta(s),t=o.data,a=o.controller;break}if(!t)return 0;for(s=0,n=t.length;s<n;++s)r=a.resolveDataElementOptions(s),\"inner\"!==r.borderAlign&&(e=Math.max(e,r.borderWidth||0,r.hoverBorderWidth||0));return e}getMaxOffset(t){let e=0;for(let i=0,s=t.length;i<s;++i){const t=this.resolveDataElementOptions(i);e=Math.max(e,t.offset||0,t.hoverOffset||0)}return e}_getRingWeightOffset(t){let e=0;for(let i=0;i<t;++i)this.chart.isDatasetVisible(i)&&(e+=this._getRingWeight(i));return e}_getRingWeight(t){return Math.max(r(this.chart.data.datasets[t].weight,1),0)}_getVisibleDatasetWeightTotal(){return this._getRingWeightOffset(this.chart.data.datasets.length)||1}}En.id=\"doughnut\",En.defaults={datasetElementType:!1,dataElementType:\"arc\",animation:{animateRotate:!0,animateScale:!1},animations:{numbers:{type:\"number\",properties:[\"circumference\",\"endAngle\",\"innerRadius\",\"outerRadius\",\"startAngle\",\"x\",\"y\",\"offset\",\"borderWidth\",\"spacing\"]}},cutout:\"50%\",rotation:0,circumference:360,radius:\"100%\",spacing:0,indexAxis:\"r\"},En.descriptors={_scriptable:t=>\"spacing\"!==t,_indexable:t=>\"spacing\"!==t},En.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>\"\",label(t){let e=t.label;const i=\": \"+t.formattedValue;return s(e)?(e=e.slice(),e[0]+=i):e+=i,e}}}}};class Rn extends Ls{initialize(){this.enableOptionSharing=!0,this.supportsDecimation=!0,super.initialize()}update(t){const e=this._cachedMeta,{dataset:i,data:s=[],_dataset:n}=e,o=this.chart._animationsDisabled;let{start:a,count:r}=gt(e,s,o);this._drawStart=a,this._drawCount=r,pt(e)&&(a=0,r=s.length),i._chart=this.chart,i._datasetIndex=this.index,i._decimated=!!n._decimated,i.points=s;const l=this.resolveDatasetElementOptions(t);this.options.showLine||(l.borderWidth=0),l.segment=this.options.segment,this.updateElement(i,void 0,{animated:!o,options:l},t),this.updateElements(s,a,r,t)}updateElements(t,e,s,n){const o=\"reset\"===n,{iScale:a,vScale:r,_stacked:l,_dataset:h}=this._cachedMeta,{sharedOptions:c,includeOptions:d}=this._getSharedOptions(e,n),u=a.axis,f=r.axis,{spanGaps:g,segment:p}=this.options,m=B(g)?g:Number.POSITIVE_INFINITY,b=this.chart._animationsDisabled||o||\"none\"===n;let x=e>0&&this.getParsed(e-1);for(let g=e;g<e+s;++g){const e=t[g],s=this.getParsed(g),_=b?e:{},y=i(s[f]),v=_[u]=a.getPixelForValue(s[u],g),w=_[f]=o||y?r.getBasePixel():r.getPixelForValue(l?this.applyStack(r,s,l):s[f],g);_.skip=isNaN(v)||isNaN(w)||y,_.stop=g>0&&Math.abs(s[u]-x[u])>m,p&&(_.parsed=s,_.raw=h.data[g]),d&&(_.options=c||this.resolveDataElementOptions(g,e.active?\"active\":n)),b||this.updateElement(e,g,_,n),x=s}}getMaxOverflow(){const t=this._cachedMeta,e=t.dataset,i=e.options&&e.options.borderWidth||0,s=t.data||[];if(!s.length)return i;const n=s[0].size(this.resolveDataElementOptions(0)),o=s[s.length-1].size(this.resolveDataElementOptions(s.length-1));return Math.max(i,n,o)/2}draw(){const t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),super.draw()}}Rn.id=\"line\",Rn.defaults={datasetElementType:\"line\",dataElementType:\"point\",showLine:!0,spanGaps:!1},Rn.overrides={scales:{_index_:{type:\"category\"},_value_:{type:\"linear\"}}};class In extends Ls{constructor(t,e){super(t,e),this.innerRadius=void 0,this.outerRadius=void 0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=li(e._parsed[t].r,i.options.locale);return{label:s[t]||\"\",value:n}}parseObjectData(t,e,i,s){return Ue.bind(this)(t,e,i,s)}update(t){const e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}getMinMax(){const t=this._cachedMeta,e={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY};return t.data.forEach(((t,i)=>{const s=this.getParsed(i).r;!isNaN(s)&&this.chart.getDataVisibility(i)&&(s<e.min&&(e.min=s),s>e.max&&(e.max=s))})),e}_updateRadius(){const t=this.chart,e=t.chartArea,i=t.options,s=Math.min(e.right-e.left,e.bottom-e.top),n=Math.max(s/2,0),o=(n-Math.max(i.cutoutPercentage?n/100*i.cutoutPercentage:1,0))/t.getVisibleDatasetCount();this.outerRadius=n-o*this.index,this.innerRadius=this.outerRadius-o}updateElements(t,e,i,s){const n=\"reset\"===s,o=this.chart,a=o.options.animation,r=this._cachedMeta.rScale,l=r.xCenter,h=r.yCenter,c=r.getIndexAngle(0)-.5*D;let d,u=c;const f=360/this.countVisibleElements();for(d=0;d<e;++d)u+=this._computeAngle(d,s,f);for(d=e;d<e+i;d++){const e=t[d];let i=u,g=u+this._computeAngle(d,s,f),p=o.getDataVisibility(d)?r.getDistanceFromCenterForValue(this.getParsed(d).r):0;u=g,n&&(a.animateScale&&(p=0),a.animateRotate&&(i=g=c));const m={x:l,y:h,innerRadius:0,outerRadius:p,startAngle:i,endAngle:g,options:this.resolveDataElementOptions(d,e.active?\"active\":s)};this.updateElement(e,d,m,s)}}countVisibleElements(){const t=this._cachedMeta;let e=0;return t.data.forEach(((t,i)=>{!isNaN(this.getParsed(i).r)&&this.chart.getDataVisibility(i)&&e++})),e}_computeAngle(t,e,i){return this.chart.getDataVisibility(t)?H(this.resolveDataElementOptions(t,e).angle||i):0}}In.id=\"polarArea\",In.defaults={dataElementType:\"arc\",animation:{animateRotate:!0,animateScale:!0},animations:{numbers:{type:\"number\",properties:[\"x\",\"y\",\"startAngle\",\"endAngle\",\"innerRadius\",\"outerRadius\"]}},indexAxis:\"r\",startAngle:0},In.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>\"\",label:t=>t.chart.data.labels[t.dataIndex]+\": \"+t.formattedValue}}},scales:{r:{type:\"radialLinear\",angleLines:{display:!1},beginAtZero:!0,grid:{circular:!0},pointLabels:{display:!1},startAngle:0}}};class zn extends En{}zn.id=\"pie\",zn.defaults={cutout:0,rotation:0,circumference:360,radius:\"100%\"};class Fn extends Ls{getLabelAndValue(t){const e=this._cachedMeta.vScale,i=this.getParsed(t);return{label:e.getLabels()[t],value:\"\"+e.getLabelForValue(i[e.axis])}}parseObjectData(t,e,i,s){return Ue.bind(this)(t,e,i,s)}update(t){const e=this._cachedMeta,i=e.dataset,s=e.data||[],n=e.iScale.getLabels();if(i.points=s,\"resize\"!==t){const e=this.resolveDatasetElementOptions(t);this.options.showLine||(e.borderWidth=0);const o={_loop:!0,_fullLoop:n.length===s.length,options:e};this.updateElement(i,void 0,o,t)}this.updateElements(s,0,s.length,t)}updateElements(t,e,i,s){const n=this._cachedMeta.rScale,o=\"reset\"===s;for(let a=e;a<e+i;a++){const e=t[a],i=this.resolveDataElementOptions(a,e.active?\"active\":s),r=n.getPointPositionForValue(a,this.getParsed(a).r),l=o?n.xCenter:r.x,h=o?n.yCenter:r.y,c={x:l,y:h,angle:r.angle,skip:isNaN(l)||isNaN(h),options:i};this.updateElement(e,a,c,s)}}}Fn.id=\"radar\",Fn.defaults={datasetElementType:\"line\",dataElementType:\"point\",indexAxis:\"r\",showLine:!0,elements:{line:{fill:\"start\"}}},Fn.overrides={aspectRatio:1,scales:{r:{type:\"radialLinear\"}}};class Vn extends Ls{update(t){const e=this._cachedMeta,{data:i=[]}=e,s=this.chart._animationsDisabled;let{start:n,count:o}=gt(e,i,s);if(this._drawStart=n,this._drawCount=o,pt(e)&&(n=0,o=i.length),this.options.showLine){const{dataset:n,_dataset:o}=e;n._chart=this.chart,n._datasetIndex=this.index,n._decimated=!!o._decimated,n.points=i;const a=this.resolveDatasetElementOptions(t);a.segment=this.options.segment,this.updateElement(n,void 0,{animated:!s,options:a},t)}this.updateElements(i,n,o,t)}addElements(){const{showLine:t}=this.options;!this.datasetElementType&&t&&(this.datasetElementType=Us.getElement(\"line\")),super.addElements()}updateElements(t,e,s,n){const o=\"reset\"===n,{iScale:a,vScale:r,_stacked:l,_dataset:h}=this._cachedMeta,c=this.resolveDataElementOptions(e,n),d=this.getSharedOptions(c),u=this.includeOptions(n,d),f=a.axis,g=r.axis,{spanGaps:p,segment:m}=this.options,b=B(p)?p:Number.POSITIVE_INFINITY,x=this.chart._animationsDisabled||o||\"none\"===n;let _=e>0&&this.getParsed(e-1);for(let c=e;c<e+s;++c){const e=t[c],s=this.getParsed(c),p=x?e:{},y=i(s[g]),v=p[f]=a.getPixelForValue(s[f],c),w=p[g]=o||y?r.getBasePixel():r.getPixelForValue(l?this.applyStack(r,s,l):s[g],c);p.skip=isNaN(v)||isNaN(w)||y,p.stop=c>0&&Math.abs(s[f]-_[f])>b,m&&(p.parsed=s,p.raw=h.data[c]),u&&(p.options=d||this.resolveDataElementOptions(c,e.active?\"active\":n)),x||this.updateElement(e,c,p,n),_=s}this.updateSharedOptions(d,n,c)}getMaxOverflow(){const t=this._cachedMeta,e=t.data||[];if(!this.options.showLine){let t=0;for(let i=e.length-1;i>=0;--i)t=Math.max(t,e[i].size(this.resolveDataElementOptions(i))/2);return t>0&&t}const i=t.dataset,s=i.options&&i.options.borderWidth||0;if(!e.length)return s;const n=e[0].size(this.resolveDataElementOptions(0)),o=e[e.length-1].size(this.resolveDataElementOptions(e.length-1));return Math.max(s,n,o)/2}}Vn.id=\"scatter\",Vn.defaults={datasetElementType:!1,dataElementType:\"point\",showLine:!1,fill:!1},Vn.overrides={interaction:{mode:\"point\"},plugins:{tooltip:{callbacks:{title:()=>\"\",label:t=>\"(\"+t.label+\", \"+t.formattedValue+\")\"}}},scales:{x:{type:\"linear\"},y:{type:\"linear\"}}};var Bn=Object.freeze({__proto__:null,BarController:Tn,BubbleController:Ln,DoughnutController:En,LineController:Rn,PolarAreaController:In,PieController:zn,RadarController:Fn,ScatterController:Vn});function Nn(t,e,i){const{startAngle:s,pixelMargin:n,x:o,y:a,outerRadius:r,innerRadius:l}=e;let h=n/r;t.beginPath(),t.arc(o,a,r,s-h,i+h),l>n?(h=n/l,t.arc(o,a,l,i+h,s-h,!0)):t.arc(o,a,n,i+L,s-L),t.closePath(),t.clip()}function Wn(t,e,i,s){const n=ui(t.options.borderRadius,[\"outerStart\",\"outerEnd\",\"innerStart\",\"innerEnd\"]);const o=(i-e)/2,a=Math.min(o,s*e/2),r=t=>{const e=(i-Math.min(o,t))*s/2;return Z(t,0,Math.min(o,e))};return{outerStart:r(n.outerStart),outerEnd:r(n.outerEnd),innerStart:Z(n.innerStart,0,a),innerEnd:Z(n.innerEnd,0,a)}}function jn(t,e,i,s){return{x:i+t*Math.cos(e),y:s+t*Math.sin(e)}}function Hn(t,e,i,s,n,o){const{x:a,y:r,startAngle:l,pixelMargin:h,innerRadius:c}=e,d=Math.max(e.outerRadius+s+i-h,0),u=c>0?c+s+i+h:0;let f=0;const g=n-l;if(s){const t=((c>0?c-s:0)+(d>0?d-s:0))/2;f=(g-(0!==t?g*t/(t+s):g))/2}const p=(g-Math.max(.001,g*d-i/D)/d)/2,m=l+p+f,b=n-p-f,{outerStart:x,outerEnd:_,innerStart:y,innerEnd:v}=Wn(e,u,d,b-m),w=d-x,M=d-_,k=m+x/w,S=b-_/M,P=u+y,O=u+v,C=m+y/P,A=b-v/O;if(t.beginPath(),o){if(t.arc(a,r,d,k,S),_>0){const e=jn(M,S,a,r);t.arc(e.x,e.y,_,S,b+L)}const e=jn(O,b,a,r);if(t.lineTo(e.x,e.y),v>0){const e=jn(O,A,a,r);t.arc(e.x,e.y,v,b+L,A+Math.PI)}if(t.arc(a,r,u,b-v/u,m+y/u,!0),y>0){const e=jn(P,C,a,r);t.arc(e.x,e.y,y,C+Math.PI,m-L)}const i=jn(w,m,a,r);if(t.lineTo(i.x,i.y),x>0){const e=jn(w,k,a,r);t.arc(e.x,e.y,x,m-L,k)}}else{t.moveTo(a,r);const e=Math.cos(k)*d+a,i=Math.sin(k)*d+r;t.lineTo(e,i);const s=Math.cos(S)*d+a,n=Math.sin(S)*d+r;t.lineTo(s,n)}t.closePath()}function $n(t,e,i,s,n,o){const{options:a}=e,{borderWidth:r,borderJoinStyle:l}=a,h=\"inner\"===a.borderAlign;r&&(h?(t.lineWidth=2*r,t.lineJoin=l||\"round\"):(t.lineWidth=r,t.lineJoin=l||\"bevel\"),e.fullCircles&&function(t,e,i){const{x:s,y:n,startAngle:o,pixelMargin:a,fullCircles:r}=e,l=Math.max(e.outerRadius-a,0),h=e.innerRadius+a;let c;for(i&&Nn(t,e,o+O),t.beginPath(),t.arc(s,n,h,o+O,o,!0),c=0;c<r;++c)t.stroke();for(t.beginPath(),t.arc(s,n,l,o,o+O),c=0;c<r;++c)t.stroke()}(t,e,h),h&&Nn(t,e,n),Hn(t,e,i,s,n,o),t.stroke())}class Yn extends Es{constructor(t){super(),this.options=void 0,this.circumference=void 0,this.startAngle=void 0,this.endAngle=void 0,this.innerRadius=void 0,this.outerRadius=void 0,this.pixelMargin=0,this.fullCircles=0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.getProps([\"x\",\"y\"],i),{angle:n,distance:o}=U(s,{x:t,y:e}),{startAngle:a,endAngle:l,innerRadius:h,outerRadius:c,circumference:d}=this.getProps([\"startAngle\",\"endAngle\",\"innerRadius\",\"outerRadius\",\"circumference\"],i),u=this.options.spacing/2,f=r(d,l-a)>=O||G(n,a,l),g=Q(o,h+u,c+u);return f&&g}getCenterPoint(t){const{x:e,y:i,startAngle:s,endAngle:n,innerRadius:o,outerRadius:a}=this.getProps([\"x\",\"y\",\"startAngle\",\"endAngle\",\"innerRadius\",\"outerRadius\",\"circumference\"],t),{offset:r,spacing:l}=this.options,h=(s+n)/2,c=(o+a+l+r)/2;return{x:e+Math.cos(h)*c,y:i+Math.sin(h)*c}}tooltipPosition(t){return this.getCenterPoint(t)}draw(t){const{options:e,circumference:i}=this,s=(e.offset||0)/2,n=(e.spacing||0)/2,o=e.circular;if(this.pixelMargin=\"inner\"===e.borderAlign?.33:0,this.fullCircles=i>O?Math.floor(i/O):0,0===i||this.innerRadius<0||this.outerRadius<0)return;t.save();let a=0;if(s){a=s/2;const e=(this.startAngle+this.endAngle)/2;t.translate(Math.cos(e)*a,Math.sin(e)*a),this.circumference>=D&&(a=s)}t.fillStyle=e.backgroundColor,t.strokeStyle=e.borderColor;const r=function(t,e,i,s,n){const{fullCircles:o,startAngle:a,circumference:r}=e;let l=e.endAngle;if(o){Hn(t,e,i,s,a+O,n);for(let e=0;e<o;++e)t.fill();isNaN(r)||(l=a+r%O,r%O==0&&(l+=O))}return Hn(t,e,i,s,l,n),t.fill(),l}(t,this,a,n,o);$n(t,this,a,n,r,o),t.restore()}}function Un(t,e,i=e){t.lineCap=r(i.borderCapStyle,e.borderCapStyle),t.setLineDash(r(i.borderDash,e.borderDash)),t.lineDashOffset=r(i.borderDashOffset,e.borderDashOffset),t.lineJoin=r(i.borderJoinStyle,e.borderJoinStyle),t.lineWidth=r(i.borderWidth,e.borderWidth),t.strokeStyle=r(i.borderColor,e.borderColor)}function Xn(t,e,i){t.lineTo(i.x,i.y)}function qn(t,e,i={}){const s=t.length,{start:n=0,end:o=s-1}=i,{start:a,end:r}=e,l=Math.max(n,a),h=Math.min(o,r),c=n<a&&o<a||n>r&&o>r;return{count:s,start:l,loop:e.loop,ilen:h<l&&!c?s+h-l:h-l}}function Kn(t,e,i,s){const{points:n,options:o}=e,{count:a,start:r,loop:l,ilen:h}=qn(n,i,s),c=function(t){return t.stepped?Oe:t.tension||\"monotone\"===t.cubicInterpolationMode?Ce:Xn}(o);let d,u,f,{move:g=!0,reverse:p}=s||{};for(d=0;d<=h;++d)u=n[(r+(p?h-d:d))%a],u.skip||(g?(t.moveTo(u.x,u.y),g=!1):c(t,f,u,p,o.stepped),f=u);return l&&(u=n[(r+(p?h:0))%a],c(t,f,u,p,o.stepped)),!!l}function Gn(t,e,i,s){const n=e.points,{count:o,start:a,ilen:r}=qn(n,i,s),{move:l=!0,reverse:h}=s||{};let c,d,u,f,g,p,m=0,b=0;const x=t=>(a+(h?r-t:t))%o,_=()=>{f!==g&&(t.lineTo(m,g),t.lineTo(m,f),t.lineTo(m,p))};for(l&&(d=n[x(0)],t.moveTo(d.x,d.y)),c=0;c<=r;++c){if(d=n[x(c)],d.skip)continue;const e=d.x,i=d.y,s=0|e;s===u?(i<f?f=i:i>g&&(g=i),m=(b*m+e)/++b):(_(),t.lineTo(e,i),u=s,b=0,f=g=i),p=i}_()}function Zn(t){const e=t.options,i=e.borderDash&&e.borderDash.length;return!(t._decimated||t._loop||e.tension||\"monotone\"===e.cubicInterpolationMode||e.stepped||i)?Gn:Kn}Yn.id=\"arc\",Yn.defaults={borderAlign:\"center\",borderColor:\"#fff\",borderJoinStyle:void 0,borderRadius:0,borderWidth:2,offset:0,spacing:0,angle:void 0,circular:!0},Yn.defaultRoutes={backgroundColor:\"backgroundColor\"};const Jn=\"function\"==typeof Path2D;function Qn(t,e,i,s){Jn&&!e.options.segment?function(t,e,i,s){let n=e._path;n||(n=e._path=new Path2D,e.path(n,i,s)&&n.closePath()),Un(t,e.options),t.stroke(n)}(t,e,i,s):function(t,e,i,s){const{segments:n,options:o}=e,a=Zn(e);for(const r of n)Un(t,o,r.style),t.beginPath(),a(t,e,r,{start:i,end:i+s-1})&&t.closePath(),t.stroke()}(t,e,i,s)}class to extends Es{constructor(t){super(),this.animated=!0,this.options=void 0,this._chart=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,this._datasetIndex=void 0,t&&Object.assign(this,t)}updateControlPoints(t,e){const i=this.options;if((i.tension||\"monotone\"===i.cubicInterpolationMode)&&!i.stepped&&!this._pointsUpdated){const s=i.spanGaps?this._loop:this._fullLoop;Qe(this._points,i,t,s,e),this._pointsUpdated=!0}}set points(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||(this._segments=Di(this,this.options.segment))}first(){const t=this.segments,e=this.points;return t.length&&e[t[0].start]}last(){const t=this.segments,e=this.points,i=t.length;return i&&e[t[i-1].end]}interpolate(t,e){const i=this.options,s=t[e],n=this.points,o=Pi(this,{property:e,start:s,end:s});if(!o.length)return;const a=[],r=function(t){return t.stepped?oi:t.tension||\"monotone\"===t.cubicInterpolationMode?ai:ni}(i);let l,h;for(l=0,h=o.length;l<h;++l){const{start:h,end:c}=o[l],d=n[h],u=n[c];if(d===u){a.push(d);continue}const f=r(d,u,Math.abs((s-d[e])/(u[e]-d[e])),i.stepped);f[e]=t[e],a.push(f)}return 1===a.length?a[0]:a}pathSegment(t,e,i){return Zn(this)(t,this,e,i)}path(t,e,i){const s=this.segments,n=Zn(this);let o=this._loop;e=e||0,i=i||this.points.length-e;for(const a of s)o&=n(t,this,a,{start:e,end:e+i-1});return!!o}draw(t,e,i,s){const n=this.options||{};(this.points||[]).length&&n.borderWidth&&(t.save(),Qn(t,this,i,s),t.restore()),this.animated&&(this._pointsUpdated=!1,this._path=void 0)}}function eo(t,e,i,s){const n=t.options,{[i]:o}=t.getProps([i],s);return Math.abs(e-o)<n.radius+n.hitRadius}to.id=\"line\",to.defaults={borderCapStyle:\"butt\",borderDash:[],borderDashOffset:0,borderJoinStyle:\"miter\",borderWidth:3,capBezierPoints:!0,cubicInterpolationMode:\"default\",fill:!1,spanGaps:!1,stepped:!1,tension:0},to.defaultRoutes={backgroundColor:\"backgroundColor\",borderColor:\"borderColor\"},to.descriptors={_scriptable:!0,_indexable:t=>\"borderDash\"!==t&&\"fill\"!==t};class io extends Es{constructor(t){super(),this.options=void 0,this.parsed=void 0,this.skip=void 0,this.stop=void 0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.options,{x:n,y:o}=this.getProps([\"x\",\"y\"],i);return Math.pow(t-n,2)+Math.pow(e-o,2)<Math.pow(s.hitRadius+s.radius,2)}inXRange(t,e){return eo(this,t,\"x\",e)}inYRange(t,e){return eo(this,t,\"y\",e)}getCenterPoint(t){const{x:e,y:i}=this.getProps([\"x\",\"y\"],t);return{x:e,y:i}}size(t){let e=(t=t||this.options||{}).radius||0;e=Math.max(e,e&&t.hoverRadius||0);return 2*(e+(e&&t.borderWidth||0))}draw(t,e){const i=this.options;this.skip||i.radius<.1||!Se(this,e,this.size(i)/2)||(t.strokeStyle=i.borderColor,t.lineWidth=i.borderWidth,t.fillStyle=i.backgroundColor,Me(t,i,this.x,this.y))}getRange(){const t=this.options||{};return t.radius+t.hitRadius}}function so(t,e){const{x:i,y:s,base:n,width:o,height:a}=t.getProps([\"x\",\"y\",\"base\",\"width\",\"height\"],e);let r,l,h,c,d;return t.horizontal?(d=a/2,r=Math.min(i,n),l=Math.max(i,n),h=s-d,c=s+d):(d=o/2,r=i-d,l=i+d,h=Math.min(s,n),c=Math.max(s,n)),{left:r,top:h,right:l,bottom:c}}function no(t,e,i,s){return t?0:Z(e,i,s)}function oo(t){const e=so(t),i=e.right-e.left,s=e.bottom-e.top,o=function(t,e,i){const s=t.options.borderWidth,n=t.borderSkipped,o=fi(s);return{t:no(n.top,o.top,0,i),r:no(n.right,o.right,0,e),b:no(n.bottom,o.bottom,0,i),l:no(n.left,o.left,0,e)}}(t,i/2,s/2),a=function(t,e,i){const{enableBorderRadius:s}=t.getProps([\"enableBorderRadius\"]),o=t.options.borderRadius,a=gi(o),r=Math.min(e,i),l=t.borderSkipped,h=s||n(o);return{topLeft:no(!h||l.top||l.left,a.topLeft,0,r),topRight:no(!h||l.top||l.right,a.topRight,0,r),bottomLeft:no(!h||l.bottom||l.left,a.bottomLeft,0,r),bottomRight:no(!h||l.bottom||l.right,a.bottomRight,0,r)}}(t,i/2,s/2);return{outer:{x:e.left,y:e.top,w:i,h:s,radius:a},inner:{x:e.left+o.l,y:e.top+o.t,w:i-o.l-o.r,h:s-o.t-o.b,radius:{topLeft:Math.max(0,a.topLeft-Math.max(o.t,o.l)),topRight:Math.max(0,a.topRight-Math.max(o.t,o.r)),bottomLeft:Math.max(0,a.bottomLeft-Math.max(o.b,o.l)),bottomRight:Math.max(0,a.bottomRight-Math.max(o.b,o.r))}}}}function ao(t,e,i,s){const n=null===e,o=null===i,a=t&&!(n&&o)&&so(t,s);return a&&(n||Q(e,a.left,a.right))&&(o||Q(i,a.top,a.bottom))}function ro(t,e){t.rect(e.x,e.y,e.w,e.h)}function lo(t,e,i={}){const s=t.x!==i.x?-e:0,n=t.y!==i.y?-e:0,o=(t.x+t.w!==i.x+i.w?e:0)-s,a=(t.y+t.h!==i.y+i.h?e:0)-n;return{x:t.x+s,y:t.y+n,w:t.w+o,h:t.h+a,radius:t.radius}}io.id=\"point\",io.defaults={borderWidth:1,hitRadius:1,hoverBorderWidth:1,hoverRadius:4,pointStyle:\"circle\",radius:3,rotation:0},io.defaultRoutes={backgroundColor:\"backgroundColor\",borderColor:\"borderColor\"};class ho extends Es{constructor(t){super(),this.options=void 0,this.horizontal=void 0,this.base=void 0,this.width=void 0,this.height=void 0,this.inflateAmount=void 0,t&&Object.assign(this,t)}draw(t){const{inflateAmount:e,options:{borderColor:i,backgroundColor:s}}=this,{inner:n,outer:o}=oo(this),a=(r=o.radius).topLeft||r.topRight||r.bottomLeft||r.bottomRight?Le:ro;var r;t.save(),o.w===n.w&&o.h===n.h||(t.beginPath(),a(t,lo(o,e,n)),t.clip(),a(t,lo(n,-e,o)),t.fillStyle=i,t.fill(\"evenodd\")),t.beginPath(),a(t,lo(n,e)),t.fillStyle=s,t.fill(),t.restore()}inRange(t,e,i){return ao(this,t,e,i)}inXRange(t,e){return ao(this,t,null,e)}inYRange(t,e){return ao(this,null,t,e)}getCenterPoint(t){const{x:e,y:i,base:s,horizontal:n}=this.getProps([\"x\",\"y\",\"base\",\"horizontal\"],t);return{x:n?(e+s)/2:e,y:n?i:(i+s)/2}}getRange(t){return\"x\"===t?this.width/2:this.height/2}}ho.id=\"bar\",ho.defaults={borderSkipped:\"start\",borderWidth:0,borderRadius:0,inflateAmount:\"auto\",pointStyle:void 0},ho.defaultRoutes={backgroundColor:\"backgroundColor\",borderColor:\"borderColor\"};var co=Object.freeze({__proto__:null,ArcElement:Yn,LineElement:to,PointElement:io,BarElement:ho});function uo(t){if(t._decimated){const e=t._data;delete t._decimated,delete t._data,Object.defineProperty(t,\"data\",{value:e})}}function fo(t){t.data.datasets.forEach((t=>{uo(t)}))}var go={id:\"decimation\",defaults:{algorithm:\"min-max\",enabled:!1},beforeElementsUpdate:(t,e,s)=>{if(!s.enabled)return void fo(t);const n=t.width;t.data.datasets.forEach(((e,o)=>{const{_data:a,indexAxis:r}=e,l=t.getDatasetMeta(o),h=a||e.data;if(\"y\"===bi([r,t.options.indexAxis]))return;if(!l.controller.supportsDecimation)return;const c=t.scales[l.xAxisID];if(\"linear\"!==c.type&&\"time\"!==c.type)return;if(t.options.parsing)return;let{start:d,count:u}=function(t,e){const i=e.length;let s,n=0;const{iScale:o}=t,{min:a,max:r,minDefined:l,maxDefined:h}=o.getUserBounds();return l&&(n=Z(et(e,o.axis,a).lo,0,i-1)),s=h?Z(et(e,o.axis,r).hi+1,n,i)-n:i-n,{start:n,count:s}}(l,h);if(u<=(s.threshold||4*n))return void uo(e);let f;switch(i(a)&&(e._data=h,delete e.data,Object.defineProperty(e,\"data\",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(t){this._data=t}})),s.algorithm){case\"lttb\":f=function(t,e,i,s,n){const o=n.samples||s;if(o>=i)return t.slice(e,e+i);const a=[],r=(i-2)/(o-2);let l=0;const h=e+i-1;let c,d,u,f,g,p=e;for(a[l++]=t[p],c=0;c<o-2;c++){let s,n=0,o=0;const h=Math.floor((c+1)*r)+1+e,m=Math.min(Math.floor((c+2)*r)+1,i)+e,b=m-h;for(s=h;s<m;s++)n+=t[s].x,o+=t[s].y;n/=b,o/=b;const x=Math.floor(c*r)+1+e,_=Math.min(Math.floor((c+1)*r)+1,i)+e,{x:y,y:v}=t[p];for(u=f=-1,s=x;s<_;s++)f=.5*Math.abs((y-n)*(t[s].y-v)-(y-t[s].x)*(o-v)),f>u&&(u=f,d=t[s],g=s);a[l++]=d,p=g}return a[l++]=t[h],a}(h,d,u,n,s);break;case\"min-max\":f=function(t,e,s,n){let o,a,r,l,h,c,d,u,f,g,p=0,m=0;const b=[],x=e+s-1,_=t[e].x,y=t[x].x-_;for(o=e;o<e+s;++o){a=t[o],r=(a.x-_)/y*n,l=a.y;const e=0|r;if(e===h)l<f?(f=l,c=o):l>g&&(g=l,d=o),p=(m*p+a.x)/++m;else{const s=o-1;if(!i(c)&&!i(d)){const e=Math.min(c,d),i=Math.max(c,d);e!==u&&e!==s&&b.push({...t[e],x:p}),i!==u&&i!==s&&b.push({...t[i],x:p})}o>0&&s!==u&&b.push(t[s]),b.push(a),h=e,m=0,f=g=l,c=d=u=o}}return b}(h,d,u,n);break;default:throw new Error(`Unsupported decimation algorithm '${s.algorithm}'`)}e._decimated=f}))},destroy(t){fo(t)}};function po(t,e,i,s){if(s)return;let n=e[t],o=i[t];return\"angle\"===t&&(n=K(n),o=K(o)),{property:t,start:n,end:o}}function mo(t,e,i){for(;e>t;e--){const t=i[e];if(!isNaN(t.x)&&!isNaN(t.y))break}return e}function bo(t,e,i,s){return t&&e?s(t[i],e[i]):t?t[i]:e?e[i]:0}function xo(t,e){let i=[],n=!1;return s(t)?(n=!0,i=t):i=function(t,e){const{x:i=null,y:s=null}=t||{},n=e.points,o=[];return e.segments.forEach((({start:t,end:e})=>{e=mo(t,e,n);const a=n[t],r=n[e];null!==s?(o.push({x:a.x,y:s}),o.push({x:r.x,y:s})):null!==i&&(o.push({x:i,y:a.y}),o.push({x:i,y:r.y}))})),o}(t,e),i.length?new to({points:i,options:{tension:0},_loop:n,_fullLoop:n}):null}function _o(t){return t&&!1!==t.fill}function yo(t,e,i){let s=t[e].fill;const n=[e];let a;if(!i)return s;for(;!1!==s&&-1===n.indexOf(s);){if(!o(s))return s;if(a=t[s],!a)return!1;if(a.visible)return s;n.push(s),s=a.fill}return!1}function vo(t,e,i){const s=function(t){const e=t.options,i=e.fill;let s=r(i&&i.target,i);void 0===s&&(s=!!e.backgroundColor);if(!1===s||null===s)return!1;if(!0===s)return\"origin\";return s}(t);if(n(s))return!isNaN(s.value)&&s;let a=parseFloat(s);return o(a)&&Math.floor(a)===a?function(t,e,i,s){\"-\"!==t&&\"+\"!==t||(i=e+i);if(i===e||i<0||i>=s)return!1;return i}(s[0],e,a,i):[\"origin\",\"start\",\"end\",\"stack\",\"shape\"].indexOf(s)>=0&&s}function wo(t,e,i){const s=[];for(let n=0;n<i.length;n++){const o=i[n],{first:a,last:r,point:l}=Mo(o,e,\"x\");if(!(!l||a&&r))if(a)s.unshift(l);else if(t.push(l),!r)break}t.push(...s)}function Mo(t,e,i){const s=t.interpolate(e,i);if(!s)return{};const n=s[i],o=t.segments,a=t.points;let r=!1,l=!1;for(let t=0;t<o.length;t++){const e=o[t],s=a[e.start][i],h=a[e.end][i];if(Q(n,s,h)){r=n===s,l=n===h;break}}return{first:r,last:l,point:s}}class ko{constructor(t){this.x=t.x,this.y=t.y,this.radius=t.radius}pathSegment(t,e,i){const{x:s,y:n,radius:o}=this;return e=e||{start:0,end:O},t.arc(s,n,o,e.end,e.start,!0),!i.bounds}interpolate(t){const{x:e,y:i,radius:s}=this,n=t.angle;return{x:e+Math.cos(n)*s,y:i+Math.sin(n)*s,angle:n}}}function So(t){const{chart:e,fill:i,line:s}=t;if(o(i))return function(t,e){const i=t.getDatasetMeta(e);return i&&t.isDatasetVisible(e)?i.dataset:null}(e,i);if(\"stack\"===i)return function(t){const{scale:e,index:i,line:s}=t,n=[],o=s.segments,a=s.points,r=function(t,e){const i=[],s=t.getMatchingVisibleMetas(\"line\");for(let t=0;t<s.length;t++){const n=s[t];if(n.index===e)break;n.hidden||i.unshift(n.dataset)}return i}(e,i);r.push(xo({x:null,y:e.bottom},s));for(let t=0;t<o.length;t++){const e=o[t];for(let t=e.start;t<=e.end;t++)wo(n,a[t],r)}return new to({points:n,options:{}})}(t);if(\"shape\"===i)return!0;const a=function(t){if((t.scale||{}).getPointPositionForValue)return function(t){const{scale:e,fill:i}=t,s=e.options,o=e.getLabels().length,a=s.reverse?e.max:e.min,r=function(t,e,i){let s;return s=\"start\"===t?i:\"end\"===t?e.options.reverse?e.min:e.max:n(t)?t.value:e.getBaseValue(),s}(i,e,a),l=[];if(s.grid.circular){const t=e.getPointPositionForValue(0,a);return new ko({x:t.x,y:t.y,radius:e.getDistanceFromCenterForValue(r)})}for(let t=0;t<o;++t)l.push(e.getPointPositionForValue(t,r));return l}(t);return function(t){const{scale:e={},fill:i}=t,s=function(t,e){let i=null;return\"start\"===t?i=e.bottom:\"end\"===t?i=e.top:n(t)?i=e.getPixelForValue(t.value):e.getBasePixel&&(i=e.getBasePixel()),i}(i,e);if(o(s)){const t=e.isHorizontal();return{x:t?s:null,y:t?null:s}}return null}(t)}(t);return a instanceof ko?a:xo(a,s)}function Po(t,e,i){const s=So(e),{line:n,scale:o,axis:a}=e,r=n.options,l=r.fill,h=r.backgroundColor,{above:c=h,below:d=h}=l||{};s&&n.points.length&&(Pe(t,i),function(t,e){const{line:i,target:s,above:n,below:o,area:a,scale:r}=e,l=i._loop?\"angle\":e.axis;t.save(),\"x\"===l&&o!==n&&(Do(t,s,a.top),Oo(t,{line:i,target:s,color:n,scale:r,property:l}),t.restore(),t.save(),Do(t,s,a.bottom));Oo(t,{line:i,target:s,color:o,scale:r,property:l}),t.restore()}(t,{line:n,target:s,above:c,below:d,area:i,scale:o,axis:a}),De(t))}function Do(t,e,i){const{segments:s,points:n}=e;let o=!0,a=!1;t.beginPath();for(const r of s){const{start:s,end:l}=r,h=n[s],c=n[mo(s,l,n)];o?(t.moveTo(h.x,h.y),o=!1):(t.lineTo(h.x,i),t.lineTo(h.x,h.y)),a=!!e.pathSegment(t,r,{move:a}),a?t.closePath():t.lineTo(c.x,i)}t.lineTo(e.first().x,i),t.closePath(),t.clip()}function Oo(t,e){const{line:i,target:s,property:n,color:o,scale:a}=e,r=function(t,e,i){const s=t.segments,n=t.points,o=e.points,a=[];for(const t of s){let{start:s,end:r}=t;r=mo(s,r,n);const l=po(i,n[s],n[r],t.loop);if(!e.segments){a.push({source:t,target:l,start:n[s],end:n[r]});continue}const h=Pi(e,l);for(const e of h){const s=po(i,o[e.start],o[e.end],e.loop),r=Si(t,n,s);for(const t of r)a.push({source:t,target:e,start:{[i]:bo(l,s,\"start\",Math.max)},end:{[i]:bo(l,s,\"end\",Math.min)}})}}return a}(i,s,n);for(const{source:e,target:l,start:h,end:c}of r){const{style:{backgroundColor:r=o}={}}=e,d=!0!==s;t.save(),t.fillStyle=r,Co(t,a,d&&po(n,h,c)),t.beginPath();const u=!!i.pathSegment(t,e);let f;if(d){u?t.closePath():Ao(t,s,c,n);const e=!!s.pathSegment(t,l,{move:u,reverse:!0});f=u&&e,f||Ao(t,s,h,n)}t.closePath(),t.fill(f?\"evenodd\":\"nonzero\"),t.restore()}}function Co(t,e,i){const{top:s,bottom:n}=e.chart.chartArea,{property:o,start:a,end:r}=i||{};\"x\"===o&&(t.beginPath(),t.rect(a,s,r-a,n-s),t.clip())}function Ao(t,e,i,s){const n=e.interpolate(i,s);n&&t.lineTo(n.x,n.y)}var To={id:\"filler\",afterDatasetsUpdate(t,e,i){const s=(t.data.datasets||[]).length,n=[];let o,a,r,l;for(a=0;a<s;++a)o=t.getDatasetMeta(a),r=o.dataset,l=null,r&&r.options&&r instanceof to&&(l={visible:t.isDatasetVisible(a),index:a,fill:vo(r,a,s),chart:t,axis:o.controller.options.indexAxis,scale:o.vScale,line:r}),o.$filler=l,n.push(l);for(a=0;a<s;++a)l=n[a],l&&!1!==l.fill&&(l.fill=yo(n,a,i.propagate))},beforeDraw(t,e,i){const s=\"beforeDraw\"===i.drawTime,n=t.getSortedVisibleDatasetMetas(),o=t.chartArea;for(let e=n.length-1;e>=0;--e){const i=n[e].$filler;i&&(i.line.updateControlPoints(o,i.axis),s&&i.fill&&Po(t.ctx,i,o))}},beforeDatasetsDraw(t,e,i){if(\"beforeDatasetsDraw\"!==i.drawTime)return;const s=t.getSortedVisibleDatasetMetas();for(let e=s.length-1;e>=0;--e){const i=s[e].$filler;_o(i)&&Po(t.ctx,i,t.chartArea)}},beforeDatasetDraw(t,e,i){const s=e.meta.$filler;_o(s)&&\"beforeDatasetDraw\"===i.drawTime&&Po(t.ctx,s,t.chartArea)},defaults:{propagate:!0,drawTime:\"beforeDatasetDraw\"}};const Lo=(t,e)=>{let{boxHeight:i=e,boxWidth:s=e}=t;return t.usePointStyle&&(i=Math.min(i,e),s=t.pointStyleWidth||Math.min(s,e)),{boxWidth:s,boxHeight:i,itemHeight:Math.max(e,i)}};class Eo extends Es{constructor(t){super(),this._added=!1,this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1,this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this.legendItems=void 0,this.columnSizes=void 0,this.lineWidths=void 0,this.maxHeight=void 0,this.maxWidth=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.height=void 0,this.width=void 0,this._margins=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e,i){this.maxWidth=t,this.maxHeight=e,this._margins=i,this.setDimensions(),this.buildLabels(),this.fit()}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}buildLabels(){const t=this.options.labels||{};let e=c(t.generateLabels,[this.chart],this)||[];t.filter&&(e=e.filter((e=>t.filter(e,this.chart.data)))),t.sort&&(e=e.sort(((e,i)=>t.sort(e,i,this.chart.data)))),this.options.reverse&&e.reverse(),this.legendItems=e}fit(){const{options:t,ctx:e}=this;if(!t.display)return void(this.width=this.height=0);const i=t.labels,s=mi(i.font),n=s.size,o=this._computeTitleHeight(),{boxWidth:a,itemHeight:r}=Lo(i,n);let l,h;e.font=s.string,this.isHorizontal()?(l=this.maxWidth,h=this._fitRows(o,n,a,r)+10):(h=this.maxHeight,l=this._fitCols(o,n,a,r)+10),this.width=Math.min(l,t.maxWidth||this.maxWidth),this.height=Math.min(h,t.maxHeight||this.maxHeight)}_fitRows(t,e,i,s){const{ctx:n,maxWidth:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.lineWidths=[0],h=s+a;let c=t;n.textAlign=\"left\",n.textBaseline=\"middle\";let d=-1,u=-h;return this.legendItems.forEach(((t,f)=>{const g=i+e/2+n.measureText(t.text).width;(0===f||l[l.length-1]+g+2*a>o)&&(c+=h,l[l.length-(f>0?0:1)]=0,u+=h,d++),r[f]={left:0,top:u,row:d,width:g,height:s},l[l.length-1]+=g+a})),c}_fitCols(t,e,i,s){const{ctx:n,maxHeight:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.columnSizes=[],h=o-t;let c=a,d=0,u=0,f=0,g=0;return this.legendItems.forEach(((t,o)=>{const p=i+e/2+n.measureText(t.text).width;o>0&&u+s+2*a>h&&(c+=d+a,l.push({width:d,height:u}),f+=d+a,g++,d=u=0),r[o]={left:f,top:u,col:g,width:p,height:s},d=Math.max(d,p),u+=s+a})),c+=d,l.push({width:d,height:u}),c}adjustHitBoxes(){if(!this.options.display)return;const t=this._computeTitleHeight(),{legendHitBoxes:e,options:{align:i,labels:{padding:s},rtl:n}}=this,o=yi(n,this.left,this.width);if(this.isHorizontal()){let n=0,a=ut(i,this.left+s,this.right-this.lineWidths[n]);for(const r of e)n!==r.row&&(n=r.row,a=ut(i,this.left+s,this.right-this.lineWidths[n])),r.top+=this.top+t+s,r.left=o.leftForLtr(o.x(a),r.width),a+=r.width+s}else{let n=0,a=ut(i,this.top+t+s,this.bottom-this.columnSizes[n].height);for(const r of e)r.col!==n&&(n=r.col,a=ut(i,this.top+t+s,this.bottom-this.columnSizes[n].height)),r.top=a,r.left+=this.left+s,r.left=o.leftForLtr(o.x(r.left),r.width),a+=r.height+s}}isHorizontal(){return\"top\"===this.options.position||\"bottom\"===this.options.position}draw(){if(this.options.display){const t=this.ctx;Pe(t,this),this._draw(),De(t)}}_draw(){const{options:t,columnSizes:e,lineWidths:i,ctx:s}=this,{align:n,labels:o}=t,a=ne.color,l=yi(t.rtl,this.left,this.width),h=mi(o.font),{color:c,padding:d}=o,u=h.size,f=u/2;let g;this.drawTitle(),s.textAlign=l.textAlign(\"left\"),s.textBaseline=\"middle\",s.lineWidth=.5,s.font=h.string;const{boxWidth:p,boxHeight:m,itemHeight:b}=Lo(o,u),x=this.isHorizontal(),_=this._computeTitleHeight();g=x?{x:ut(n,this.left+d,this.right-i[0]),y:this.top+d+_,line:0}:{x:this.left+d,y:ut(n,this.top+_+d,this.bottom-e[0].height),line:0},vi(this.ctx,t.textDirection);const y=b+d;this.legendItems.forEach(((v,w)=>{s.strokeStyle=v.fontColor||c,s.fillStyle=v.fontColor||c;const M=s.measureText(v.text).width,k=l.textAlign(v.textAlign||(v.textAlign=o.textAlign)),S=p+f+M;let P=g.x,D=g.y;l.setWidth(this.width),x?w>0&&P+S+d>this.right&&(D=g.y+=y,g.line++,P=g.x=ut(n,this.left+d,this.right-i[g.line])):w>0&&D+y>this.bottom&&(P=g.x=P+e[g.line].width+d,g.line++,D=g.y=ut(n,this.top+_+d,this.bottom-e[g.line].height));!function(t,e,i){if(isNaN(p)||p<=0||isNaN(m)||m<0)return;s.save();const n=r(i.lineWidth,1);if(s.fillStyle=r(i.fillStyle,a),s.lineCap=r(i.lineCap,\"butt\"),s.lineDashOffset=r(i.lineDashOffset,0),s.lineJoin=r(i.lineJoin,\"miter\"),s.lineWidth=n,s.strokeStyle=r(i.strokeStyle,a),s.setLineDash(r(i.lineDash,[])),o.usePointStyle){const a={radius:m*Math.SQRT2/2,pointStyle:i.pointStyle,rotation:i.rotation,borderWidth:n},r=l.xPlus(t,p/2);ke(s,a,r,e+f,o.pointStyleWidth&&p)}else{const o=e+Math.max((u-m)/2,0),a=l.leftForLtr(t,p),r=gi(i.borderRadius);s.beginPath(),Object.values(r).some((t=>0!==t))?Le(s,{x:a,y:o,w:p,h:m,radius:r}):s.rect(a,o,p,m),s.fill(),0!==n&&s.stroke()}s.restore()}(l.x(P),D,v),P=ft(k,P+p+f,x?P+S:this.right,t.rtl),function(t,e,i){Ae(s,i.text,t,e+b/2,h,{strikethrough:i.hidden,textAlign:l.textAlign(i.textAlign)})}(l.x(P),D,v),x?g.x+=S+d:g.y+=y})),wi(this.ctx,t.textDirection)}drawTitle(){const t=this.options,e=t.title,i=mi(e.font),s=pi(e.padding);if(!e.display)return;const n=yi(t.rtl,this.left,this.width),o=this.ctx,a=e.position,r=i.size/2,l=s.top+r;let h,c=this.left,d=this.width;if(this.isHorizontal())d=Math.max(...this.lineWidths),h=this.top+l,c=ut(t.align,c,this.right-d);else{const e=this.columnSizes.reduce(((t,e)=>Math.max(t,e.height)),0);h=l+ut(t.align,this.top,this.bottom-e-t.labels.padding-this._computeTitleHeight())}const u=ut(a,c,c+d);o.textAlign=n.textAlign(dt(a)),o.textBaseline=\"middle\",o.strokeStyle=e.color,o.fillStyle=e.color,o.font=i.string,Ae(o,e.text,u,h,i)}_computeTitleHeight(){const t=this.options.title,e=mi(t.font),i=pi(t.padding);return t.display?e.lineHeight+i.height:0}_getLegendItemAt(t,e){let i,s,n;if(Q(t,this.left,this.right)&&Q(e,this.top,this.bottom))for(n=this.legendHitBoxes,i=0;i<n.length;++i)if(s=n[i],Q(t,s.left,s.left+s.width)&&Q(e,s.top,s.top+s.height))return this.legendItems[i];return null}handleEvent(t){const e=this.options;if(!function(t,e){if((\"mousemove\"===t||\"mouseout\"===t)&&(e.onHover||e.onLeave))return!0;if(e.onClick&&(\"click\"===t||\"mouseup\"===t))return!0;return!1}(t.type,e))return;const i=this._getLegendItemAt(t.x,t.y);if(\"mousemove\"===t.type||\"mouseout\"===t.type){const o=this._hoveredItem,a=(n=i,null!==(s=o)&&null!==n&&s.datasetIndex===n.datasetIndex&&s.index===n.index);o&&!a&&c(e.onLeave,[t,o,this],this),this._hoveredItem=i,i&&!a&&c(e.onHover,[t,i,this],this)}else i&&c(e.onClick,[t,i,this],this);var s,n}}var Ro={id:\"legend\",_element:Eo,start(t,e,i){const s=t.legend=new Eo({ctx:t.ctx,options:i,chart:t});Zi.configure(t,s,i),Zi.addBox(t,s)},stop(t){Zi.removeBox(t,t.legend),delete t.legend},beforeUpdate(t,e,i){const s=t.legend;Zi.configure(t,s,i),s.options=i},afterUpdate(t){const e=t.legend;e.buildLabels(),e.adjustHitBoxes()},afterEvent(t,e){e.replay||t.legend.handleEvent(e.event)},defaults:{display:!0,position:\"top\",align:\"center\",fullSize:!0,reverse:!1,weight:1e3,onClick(t,e,i){const s=e.datasetIndex,n=i.chart;n.isDatasetVisible(s)?(n.hide(s),e.hidden=!0):(n.show(s),e.hidden=!1)},onHover:null,onLeave:null,labels:{color:t=>t.chart.options.color,boxWidth:40,padding:10,generateLabels(t){const e=t.data.datasets,{labels:{usePointStyle:i,pointStyle:s,textAlign:n,color:o}}=t.legend.options;return t._getSortedDatasetMetas().map((t=>{const a=t.controller.getStyle(i?0:void 0),r=pi(a.borderWidth);return{text:e[t.index].label,fillStyle:a.backgroundColor,fontColor:o,hidden:!t.visible,lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:(r.width+r.height)/4,strokeStyle:a.borderColor,pointStyle:s||a.pointStyle,rotation:a.rotation,textAlign:n||a.textAlign,borderRadius:0,datasetIndex:t.index}}),this)}},title:{color:t=>t.chart.options.color,display:!1,position:\"center\",text:\"\"}},descriptors:{_scriptable:t=>!t.startsWith(\"on\"),labels:{_scriptable:t=>![\"generateLabels\",\"filter\",\"sort\"].includes(t)}}};class Io extends Es{constructor(t){super(),this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this._padding=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e){const i=this.options;if(this.left=0,this.top=0,!i.display)return void(this.width=this.height=this.right=this.bottom=0);this.width=this.right=t,this.height=this.bottom=e;const n=s(i.text)?i.text.length:1;this._padding=pi(i.padding);const o=n*mi(i.font).lineHeight+this._padding.height;this.isHorizontal()?this.height=o:this.width=o}isHorizontal(){const t=this.options.position;return\"top\"===t||\"bottom\"===t}_drawArgs(t){const{top:e,left:i,bottom:s,right:n,options:o}=this,a=o.align;let r,l,h,c=0;return this.isHorizontal()?(l=ut(a,i,n),h=e+t,r=n-i):(\"left\"===o.position?(l=i+t,h=ut(a,s,e),c=-.5*D):(l=n-t,h=ut(a,e,s),c=.5*D),r=s-e),{titleX:l,titleY:h,maxWidth:r,rotation:c}}draw(){const t=this.ctx,e=this.options;if(!e.display)return;const i=mi(e.font),s=i.lineHeight/2+this._padding.top,{titleX:n,titleY:o,maxWidth:a,rotation:r}=this._drawArgs(s);Ae(t,e.text,0,0,i,{color:e.color,maxWidth:a,rotation:r,textAlign:dt(e.align),textBaseline:\"middle\",translation:[n,o]})}}var zo={id:\"title\",_element:Io,start(t,e,i){!function(t,e){const i=new Io({ctx:t.ctx,options:e,chart:t});Zi.configure(t,i,e),Zi.addBox(t,i),t.titleBlock=i}(t,i)},stop(t){const e=t.titleBlock;Zi.removeBox(t,e),delete t.titleBlock},beforeUpdate(t,e,i){const s=t.titleBlock;Zi.configure(t,s,i),s.options=i},defaults:{align:\"center\",display:!1,font:{weight:\"bold\"},fullSize:!0,padding:10,position:\"top\",text:\"\",weight:2e3},defaultRoutes:{color:\"color\"},descriptors:{_scriptable:!0,_indexable:!1}};const Fo=new WeakMap;var Vo={id:\"subtitle\",start(t,e,i){const s=new Io({ctx:t.ctx,options:i,chart:t});Zi.configure(t,s,i),Zi.addBox(t,s),Fo.set(t,s)},stop(t){Zi.removeBox(t,Fo.get(t)),Fo.delete(t)},beforeUpdate(t,e,i){const s=Fo.get(t);Zi.configure(t,s,i),s.options=i},defaults:{align:\"center\",display:!1,font:{weight:\"normal\"},fullSize:!0,padding:0,position:\"top\",text:\"\",weight:1500},defaultRoutes:{color:\"color\"},descriptors:{_scriptable:!0,_indexable:!1}};const Bo={average(t){if(!t.length)return!1;let e,i,s=0,n=0,o=0;for(e=0,i=t.length;e<i;++e){const i=t[e].element;if(i&&i.hasValue()){const t=i.tooltipPosition();s+=t.x,n+=t.y,++o}}return{x:s/o,y:n/o}},nearest(t,e){if(!t.length)return!1;let i,s,n,o=e.x,a=e.y,r=Number.POSITIVE_INFINITY;for(i=0,s=t.length;i<s;++i){const s=t[i].element;if(s&&s.hasValue()){const t=X(e,s.getCenterPoint());t<r&&(r=t,n=s)}}if(n){const t=n.tooltipPosition();o=t.x,a=t.y}return{x:o,y:a}}};function No(t,e){return e&&(s(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function Wo(t){return(\"string\"==typeof t||t instanceof String)&&t.indexOf(\"\\n\")>-1?t.split(\"\\n\"):t}function jo(t,e){const{element:i,datasetIndex:s,index:n}=e,o=t.getDatasetMeta(s).controller,{label:a,value:r}=o.getLabelAndValue(n);return{chart:t,label:a,parsed:o.getParsed(n),raw:t.data.datasets[s].data[n],formattedValue:r,dataset:o.getDataset(),dataIndex:n,datasetIndex:s,element:i}}function Ho(t,e){const i=t.chart.ctx,{body:s,footer:n,title:o}=t,{boxWidth:a,boxHeight:r}=e,l=mi(e.bodyFont),h=mi(e.titleFont),c=mi(e.footerFont),u=o.length,f=n.length,g=s.length,p=pi(e.padding);let m=p.height,b=0,x=s.reduce(((t,e)=>t+e.before.length+e.lines.length+e.after.length),0);if(x+=t.beforeBody.length+t.afterBody.length,u&&(m+=u*h.lineHeight+(u-1)*e.titleSpacing+e.titleMarginBottom),x){m+=g*(e.displayColors?Math.max(r,l.lineHeight):l.lineHeight)+(x-g)*l.lineHeight+(x-1)*e.bodySpacing}f&&(m+=e.footerMarginTop+f*c.lineHeight+(f-1)*e.footerSpacing);let _=0;const y=function(t){b=Math.max(b,i.measureText(t).width+_)};return i.save(),i.font=h.string,d(t.title,y),i.font=l.string,d(t.beforeBody.concat(t.afterBody),y),_=e.displayColors?a+2+e.boxPadding:0,d(s,(t=>{d(t.before,y),d(t.lines,y),d(t.after,y)})),_=0,i.font=c.string,d(t.footer,y),i.restore(),b+=p.width,{width:b,height:m}}function $o(t,e,i,s){const{x:n,width:o}=i,{width:a,chartArea:{left:r,right:l}}=t;let h=\"center\";return\"center\"===s?h=n<=(r+l)/2?\"left\":\"right\":n<=o/2?h=\"left\":n>=a-o/2&&(h=\"right\"),function(t,e,i,s){const{x:n,width:o}=s,a=i.caretSize+i.caretPadding;return\"left\"===t&&n+o+a>e.width||\"right\"===t&&n-o-a<0||void 0}(h,t,e,i)&&(h=\"center\"),h}function Yo(t,e,i){const s=i.yAlign||e.yAlign||function(t,e){const{y:i,height:s}=e;return i<s/2?\"top\":i>t.height-s/2?\"bottom\":\"center\"}(t,i);return{xAlign:i.xAlign||e.xAlign||$o(t,e,i,s),yAlign:s}}function Uo(t,e,i,s){const{caretSize:n,caretPadding:o,cornerRadius:a}=t,{xAlign:r,yAlign:l}=i,h=n+o,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=gi(a);let g=function(t,e){let{x:i,width:s}=t;return\"right\"===e?i-=s:\"center\"===e&&(i-=s/2),i}(e,r);const p=function(t,e,i){let{y:s,height:n}=t;return\"top\"===e?s+=i:s-=\"bottom\"===e?n+i:n/2,s}(e,l,h);return\"center\"===l?\"left\"===r?g+=h:\"right\"===r&&(g-=h):\"left\"===r?g-=Math.max(c,u)+n:\"right\"===r&&(g+=Math.max(d,f)+n),{x:Z(g,0,s.width-e.width),y:Z(p,0,s.height-e.height)}}function Xo(t,e,i){const s=pi(i.padding);return\"center\"===e?t.x+t.width/2:\"right\"===e?t.x+t.width-s.right:t.x+s.left}function qo(t){return No([],Wo(t))}function Ko(t,e){const i=e&&e.dataset&&e.dataset.tooltip&&e.dataset.tooltip.callbacks;return i?t.override(i):t}class Go extends Es{constructor(t){super(),this.opacity=0,this._active=[],this._eventPosition=void 0,this._size=void 0,this._cachedAnimations=void 0,this._tooltipItems=[],this.$animations=void 0,this.$context=void 0,this.chart=t.chart||t._chart,this._chart=this.chart,this.options=t.options,this.dataPoints=void 0,this.title=void 0,this.beforeBody=void 0,this.body=void 0,this.afterBody=void 0,this.footer=void 0,this.xAlign=void 0,this.yAlign=void 0,this.x=void 0,this.y=void 0,this.height=void 0,this.width=void 0,this.caretX=void 0,this.caretY=void 0,this.labelColors=void 0,this.labelPointStyles=void 0,this.labelTextColors=void 0}initialize(t){this.options=t,this._cachedAnimations=void 0,this.$context=void 0}_resolveAnimations(){const t=this._cachedAnimations;if(t)return t;const e=this.chart,i=this.options.setContext(this.getContext()),s=i.enabled&&e.options.animation&&i.animations,n=new ys(this.chart,s);return s._cacheable&&(this._cachedAnimations=Object.freeze(n)),n}getContext(){return this.$context||(this.$context=(t=this.chart.getContext(),e=this,i=this._tooltipItems,_i(t,{tooltip:e,tooltipItems:i,type:\"tooltip\"})));var t,e,i}getTitle(t,e){const{callbacks:i}=e,s=i.beforeTitle.apply(this,[t]),n=i.title.apply(this,[t]),o=i.afterTitle.apply(this,[t]);let a=[];return a=No(a,Wo(s)),a=No(a,Wo(n)),a=No(a,Wo(o)),a}getBeforeBody(t,e){return qo(e.callbacks.beforeBody.apply(this,[t]))}getBody(t,e){const{callbacks:i}=e,s=[];return d(t,(t=>{const e={before:[],lines:[],after:[]},n=Ko(i,t);No(e.before,Wo(n.beforeLabel.call(this,t))),No(e.lines,n.label.call(this,t)),No(e.after,Wo(n.afterLabel.call(this,t))),s.push(e)})),s}getAfterBody(t,e){return qo(e.callbacks.afterBody.apply(this,[t]))}getFooter(t,e){const{callbacks:i}=e,s=i.beforeFooter.apply(this,[t]),n=i.footer.apply(this,[t]),o=i.afterFooter.apply(this,[t]);let a=[];return a=No(a,Wo(s)),a=No(a,Wo(n)),a=No(a,Wo(o)),a}_createItems(t){const e=this._active,i=this.chart.data,s=[],n=[],o=[];let a,r,l=[];for(a=0,r=e.length;a<r;++a)l.push(jo(this.chart,e[a]));return t.filter&&(l=l.filter(((e,s,n)=>t.filter(e,s,n,i)))),t.itemSort&&(l=l.sort(((e,s)=>t.itemSort(e,s,i)))),d(l,(e=>{const i=Ko(t.callbacks,e);s.push(i.labelColor.call(this,e)),n.push(i.labelPointStyle.call(this,e)),o.push(i.labelTextColor.call(this,e))})),this.labelColors=s,this.labelPointStyles=n,this.labelTextColors=o,this.dataPoints=l,l}update(t,e){const i=this.options.setContext(this.getContext()),s=this._active;let n,o=[];if(s.length){const t=Bo[i.position].call(this,s,this._eventPosition);o=this._createItems(i),this.title=this.getTitle(o,i),this.beforeBody=this.getBeforeBody(o,i),this.body=this.getBody(o,i),this.afterBody=this.getAfterBody(o,i),this.footer=this.getFooter(o,i);const e=this._size=Ho(this,i),a=Object.assign({},t,e),r=Yo(this.chart,i,a),l=Uo(i,a,r,this.chart);this.xAlign=r.xAlign,this.yAlign=r.yAlign,n={opacity:1,x:l.x,y:l.y,width:e.width,height:e.height,caretX:t.x,caretY:t.y}}else 0!==this.opacity&&(n={opacity:0});this._tooltipItems=o,this.$context=void 0,n&&this._resolveAnimations().update(this,n),t&&i.external&&i.external.call(this,{chart:this.chart,tooltip:this,replay:e})}drawCaret(t,e,i,s){const n=this.getCaretPosition(t,i,s);e.lineTo(n.x1,n.y1),e.lineTo(n.x2,n.y2),e.lineTo(n.x3,n.y3)}getCaretPosition(t,e,i){const{xAlign:s,yAlign:n}=this,{caretSize:o,cornerRadius:a}=i,{topLeft:r,topRight:l,bottomLeft:h,bottomRight:c}=gi(a),{x:d,y:u}=t,{width:f,height:g}=e;let p,m,b,x,_,y;return\"center\"===n?(_=u+g/2,\"left\"===s?(p=d,m=p-o,x=_+o,y=_-o):(p=d+f,m=p+o,x=_-o,y=_+o),b=p):(m=\"left\"===s?d+Math.max(r,h)+o:\"right\"===s?d+f-Math.max(l,c)-o:this.caretX,\"top\"===n?(x=u,_=x-o,p=m-o,b=m+o):(x=u+g,_=x+o,p=m+o,b=m-o),y=x),{x1:p,x2:m,x3:b,y1:x,y2:_,y3:y}}drawTitle(t,e,i){const s=this.title,n=s.length;let o,a,r;if(n){const l=yi(i.rtl,this.x,this.width);for(t.x=Xo(this,i.titleAlign,i),e.textAlign=l.textAlign(i.titleAlign),e.textBaseline=\"middle\",o=mi(i.titleFont),a=i.titleSpacing,e.fillStyle=i.titleColor,e.font=o.string,r=0;r<n;++r)e.fillText(s[r],l.x(t.x),t.y+o.lineHeight/2),t.y+=o.lineHeight+a,r+1===n&&(t.y+=i.titleMarginBottom-a)}}_drawColorBox(t,e,i,s,o){const a=this.labelColors[i],r=this.labelPointStyles[i],{boxHeight:l,boxWidth:h,boxPadding:c}=o,d=mi(o.bodyFont),u=Xo(this,\"left\",o),f=s.x(u),g=l<d.lineHeight?(d.lineHeight-l)/2:0,p=e.y+g;if(o.usePointStyle){const e={radius:Math.min(h,l)/2,pointStyle:r.pointStyle,rotation:r.rotation,borderWidth:1},i=s.leftForLtr(f,h)+h/2,n=p+l/2;t.strokeStyle=o.multiKeyBackground,t.fillStyle=o.multiKeyBackground,Me(t,e,i,n),t.strokeStyle=a.borderColor,t.fillStyle=a.backgroundColor,Me(t,e,i,n)}else{t.lineWidth=n(a.borderWidth)?Math.max(...Object.values(a.borderWidth)):a.borderWidth||1,t.strokeStyle=a.borderColor,t.setLineDash(a.borderDash||[]),t.lineDashOffset=a.borderDashOffset||0;const e=s.leftForLtr(f,h-c),i=s.leftForLtr(s.xPlus(f,1),h-c-2),r=gi(a.borderRadius);Object.values(r).some((t=>0!==t))?(t.beginPath(),t.fillStyle=o.multiKeyBackground,Le(t,{x:e,y:p,w:h,h:l,radius:r}),t.fill(),t.stroke(),t.fillStyle=a.backgroundColor,t.beginPath(),Le(t,{x:i,y:p+1,w:h-2,h:l-2,radius:r}),t.fill()):(t.fillStyle=o.multiKeyBackground,t.fillRect(e,p,h,l),t.strokeRect(e,p,h,l),t.fillStyle=a.backgroundColor,t.fillRect(i,p+1,h-2,l-2))}t.fillStyle=this.labelTextColors[i]}drawBody(t,e,i){const{body:s}=this,{bodySpacing:n,bodyAlign:o,displayColors:a,boxHeight:r,boxWidth:l,boxPadding:h}=i,c=mi(i.bodyFont);let u=c.lineHeight,f=0;const g=yi(i.rtl,this.x,this.width),p=function(i){e.fillText(i,g.x(t.x+f),t.y+u/2),t.y+=u+n},m=g.textAlign(o);let b,x,_,y,v,w,M;for(e.textAlign=o,e.textBaseline=\"middle\",e.font=c.string,t.x=Xo(this,m,i),e.fillStyle=i.bodyColor,d(this.beforeBody,p),f=a&&\"right\"!==m?\"center\"===o?l/2+h:l+2+h:0,y=0,w=s.length;y<w;++y){for(b=s[y],x=this.labelTextColors[y],e.fillStyle=x,d(b.before,p),_=b.lines,a&&_.length&&(this._drawColorBox(e,t,y,g,i),u=Math.max(c.lineHeight,r)),v=0,M=_.length;v<M;++v)p(_[v]),u=c.lineHeight;d(b.after,p)}f=0,u=c.lineHeight,d(this.afterBody,p),t.y-=n}drawFooter(t,e,i){const s=this.footer,n=s.length;let o,a;if(n){const r=yi(i.rtl,this.x,this.width);for(t.x=Xo(this,i.footerAlign,i),t.y+=i.footerMarginTop,e.textAlign=r.textAlign(i.footerAlign),e.textBaseline=\"middle\",o=mi(i.footerFont),e.fillStyle=i.footerColor,e.font=o.string,a=0;a<n;++a)e.fillText(s[a],r.x(t.x),t.y+o.lineHeight/2),t.y+=o.lineHeight+i.footerSpacing}}drawBackground(t,e,i,s){const{xAlign:n,yAlign:o}=this,{x:a,y:r}=t,{width:l,height:h}=i,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=gi(s.cornerRadius);e.fillStyle=s.backgroundColor,e.strokeStyle=s.borderColor,e.lineWidth=s.borderWidth,e.beginPath(),e.moveTo(a+c,r),\"top\"===o&&this.drawCaret(t,e,i,s),e.lineTo(a+l-d,r),e.quadraticCurveTo(a+l,r,a+l,r+d),\"center\"===o&&\"right\"===n&&this.drawCaret(t,e,i,s),e.lineTo(a+l,r+h-f),e.quadraticCurveTo(a+l,r+h,a+l-f,r+h),\"bottom\"===o&&this.drawCaret(t,e,i,s),e.lineTo(a+u,r+h),e.quadraticCurveTo(a,r+h,a,r+h-u),\"center\"===o&&\"left\"===n&&this.drawCaret(t,e,i,s),e.lineTo(a,r+c),e.quadraticCurveTo(a,r,a+c,r),e.closePath(),e.fill(),s.borderWidth>0&&e.stroke()}_updateAnimationTarget(t){const e=this.chart,i=this.$animations,s=i&&i.x,n=i&&i.y;if(s||n){const i=Bo[t.position].call(this,this._active,this._eventPosition);if(!i)return;const o=this._size=Ho(this,t),a=Object.assign({},i,this._size),r=Yo(e,t,a),l=Uo(t,a,r,e);s._to===l.x&&n._to===l.y||(this.xAlign=r.xAlign,this.yAlign=r.yAlign,this.width=o.width,this.height=o.height,this.caretX=i.x,this.caretY=i.y,this._resolveAnimations().update(this,l))}}_willRender(){return!!this.opacity}draw(t){const e=this.options.setContext(this.getContext());let i=this.opacity;if(!i)return;this._updateAnimationTarget(e);const s={width:this.width,height:this.height},n={x:this.x,y:this.y};i=Math.abs(i)<.001?0:i;const o=pi(e.padding),a=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;e.enabled&&a&&(t.save(),t.globalAlpha=i,this.drawBackground(n,t,s,e),vi(t,e.textDirection),n.y+=o.top,this.drawTitle(n,t,e),this.drawBody(n,t,e),this.drawFooter(n,t,e),wi(t,e.textDirection),t.restore())}getActiveElements(){return this._active||[]}setActiveElements(t,e){const i=this._active,s=t.map((({datasetIndex:t,index:e})=>{const i=this.chart.getDatasetMeta(t);if(!i)throw new Error(\"Cannot find a dataset at index \"+t);return{datasetIndex:t,element:i.data[e],index:e}})),n=!u(i,s),o=this._positionChanged(s,e);(n||o)&&(this._active=s,this._eventPosition=e,this._ignoreReplayEvents=!0,this.update(!0))}handleEvent(t,e,i=!0){if(e&&this._ignoreReplayEvents)return!1;this._ignoreReplayEvents=!1;const s=this.options,n=this._active||[],o=this._getActiveElements(t,n,e,i),a=this._positionChanged(o,t),r=e||!u(o,n)||a;return r&&(this._active=o,(s.enabled||s.external)&&(this._eventPosition={x:t.x,y:t.y},this.update(!0,e))),r}_getActiveElements(t,e,i,s){const n=this.options;if(\"mouseout\"===t.type)return[];if(!s)return e;const o=this.chart.getElementsAtEventForMode(t,n.mode,n,i);return n.reverse&&o.reverse(),o}_positionChanged(t,e){const{caretX:i,caretY:s,options:n}=this,o=Bo[n.position].call(this,t,e);return!1!==o&&(i!==o.x||s!==o.y)}}Go.positioners=Bo;var Zo={id:\"tooltip\",_element:Go,positioners:Bo,afterInit(t,e,i){i&&(t.tooltip=new Go({chart:t,options:i}))},beforeUpdate(t,e,i){t.tooltip&&t.tooltip.initialize(i)},reset(t,e,i){t.tooltip&&t.tooltip.initialize(i)},afterDraw(t){const e=t.tooltip;if(e&&e._willRender()){const i={tooltip:e};if(!1===t.notifyPlugins(\"beforeTooltipDraw\",i))return;e.draw(t.ctx),t.notifyPlugins(\"afterTooltipDraw\",i)}},afterEvent(t,e){if(t.tooltip){const i=e.replay;t.tooltip.handleEvent(e.event,i,e.inChartArea)&&(e.changed=!0)}},defaults:{enabled:!0,external:null,position:\"average\",backgroundColor:\"rgba(0,0,0,0.8)\",titleColor:\"#fff\",titleFont:{weight:\"bold\"},titleSpacing:2,titleMarginBottom:6,titleAlign:\"left\",bodyColor:\"#fff\",bodySpacing:2,bodyFont:{},bodyAlign:\"left\",footerColor:\"#fff\",footerSpacing:2,footerMarginTop:6,footerFont:{weight:\"bold\"},footerAlign:\"left\",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(t,e)=>e.bodyFont.size,boxWidth:(t,e)=>e.bodyFont.size,multiKeyBackground:\"#fff\",displayColors:!0,boxPadding:0,borderColor:\"rgba(0,0,0,0)\",borderWidth:0,animation:{duration:400,easing:\"easeOutQuart\"},animations:{numbers:{type:\"number\",properties:[\"x\",\"y\",\"width\",\"height\",\"caretX\",\"caretY\"]},opacity:{easing:\"linear\",duration:200}},callbacks:{beforeTitle:t,title(t){if(t.length>0){const e=t[0],i=e.chart.data.labels,s=i?i.length:0;if(this&&this.options&&\"dataset\"===this.options.mode)return e.dataset.label||\"\";if(e.label)return e.label;if(s>0&&e.dataIndex<s)return i[e.dataIndex]}return\"\"},afterTitle:t,beforeBody:t,beforeLabel:t,label(t){if(this&&this.options&&\"dataset\"===this.options.mode)return t.label+\": \"+t.formattedValue||t.formattedValue;let e=t.dataset.label||\"\";e&&(e+=\": \");const s=t.formattedValue;return i(s)||(e+=s),e},labelColor(t){const e=t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex);return{borderColor:e.borderColor,backgroundColor:e.backgroundColor,borderWidth:e.borderWidth,borderDash:e.borderDash,borderDashOffset:e.borderDashOffset,borderRadius:0}},labelTextColor(){return this.options.bodyColor},labelPointStyle(t){const e=t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex);return{pointStyle:e.pointStyle,rotation:e.rotation}},afterLabel:t,afterBody:t,beforeFooter:t,footer:t,afterFooter:t}},defaultRoutes:{bodyFont:\"font\",footerFont:\"font\",titleFont:\"font\"},descriptors:{_scriptable:t=>\"filter\"!==t&&\"itemSort\"!==t&&\"external\"!==t,_indexable:!1,callbacks:{_scriptable:!1,_indexable:!1},animation:{_fallback:!1},animations:{_fallback:\"animation\"}},additionalOptionScopes:[\"interaction\"]},Jo=Object.freeze({__proto__:null,Decimation:go,Filler:To,Legend:Ro,SubTitle:Vo,Title:zo,Tooltip:Zo});function Qo(t,e,i,s){const n=t.indexOf(e);if(-1===n)return((t,e,i,s)=>(\"string\"==typeof e?(i=t.push(e)-1,s.unshift({index:i,label:e})):isNaN(e)&&(i=null),i))(t,e,i,s);return n!==t.lastIndexOf(e)?i:n}class ta extends $s{constructor(t){super(t),this._startValue=void 0,this._valueRange=0,this._addedLabels=[]}init(t){const e=this._addedLabels;if(e.length){const t=this.getLabels();for(const{index:i,label:s}of e)t[i]===s&&t.splice(i,1);this._addedLabels=[]}super.init(t)}parse(t,e){if(i(t))return null;const s=this.getLabels();return((t,e)=>null===t?null:Z(Math.round(t),0,e))(e=isFinite(e)&&s[e]===t?e:Qo(s,t,r(e,t),this._addedLabels),s.length-1)}determineDataLimits(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let{min:i,max:s}=this.getMinMax(!0);\"ticks\"===this.options.bounds&&(t||(i=0),e||(s=this.getLabels().length-1)),this.min=i,this.max=s}buildTicks(){const t=this.min,e=this.max,i=this.options.offset,s=[];let n=this.getLabels();n=0===t&&e===n.length-1?n:n.slice(t,e+1),this._valueRange=Math.max(n.length-(i?0:1),1),this._startValue=this.min-(i?.5:0);for(let i=t;i<=e;i++)s.push({value:i});return s}getLabelForValue(t){const e=this.getLabels();return t>=0&&t<e.length?e[t]:t}configure(){super.configure(),this.isHorizontal()||(this._reversePixels=!this._reversePixels)}getPixelForValue(t){return\"number\"!=typeof t&&(t=this.parse(t)),null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getValueForPixel(t){return Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange)}getBasePixel(){return this.bottom}}function ea(t,e,{horizontal:i,minRotation:s}){const n=H(s),o=(i?Math.sin(n):Math.cos(n))||.001,a=.75*e*(\"\"+t).length;return Math.min(e/o,a)}ta.id=\"category\",ta.defaults={ticks:{callback:ta.prototype.getLabelForValue}};class ia extends $s{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._endValue=void 0,this._valueRange=0}parse(t,e){return i(t)||(\"number\"==typeof t||t instanceof Number)&&!isFinite(+t)?null:+t}handleTickRangeOptions(){const{beginAtZero:t}=this.options,{minDefined:e,maxDefined:i}=this.getUserBounds();let{min:s,max:n}=this;const o=t=>s=e?s:t,a=t=>n=i?n:t;if(t){const t=z(s),e=z(n);t<0&&e<0?a(0):t>0&&e>0&&o(0)}if(s===n){let e=1;(n>=Number.MAX_SAFE_INTEGER||s<=Number.MIN_SAFE_INTEGER)&&(e=Math.abs(.05*n)),a(n+e),t||o(s-e)}this.min=s,this.max=n}getTickLimit(){const t=this.options.ticks;let e,{maxTicksLimit:i,stepSize:s}=t;return s?(e=Math.ceil(this.max/s)-Math.floor(this.min/s)+1,e>1e3&&(console.warn(`scales.${this.id}.ticks.stepSize: ${s} would result generating up to ${e} ticks. Limiting to 1000.`),e=1e3)):(e=this.computeTickLimit(),i=i||11),i&&(e=Math.min(i,e)),e}computeTickLimit(){return Number.POSITIVE_INFINITY}buildTicks(){const t=this.options,e=t.ticks;let s=this.getTickLimit();s=Math.max(2,s);const n=function(t,e){const s=[],{bounds:n,step:o,min:a,max:r,precision:l,count:h,maxTicks:c,maxDigits:d,includeBounds:u}=t,f=o||1,g=c-1,{min:p,max:m}=e,b=!i(a),x=!i(r),_=!i(h),y=(m-p)/(d+1);let v,w,M,k,S=F((m-p)/g/f)*f;if(S<1e-14&&!b&&!x)return[{value:p},{value:m}];k=Math.ceil(m/S)-Math.floor(p/S),k>g&&(S=F(k*S/g/f)*f),i(l)||(v=Math.pow(10,l),S=Math.ceil(S*v)/v),\"ticks\"===n?(w=Math.floor(p/S)*S,M=Math.ceil(m/S)*S):(w=p,M=m),b&&x&&o&&W((r-a)/o,S/1e3)?(k=Math.round(Math.min((r-a)/S,c)),S=(r-a)/k,w=a,M=r):_?(w=b?a:w,M=x?r:M,k=h-1,S=(M-w)/k):(k=(M-w)/S,k=N(k,Math.round(k),S/1e3)?Math.round(k):Math.ceil(k));const P=Math.max(Y(S),Y(w));v=Math.pow(10,i(l)?P:l),w=Math.round(w*v)/v,M=Math.round(M*v)/v;let D=0;for(b&&(u&&w!==a?(s.push({value:a}),w<a&&D++,N(Math.round((w+D*S)*v)/v,a,ea(a,y,t))&&D++):w<a&&D++);D<k;++D)s.push({value:Math.round((w+D*S)*v)/v});return x&&u&&M!==r?s.length&&N(s[s.length-1].value,r,ea(r,y,t))?s[s.length-1].value=r:s.push({value:r}):x&&M!==r||s.push({value:M}),s}({maxTicks:s,bounds:t.bounds,min:t.min,max:t.max,precision:e.precision,step:e.stepSize,count:e.count,maxDigits:this._maxDigits(),horizontal:this.isHorizontal(),minRotation:e.minRotation||0,includeBounds:!1!==e.includeBounds},this._range||this);return\"ticks\"===t.bounds&&j(n,this,\"value\"),t.reverse?(n.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),n}configure(){const t=this.ticks;let e=this.min,i=this.max;if(super.configure(),this.options.offset&&t.length){const s=(i-e)/Math.max(t.length-1,1)/2;e-=s,i+=s}this._startValue=e,this._endValue=i,this._valueRange=i-e}getLabelForValue(t){return li(t,this.chart.options.locale,this.options.ticks.format)}}class sa extends ia{determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=o(t)?t:0,this.max=o(e)?e:1,this.handleTickRangeOptions()}computeTickLimit(){const t=this.isHorizontal(),e=t?this.width:this.height,i=H(this.options.ticks.minRotation),s=(t?Math.sin(i):Math.cos(i))||.001,n=this._resolveTickFontOptions(0);return Math.ceil(e/Math.min(40,n.lineHeight/s))}getPixelForValue(t){return null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getValueForPixel(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange}}function na(t){return 1===t/Math.pow(10,Math.floor(I(t)))}sa.id=\"linear\",sa.defaults={ticks:{callback:Is.formatters.numeric}};class oa extends $s{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._valueRange=0}parse(t,e){const i=ia.prototype.parse.apply(this,[t,e]);if(0!==i)return o(i)&&i>0?i:null;this._zero=!0}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=o(t)?Math.max(0,t):null,this.max=o(e)?Math.max(0,e):null,this.options.beginAtZero&&(this._zero=!0),this.handleTickRangeOptions()}handleTickRangeOptions(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let i=this.min,s=this.max;const n=e=>i=t?i:e,o=t=>s=e?s:t,a=(t,e)=>Math.pow(10,Math.floor(I(t))+e);i===s&&(i<=0?(n(1),o(10)):(n(a(i,-1)),o(a(s,1)))),i<=0&&n(a(s,-1)),s<=0&&o(a(i,1)),this._zero&&this.min!==this._suggestedMin&&i===a(this.min,0)&&n(a(i,-1)),this.min=i,this.max=s}buildTicks(){const t=this.options,e=function(t,e){const i=Math.floor(I(e.max)),s=Math.ceil(e.max/Math.pow(10,i)),n=[];let o=a(t.min,Math.pow(10,Math.floor(I(e.min)))),r=Math.floor(I(o)),l=Math.floor(o/Math.pow(10,r)),h=r<0?Math.pow(10,Math.abs(r)):1;do{n.push({value:o,major:na(o)}),++l,10===l&&(l=1,++r,h=r>=0?1:h),o=Math.round(l*Math.pow(10,r)*h)/h}while(r<i||r===i&&l<s);const c=a(t.max,o);return n.push({value:c,major:na(o)}),n}({min:this._userMin,max:this._userMax},this);return\"ticks\"===t.bounds&&j(e,this,\"value\"),t.reverse?(e.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),e}getLabelForValue(t){return void 0===t?\"0\":li(t,this.chart.options.locale,this.options.ticks.format)}configure(){const t=this.min;super.configure(),this._startValue=I(t),this._valueRange=I(this.max)-I(t)}getPixelForValue(t){return void 0!==t&&0!==t||(t=this.min),null===t||isNaN(t)?NaN:this.getPixelForDecimal(t===this.min?0:(I(t)-this._startValue)/this._valueRange)}getValueForPixel(t){const e=this.getDecimalForPixel(t);return Math.pow(10,this._startValue+e*this._valueRange)}}function aa(t){const e=t.ticks;if(e.display&&t.display){const t=pi(e.backdropPadding);return r(e.font&&e.font.size,ne.font.size)+t.height}return 0}function ra(t,e,i,s,n){return t===s||t===n?{start:e-i/2,end:e+i/2}:t<s||t>n?{start:e-i,end:e}:{start:e,end:e+i}}function la(t){const e={l:t.left+t._padding.left,r:t.right-t._padding.right,t:t.top+t._padding.top,b:t.bottom-t._padding.bottom},i=Object.assign({},e),n=[],o=[],a=t._pointLabels.length,r=t.options.pointLabels,l=r.centerPointLabels?D/a:0;for(let u=0;u<a;u++){const a=r.setContext(t.getPointLabelContext(u));o[u]=a.padding;const f=t.getPointPosition(u,t.drawingArea+o[u],l),g=mi(a.font),p=(h=t.ctx,c=g,d=s(d=t._pointLabels[u])?d:[d],{w:ye(h,c.string,d),h:d.length*c.lineHeight});n[u]=p;const m=K(t.getIndexAngle(u)+l),b=Math.round($(m));ha(i,e,m,ra(b,f.x,p.w,0,180),ra(b,f.y,p.h,90,270))}var h,c,d;t.setCenterPoint(e.l-i.l,i.r-e.r,e.t-i.t,i.b-e.b),t._pointLabelItems=function(t,e,i){const s=[],n=t._pointLabels.length,o=t.options,a=aa(o)/2,r=t.drawingArea,l=o.pointLabels.centerPointLabels?D/n:0;for(let o=0;o<n;o++){const n=t.getPointPosition(o,r+a+i[o],l),h=Math.round($(K(n.angle+L))),c=e[o],d=ua(n.y,c.h,h),u=ca(h),f=da(n.x,c.w,u);s.push({x:n.x,y:d,textAlign:u,left:f,top:d,right:f+c.w,bottom:d+c.h})}return s}(t,n,o)}function ha(t,e,i,s,n){const o=Math.abs(Math.sin(i)),a=Math.abs(Math.cos(i));let r=0,l=0;s.start<e.l?(r=(e.l-s.start)/o,t.l=Math.min(t.l,e.l-r)):s.end>e.r&&(r=(s.end-e.r)/o,t.r=Math.max(t.r,e.r+r)),n.start<e.t?(l=(e.t-n.start)/a,t.t=Math.min(t.t,e.t-l)):n.end>e.b&&(l=(n.end-e.b)/a,t.b=Math.max(t.b,e.b+l))}function ca(t){return 0===t||180===t?\"center\":t<180?\"left\":\"right\"}function da(t,e,i){return\"right\"===i?t-=e:\"center\"===i&&(t-=e/2),t}function ua(t,e,i){return 90===i||270===i?t-=e/2:(i>270||i<90)&&(t-=e),t}function fa(t,e,i,s){const{ctx:n}=t;if(i)n.arc(t.xCenter,t.yCenter,e,0,O);else{let i=t.getPointPosition(0,e);n.moveTo(i.x,i.y);for(let o=1;o<s;o++)i=t.getPointPosition(o,e),n.lineTo(i.x,i.y)}}oa.id=\"logarithmic\",oa.defaults={ticks:{callback:Is.formatters.logarithmic,major:{enabled:!0}}};class ga extends ia{constructor(t){super(t),this.xCenter=void 0,this.yCenter=void 0,this.drawingArea=void 0,this._pointLabels=[],this._pointLabelItems=[]}setDimensions(){const t=this._padding=pi(aa(this.options)/2),e=this.width=this.maxWidth-t.width,i=this.height=this.maxHeight-t.height;this.xCenter=Math.floor(this.left+e/2+t.left),this.yCenter=Math.floor(this.top+i/2+t.top),this.drawingArea=Math.floor(Math.min(e,i)/2)}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!1);this.min=o(t)&&!isNaN(t)?t:0,this.max=o(e)&&!isNaN(e)?e:0,this.handleTickRangeOptions()}computeTickLimit(){return Math.ceil(this.drawingArea/aa(this.options))}generateTickLabels(t){ia.prototype.generateTickLabels.call(this,t),this._pointLabels=this.getLabels().map(((t,e)=>{const i=c(this.options.pointLabels.callback,[t,e],this);return i||0===i?i:\"\"})).filter(((t,e)=>this.chart.getDataVisibility(e)))}fit(){const t=this.options;t.display&&t.pointLabels.display?la(this):this.setCenterPoint(0,0,0,0)}setCenterPoint(t,e,i,s){this.xCenter+=Math.floor((t-e)/2),this.yCenter+=Math.floor((i-s)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(t,e,i,s))}getIndexAngle(t){return K(t*(O/(this._pointLabels.length||1))+H(this.options.startAngle||0))}getDistanceFromCenterForValue(t){if(i(t))return NaN;const e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}getValueForDistanceFromCenter(t){if(i(t))return NaN;const e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}getPointLabelContext(t){const e=this._pointLabels||[];if(t>=0&&t<e.length){const i=e[t];return function(t,e,i){return _i(t,{label:i,index:e,type:\"pointLabel\"})}(this.getContext(),t,i)}}getPointPosition(t,e,i=0){const s=this.getIndexAngle(t)-L+i;return{x:Math.cos(s)*e+this.xCenter,y:Math.sin(s)*e+this.yCenter,angle:s}}getPointPositionForValue(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))}getBasePosition(t){return this.getPointPositionForValue(t||0,this.getBaseValue())}getPointLabelPosition(t){const{left:e,top:i,right:s,bottom:n}=this._pointLabelItems[t];return{left:e,top:i,right:s,bottom:n}}drawBackground(){const{backgroundColor:t,grid:{circular:e}}=this.options;if(t){const i=this.ctx;i.save(),i.beginPath(),fa(this,this.getDistanceFromCenterForValue(this._endValue),e,this._pointLabels.length),i.closePath(),i.fillStyle=t,i.fill(),i.restore()}}drawGrid(){const t=this.ctx,e=this.options,{angleLines:s,grid:n}=e,o=this._pointLabels.length;let a,r,l;if(e.pointLabels.display&&function(t,e){const{ctx:s,options:{pointLabels:n}}=t;for(let o=e-1;o>=0;o--){const e=n.setContext(t.getPointLabelContext(o)),a=mi(e.font),{x:r,y:l,textAlign:h,left:c,top:d,right:u,bottom:f}=t._pointLabelItems[o],{backdropColor:g}=e;if(!i(g)){const t=gi(e.borderRadius),i=pi(e.backdropPadding);s.fillStyle=g;const n=c-i.left,o=d-i.top,a=u-c+i.width,r=f-d+i.height;Object.values(t).some((t=>0!==t))?(s.beginPath(),Le(s,{x:n,y:o,w:a,h:r,radius:t}),s.fill()):s.fillRect(n,o,a,r)}Ae(s,t._pointLabels[o],r,l+a.lineHeight/2,a,{color:e.color,textAlign:h,textBaseline:\"middle\"})}}(this,o),n.display&&this.ticks.forEach(((t,e)=>{if(0!==e){r=this.getDistanceFromCenterForValue(t.value);!function(t,e,i,s){const n=t.ctx,o=e.circular,{color:a,lineWidth:r}=e;!o&&!s||!a||!r||i<0||(n.save(),n.strokeStyle=a,n.lineWidth=r,n.setLineDash(e.borderDash),n.lineDashOffset=e.borderDashOffset,n.beginPath(),fa(t,i,o,s),n.closePath(),n.stroke(),n.restore())}(this,n.setContext(this.getContext(e-1)),r,o)}})),s.display){for(t.save(),a=o-1;a>=0;a--){const i=s.setContext(this.getPointLabelContext(a)),{color:n,lineWidth:o}=i;o&&n&&(t.lineWidth=o,t.strokeStyle=n,t.setLineDash(i.borderDash),t.lineDashOffset=i.borderDashOffset,r=this.getDistanceFromCenterForValue(e.ticks.reverse?this.min:this.max),l=this.getPointPosition(a,r),t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(l.x,l.y),t.stroke())}t.restore()}}drawBorder(){}drawLabels(){const t=this.ctx,e=this.options,i=e.ticks;if(!i.display)return;const s=this.getIndexAngle(0);let n,o;t.save(),t.translate(this.xCenter,this.yCenter),t.rotate(s),t.textAlign=\"center\",t.textBaseline=\"middle\",this.ticks.forEach(((s,a)=>{if(0===a&&!e.reverse)return;const r=i.setContext(this.getContext(a)),l=mi(r.font);if(n=this.getDistanceFromCenterForValue(this.ticks[a].value),r.showLabelBackdrop){t.font=l.string,o=t.measureText(s.label).width,t.fillStyle=r.backdropColor;const e=pi(r.backdropPadding);t.fillRect(-o/2-e.left,-n-l.size/2-e.top,o+e.width,l.size+e.height)}Ae(t,s.label,0,-n,l,{color:r.color})})),t.restore()}drawTitle(){}}ga.id=\"radialLinear\",ga.defaults={display:!0,animate:!0,position:\"chartArea\",angleLines:{display:!0,lineWidth:1,borderDash:[],borderDashOffset:0},grid:{circular:!1},startAngle:0,ticks:{showLabelBackdrop:!0,callback:Is.formatters.numeric},pointLabels:{backdropColor:void 0,backdropPadding:2,display:!0,font:{size:10},callback:t=>t,padding:5,centerPointLabels:!1}},ga.defaultRoutes={\"angleLines.color\":\"borderColor\",\"pointLabels.color\":\"color\",\"ticks.color\":\"color\"},ga.descriptors={angleLines:{_fallback:\"grid\"}};const pa={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ma=Object.keys(pa);function ba(t,e){return t-e}function xa(t,e){if(i(e))return null;const s=t._adapter,{parser:n,round:a,isoWeekday:r}=t._parseOpts;let l=e;return\"function\"==typeof n&&(l=n(l)),o(l)||(l=\"string\"==typeof n?s.parse(l,n):s.parse(l)),null===l?null:(a&&(l=\"week\"!==a||!B(r)&&!0!==r?s.startOf(l,a):s.startOf(l,\"isoWeek\",r)),+l)}function _a(t,e,i,s){const n=ma.length;for(let o=ma.indexOf(t);o<n-1;++o){const t=pa[ma[o]],n=t.steps?t.steps:Number.MAX_SAFE_INTEGER;if(t.common&&Math.ceil((i-e)/(n*t.size))<=s)return ma[o]}return ma[n-1]}function ya(t,e,i){if(i){if(i.length){const{lo:s,hi:n}=tt(i,e);t[i[s]>=e?i[s]:i[n]]=!0}}else t[e]=!0}function va(t,e,i){const s=[],n={},o=e.length;let a,r;for(a=0;a<o;++a)r=e[a],n[r]=a,s.push({value:r,major:!1});return 0!==o&&i?function(t,e,i,s){const n=t._adapter,o=+n.startOf(e[0].value,s),a=e[e.length-1].value;let r,l;for(r=o;r<=a;r=+n.add(r,1,s))l=i[r],l>=0&&(e[l].major=!0);return e}(t,s,n,i):s}class wa extends $s{constructor(t){super(t),this._cache={data:[],labels:[],all:[]},this._unit=\"day\",this._majorUnit=void 0,this._offsets={},this._normalized=!1,this._parseOpts=void 0}init(t,e){const i=t.time||(t.time={}),s=this._adapter=new wn._date(t.adapters.date);s.init(e),b(i.displayFormats,s.formats()),this._parseOpts={parser:i.parser,round:i.round,isoWeekday:i.isoWeekday},super.init(t),this._normalized=e.normalized}parse(t,e){return void 0===t?null:xa(this,t)}beforeLayout(){super.beforeLayout(),this._cache={data:[],labels:[],all:[]}}determineDataLimits(){const t=this.options,e=this._adapter,i=t.time.unit||\"day\";let{min:s,max:n,minDefined:a,maxDefined:r}=this.getUserBounds();function l(t){a||isNaN(t.min)||(s=Math.min(s,t.min)),r||isNaN(t.max)||(n=Math.max(n,t.max))}a&&r||(l(this._getLabelBounds()),\"ticks\"===t.bounds&&\"labels\"===t.ticks.source||l(this.getMinMax(!1))),s=o(s)&&!isNaN(s)?s:+e.startOf(Date.now(),i),n=o(n)&&!isNaN(n)?n:+e.endOf(Date.now(),i)+1,this.min=Math.min(s,n-1),this.max=Math.max(s+1,n)}_getLabelBounds(){const t=this.getLabelTimestamps();let e=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;return t.length&&(e=t[0],i=t[t.length-1]),{min:e,max:i}}buildTicks(){const t=this.options,e=t.time,i=t.ticks,s=\"labels\"===i.source?this.getLabelTimestamps():this._generate();\"ticks\"===t.bounds&&s.length&&(this.min=this._userMin||s[0],this.max=this._userMax||s[s.length-1]);const n=this.min,o=st(s,n,this.max);return this._unit=e.unit||(i.autoSkip?_a(e.minUnit,this.min,this.max,this._getLabelCapacity(n)):function(t,e,i,s,n){for(let o=ma.length-1;o>=ma.indexOf(i);o--){const i=ma[o];if(pa[i].common&&t._adapter.diff(n,s,i)>=e-1)return i}return ma[i?ma.indexOf(i):0]}(this,o.length,e.minUnit,this.min,this.max)),this._majorUnit=i.major.enabled&&\"year\"!==this._unit?function(t){for(let e=ma.indexOf(t)+1,i=ma.length;e<i;++e)if(pa[ma[e]].common)return ma[e]}(this._unit):void 0,this.initOffsets(s),t.reverse&&o.reverse(),va(this,o,this._majorUnit)}afterAutoSkip(){this.options.offsetAfterAutoskip&&this.initOffsets(this.ticks.map((t=>+t.value)))}initOffsets(t){let e,i,s=0,n=0;this.options.offset&&t.length&&(e=this.getDecimalForValue(t[0]),s=1===t.length?1-e:(this.getDecimalForValue(t[1])-e)/2,i=this.getDecimalForValue(t[t.length-1]),n=1===t.length?i:(i-this.getDecimalForValue(t[t.length-2]))/2);const o=t.length<3?.5:.25;s=Z(s,0,o),n=Z(n,0,o),this._offsets={start:s,end:n,factor:1/(s+1+n)}}_generate(){const t=this._adapter,e=this.min,i=this.max,s=this.options,n=s.time,o=n.unit||_a(n.minUnit,e,i,this._getLabelCapacity(e)),a=r(n.stepSize,1),l=\"week\"===o&&n.isoWeekday,h=B(l)||!0===l,c={};let d,u,f=e;if(h&&(f=+t.startOf(f,\"isoWeek\",l)),f=+t.startOf(f,h?\"day\":o),t.diff(i,e,o)>1e5*a)throw new Error(e+\" and \"+i+\" are too far apart with stepSize of \"+a+\" \"+o);const g=\"data\"===s.ticks.source&&this.getDataTimestamps();for(d=f,u=0;d<i;d=+t.add(d,a,o),u++)ya(c,d,g);return d!==i&&\"ticks\"!==s.bounds&&1!==u||ya(c,d,g),Object.keys(c).sort(((t,e)=>t-e)).map((t=>+t))}getLabelForValue(t){const e=this._adapter,i=this.options.time;return i.tooltipFormat?e.format(t,i.tooltipFormat):e.format(t,i.displayFormats.datetime)}_tickFormatFunction(t,e,i,s){const n=this.options,o=n.time.displayFormats,a=this._unit,r=this._majorUnit,l=a&&o[a],h=r&&o[r],d=i[e],u=r&&h&&d&&d.major,f=this._adapter.format(t,s||(u?h:l)),g=n.ticks.callback;return g?c(g,[f,e,i],this):f}generateTickLabels(t){let e,i,s;for(e=0,i=t.length;e<i;++e)s=t[e],s.label=this._tickFormatFunction(s.value,e,t)}getDecimalForValue(t){return null===t?NaN:(t-this.min)/(this.max-this.min)}getPixelForValue(t){const e=this._offsets,i=this.getDecimalForValue(t);return this.getPixelForDecimal((e.start+i)*e.factor)}getValueForPixel(t){const e=this._offsets,i=this.getDecimalForPixel(t)/e.factor-e.end;return this.min+i*(this.max-this.min)}_getLabelSize(t){const e=this.options.ticks,i=this.ctx.measureText(t).width,s=H(this.isHorizontal()?e.maxRotation:e.minRotation),n=Math.cos(s),o=Math.sin(s),a=this._resolveTickFontOptions(0).size;return{w:i*n+a*o,h:i*o+a*n}}_getLabelCapacity(t){const e=this.options.time,i=e.displayFormats,s=i[e.unit]||i.millisecond,n=this._tickFormatFunction(t,0,va(this,[t],this._majorUnit),s),o=this._getLabelSize(n),a=Math.floor(this.isHorizontal()?this.width/o.w:this.height/o.h)-1;return a>0?a:1}getDataTimestamps(){let t,e,i=this._cache.data||[];if(i.length)return i;const s=this.getMatchingVisibleMetas();if(this._normalized&&s.length)return this._cache.data=s[0].controller.getAllParsedValues(this);for(t=0,e=s.length;t<e;++t)i=i.concat(s[t].controller.getAllParsedValues(this));return this._cache.data=this.normalize(i)}getLabelTimestamps(){const t=this._cache.labels||[];let e,i;if(t.length)return t;const s=this.getLabels();for(e=0,i=s.length;e<i;++e)t.push(xa(this,s[e]));return this._cache.labels=this._normalized?t:this.normalize(t)}normalize(t){return rt(t.sort(ba))}}function Ma(t,e,i){let s,n,o,a,r=0,l=t.length-1;i?(e>=t[r].pos&&e<=t[l].pos&&({lo:r,hi:l}=et(t,\"pos\",e)),({pos:s,time:o}=t[r]),({pos:n,time:a}=t[l])):(e>=t[r].time&&e<=t[l].time&&({lo:r,hi:l}=et(t,\"time\",e)),({time:s,pos:o}=t[r]),({time:n,pos:a}=t[l]));const h=n-s;return h?o+(a-o)*(e-s)/h:o}wa.id=\"time\",wa.defaults={bounds:\"data\",adapters:{},time:{parser:!1,unit:!1,round:!1,isoWeekday:!1,minUnit:\"millisecond\",displayFormats:{}},ticks:{source:\"auto\",major:{enabled:!1}}};class ka extends wa{constructor(t){super(t),this._table=[],this._minPos=void 0,this._tableRange=void 0}initOffsets(){const t=this._getTimestampsForTable(),e=this._table=this.buildLookupTable(t);this._minPos=Ma(e,this.min),this._tableRange=Ma(e,this.max)-this._minPos,super.initOffsets(t)}buildLookupTable(t){const{min:e,max:i}=this,s=[],n=[];let o,a,r,l,h;for(o=0,a=t.length;o<a;++o)l=t[o],l>=e&&l<=i&&s.push(l);if(s.length<2)return[{time:e,pos:0},{time:i,pos:1}];for(o=0,a=s.length;o<a;++o)h=s[o+1],r=s[o-1],l=s[o],Math.round((h+r)/2)!==l&&n.push({time:l,pos:o/(a-1)});return n}_getTimestampsForTable(){let t=this._cache.all||[];if(t.length)return t;const e=this.getDataTimestamps(),i=this.getLabelTimestamps();return t=e.length&&i.length?this.normalize(e.concat(i)):e.length?e:i,t=this._cache.all=t,t}getDecimalForValue(t){return(Ma(this._table,t)-this._minPos)/this._tableRange}getValueForPixel(t){const e=this._offsets,i=this.getDecimalForPixel(t)/e.factor-e.end;return Ma(this._table,i*this._tableRange+this._minPos,!0)}}ka.id=\"timeseries\",ka.defaults=wa.defaults;var Sa=Object.freeze({__proto__:null,CategoryScale:ta,LinearScale:sa,LogarithmicScale:oa,RadialLinearScale:ga,TimeScale:wa,TimeSeriesScale:ka});return bn.register(Bn,Sa,co,Jo),bn.helpers={...Ti},bn._adapters=wn,bn.Animation=xs,bn.Animations=ys,bn.animator=mt,bn.controllers=Us.controllers.items,bn.DatasetController=Ls,bn.Element=Es,bn.elements=co,bn.Interaction=Vi,bn.layouts=Zi,bn.platforms=ps,bn.Scale=$s,bn.Ticks=Is,Object.assign(bn,Bn,Sa,co,Jo,ps),bn.Chart=bn,\"undefined\"!=typeof window&&(window.Chart=bn),bn}));\n","chartjs/es6-shim.min.js":"/*!\n * https://github.com/paulmillr/es6-shim\n * @license es6-shim Copyright 2013-2014 by Paul Miller (http://paulmillr.com)\n * and contributors, MIT License\n * es6-shim: v0.25.0\n * see https://github.com/paulmillr/es6-shim/blob/0.25.0/LICENSE\n * Details and documentation:\n * https://github.com/paulmillr/es6-shim/\n */\n(function(e,t){if(typeof define===\"function\"&&define.amd){define(t)}else if(typeof exports===\"object\"){module.exports=t()}else{e.returnExports=t()}})(this,function(){\"use strict\";var e=function(e){try{e()}catch(t){return false}return true};var t=function(e,t){try{var r=function(){e.apply(this,arguments)};if(!r.__proto__){return false}Object.setPrototypeOf(r,e);r.prototype=Object.create(e.prototype,{constructor:{value:e}});return t(r)}catch(n){return false}};var r=function(){try{Object.defineProperty({},\"x\",{});return true}catch(e){return false}};var n=function(){var e=false;if(String.prototype.startsWith){try{\"/a/\".startsWith(/a/)}catch(t){e=true}}return e};var i=new Function(\"return this;\");var o=i();var a=o.isFinite;var u=!!Object.defineProperty&&r();var s=n();var f=Function.call.bind(String.prototype.indexOf);var c=Function.call.bind(Object.prototype.toString);var l=Function.call.bind(Object.prototype.hasOwnProperty);var p;var h=function(){};var v=o.Symbol||{};var y=v.species||\"@@species\";var b={string:function(e){return c(e)===\"[object String]\"},regex:function(e){return c(e)===\"[object RegExp]\"},symbol:function(e){return typeof o.Symbol===\"function\"&&typeof e===\"symbol\"}};var g=function(e,t,r,n){if(!n&&t in e){return}if(u){Object.defineProperty(e,t,{configurable:true,enumerable:false,writable:true,value:r})}else{e[t]=r}};var d={getter:function(e,t,r){if(!u){throw new TypeError(\"getters require true ES5 support\")}Object.defineProperty(e,t,{configurable:true,enumerable:false,get:r})},proxy:function(e,t,r){if(!u){throw new TypeError(\"getters require true ES5 support\")}var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,{configurable:n.configurable,enumerable:n.enumerable,get:function i(){return e[t]},set:function o(r){e[t]=r}})},redefine:function(e,t,r){if(u){var n=Object.getOwnPropertyDescriptor(e,t);n.value=r;Object.defineProperty(e,t,n)}else{e[t]=r}}};var m=function(e,t){Object.keys(t).forEach(function(r){var n=t[r];g(e,r,n,false)})};var w=Object.create||function(e,t){function r(){}r.prototype=e;var n=new r;if(typeof t!==\"undefined\"){m(n,t)}return n};var O=b.symbol(v.iterator)?v.iterator:\"_es6-shim iterator_\";if(o.Set&&typeof(new o.Set)[\"@@iterator\"]===\"function\"){O=\"@@iterator\"}var j=function(e,t){if(!t){t=function n(){return this}}var r={};r[O]=t;m(e,r);if(!e[O]&&b.symbol(O)){e[O]=t}};var I=function dt(e){var t=c(e);var r=t===\"[object Arguments]\";if(!r){r=t!==\"[object Array]\"&&e!==null&&typeof e===\"object\"&&typeof e.length===\"number\"&&e.length>=0&&c(e.callee)===\"[object Function]\"}return r};var T=Function.call.bind(Function.apply);var M={Call:function mt(e,t){var r=arguments.length>2?arguments[2]:[];if(!M.IsCallable(e)){throw new TypeError(e+\" is not a function\")}return T(e,t,r)},RequireObjectCoercible:function(e,t){if(e==null){throw new TypeError(t||\"Cannot call method on \"+e)}},TypeIsObject:function(e){return e!=null&&Object(e)===e},ToObject:function(e,t){M.RequireObjectCoercible(e,t);return Object(e)},IsCallable:function(e){return typeof e===\"function\"&&c(e)===\"[object Function]\"},ToInt32:function(e){return M.ToNumber(e)>>0},ToUint32:function(e){return M.ToNumber(e)>>>0},ToNumber:function(e){if(c(e)===\"[object Symbol]\"){throw new TypeError(\"Cannot convert a Symbol value to a number\")}return+e},ToInteger:function(e){var t=M.ToNumber(e);if(Number.isNaN(t)){return 0}if(t===0||!Number.isFinite(t)){return t}return(t>0?1:-1)*Math.floor(Math.abs(t))},ToLength:function(e){var t=M.ToInteger(e);if(t<=0){return 0}if(t>Number.MAX_SAFE_INTEGER){return Number.MAX_SAFE_INTEGER}return t},SameValue:function(e,t){if(e===t){if(e===0){return 1/e===1/t}return true}return Number.isNaN(e)&&Number.isNaN(t)},SameValueZero:function(e,t){return e===t||Number.isNaN(e)&&Number.isNaN(t)},IsIterable:function(e){return M.TypeIsObject(e)&&(typeof e[O]!==\"undefined\"||I(e))},GetIterator:function(e){if(I(e)){return new p(e,\"value\")}var t=e[O];if(!M.IsCallable(t)){throw new TypeError(\"value is not an iterable\")}var r=t.call(e);if(!M.TypeIsObject(r)){throw new TypeError(\"bad iterator\")}return r},IteratorNext:function(e){var t=arguments.length>1?e.next(arguments[1]):e.next();if(!M.TypeIsObject(t)){throw new TypeError(\"bad iterator\")}return t},Construct:function(e,t){var r;if(M.IsCallable(e[y])){r=e[y]()}else{r=w(e.prototype||null)}m(r,{_es6construct:true});var n=M.Call(e,r,t);return M.TypeIsObject(n)?n:r}};var N=function(e){if(!M.TypeIsObject(e)){throw new TypeError(\"bad object\")}if(!e._es6construct){if(e.constructor&&M.IsCallable(e.constructor[y])){e=e.constructor[y](e)}m(e,{_es6construct:true})}return e};var _=function(){function e(e){var t=Math.floor(e),r=e-t;if(r<.5){return t}if(r>.5){return t+1}return t%2?t+1:t}function t(t,r,n){var i=(1<<r-1)-1,o,a,u,s,f,c,l;if(t!==t){a=(1<<r)-1;u=Math.pow(2,n-1);o=0}else if(t===Infinity||t===-Infinity){a=(1<<r)-1;u=0;o=t<0?1:0}else if(t===0){a=0;u=0;o=1/t===-Infinity?1:0}else{o=t<0;t=Math.abs(t);if(t>=Math.pow(2,1-i)){a=Math.min(Math.floor(Math.log(t)/Math.LN2),1023);u=e(t/Math.pow(2,a)*Math.pow(2,n));if(u/Math.pow(2,n)>=2){a=a+1;u=1}if(a>i){a=(1<<r)-1;u=0}else{a=a+i;u=u-Math.pow(2,n)}}else{a=0;u=e(t/Math.pow(2,1-i-n))}}f=[];for(s=n;s;s-=1){f.push(u%2?1:0);u=Math.floor(u/2)}for(s=r;s;s-=1){f.push(a%2?1:0);a=Math.floor(a/2)}f.push(o?1:0);f.reverse();c=f.join(\"\");l=[];while(c.length){l.push(parseInt(c.slice(0,8),2));c=c.slice(8)}return l}function r(e,t,r){var n=[],i,o,a,u,s,f,c,l;for(i=e.length;i;i-=1){a=e[i-1];for(o=8;o;o-=1){n.push(a%2?1:0);a=a>>1}}n.reverse();u=n.join(\"\");s=(1<<t-1)-1;f=parseInt(u.slice(0,1),2)?-1:1;c=parseInt(u.slice(1,1+t),2);l=parseInt(u.slice(1+t),2);if(c===(1<<t)-1){return l!==0?NaN:f*Infinity}else if(c>0){return f*Math.pow(2,c-s)*(1+l/Math.pow(2,r))}else if(l!==0){return f*Math.pow(2,-(s-1))*(l/Math.pow(2,r))}else{return f<0?-0:0}}function n(e){return r(e,11,52)}function i(e){return t(e,11,52)}function o(e){return r(e,8,23)}function a(e){return t(e,8,23)}var u={toFloat32:function(e){return o(a(e))}};if(typeof Float32Array!==\"undefined\"){var s=new Float32Array(1);u.toFloat32=function(e){s[0]=e;return s[0]}}return u}();m(String,{fromCodePoint:function wt(e){var t=[];var r;for(var n=0,i=arguments.length;n<i;n++){r=Number(arguments[n]);if(!M.SameValue(r,M.ToInteger(r))||r<0||r>1114111){throw new RangeError(\"Invalid code point \"+r)}if(r<65536){t.push(String.fromCharCode(r))}else{r-=65536;t.push(String.fromCharCode((r>>10)+55296));t.push(String.fromCharCode(r%1024+56320))}}return t.join(\"\")},raw:function Ot(e){var t=M.ToObject(e,\"bad callSite\");var r=t.raw;var n=M.ToObject(r,\"bad raw value\");var i=n.length;var o=M.ToLength(i);if(o<=0){return\"\"}var a=[];var u=0;var s,f,c,l;while(u<o){s=String(u);f=n[s];c=String(f);a.push(c);if(u+1>=o){break}f=u+1<arguments.length?arguments[u+1]:\"\";l=String(f);a.push(l);u++}return a.join(\"\")}});if(String.fromCodePoint.length!==1){var E=Function.apply.bind(String.fromCodePoint);g(String,\"fromCodePoint\",function jt(e){return E(this,arguments)},true)}var x=function It(e,t){if(t<1){return\"\"}if(t%2){return It(e,t-1)+e}var r=It(e,t/2);return r+r};var S=Infinity;var P={repeat:function Tt(e){M.RequireObjectCoercible(this);var t=String(this);e=M.ToInteger(e);if(e<0||e>=S){throw new RangeError(\"repeat count must be less than infinity and not overflow maximum string size\")}return x(t,e)},startsWith:function(e){M.RequireObjectCoercible(this);var t=String(this);if(b.regex(e)){throw new TypeError('Cannot call method \"startsWith\" with a regex')}e=String(e);var r=arguments.length>1?arguments[1]:void 0;var n=Math.max(M.ToInteger(r),0);return t.slice(n,n+e.length)===e},endsWith:function(e){M.RequireObjectCoercible(this);var t=String(this);if(b.regex(e)){throw new TypeError('Cannot call method \"endsWith\" with a regex')}e=String(e);var r=t.length;var n=arguments.length>1?arguments[1]:void 0;var i=typeof n===\"undefined\"?r:M.ToInteger(n);var o=Math.min(Math.max(i,0),r);return t.slice(o-e.length,o)===e},includes:function Mt(e){var t=arguments.length>1?arguments[1]:void 0;return f(this,e,t)!==-1},codePointAt:function(e){M.RequireObjectCoercible(this);var t=String(this);var r=M.ToInteger(e);var n=t.length;if(r>=0&&r<n){var i=t.charCodeAt(r);var o=r+1===n;if(i<55296||i>56319||o){return i}var a=t.charCodeAt(r+1);if(a<56320||a>57343){return i}return(i-55296)*1024+(a-56320)+65536}}};m(String.prototype,P);var C=\"\\x85\".trim().length!==1;if(C){delete String.prototype.trim;var k=[\"\t\\n\u000b\\f\\r \\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\",\"\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\",\"\\u2029\\ufeff\"].join(\"\");var A=new RegExp(\"(^[\"+k+\"]+)|([\"+k+\"]+$)\",\"g\");m(String.prototype,{trim:function(){if(typeof this===\"undefined\"||this===null){throw new TypeError(\"can't convert \"+this+\" to object\")}return String(this).replace(A,\"\")}})}var R=function(e){M.RequireObjectCoercible(e);this._s=String(e);this._i=0};R.prototype.next=function(){var e=this._s,t=this._i;if(typeof e===\"undefined\"||t>=e.length){this._s=void 0;return{value:void 0,done:true}}var r=e.charCodeAt(t),n,i;if(r<55296||r>56319||t+1===e.length){i=1}else{n=e.charCodeAt(t+1);i=n<56320||n>57343?1:2}this._i=t+i;return{value:e.substr(t,i),done:false}};j(R.prototype);j(String.prototype,function(){return new R(this)});if(!s){g(String.prototype,\"startsWith\",P.startsWith,true);g(String.prototype,\"endsWith\",P.endsWith,true)}var F={from:function(e){var t=arguments.length>1?arguments[1]:void 0;var r=M.ToObject(e,\"bad iterable\");if(typeof t!==\"undefined\"&&!M.IsCallable(t)){throw new TypeError(\"Array.from: when provided, the second argument must be a function\")}var n=arguments.length>2;var i=n?arguments[2]:void 0;var o=M.IsIterable(r);var a;var u,s,f;if(o){s=0;u=M.IsCallable(this)?Object(new this):[];var c=o?M.GetIterator(r):null;var l;do{l=M.IteratorNext(c);if(!l.done){f=l.value;if(t){u[s]=n?t.call(i,f,s):t(f,s)}else{u[s]=f}s+=1}}while(!l.done);a=s}else{a=M.ToLength(r.length);u=M.IsCallable(this)?Object(new this(a)):new Array(a);for(s=0;s<a;++s){f=r[s];if(t){u[s]=n?t.call(i,f,s):t(f,s)}else{u[s]=f}}}u.length=a;return u},of:function(){return Array.from(arguments)}};m(Array,F);var D=function(){try{return Array.from({length:-1}).length===0}catch(e){return false}};if(!D()){g(Array,\"from\",F.from,true)}var z=function(e){return{value:e,done:arguments.length===0}};p=function(e,t){this.i=0;this.array=e;this.kind=t};m(p.prototype,{next:function(){var e=this.i,t=this.array;if(!(this instanceof p)){throw new TypeError(\"Not an ArrayIterator\")}if(typeof t!==\"undefined\"){var r=M.ToLength(t.length);for(;e<r;e++){var n=this.kind;var i;if(n===\"key\"){i=e}else if(n===\"value\"){i=t[e]}else if(n===\"entry\"){i=[e,t[e]]}this.i=e+1;return{value:i,done:false}}}this.array=void 0;return{value:void 0,done:true}}});j(p.prototype);var L=function(e,t){this.object=e;this.array=null;this.kind=t};function q(e){var t=[];for(var r in e){t.push(r)}return t}m(L.prototype,{next:function(){var e,t=this.array;if(!(this instanceof L)){throw new TypeError(\"Not an ObjectIterator\")}if(t===null){t=this.array=q(this.object)}while(M.ToLength(t.length)>0){e=t.shift();if(!(e in this.object)){continue}if(this.kind===\"key\"){return z(e)}else if(this.kind===\"value\"){return z(this.object[e])}else{return z([e,this.object[e]])}}return z()}});j(L.prototype);var G={copyWithin:function(e,t){var r=arguments[2];var n=M.ToObject(this);var i=M.ToLength(n.length);e=M.ToInteger(e);t=M.ToInteger(t);var o=e<0?Math.max(i+e,0):Math.min(e,i);var a=t<0?Math.max(i+t,0):Math.min(t,i);r=typeof r===\"undefined\"?i:M.ToInteger(r);var u=r<0?Math.max(i+r,0):Math.min(r,i);var s=Math.min(u-a,i-o);var f=1;if(a<o&&o<a+s){f=-1;a+=s-1;o+=s-1}while(s>0){if(l(n,a)){n[o]=n[a]}else{delete n[a]}a+=f;o+=f;s-=1}return n},fill:function(e){var t=arguments.length>1?arguments[1]:void 0;var r=arguments.length>2?arguments[2]:void 0;var n=M.ToObject(this);var i=M.ToLength(n.length);t=M.ToInteger(typeof t===\"undefined\"?0:t);r=M.ToInteger(typeof r===\"undefined\"?i:r);var o=t<0?Math.max(i+t,0):Math.min(t,i);var a=r<0?i+r:r;for(var u=o;u<i&&u<a;++u){n[u]=e}return n},find:function Nt(e){var t=M.ToObject(this);var r=M.ToLength(t.length);if(!M.IsCallable(e)){throw new TypeError(\"Array#find: predicate must be a function\")}var n=arguments.length>1?arguments[1]:null;for(var i=0,o;i<r;i++){o=t[i];if(n){if(e.call(n,o,i,t)){return o}}else if(e(o,i,t)){return o}}},findIndex:function _t(e){var t=M.ToObject(this);var r=M.ToLength(t.length);if(!M.IsCallable(e)){throw new TypeError(\"Array#findIndex: predicate must be a function\")}var n=arguments.length>1?arguments[1]:null;for(var i=0;i<r;i++){if(n){if(e.call(n,t[i],i,t)){return i}}else if(e(t[i],i,t)){return i}}return-1},keys:function(){return new p(this,\"key\")},values:function(){return new p(this,\"value\")},entries:function(){return new p(this,\"entry\")}};if(Array.prototype.keys&&!M.IsCallable([1].keys().next)){delete Array.prototype.keys}if(Array.prototype.entries&&!M.IsCallable([1].entries().next)){delete Array.prototype.entries}if(Array.prototype.keys&&Array.prototype.entries&&!Array.prototype.values&&Array.prototype[O]){m(Array.prototype,{values:Array.prototype[O]});if(b.symbol(v.unscopables)){Array.prototype[v.unscopables].values=true}}m(Array.prototype,G);j(Array.prototype,function(){return this.values()});if(Object.getPrototypeOf){j(Object.getPrototypeOf([].values()))}var W=Math.pow(2,53)-1;m(Number,{MAX_SAFE_INTEGER:W,MIN_SAFE_INTEGER:-W,EPSILON:2.220446049250313e-16,parseInt:o.parseInt,parseFloat:o.parseFloat,isFinite:function(e){return typeof e===\"number\"&&a(e)},isInteger:function(e){return Number.isFinite(e)&&M.ToInteger(e)===e},isSafeInteger:function(e){return Number.isInteger(e)&&Math.abs(e)<=Number.MAX_SAFE_INTEGER},isNaN:function(e){return e!==e}});if(![,1].find(function(e,t){return t===0})){g(Array.prototype,\"find\",G.find,true)}if([,1].findIndex(function(e,t){return t===0})!==0){g(Array.prototype,\"findIndex\",G.findIndex,true)}if(u){m(Object,{assign:function(e,t){if(!M.TypeIsObject(e)){throw new TypeError(\"target must be an object\")}return Array.prototype.reduce.call(arguments,function(e,t){return Object.keys(Object(t)).reduce(function(e,r){e[r]=t[r];return e},e)})},is:function(e,t){return M.SameValue(e,t)},setPrototypeOf:function(e,t){var r;var n=function(e,t){if(!M.TypeIsObject(e)){throw new TypeError(\"cannot set prototype on a non-object\")}if(!(t===null||M.TypeIsObject(t))){throw new TypeError(\"can only set prototype to an object or null\"+t)}};var i=function(e,t){n(e,t);r.call(e,t);return e};try{r=e.getOwnPropertyDescriptor(e.prototype,t).set;r.call({},null)}catch(o){if(e.prototype!=={}[t]){return}r=function(e){this[t]=e};i.polyfill=i(i({},null),e.prototype)instanceof e}return i}(Object,\"__proto__\")})}if(Object.setPrototypeOf&&Object.getPrototypeOf&&Object.getPrototypeOf(Object.setPrototypeOf({},null))!==null&&Object.getPrototypeOf(Object.create(null))===null){(function(){var e=Object.create(null);var t=Object.getPrototypeOf,r=Object.setPrototypeOf;Object.getPrototypeOf=function(r){var n=t(r);return n===e?null:n};Object.setPrototypeOf=function(t,n){if(n===null){n=e}return r(t,n)};Object.setPrototypeOf.polyfill=false})()}var V=function(){try{Object.keys(\"foo\");return true}catch(e){return false}}();if(!V){var U=Object.keys;g(Object,\"keys\",function Et(e){return U(M.ToObject(e))},true)}if(Object.getOwnPropertyNames){var X=function(){try{Object.getOwnPropertyNames(\"foo\");return true}catch(e){return false}}();if(!X){var Z=Object.getOwnPropertyNames;g(Object,\"getOwnPropertyNames\",function xt(e){return Z(M.ToObject(e))},true)}}if(!RegExp.prototype.flags&&u){var $=function St(){if(!M.TypeIsObject(this)){throw new TypeError(\"Method called on incompatible type: must be an object.\")}var e=\"\";if(this.global){e+=\"g\"}if(this.ignoreCase){e+=\"i\"}if(this.multiline){e+=\"m\"}if(this.unicode){e+=\"u\"}if(this.sticky){e+=\"y\"}return e};d.getter(RegExp.prototype,\"flags\",$)}var K=function(){try{return String(new RegExp(/a/g,\"i\"))===\"/a/i\"}catch(e){return false}}();if(!K&&u){var B=RegExp;var H=function Pt(e,t){if(b.regex(e)&&b.string(t)){return new Pt(e.source,t)}return new B(e,t)};g(H,\"toString\",B.toString.bind(B),true);if(Object.setPrototypeOf){Object.setPrototypeOf(B,H)}Object.getOwnPropertyNames(B).forEach(function(e){if(e===\"$input\"){return}if(e in h){return}d.proxy(B,e,H)});H.prototype=B.prototype;d.redefine(B.prototype,\"constructor\",H);RegExp=H;d.redefine(o,\"RegExp\",H)}var J={acosh:function(e){var t=Number(e);if(Number.isNaN(t)||e<1){return NaN}if(t===1){return 0}if(t===Infinity){return t}return Math.log(t/Math.E+Math.sqrt(t+1)*Math.sqrt(t-1)/Math.E)+1},asinh:function(e){e=Number(e);if(e===0||!a(e)){return e}return e<0?-Math.asinh(-e):Math.log(e+Math.sqrt(e*e+1))},atanh:function(e){e=Number(e);if(Number.isNaN(e)||e<-1||e>1){return NaN}if(e===-1){return-Infinity}if(e===1){return Infinity}if(e===0){return e}return.5*Math.log((1+e)/(1-e))},cbrt:function(e){e=Number(e);if(e===0){return e}var t=e<0,r;if(t){e=-e}r=Math.pow(e,1/3);return t?-r:r},clz32:function(e){e=Number(e);var t=M.ToUint32(e);if(t===0){return 32}return 32-t.toString(2).length},cosh:function(e){e=Number(e);if(e===0){return 1}if(Number.isNaN(e)){return NaN}if(!a(e)){return Infinity}if(e<0){e=-e}if(e>21){return Math.exp(e)/2}return(Math.exp(e)+Math.exp(-e))/2},expm1:function(e){var t=Number(e);if(t===-Infinity){return-1}if(!a(t)||e===0){return t}if(Math.abs(t)>.5){return Math.exp(t)-1}var r=t;var n=0;var i=1;while(n+r!==n){n+=r;i+=1;r*=t/i}return n},hypot:function(e,t){var r=false;var n=true;var i=false;var o=[];Array.prototype.every.call(arguments,function(e){var t=Number(e);if(Number.isNaN(t)){r=true}else if(t===Infinity||t===-Infinity){i=true}else if(t!==0){n=false}if(i){return false}else if(!r){o.push(Math.abs(t))}return true});if(i){return Infinity}if(r){return NaN}if(n){return 0}o.sort(function(e,t){return t-e});var a=o[0];var u=o.map(function(e){return e/a});var s=u.reduce(function(e,t){return e+t*t},0);return a*Math.sqrt(s)},log2:function(e){return Math.log(e)*Math.LOG2E},log10:function(e){return Math.log(e)*Math.LOG10E},log1p:function(e){var t=Number(e);if(t<-1||Number.isNaN(t)){return NaN}if(t===0||t===Infinity){return t}if(t===-1){return-Infinity}return 1+t-1===0?t:t*(Math.log(1+t)/(1+t-1))},sign:function(e){var t=+e;if(t===0){return t}if(Number.isNaN(t)){return t}return t<0?-1:1},sinh:function(e){var t=Number(e);if(!a(e)||e===0){return e}if(Math.abs(t)<1){return(Math.expm1(t)-Math.expm1(-t))/2}return(Math.exp(t-1)-Math.exp(-t-1))*Math.E/2},tanh:function(e){var t=Number(e);if(Number.isNaN(e)||t===0){return t}if(t===Infinity){return 1}if(t===-Infinity){return-1}var r=Math.expm1(t);var n=Math.expm1(-t);if(r===Infinity){return 1}if(n===Infinity){return-1}return(r-n)/(Math.exp(t)+Math.exp(-t))},trunc:function(e){var t=Number(e);return t<0?-Math.floor(-t):Math.floor(t)},imul:function(e,t){e=M.ToUint32(e);t=M.ToUint32(t);var r=e>>>16&65535;var n=e&65535;var i=t>>>16&65535;var o=t&65535;return n*o+(r*o+n*i<<16>>>0)|0},fround:function(e){if(e===0||e===Infinity||e===-Infinity||Number.isNaN(e)){return e}var t=Number(e);return _.toFloat32(t)}};m(Math,J);g(Math,\"tanh\",J.tanh,Math.tanh(-2e-17)!==-2e-17);g(Math,\"acosh\",J.acosh,Math.acosh(Number.MAX_VALUE)===Infinity);g(Math,\"sinh\",J.sinh,Math.sinh(-2e-17)!==-2e-17);var Q=Math.expm1(10);g(Math,\"expm1\",J.expm1,Q>22025.465794806718||Q<22025.465794806718);var Y=Math.round(.5-Number.EPSILON/4)===0&&Math.round(-.5+Number.EPSILON/3.99)===1;var et=Math.round;g(Math,\"round\",function Ct(e){if(-.5<=e&&e<.5&&e!==0){return Math.sign(e*0)}return et(e)},!Y);if(Math.imul(4294967295,5)!==-5){Math.imul=J.imul}var tt=function(){var e,t;M.IsPromise=function(e){if(!M.TypeIsObject(e)){return false}if(!e._promiseConstructor){return false}if(typeof e._status===\"undefined\"){return false}return true};var r=function(e){if(!M.IsCallable(e)){throw new TypeError(\"bad promise constructor\")}var t=this;var r=function(e,r){t.resolve=e;t.reject=r};t.promise=M.Construct(e,[r]);if(!t.promise._es6construct){throw new TypeError(\"bad promise constructor\")}if(!(M.IsCallable(t.resolve)&&M.IsCallable(t.reject))){throw new TypeError(\"bad promise constructor\")}};var n=o.setTimeout;var i;if(typeof window!==\"undefined\"&&M.IsCallable(window.postMessage)){i=function(){var e=[];var t=\"zero-timeout-message\";var r=function(r){e.push(r);window.postMessage(t,\"*\")};var n=function(r){if(r.source===window&&r.data===t){r.stopPropagation();if(e.length===0){return}var n=e.shift();n()}};window.addEventListener(\"message\",n,true);return r}}var a=function(){var e=o.Promise;return e&&e.resolve&&function(t){return e.resolve().then(t)}};var u=M.IsCallable(o.setImmediate)?o.setImmediate.bind(o):typeof process===\"object\"&&process.nextTick?process.nextTick:a()||(M.IsCallable(i)?i():function(e){n(e,0)});var s=function(e,t){if(!M.TypeIsObject(e)){return false}var r=t.resolve;var n=t.reject;try{var i=e.then;if(!M.IsCallable(i)){return false}i.call(e,r,n)}catch(o){n(o)}return true};var f=function(e,t){e.forEach(function(e){u(function(){var r=e.handler;var n=e.capability;var i=n.resolve;var o=n.reject;try{var a=r(t);if(a===n.promise){throw new TypeError(\"self resolution\")}var u=s(a,n);if(!u){i(a)}}catch(f){o(f)}})})};var c=function(e,t,n){return function(i){if(i===e){return n(new TypeError(\"self resolution\"))}var o=e._promiseConstructor;var a=new r(o);var u=s(i,a);if(u){return a.promise.then(t,n)}else{return t(i)}}};e=function(e){var t=this;t=N(t);if(!t._promiseConstructor){throw new TypeError(\"bad promise\")}if(typeof t._status!==\"undefined\"){throw new TypeError(\"promise already initialized\")}if(!M.IsCallable(e)){throw new TypeError(\"not a valid resolver\")}t._status=\"unresolved\";t._resolveReactions=[];t._rejectReactions=[];var r=function(e){if(t._status!==\"unresolved\"){return}var r=t._resolveReactions;t._result=e;t._resolveReactions=void 0;t._rejectReactions=void 0;t._status=\"has-resolution\";f(r,e)};var n=function(e){if(t._status!==\"unresolved\"){return}var r=t._rejectReactions;t._result=e;t._resolveReactions=void 0;t._rejectReactions=void 0;t._status=\"has-rejection\";f(r,e)};try{e(r,n)}catch(i){n(i)}return t};t=e.prototype;var l=function(e,t,r,n){var i=false;return function(o){if(i){return}i=true;t[e]=o;if(--n.count===0){var a=r.resolve;a(t)}}};g(e,y,function(e){var r=this;var n=r.prototype||t;e=e||w(n);m(e,{_status:void 0,_result:void 0,_resolveReactions:void 0,_rejectReactions:void 0,_promiseConstructor:void 0});e._promiseConstructor=r;return e});m(e,{all:function p(e){var t=this;var n=new r(t);var i=n.resolve;var o=n.reject;try{if(!M.IsIterable(e)){throw new TypeError(\"bad iterable\")}var a=M.GetIterator(e);var u=[],s={count:1};for(var f=0;;f++){var c=M.IteratorNext(a);if(c.done){break}var p=t.resolve(c.value);var h=l(f,u,n,s);s.count++;p.then(h,n.reject)}if(--s.count===0){i(u)}}catch(v){o(v)}return n.promise},race:function h(e){var t=this;var n=new r(t);var i=n.resolve;var o=n.reject;try{if(!M.IsIterable(e)){throw new TypeError(\"bad iterable\")}var a=M.GetIterator(e);while(true){var u=M.IteratorNext(a);if(u.done){break}var s=t.resolve(u.value);s.then(i,o)}}catch(f){o(f)}return n.promise},reject:function v(e){var t=this;var n=new r(t);var i=n.reject;i(e);return n.promise},resolve:function b(e){var t=this;if(M.IsPromise(e)){var n=e._promiseConstructor;if(n===t){return e}}var i=new r(t);var o=i.resolve;o(e);return i.promise}});m(t,{\"catch\":function(e){return this.then(void 0,e)},then:function d(e,t){var n=this;if(!M.IsPromise(n)){throw new TypeError(\"not a promise\")}var i=this.constructor;var o=new r(i);if(!M.IsCallable(t)){t=function(e){throw e}}if(!M.IsCallable(e)){e=function(e){return e}}var a=c(n,e,t);var u={capability:o,handler:a};var s={capability:o,handler:t};switch(n._status){case\"unresolved\":n._resolveReactions.push(u);n._rejectReactions.push(s);break;case\"has-resolution\":f([u],n._result);break;case\"has-rejection\":f([s],n._result);break;default:throw new TypeError(\"unexpected\")}return o.promise}});return e}();if(o.Promise){delete o.Promise.accept;delete o.Promise.defer;delete o.Promise.prototype.chain}m(o,{Promise:tt});var rt=t(o.Promise,function(e){return e.resolve(42)instanceof e});var nt=function(){try{o.Promise.reject(42).then(null,5).then(null,h);return true}catch(e){return false}}();var it=function(){try{Promise.call(3,h)}catch(e){return true}return false}();if(!rt||!nt||!it){Promise=tt;g(o,\"Promise\",tt,true)}var ot=function(e){var t=Object.keys(e.reduce(function(e,t){e[t]=true;return e},{}));return e.join(\":\")===t.join(\":\")};var at=ot([\"z\",\"a\",\"bb\"]);var ut=ot([\"z\",1,\"a\",\"3\",2]);if(u){var st=function kt(e){if(!at){return null}var t=typeof e;if(t===\"string\"){return\"$\"+e}else if(t===\"number\"){if(!ut){return\"n\"+e}return e}return null};var ft=function At(){return Object.create?Object.create(null):{}};var ct={Map:function(){var e={};function t(e,t){this.key=e;this.value=t;this.next=null;this.prev=null}t.prototype.isRemoved=function(){return this.key===e};function r(e,t){this.head=e._head;this.i=this.head;this.kind=t}r.prototype={next:function(){var e=this.i,t=this.kind,r=this.head,n;if(typeof this.i===\"undefined\"){return{value:void 0,done:true}}while(e.isRemoved()&&e!==r){e=e.prev}while(e.next!==r){e=e.next;if(!e.isRemoved()){if(t===\"key\"){n=e.key}else if(t===\"value\"){n=e.value}else{n=[e.key,e.value]}this.i=e;return{value:n,done:false}}}this.i=void 0;return{value:void 0,done:true}}};j(r.prototype);function n(e){var r=this;if(!M.TypeIsObject(r)){throw new TypeError(\"Map does not accept arguments when called as a function\")}r=N(r);if(!r._es6map){throw new TypeError(\"bad map\")}var n=new t(null,null);n.next=n.prev=n;m(r,{_head:n,_storage:ft(),_size:0});if(typeof e!==\"undefined\"&&e!==null){var i=M.GetIterator(e);var o=r.set;if(!M.IsCallable(o)){throw new TypeError(\"bad map\")}while(true){var a=M.IteratorNext(i);if(a.done){break}var u=a.value;if(!M.TypeIsObject(u)){throw new TypeError(\"expected iterable of pairs\")}o.call(r,u[0],u[1])}}return r}var i=n.prototype;g(n,y,function(e){var t=this;var r=t.prototype||i;e=e||w(r);m(e,{_es6map:true});return e});d.getter(n.prototype,\"size\",function(){if(typeof this._size===\"undefined\"){throw new TypeError(\"size method called on incompatible Map\")}return this._size});m(n.prototype,{get:function(e){var t=st(e);if(t!==null){var r=this._storage[t];if(r){return r.value}else{return}}var n=this._head,i=n;while((i=i.next)!==n){if(M.SameValueZero(i.key,e)){return i.value}}},has:function(e){var t=st(e);if(t!==null){return typeof this._storage[t]!==\"undefined\"}var r=this._head,n=r;while((n=n.next)!==r){if(M.SameValueZero(n.key,e)){return true}}return false},set:function(e,r){var n=this._head,i=n,o;var a=st(e);if(a!==null){if(typeof this._storage[a]!==\"undefined\"){this._storage[a].value=r;return this}else{o=this._storage[a]=new t(e,r);i=n.prev}}while((i=i.next)!==n){if(M.SameValueZero(i.key,e)){i.value=r;return this}}o=o||new t(e,r);if(M.SameValue(-0,e)){o.key=+0}o.next=this._head;o.prev=this._head.prev;o.prev.next=o;o.next.prev=o;this._size+=1;return this},\"delete\":function(t){var r=this._head,n=r;var i=st(t);if(i!==null){if(typeof this._storage[i]===\"undefined\"){return false}n=this._storage[i].prev;delete this._storage[i]}while((n=n.next)!==r){if(M.SameValueZero(n.key,t)){n.key=n.value=e;n.prev.next=n.next;n.next.prev=n.prev;this._size-=1;return true}}return false},clear:function(){this._size=0;this._storage=ft();var t=this._head,r=t,n=r.next;while((r=n)!==t){r.key=r.value=e;n=r.next;r.next=r.prev=t}t.next=t.prev=t},keys:function(){return new r(this,\"key\")},values:function(){return new r(this,\"value\")},entries:function(){return new r(this,\"key+value\")},forEach:function(e){var t=arguments.length>1?arguments[1]:null;var r=this.entries();for(var n=r.next();!n.done;n=r.next()){if(t){e.call(t,n.value[1],n.value[0],this)}else{e(n.value[1],n.value[0],this)}}}});j(n.prototype,function(){return this.entries()});return n}(),Set:function(){var e=function n(e){var t=this;if(!M.TypeIsObject(t)){throw new TypeError(\"Set does not accept arguments when called as a function\")}t=N(t);if(!t._es6set){throw new TypeError(\"bad set\")}m(t,{\"[[SetData]]\":null,_storage:ft()});if(typeof e!==\"undefined\"&&e!==null){var r=M.GetIterator(e);var n=t.add;if(!M.IsCallable(n)){throw new TypeError(\"bad set\")}while(true){var i=M.IteratorNext(r);if(i.done){break}var o=i.value;n.call(t,o)}}return t};var t=e.prototype;g(e,y,function(e){var r=this;var n=r.prototype||t;e=e||w(n);m(e,{_es6set:true});return e});var r=function i(e){if(!e[\"[[SetData]]\"]){var t=e[\"[[SetData]]\"]=new ct.Map;Object.keys(e._storage).forEach(function(e){if(e.charCodeAt(0)===36){e=e.slice(1)}else if(e.charAt(0)===\"n\"){e=+e.slice(1)}else{e=+e}t.set(e,e)});e._storage=null}};d.getter(e.prototype,\"size\",function(){if(typeof this._storage===\"undefined\"){throw new TypeError(\"size method called on incompatible Set\")}r(this);return this[\"[[SetData]]\"].size});m(e.prototype,{has:function(e){var t;if(this._storage&&(t=st(e))!==null){return!!this._storage[t]}r(this);return this[\"[[SetData]]\"].has(e)},add:function(e){var t;if(this._storage&&(t=st(e))!==null){this._storage[t]=true;return this}r(this);this[\"[[SetData]]\"].set(e,e);return this},\"delete\":function(e){var t;if(this._storage&&(t=st(e))!==null){var n=l(this._storage,t);return delete this._storage[t]&&n}r(this);return this[\"[[SetData]]\"][\"delete\"](e)},clear:function(){if(this._storage){this._storage=ft()}else{this[\"[[SetData]]\"].clear()}},values:function(){r(this);return this[\"[[SetData]]\"].values()},entries:function(){r(this);return this[\"[[SetData]]\"].entries()},forEach:function(e){var t=arguments.length>1?arguments[1]:null;var n=this;r(n);this[\"[[SetData]]\"].forEach(function(r,i){if(t){e.call(t,i,i,n)}else{e(i,i,n)}})}});g(e,\"keys\",e.values,true);j(e.prototype,function(){return this.values()});return e}()};m(o,ct);if(o.Map||o.Set){if(typeof o.Map.prototype.clear!==\"function\"||(new o.Set).size!==0||(new o.Map).size!==0||typeof o.Map.prototype.keys!==\"function\"||typeof o.Set.prototype.keys!==\"function\"||typeof o.Map.prototype.forEach!==\"function\"||typeof o.Set.prototype.forEach!==\"function\"||e(o.Map)||e(o.Set)||!t(o.Map,function(e){var t=new e([]);t.set(42,42);return t instanceof e})){o.Map=ct.Map;o.Set=ct.Set}}if(o.Set.prototype.keys!==o.Set.prototype.values){g(o.Set.prototype,\"keys\",o.Set.prototype.values,true)}j(Object.getPrototypeOf((new o.Map).keys()));j(Object.getPrototypeOf((new o.Set).keys()))}if(!o.Reflect){g(o,\"Reflect\",{})}var lt=o.Reflect;var pt=function Rt(e){if(!M.TypeIsObject(e)){throw new TypeError(\"target must be an object\")}};m(o.Reflect,{apply:function Ft(){return M.Call.apply(null,arguments)},construct:function Dt(e,t){if(!M.IsCallable(e)){throw new TypeError(\"First argument must be callable.\")}return M.Construct(e,t)},deleteProperty:function zt(e,t){pt(e);if(u){var r=Object.getOwnPropertyDescriptor(e,t);if(r&&!r.configurable){return false}}return delete e[t]},enumerate:function Lt(e){pt(e);return new L(e,\"key\")},has:function qt(e,t){pt(e);return t in e}});if(Object.getOwnPropertyNames){m(o.Reflect,{ownKeys:function Gt(e){pt(e);var t=Object.getOwnPropertyNames(e);if(M.IsCallable(Object.getOwnPropertySymbols)){t.push.apply(t,Object.getOwnPropertySymbols(e))}return t}})}if(Object.preventExtensions){m(o.Reflect,{isExtensible:function Wt(e){pt(e);return Object.isExtensible(e)},preventExtensions:function Vt(e){pt(e);return yt(function(){Object.preventExtensions(e)})}})}if(u){var ht=function Ut(e,t,r){var n=Object.getOwnPropertyDescriptor(e,t);if(!n){var i=Object.getPrototypeOf(e);if(i===null){return undefined}return ht(i,t,r)}if(\"value\"in n){return n.value}if(n.get){return n.get.call(r)}return undefined};var vt=function Xt(e,t,r,n){var i=Object.getOwnPropertyDescriptor(e,t);if(!i){var o=Object.getPrototypeOf(e);if(o!==null){return vt(o,t,r,n)}i={value:void 0,writable:true,enumerable:true,configurable:true}}if(\"value\"in i){if(!i.writable){return false}if(!M.TypeIsObject(n)){return false}var a=Object.getOwnPropertyDescriptor(n,t);if(a){return lt.defineProperty(n,t,{value:r})}else{return lt.defineProperty(n,t,{value:r,writable:true,enumerable:true,configurable:true})}}if(i.set){i.set.call(n,r);return true}return false\n};var yt=function Zt(e){try{e()}catch(t){return false}return true};m(o.Reflect,{defineProperty:function $t(e,t,r){pt(e);return yt(function(){Object.defineProperty(e,t,r)})},getOwnPropertyDescriptor:function Kt(e,t){pt(e);return Object.getOwnPropertyDescriptor(e,t)},get:function Bt(e,t){pt(e);var r=arguments.length>2?arguments[2]:e;return ht(e,t,r)},set:function Ht(e,t,r){pt(e);var n=arguments.length>3?arguments[3]:e;return vt(e,t,r,n)}})}if(Object.getPrototypeOf){var bt=Object.getPrototypeOf;m(o.Reflect,{getPrototypeOf:function Jt(e){pt(e);return bt(e)}})}if(Object.setPrototypeOf){var gt=function(e,t){while(t){if(e===t){return true}t=lt.getPrototypeOf(t)}return false};m(o.Reflect,{setPrototypeOf:function Qt(e,t){pt(e);if(t!==null&&!M.TypeIsObject(t)){throw new TypeError(\"proto must be an object or null\")}if(t===lt.getPrototypeOf(e)){return true}if(lt.isExtensible&&!lt.isExtensible(e)){return false}if(gt(e,t)){return false}Object.setPrototypeOf(e,t);return true}})}return o});\n\n","js-storage/storage-wrapper.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'js-storage/js.storage'\n], function ($, storage) {\n 'use strict';\n\n if (window.cookieStorage) {\n var cookiesConfig = window.cookiesConfig || {};\n\n $.extend(window.cookieStorage, {\n _secure: !!cookiesConfig.secure,\n _samesite: cookiesConfig.samesite ? cookiesConfig.samesite : 'lax',\n\n /**\n * Set value under name\n * @param {String} name\n * @param {String} value\n * @param {Object} [options]\n */\n setItem: function (name, value, options) {\n var _default = {\n expires: this._expires,\n path: this._path,\n domain: this._domain,\n secure: this._secure,\n samesite: this._samesite\n };\n\n $.cookie(this._prefix + name, value, $.extend(_default, options || {}));\n },\n\n /**\n * Set default options\n * @param {Object} c\n * @returns {storage}\n */\n setConf: function (c) {\n if (c.path) {\n this._path = c.path;\n }\n\n if (c.domain) {\n this._domain = c.domain;\n }\n\n if (c.expires) {\n this._expires = c.expires;\n }\n\n if (typeof c.secure !== 'undefined') {\n this._secure = c.secure;\n }\n\n if (typeof c.samesite !== 'undefined') {\n this._samesite = c.samesite;\n }\n\n return this;\n }\n });\n }\n\n $.alwaysUseJsonInStorage = $.alwaysUseJsonInStorage || storage.alwaysUseJsonInStorage;\n $.cookieStorage = $.cookieStorage || storage.cookieStorage;\n $.initNamespaceStorage = $.initNamespaceStorage || storage.initNamespaceStorage;\n $.localStorage = $.localStorage || storage.localStorage;\n $.namespaceStorages = $.namespaceStorages || storage.namespaceStorages;\n $.removeAllStorages = $.removeAllStorages || storage.removeAllStorages;\n $.sessionStorage = $.sessionStorage || storage.sessionStorage;\n});\n","js-storage/js.storage.js":"/*\n * JS Storage Plugin\n *\n * Copyright (c) 2019 Julien Maurel\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/mit-license.php\n *\n * Project home:\n * https://github.com/julien-maurel/js-storage\n *\n * Version: 1.1.0\n */\n(function (factory) {\n var registeredInModuleLoader = false;\n if (typeof define === 'function' && define.amd) {\n define(['jquery', 'jquery/jquery.cookie'], factory);\n registeredInModuleLoader = true;\n }\n if (typeof exports === 'object') {\n module.exports = factory();\n registeredInModuleLoader = true;\n }\n if (!registeredInModuleLoader) {\n var OldStorages = window.Storages;\n var api = window.Storages = factory();\n api.noConflict = function () {\n window.Storages = OldStorages;\n return api;\n };\n }\n}(function () {\n // Variables used by utilities functions (like isPlainObject...)\n var class2type = {};\n var toString = class2type.toString;\n var hasOwn = class2type.hasOwnProperty;\n var fnToString = hasOwn.toString;\n var ObjectFunctionString = fnToString.call(Object);\n var getProto = Object.getPrototypeOf;\n var apis = {};\n\n // Prefix to use with cookie fallback\n var cookie_local_prefix = \"ls_\";\n var cookie_session_prefix = \"ss_\";\n\n // Get items from a storage\n function _get() {\n var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], vi, ret, tmp, i, j;\n if (l < 1) {\n throw new Error('Minimum 1 argument must be given');\n } else if (Array.isArray(a0)) {\n // If second argument is an array, return an object with value of storage for each item in this array\n ret = {};\n for (i in a0) {\n if (a0.hasOwnProperty(i)) {\n vi = a0[i];\n try {\n ret[vi] = JSON.parse(s.getItem(vi));\n } catch (e) {\n ret[vi] = s.getItem(vi);\n }\n }\n }\n return ret;\n } else if (l == 1) {\n // If only 1 argument, return value directly\n try {\n return JSON.parse(s.getItem(a0));\n } catch (e) {\n return s.getItem(a0);\n }\n } else {\n // If more than 1 argument, parse storage to retrieve final value to return it\n // Get first level\n try {\n ret = JSON.parse(s.getItem(a0));\n if (!ret) {\n throw new ReferenceError(a0 + ' is not defined in this storage');\n }\n } catch (e) {\n throw new ReferenceError(a0 + ' is not defined in this storage');\n }\n // Parse next levels\n for (i = 1; i < l - 1; i++) {\n ret = ret[a[i]];\n if (ret === undefined) {\n throw new ReferenceError([].slice.call(a, 0, i + 1).join('.') + ' is not defined in this storage');\n }\n }\n // If last argument is an array, return an object with value for each item in this array\n // Else return value normally\n if (Array.isArray(a[i])) {\n tmp = ret;\n ret = {};\n for (j in a[i]) {\n if (a[i].hasOwnProperty(j)) {\n ret[a[i][j]] = tmp[a[i][j]];\n }\n }\n return ret;\n } else {\n return ret[a[i]];\n }\n }\n }\n\n // Set items of a storage\n function _set() {\n var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], a1 = a[1], vi, to_store = isNaN(a1) ? {} : [], type, tmp, i;\n if (l < 1 || !_isPlainObject(a0) && l < 2) {\n throw new Error('Minimum 2 arguments must be given or first parameter must be an object');\n } else if (_isPlainObject(a0)) {\n // If first argument is an object, set values of storage for each property of this object\n for (i in a0) {\n if (a0.hasOwnProperty(i)) {\n vi = a0[i];\n if (!_isPlainObject(vi) && !this.alwaysUseJson) {\n s.setItem(i, vi);\n } else {\n s.setItem(i, JSON.stringify(vi));\n }\n }\n }\n return a0;\n } else if (l == 2) {\n // If only 2 arguments, set value of storage directly\n if (typeof a1 === 'object' || this.alwaysUseJson) {\n s.setItem(a0, JSON.stringify(a1));\n } else {\n s.setItem(a0, a1);\n }\n return a1;\n } else {\n // If more than 3 arguments, parse storage to retrieve final node and set value\n // Get first level\n try {\n tmp = s.getItem(a0);\n if (tmp != null) {\n to_store = JSON.parse(tmp);\n }\n } catch (e) {\n }\n tmp = to_store;\n // Parse next levels and set value\n for (i = 1; i < l - 2; i++) {\n vi = a[i];\n type = isNaN(a[i + 1]) ? \"object\" : \"array\";\n if (!tmp[vi] || type == \"object\" && !_isPlainObject(tmp[vi]) || type == \"array\" && !Array.isArray(tmp[vi])) {\n if (type == \"array\") tmp[vi] = [];\n else tmp[vi] = {};\n }\n tmp = tmp[vi];\n }\n tmp[a[i]] = a[i + 1];\n s.setItem(a0, JSON.stringify(to_store));\n return to_store;\n }\n }\n\n // Remove items from a storage\n function _remove() {\n var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], to_store, tmp, i, j;\n if (l < 1) {\n throw new Error('Minimum 1 argument must be given');\n } else if (Array.isArray(a0)) {\n // If first argument is an array, remove values from storage for each item of this array\n for (i in a0) {\n if (a0.hasOwnProperty(i)) {\n s.removeItem(a0[i]);\n }\n }\n return true;\n } else if (l == 1) {\n // If only 2 arguments, remove value from storage directly\n s.removeItem(a0);\n return true;\n } else {\n // If more than 2 arguments, parse storage to retrieve final node and remove value\n // Get first level\n try {\n to_store = tmp = JSON.parse(s.getItem(a0));\n } catch (e) {\n throw new ReferenceError(a0 + ' is not defined in this storage');\n }\n // Parse next levels and remove value\n for (i = 1; i < l - 1; i++) {\n tmp = tmp[a[i]];\n if (tmp === undefined) {\n throw new ReferenceError([].slice.call(a, 1, i).join('.') + ' is not defined in this storage');\n }\n }\n // If last argument is an array,remove value for each item in this array\n // Else remove value normally\n if (Array.isArray(a[i])) {\n for (j in a[i]) {\n if (a[i].hasOwnProperty(j)) {\n delete tmp[a[i][j]];\n }\n }\n } else {\n delete tmp[a[i]];\n }\n s.setItem(a0, JSON.stringify(to_store));\n return true;\n }\n }\n\n // Remove all items from a storage\n function _removeAll(reinit_ns) {\n var keys = _keys.call(this), i;\n for (i in keys) {\n if (keys.hasOwnProperty(i)) {\n _remove.call(this, keys[i]);\n }\n }\n // Reinitialize all namespace storages\n if (reinit_ns) {\n for (i in apis.namespaceStorages) {\n if (apis.namespaceStorages.hasOwnProperty(i)) {\n _createNamespace(i);\n }\n }\n }\n }\n\n // Check if items of a storage are empty\n function _isEmpty() {\n var l = arguments.length, a = arguments, a0 = a[0], i;\n if (l == 0) {\n // If no argument, test if storage is empty\n return (_keys.call(this).length == 0);\n } else if (Array.isArray(a0)) {\n // If first argument is an array, test each item of this array and return true only if all items are empty\n for (i = 0; i < a0.length; i++) {\n if (!_isEmpty.call(this, a0[i])) {\n return false;\n }\n }\n return true;\n } else {\n // If at least 1 argument, try to get value and test it\n try {\n var v = _get.apply(this, arguments);\n // Convert result to an object (if last argument is an array, _get return already an object) and test each item\n if (!Array.isArray(a[l - 1])) {\n v = {'totest': v};\n }\n for (i in v) {\n if (v.hasOwnProperty(i) && !(\n (_isPlainObject(v[i]) && _isEmptyObject(v[i])) ||\n (Array.isArray(v[i]) && !v[i].length) ||\n (typeof v[i] !== 'boolean' && !v[i])\n )) {\n return false;\n }\n }\n return true;\n } catch (e) {\n return true;\n }\n }\n }\n\n // Check if items of a storage exist\n function _isSet() {\n var l = arguments.length, a = arguments, a0 = a[0], i;\n if (l < 1) {\n throw new Error('Minimum 1 argument must be given');\n }\n if (Array.isArray(a0)) {\n // If first argument is an array, test each item of this array and return true only if all items exist\n for (i = 0; i < a0.length; i++) {\n if (!_isSet.call(this, a0[i])) {\n return false;\n }\n }\n return true;\n } else {\n // For other case, try to get value and test it\n try {\n var v = _get.apply(this, arguments);\n // Convert result to an object (if last argument is an array, _get return already an object) and test each item\n if (!Array.isArray(a[l - 1])) {\n v = {'totest': v};\n }\n for (i in v) {\n if (v.hasOwnProperty(i) && !(v[i] !== undefined && v[i] !== null)) {\n return false;\n }\n }\n return true;\n } catch (e) {\n return false;\n }\n }\n }\n\n // Get keys of a storage or of an item of the storage\n function _keys() {\n var storage = this._type, l = arguments.length, s = window[storage], keys = [], o = {};\n // If at least 1 argument, get value from storage to retrieve keys\n // Else, use storage to retrieve keys\n if (l > 0) {\n o = _get.apply(this, arguments);\n } else {\n o = s;\n }\n if (o && o._cookie) {\n // If storage is a cookie, use js-cookie to retrieve keys\n var cookies = Cookies.get();\n for (var key in cookies) {\n if (cookies.hasOwnProperty(key) && key != '') {\n keys.push(key.replace(o._prefix, ''));\n }\n }\n } else {\n for (var i in o) {\n if (o.hasOwnProperty(i)) {\n keys.push(i);\n }\n }\n }\n return keys;\n }\n\n // Create new namespace storage\n function _createNamespace(name) {\n if (!name || typeof name != \"string\") {\n throw new Error('First parameter must be a string');\n }\n if (storage_available) {\n if (!window.localStorage.getItem(name)) {\n window.localStorage.setItem(name, '{}');\n }\n if (!window.sessionStorage.getItem(name)) {\n window.sessionStorage.setItem(name, '{}');\n }\n } else {\n if (!window.localCookieStorage.getItem(name)) {\n window.localCookieStorage.setItem(name, '{}');\n }\n if (!window.sessionCookieStorage.getItem(name)) {\n window.sessionCookieStorage.setItem(name, '{}');\n }\n }\n var ns = {\n localStorage: _extend({}, apis.localStorage, {_ns: name}),\n sessionStorage: _extend({}, apis.sessionStorage, {_ns: name})\n };\n if (cookies_available) {\n if (!window.cookieStorage.getItem(name)) {\n window.cookieStorage.setItem(name, '{}');\n }\n ns.cookieStorage = _extend({}, apis.cookieStorage, {_ns: name});\n }\n apis.namespaceStorages[name] = ns;\n return ns;\n }\n\n // Test if storage is natively available on browser\n function _testStorage(name) {\n var foo = 'jsapi';\n try {\n if (!window[name]) {\n return false;\n }\n window[name].setItem(foo, foo);\n window[name].removeItem(foo);\n return true;\n } catch (e) {\n return false;\n }\n }\n\n // Test if a variable is a plain object (from jQuery)\n function _isPlainObject(obj) {\n var proto, Ctor;\n\n // Detect obvious negatives\n // Use toString instead of jQuery.type to catch host objects\n if (!obj || toString.call(obj) !== \"[object Object]\") {\n return false;\n }\n\n proto = getProto(obj);\n\n // Objects with no prototype (e.g., `Object.create( null )`) are plain\n if (!proto) {\n return true;\n }\n\n // Objects with prototype are plain iff they were constructed by a global Object function\n Ctor = hasOwn.call(proto, \"constructor\") && proto.constructor;\n return typeof Ctor === \"function\" && fnToString.call(Ctor) === ObjectFunctionString;\n }\n\n // Test if a variable is an empty object (from jQuery)\n function _isEmptyObject(obj) {\n var name;\n\n for (name in obj) {\n return false;\n }\n return true;\n }\n\n // Merge objects\n function _extend() {\n var i = 1;\n var result = arguments[0];\n for (; i < arguments.length; i++) {\n var attributes = arguments[i];\n for (var key in attributes) {\n if (attributes.hasOwnProperty(key)) {\n result[key] = attributes[key];\n }\n }\n }\n return result;\n }\n\n // Check if storages are natively available on browser and check is js-cookie is present\n var storage_available = _testStorage('localStorage');\n var cookies_available = typeof Cookies !== 'undefined';\n\n // Namespace object\n var storage = {\n _type: '',\n _ns: '',\n _callMethod: function (f, a) {\n a = Array.prototype.slice.call(a);\n var p = [], a0 = a[0];\n if (this._ns) {\n p.push(this._ns);\n }\n if (typeof a0 === 'string' && a0.indexOf('.') !== -1) {\n a.shift();\n [].unshift.apply(a, a0.split('.'));\n }\n [].push.apply(p, a);\n return f.apply(this, p);\n },\n // Define if plugin always use JSON to store values (even to store simple values like string, int...) or not\n alwaysUseJson: false,\n // Get items. If no parameters and storage have a namespace, return all namespace\n get: function () {\n if (!storage_available && !cookies_available){\n return null;\n }\n return this._callMethod(_get, arguments);\n },\n // Set items\n set: function () {\n var l = arguments.length, a = arguments, a0 = a[0];\n if (l < 1 || !_isPlainObject(a0) && l < 2) {\n throw new Error('Minimum 2 arguments must be given or first parameter must be an object');\n }\n if (!storage_available && !cookies_available){\n return null;\n }\n // If first argument is an object and storage is a namespace storage, set values individually\n if (_isPlainObject(a0) && this._ns) {\n for (var i in a0) {\n if (a0.hasOwnProperty(i)) {\n this._callMethod(_set, [i, a0[i]]);\n }\n }\n return a0;\n } else {\n var r = this._callMethod(_set, a);\n if (this._ns) {\n return r[a0.split('.')[0]];\n } else {\n return r;\n }\n }\n },\n // Delete items\n remove: function () {\n if (arguments.length < 1) {\n throw new Error('Minimum 1 argument must be given');\n }\n if (!storage_available && !cookies_available){\n return null;\n }\n return this._callMethod(_remove, arguments);\n },\n // Delete all items\n removeAll: function (reinit_ns) {\n if (!storage_available && !cookies_available){\n return null;\n }\n if (this._ns) {\n this._callMethod(_set, [{}]);\n return true;\n } else {\n return this._callMethod(_removeAll, [reinit_ns]);\n }\n },\n // Items empty\n isEmpty: function () {\n if (!storage_available && !cookies_available){\n return null;\n }\n return this._callMethod(_isEmpty, arguments);\n },\n // Items exists\n isSet: function () {\n if (arguments.length < 1) {\n throw new Error('Minimum 1 argument must be given');\n }\n if (!storage_available && !cookies_available){\n return null;\n }\n return this._callMethod(_isSet, arguments);\n },\n // Get keys of items\n keys: function () {\n if (!storage_available && !cookies_available){\n return null;\n }\n return this._callMethod(_keys, arguments);\n }\n };\n\n // Use js-cookie for compatibility with old browsers and give access to cookieStorage\n if (cookies_available) {\n // sessionStorage is valid for one window/tab. To simulate that with cookie, we set a name for the window and use it for the name of the cookie\n if (!window.name) {\n window.name = Math.floor(Math.random() * 100000000);\n }\n var cookie_storage = {\n _cookie: true,\n _prefix: '',\n _expires: null,\n _path: null,\n _domain: null,\n _secure: false,\n setItem: function (n, v) {\n Cookies.set(this._prefix + n, v, {expires: this._expires, path: this._path, domain: this._domain, secure: this._secure});\n },\n getItem: function (n) {\n return Cookies.get(this._prefix + n);\n },\n removeItem: function (n) {\n return Cookies.remove(this._prefix + n, {path: this._path});\n },\n clear: function () {\n var cookies = Cookies.get();\n for (var key in cookies) {\n if (cookies.hasOwnProperty(key) && key != '') {\n if (!this._prefix && key.indexOf(cookie_local_prefix) === -1 && key.indexOf(cookie_session_prefix) === -1 || this._prefix && key.indexOf(this._prefix) === 0) {\n Cookies.remove(key);\n }\n }\n }\n },\n setExpires: function (e) {\n this._expires = e;\n return this;\n },\n setPath: function (p) {\n this._path = p;\n return this;\n },\n setDomain: function (d) {\n this._domain = d;\n return this;\n },\n setSecure: function (s) {\n this._secure = s;\n return this;\n },\n setConf: function (c) {\n if (c.path) {\n this._path = c.path;\n }\n if (c.domain) {\n this._domain = c.domain;\n }\n if (c.secure) {\n this._secure = c.secure;\n }\n if (c.expires) {\n this._expires = c.expires;\n }\n return this;\n },\n setDefaultConf: function () {\n this._path = this._domain = this._expires = null;\n this._secure = false;\n }\n };\n if (!storage_available) {\n window.localCookieStorage = _extend({}, cookie_storage, {\n _prefix: cookie_local_prefix,\n _expires: 365 * 10,\n _secure: true\n });\n window.sessionCookieStorage = _extend({}, cookie_storage, {\n _prefix: cookie_session_prefix + window.name + '_',\n _secure: true\n });\n }\n window.cookieStorage = _extend({}, cookie_storage);\n // cookieStorage API\n apis.cookieStorage = _extend({}, storage, {\n _type: 'cookieStorage',\n setExpires: function (e) {\n window.cookieStorage.setExpires(e);\n return this;\n },\n setPath: function (p) {\n window.cookieStorage.setPath(p);\n return this;\n },\n setDomain: function (d) {\n window.cookieStorage.setDomain(d);\n return this;\n },\n setSecure: function (s) {\n window.cookieStorage.setSecure(s);\n return this;\n },\n setConf: function (c) {\n window.cookieStorage.setConf(c);\n return this;\n },\n setDefaultConf: function () {\n window.cookieStorage.setDefaultConf();\n return this;\n }\n });\n }\n\n // Get a new API on a namespace\n apis.initNamespaceStorage = function (ns) {\n return _createNamespace(ns);\n };\n if (storage_available) {\n // localStorage API\n apis.localStorage = _extend({}, storage, {_type: 'localStorage'});\n // sessionStorage API\n apis.sessionStorage = _extend({}, storage, {_type: 'sessionStorage'});\n } else {\n // localStorage API\n apis.localStorage = _extend({}, storage, {_type: 'localCookieStorage'});\n // sessionStorage API\n apis.sessionStorage = _extend({}, storage, {_type: 'sessionCookieStorage'});\n }\n // List of all namespace storage\n apis.namespaceStorages = {};\n // Remove all items in all storages\n apis.removeAllStorages = function (reinit_ns) {\n apis.localStorage.removeAll(reinit_ns);\n apis.sessionStorage.removeAll(reinit_ns);\n if (apis.cookieStorage) {\n apis.cookieStorage.removeAll(reinit_ns);\n }\n if (!reinit_ns) {\n apis.namespaceStorages = {};\n }\n };\n // About alwaysUseJson\n // By default, all values are string on html storages and the plugin don't use json to store simple values (strings, int, float...)\n // So by default, if you do storage.setItem('test',2), value in storage will be \"2\", not 2\n // If you set this property to true, all values set with the plugin will be stored as json to have typed values in any cases\n apis.alwaysUseJsonInStorage = function (value) {\n storage.alwaysUseJson = value;\n apis.localStorage.alwaysUseJson = value;\n apis.sessionStorage.alwaysUseJson = value;\n if (apis.cookieStorage) {\n apis.cookieStorage.alwaysUseJson = value;\n }\n };\n\n return apis;\n}));\n","jquery/compat.js":"// Import every plugin under the sun. Bad for performance,\n// but prevents the store from breaking in situations\n// where a dependency was missed during the migration from\n// a monolith build of jQueryUI to a modular one\n\ndefine([\n 'jquery-ui-modules/core',\n 'jquery-ui-modules/accordion',\n 'jquery-ui-modules/autocomplete',\n 'jquery-ui-modules/button',\n 'jquery-ui-modules/datepicker',\n 'jquery-ui-modules/dialog',\n 'jquery-ui-modules/draggable',\n 'jquery-ui-modules/droppable',\n 'jquery-ui-modules/effect-blind',\n 'jquery-ui-modules/effect-bounce',\n 'jquery-ui-modules/effect-clip',\n 'jquery-ui-modules/effect-drop',\n 'jquery-ui-modules/effect-explode',\n 'jquery-ui-modules/effect-fade',\n 'jquery-ui-modules/effect-fold',\n 'jquery-ui-modules/effect-highlight',\n 'jquery-ui-modules/effect-scale',\n 'jquery-ui-modules/effect-pulsate',\n 'jquery-ui-modules/effect-shake',\n 'jquery-ui-modules/effect-slide',\n 'jquery-ui-modules/effect-transfer',\n 'jquery-ui-modules/effect',\n 'jquery-ui-modules/menu',\n 'jquery-ui-modules/mouse',\n 'jquery-ui-modules/position',\n 'jquery-ui-modules/progressbar',\n 'jquery-ui-modules/resizable',\n 'jquery-ui-modules/selectable',\n 'jquery-ui-modules/slider',\n 'jquery-ui-modules/sortable',\n 'jquery-ui-modules/spinner',\n 'jquery-ui-modules/tabs',\n 'jquery-ui-modules/timepicker',\n 'jquery-ui-modules/tooltip',\n 'jquery-ui-modules/widget'\n], function() {\n console.warn(\n 'Fallback to JQueryUI Compat activated. ' +\n 'Your store is missing a dependency for a ' +\n 'jQueryUI widget. Identifying and addressing the dependency ' +\n 'will drastically improve the performance of your site.'\n );\n});\n","jquery/timepicker.js":"/*! jQuery Timepicker Addon - v1.6.3 - 2016-04-20\n* http://trentrichardson.com/examples/timepicker\n* Copyright (c) 2016 Trent Richardson; Licensed MIT */\n(function (factory) {\n if (typeof define === 'function' && define.amd) {\n define(['jquery', 'jquery-ui-modules/datepicker', 'jquery-ui-modules/slider'], factory);\n } else {\n factory(jQuery);\n }\n}(function ($) {\n\n /*\n * Lets not redefine timepicker, Prevent \"Uncaught RangeError: Maximum call stack size exceeded\"\n */\n $.ui.timepicker = $.ui.timepicker || {};\n if ($.ui.timepicker.version) {\n return;\n }\n\n /*\n * Extend jQueryUI, get it started with our version number\n */\n $.extend($.ui, {\n timepicker: {\n version: \"1.6.3\"\n }\n });\n\n /*\n * Timepicker manager.\n * Use the singleton instance of this class, $.timepicker, to interact with the time picker.\n * Settings for (groups of) time pickers are maintained in an instance object,\n * allowing multiple different settings on the same page.\n */\n var Timepicker = function () {\n this.regional = []; // Available regional settings, indexed by language code\n this.regional[''] = { // Default regional settings\n currentText: 'Now',\n closeText: 'Done',\n amNames: ['AM', 'A'],\n pmNames: ['PM', 'P'],\n timeFormat: 'HH:mm',\n timeSuffix: '',\n timeOnlyTitle: 'Choose Time',\n timeText: 'Time',\n hourText: 'Hour',\n minuteText: 'Minute',\n secondText: 'Second',\n millisecText: 'Millisecond',\n microsecText: 'Microsecond',\n timezoneText: 'Time Zone',\n isRTL: false\n };\n this._defaults = { // Global defaults for all the datetime picker instances\n showButtonPanel: true,\n timeOnly: false,\n timeOnlyShowDate: false,\n showHour: null,\n showMinute: null,\n showSecond: null,\n showMillisec: null,\n showMicrosec: null,\n showTimezone: null,\n showTime: true,\n stepHour: 1,\n stepMinute: 1,\n stepSecond: 1,\n stepMillisec: 1,\n stepMicrosec: 1,\n hour: 0,\n minute: 0,\n second: 0,\n millisec: 0,\n microsec: 0,\n timezone: null,\n hourMin: 0,\n minuteMin: 0,\n secondMin: 0,\n millisecMin: 0,\n microsecMin: 0,\n hourMax: 23,\n minuteMax: 59,\n secondMax: 59,\n millisecMax: 999,\n microsecMax: 999,\n minDateTime: null,\n maxDateTime: null,\n maxTime: null,\n minTime: null,\n onSelect: null,\n hourGrid: 0,\n minuteGrid: 0,\n secondGrid: 0,\n millisecGrid: 0,\n microsecGrid: 0,\n alwaysSetTime: true,\n separator: ' ',\n altFieldTimeOnly: true,\n altTimeFormat: null,\n altSeparator: null,\n altTimeSuffix: null,\n altRedirectFocus: true,\n pickerTimeFormat: null,\n pickerTimeSuffix: null,\n showTimepicker: true,\n timezoneList: null,\n addSliderAccess: false,\n sliderAccessArgs: null,\n controlType: 'slider',\n oneLine: false,\n defaultValue: null,\n parse: 'strict',\n afterInject: null\n };\n $.extend(this._defaults, this.regional['']);\n };\n\n $.extend(Timepicker.prototype, {\n $input: null,\n $altInput: null,\n $timeObj: null,\n inst: null,\n hour_slider: null,\n minute_slider: null,\n second_slider: null,\n millisec_slider: null,\n microsec_slider: null,\n timezone_select: null,\n maxTime: null,\n minTime: null,\n hour: 0,\n minute: 0,\n second: 0,\n millisec: 0,\n microsec: 0,\n timezone: null,\n hourMinOriginal: null,\n minuteMinOriginal: null,\n secondMinOriginal: null,\n millisecMinOriginal: null,\n microsecMinOriginal: null,\n hourMaxOriginal: null,\n minuteMaxOriginal: null,\n secondMaxOriginal: null,\n millisecMaxOriginal: null,\n microsecMaxOriginal: null,\n ampm: '',\n formattedDate: '',\n formattedTime: '',\n formattedDateTime: '',\n timezoneList: null,\n units: ['hour', 'minute', 'second', 'millisec', 'microsec'],\n support: {},\n control: null,\n\n /*\n * Override the default settings for all instances of the time picker.\n * @param {Object} settings object - the new settings to use as defaults (anonymous object)\n * @return {Object} the manager object\n */\n setDefaults: function (settings) {\n extendRemove(this._defaults, settings || {});\n return this;\n },\n\n /*\n * Create a new Timepicker instance\n */\n _newInst: function ($input, opts) {\n var tp_inst = new Timepicker(),\n inlineSettings = {},\n fns = {},\n overrides, i;\n\n for (var attrName in this._defaults) {\n if (this._defaults.hasOwnProperty(attrName)) {\n var attrValue = $input.attr('time:' + attrName);\n if (attrValue) {\n try {\n inlineSettings[attrName] = eval(attrValue);\n } catch (err) {\n inlineSettings[attrName] = attrValue;\n }\n }\n }\n }\n\n overrides = {\n beforeShow: function (input, dp_inst) {\n if ($.isFunction(tp_inst._defaults.evnts.beforeShow)) {\n return tp_inst._defaults.evnts.beforeShow.call($input[0], input, dp_inst, tp_inst);\n }\n },\n onChangeMonthYear: function (year, month, dp_inst) {\n // Update the time as well : this prevents the time from disappearing from the $input field.\n // tp_inst._updateDateTime(dp_inst);\n if ($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)) {\n tp_inst._defaults.evnts.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst);\n }\n },\n onClose: function (dateText, dp_inst) {\n if (tp_inst.timeDefined === true && $input.val() !== '') {\n tp_inst._updateDateTime(dp_inst);\n }\n if ($.isFunction(tp_inst._defaults.evnts.onClose)) {\n tp_inst._defaults.evnts.onClose.call($input[0], dateText, dp_inst, tp_inst);\n }\n }\n };\n for (i in overrides) {\n if (overrides.hasOwnProperty(i)) {\n fns[i] = opts[i] || this._defaults[i] || null;\n }\n }\n\n tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, opts, overrides, {\n evnts: fns,\n timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');\n });\n tp_inst.amNames = $.map(tp_inst._defaults.amNames, function (val) {\n return val.toUpperCase();\n });\n tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function (val) {\n return val.toUpperCase();\n });\n\n // detect which units are supported\n tp_inst.support = detectSupport(\n tp_inst._defaults.timeFormat +\n (tp_inst._defaults.pickerTimeFormat ? tp_inst._defaults.pickerTimeFormat : '') +\n (tp_inst._defaults.altTimeFormat ? tp_inst._defaults.altTimeFormat : ''));\n\n // controlType is string - key to our this._controls\n if (typeof(tp_inst._defaults.controlType) === 'string') {\n if (tp_inst._defaults.controlType === 'slider' && typeof($.ui.slider) === 'undefined') {\n tp_inst._defaults.controlType = 'select';\n }\n tp_inst.control = tp_inst._controls[tp_inst._defaults.controlType];\n }\n // controlType is an object and must implement create, options, value methods\n else {\n tp_inst.control = tp_inst._defaults.controlType;\n }\n\n // prep the timezone options\n var timezoneList = [-720, -660, -600, -570, -540, -480, -420, -360, -300, -270, -240, -210, -180, -120, -60,\n 0, 60, 120, 180, 210, 240, 270, 300, 330, 345, 360, 390, 420, 480, 525, 540, 570, 600, 630, 660, 690, 720, 765, 780, 840];\n if (tp_inst._defaults.timezoneList !== null) {\n timezoneList = tp_inst._defaults.timezoneList;\n }\n var tzl = timezoneList.length, tzi = 0, tzv = null;\n if (tzl > 0 && typeof timezoneList[0] !== 'object') {\n for (; tzi < tzl; tzi++) {\n tzv = timezoneList[tzi];\n timezoneList[tzi] = { value: tzv, label: $.timepicker.timezoneOffsetString(tzv, tp_inst.support.iso8601) };\n }\n }\n tp_inst._defaults.timezoneList = timezoneList;\n\n // set the default units\n tp_inst.timezone = tp_inst._defaults.timezone !== null ? $.timepicker.timezoneOffsetNumber(tp_inst._defaults.timezone) :\n ((new Date()).getTimezoneOffset() * -1);\n tp_inst.hour = tp_inst._defaults.hour < tp_inst._defaults.hourMin ? tp_inst._defaults.hourMin :\n tp_inst._defaults.hour > tp_inst._defaults.hourMax ? tp_inst._defaults.hourMax : tp_inst._defaults.hour;\n tp_inst.minute = tp_inst._defaults.minute < tp_inst._defaults.minuteMin ? tp_inst._defaults.minuteMin :\n tp_inst._defaults.minute > tp_inst._defaults.minuteMax ? tp_inst._defaults.minuteMax : tp_inst._defaults.minute;\n tp_inst.second = tp_inst._defaults.second < tp_inst._defaults.secondMin ? tp_inst._defaults.secondMin :\n tp_inst._defaults.second > tp_inst._defaults.secondMax ? tp_inst._defaults.secondMax : tp_inst._defaults.second;\n tp_inst.millisec = tp_inst._defaults.millisec < tp_inst._defaults.millisecMin ? tp_inst._defaults.millisecMin :\n tp_inst._defaults.millisec > tp_inst._defaults.millisecMax ? tp_inst._defaults.millisecMax : tp_inst._defaults.millisec;\n tp_inst.microsec = tp_inst._defaults.microsec < tp_inst._defaults.microsecMin ? tp_inst._defaults.microsecMin :\n tp_inst._defaults.microsec > tp_inst._defaults.microsecMax ? tp_inst._defaults.microsecMax : tp_inst._defaults.microsec;\n tp_inst.ampm = '';\n tp_inst.$input = $input;\n\n if (tp_inst._defaults.altField) {\n tp_inst.$altInput = $(tp_inst._defaults.altField);\n if (tp_inst._defaults.altRedirectFocus === true) {\n tp_inst.$altInput.css({\n cursor: 'pointer'\n }).focus(function () {\n $input.trigger(\"focus\");\n });\n }\n }\n\n if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) {\n tp_inst._defaults.minDate = new Date();\n }\n if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) {\n tp_inst._defaults.maxDate = new Date();\n }\n\n // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime..\n if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) {\n tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime());\n }\n if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) {\n tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());\n }\n if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) {\n tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime());\n }\n if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) {\n tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());\n }\n tp_inst.$input.bind('focus', function () {\n tp_inst._onFocus();\n });\n\n return tp_inst;\n },\n\n /*\n * add our sliders to the calendar\n */\n _addTimePicker: function (dp_inst) {\n var currDT = $.trim((this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val());\n\n this.timeDefined = this._parseTime(currDT);\n this._limitMinMaxDateTime(dp_inst, false);\n this._injectTimePicker();\n this._afterInject();\n },\n\n /*\n * parse the time string from input value or _setTime\n */\n _parseTime: function (timeString, withDate) {\n if (!this.inst) {\n this.inst = $.datepicker._getInst(this.$input[0]);\n }\n\n if (withDate || !this._defaults.timeOnly) {\n var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');\n try {\n var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults);\n if (!parseRes.timeObj) {\n return false;\n }\n $.extend(this, parseRes.timeObj);\n } catch (err) {\n $.timepicker.log(\"Error parsing the date/time string: \" + err +\n \"\\ndate/time string = \" + timeString +\n \"\\ntimeFormat = \" + this._defaults.timeFormat +\n \"\\ndateFormat = \" + dp_dateFormat);\n return false;\n }\n return true;\n } else {\n var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults);\n if (!timeObj) {\n return false;\n }\n $.extend(this, timeObj);\n return true;\n }\n },\n\n /*\n * Handle callback option after injecting timepicker\n */\n _afterInject: function() {\n var o = this.inst.settings;\n if ($.isFunction(o.afterInject)) {\n o.afterInject.call(this);\n }\n },\n\n /*\n * generate and inject html for timepicker into ui datepicker\n */\n _injectTimePicker: function () {\n var $dp = this.inst.dpDiv,\n o = this.inst.settings,\n tp_inst = this,\n litem = '',\n uitem = '',\n show = null,\n max = {},\n gridSize = {},\n size = null,\n i = 0,\n l = 0;\n\n // Prevent displaying twice\n if ($dp.find(\"div.ui-timepicker-div\").length === 0 && o.showTimepicker) {\n var noDisplay = ' ui_tpicker_unit_hide',\n html = '<div class=\"ui-timepicker-div' + (o.isRTL ? ' ui-timepicker-rtl' : '') + (o.oneLine && o.controlType === 'select' ? ' ui-timepicker-oneLine' : '') + '\"><dl>' + '<dt class=\"ui_tpicker_time_label' + ((o.showTime) ? '' : noDisplay) + '\">' + o.timeText + '</dt>' +\n '<dd class=\"ui_tpicker_time '+ ((o.showTime) ? '' : noDisplay) + '\"><input class=\"ui_tpicker_time_input\" ' + (o.timeInput ? '' : 'disabled') + '/></dd>';\n\n // Create the markup\n for (i = 0, l = this.units.length; i < l; i++) {\n litem = this.units[i];\n uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);\n show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];\n\n // Added by Peter Medeiros:\n // - Figure out what the hour/minute/second max should be based on the step values.\n // - Example: if stepMinute is 15, then minMax is 45.\n max[litem] = parseInt((o[litem + 'Max'] - ((o[litem + 'Max'] - o[litem + 'Min']) % o['step' + uitem])), 10);\n gridSize[litem] = 0;\n\n html += '<dt class=\"ui_tpicker_' + litem + '_label' + (show ? '' : noDisplay) + '\">' + o[litem + 'Text'] + '</dt>' +\n '<dd class=\"ui_tpicker_' + litem + (show ? '' : noDisplay) + '\"><div class=\"ui_tpicker_' + litem + '_slider' + (show ? '' : noDisplay) + '\"></div>';\n\n if (show && o[litem + 'Grid'] > 0) {\n html += '<div style=\"padding-left: 1px\"><table class=\"ui-tpicker-grid-label\"><tr>';\n\n if (litem === 'hour') {\n for (var h = o[litem + 'Min']; h <= max[litem]; h += parseInt(o[litem + 'Grid'], 10)) {\n gridSize[litem]++;\n var tmph = $.datepicker.formatTime(this.support.ampm ? 'hht' : 'HH', {hour: h}, o);\n html += '<td data-for=\"' + litem + '\">' + tmph + '</td>';\n }\n }\n else {\n for (var m = o[litem + 'Min']; m <= max[litem]; m += parseInt(o[litem + 'Grid'], 10)) {\n gridSize[litem]++;\n html += '<td data-for=\"' + litem + '\">' + ((m < 10) ? '0' : '') + m + '</td>';\n }\n }\n\n html += '</tr></table></div>';\n }\n html += '</dd>';\n }\n\n // Timezone\n var showTz = o.showTimezone !== null ? o.showTimezone : this.support.timezone;\n html += '<dt class=\"ui_tpicker_timezone_label' + (showTz ? '' : noDisplay) + '\">' + o.timezoneText + '</dt>';\n html += '<dd class=\"ui_tpicker_timezone' + (showTz ? '' : noDisplay) + '\"></dd>';\n\n // Create the elements from string\n html += '</dl></div>';\n var $tp = $(html);\n\n // if we only want time picker...\n if (o.timeOnly === true) {\n $tp.prepend('<div class=\"ui-widget-header ui-helper-clearfix ui-corner-all\">' + '<div class=\"ui-datepicker-title\">' + o.timeOnlyTitle + '</div>' + '</div>');\n $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide();\n }\n\n // add sliders, adjust grids, add events\n for (i = 0, l = tp_inst.units.length; i < l; i++) {\n litem = tp_inst.units[i];\n uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);\n show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];\n\n // add the slider\n tp_inst[litem + '_slider'] = tp_inst.control.create(tp_inst, $tp.find('.ui_tpicker_' + litem + '_slider'), litem, tp_inst[litem], o[litem + 'Min'], max[litem], o['step' + uitem]);\n\n // adjust the grid and add click event\n if (show && o[litem + 'Grid'] > 0) {\n size = 100 * gridSize[litem] * o[litem + 'Grid'] / (max[litem] - o[litem + 'Min']);\n $tp.find('.ui_tpicker_' + litem + ' table').css({\n width: size + \"%\",\n marginLeft: o.isRTL ? '0' : ((size / (-2 * gridSize[litem])) + \"%\"),\n marginRight: o.isRTL ? ((size / (-2 * gridSize[litem])) + \"%\") : '0',\n borderCollapse: 'collapse'\n }).find(\"td\").click(function (e) {\n var $t = $(this),\n h = $t.html(),\n n = parseInt(h.replace(/[^0-9]/g), 10),\n ap = h.replace(/[^apm]/ig),\n f = $t.data('for'); // loses scope, so we use data-for\n\n if (f === 'hour') {\n if (ap.indexOf('p') !== -1 && n < 12) {\n n += 12;\n }\n else {\n if (ap.indexOf('a') !== -1 && n === 12) {\n n = 0;\n }\n }\n }\n\n tp_inst.control.value(tp_inst, tp_inst[f + '_slider'], litem, n);\n\n tp_inst._onTimeChange();\n tp_inst._onSelectHandler();\n }).css({\n cursor: 'pointer',\n width: (100 / gridSize[litem]) + '%',\n textAlign: 'center',\n overflow: 'hidden'\n });\n } // end if grid > 0\n } // end for loop\n\n // Add timezone options\n this.timezone_select = $tp.find('.ui_tpicker_timezone').append('<select></select>').find(\"select\");\n $.fn.append.apply(this.timezone_select,\n $.map(o.timezoneList, function (val, idx) {\n return $(\"<option />\").val(typeof val === \"object\" ? val.value : val).text(typeof val === \"object\" ? val.label : val);\n }));\n if (typeof(this.timezone) !== \"undefined\" && this.timezone !== null && this.timezone !== \"\") {\n var local_timezone = (new Date(this.inst.selectedYear, this.inst.selectedMonth, this.inst.selectedDay, 12)).getTimezoneOffset() * -1;\n if (local_timezone === this.timezone) {\n selectLocalTimezone(tp_inst);\n } else {\n this.timezone_select.val(this.timezone);\n }\n } else {\n if (typeof(this.hour) !== \"undefined\" && this.hour !== null && this.hour !== \"\") {\n this.timezone_select.val(o.timezone);\n } else {\n selectLocalTimezone(tp_inst);\n }\n }\n this.timezone_select.change(function () {\n tp_inst._onTimeChange();\n tp_inst._onSelectHandler();\n tp_inst._afterInject();\n });\n // End timezone options\n\n // inject timepicker into datepicker\n var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');\n if ($buttonPanel.length) {\n $buttonPanel.before($tp);\n } else {\n $dp.append($tp);\n }\n\n this.$timeObj = $tp.find('.ui_tpicker_time_input');\n this.$timeObj.change(function () {\n var timeFormat = tp_inst.inst.settings.timeFormat;\n var parsedTime = $.datepicker.parseTime(timeFormat, this.value);\n var update = new Date();\n if (parsedTime) {\n update.setHours(parsedTime.hour);\n update.setMinutes(parsedTime.minute);\n update.setSeconds(parsedTime.second);\n $.datepicker._setTime(tp_inst.inst, update);\n } else {\n this.value = tp_inst.formattedTime;\n this.blur();\n }\n });\n\n if (this.inst !== null) {\n var timeDefined = this.timeDefined;\n this._onTimeChange();\n this.timeDefined = timeDefined;\n }\n\n // slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/\n if (this._defaults.addSliderAccess) {\n var sliderAccessArgs = this._defaults.sliderAccessArgs,\n rtl = this._defaults.isRTL;\n sliderAccessArgs.isRTL = rtl;\n\n setTimeout(function () { // fix for inline mode\n if ($tp.find('.ui-slider-access').length === 0) {\n $tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs);\n\n // fix any grids since sliders are shorter\n var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true);\n if (sliderAccessWidth) {\n $tp.find('table:visible').each(function () {\n var $g = $(this),\n oldWidth = $g.outerWidth(),\n oldMarginLeft = $g.css(rtl ? 'marginRight' : 'marginLeft').toString().replace('%', ''),\n newWidth = oldWidth - sliderAccessWidth,\n newMarginLeft = ((oldMarginLeft * newWidth) / oldWidth) + '%',\n css = { width: newWidth, marginRight: 0, marginLeft: 0 };\n css[rtl ? 'marginRight' : 'marginLeft'] = newMarginLeft;\n $g.css(css);\n });\n }\n }\n }, 10);\n }\n // end slideAccess integration\n\n tp_inst._limitMinMaxDateTime(this.inst, true);\n }\n },\n\n /*\n * This function tries to limit the ability to go outside the\n * min/max date range\n */\n _limitMinMaxDateTime: function (dp_inst, adjustSliders) {\n var o = this._defaults,\n dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);\n\n if (!this._defaults.showTimepicker) {\n return;\n } // No time so nothing to check here\n\n if ($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date) {\n var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'),\n minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);\n\n if (this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null || this.microsecMinOriginal === null) {\n this.hourMinOriginal = o.hourMin;\n this.minuteMinOriginal = o.minuteMin;\n this.secondMinOriginal = o.secondMin;\n this.millisecMinOriginal = o.millisecMin;\n this.microsecMinOriginal = o.microsecMin;\n }\n\n if (dp_inst.settings.timeOnly || minDateTimeDate.getTime() === dp_date.getTime()) {\n this._defaults.hourMin = minDateTime.getHours();\n if (this.hour <= this._defaults.hourMin) {\n this.hour = this._defaults.hourMin;\n this._defaults.minuteMin = minDateTime.getMinutes();\n if (this.minute <= this._defaults.minuteMin) {\n this.minute = this._defaults.minuteMin;\n this._defaults.secondMin = minDateTime.getSeconds();\n if (this.second <= this._defaults.secondMin) {\n this.second = this._defaults.secondMin;\n this._defaults.millisecMin = minDateTime.getMilliseconds();\n if (this.millisec <= this._defaults.millisecMin) {\n this.millisec = this._defaults.millisecMin;\n this._defaults.microsecMin = minDateTime.getMicroseconds();\n } else {\n if (this.microsec < this._defaults.microsecMin) {\n this.microsec = this._defaults.microsecMin;\n }\n this._defaults.microsecMin = this.microsecMinOriginal;\n }\n } else {\n this._defaults.millisecMin = this.millisecMinOriginal;\n this._defaults.microsecMin = this.microsecMinOriginal;\n }\n } else {\n this._defaults.secondMin = this.secondMinOriginal;\n this._defaults.millisecMin = this.millisecMinOriginal;\n this._defaults.microsecMin = this.microsecMinOriginal;\n }\n } else {\n this._defaults.minuteMin = this.minuteMinOriginal;\n this._defaults.secondMin = this.secondMinOriginal;\n this._defaults.millisecMin = this.millisecMinOriginal;\n this._defaults.microsecMin = this.microsecMinOriginal;\n }\n } else {\n this._defaults.hourMin = this.hourMinOriginal;\n this._defaults.minuteMin = this.minuteMinOriginal;\n this._defaults.secondMin = this.secondMinOriginal;\n this._defaults.millisecMin = this.millisecMinOriginal;\n this._defaults.microsecMin = this.microsecMinOriginal;\n }\n }\n\n if ($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date) {\n var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'),\n maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);\n\n if (this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null || this.millisecMaxOriginal === null) {\n this.hourMaxOriginal = o.hourMax;\n this.minuteMaxOriginal = o.minuteMax;\n this.secondMaxOriginal = o.secondMax;\n this.millisecMaxOriginal = o.millisecMax;\n this.microsecMaxOriginal = o.microsecMax;\n }\n\n if (dp_inst.settings.timeOnly || maxDateTimeDate.getTime() === dp_date.getTime()) {\n this._defaults.hourMax = maxDateTime.getHours();\n if (this.hour >= this._defaults.hourMax) {\n this.hour = this._defaults.hourMax;\n this._defaults.minuteMax = maxDateTime.getMinutes();\n if (this.minute >= this._defaults.minuteMax) {\n this.minute = this._defaults.minuteMax;\n this._defaults.secondMax = maxDateTime.getSeconds();\n if (this.second >= this._defaults.secondMax) {\n this.second = this._defaults.secondMax;\n this._defaults.millisecMax = maxDateTime.getMilliseconds();\n if (this.millisec >= this._defaults.millisecMax) {\n this.millisec = this._defaults.millisecMax;\n this._defaults.microsecMax = maxDateTime.getMicroseconds();\n } else {\n if (this.microsec > this._defaults.microsecMax) {\n this.microsec = this._defaults.microsecMax;\n }\n this._defaults.microsecMax = this.microsecMaxOriginal;\n }\n } else {\n this._defaults.millisecMax = this.millisecMaxOriginal;\n this._defaults.microsecMax = this.microsecMaxOriginal;\n }\n } else {\n this._defaults.secondMax = this.secondMaxOriginal;\n this._defaults.millisecMax = this.millisecMaxOriginal;\n this._defaults.microsecMax = this.microsecMaxOriginal;\n }\n } else {\n this._defaults.minuteMax = this.minuteMaxOriginal;\n this._defaults.secondMax = this.secondMaxOriginal;\n this._defaults.millisecMax = this.millisecMaxOriginal;\n this._defaults.microsecMax = this.microsecMaxOriginal;\n }\n } else {\n this._defaults.hourMax = this.hourMaxOriginal;\n this._defaults.minuteMax = this.minuteMaxOriginal;\n this._defaults.secondMax = this.secondMaxOriginal;\n this._defaults.millisecMax = this.millisecMaxOriginal;\n this._defaults.microsecMax = this.microsecMaxOriginal;\n }\n }\n\n if (dp_inst.settings.minTime!==null) {\n var tempMinTime=new Date(\"01/01/1970 \" + dp_inst.settings.minTime);\n if (this.hour<tempMinTime.getHours()) {\n this.hour=this._defaults.hourMin=tempMinTime.getHours();\n this.minute=this._defaults.minuteMin=tempMinTime.getMinutes();\n } else if (this.hour===tempMinTime.getHours() && this.minute<tempMinTime.getMinutes()) {\n this.minute=this._defaults.minuteMin=tempMinTime.getMinutes();\n } else {\n if (this._defaults.hourMin<tempMinTime.getHours()) {\n this._defaults.hourMin=tempMinTime.getHours();\n this._defaults.minuteMin=tempMinTime.getMinutes();\n } else if (this._defaults.hourMin===tempMinTime.getHours()===this.hour && this._defaults.minuteMin<tempMinTime.getMinutes()) {\n this._defaults.minuteMin=tempMinTime.getMinutes();\n } else {\n this._defaults.minuteMin=0;\n }\n }\n }\n\n if (dp_inst.settings.maxTime!==null) {\n var tempMaxTime=new Date(\"01/01/1970 \" + dp_inst.settings.maxTime);\n if (this.hour>tempMaxTime.getHours()) {\n this.hour=this._defaults.hourMax=tempMaxTime.getHours();\n this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes();\n } else if (this.hour===tempMaxTime.getHours() && this.minute>tempMaxTime.getMinutes()) {\n this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes();\n } else {\n if (this._defaults.hourMax>tempMaxTime.getHours()) {\n this._defaults.hourMax=tempMaxTime.getHours();\n this._defaults.minuteMax=tempMaxTime.getMinutes();\n } else if (this._defaults.hourMax===tempMaxTime.getHours()===this.hour && this._defaults.minuteMax>tempMaxTime.getMinutes()) {\n this._defaults.minuteMax=tempMaxTime.getMinutes();\n } else {\n this._defaults.minuteMax=59;\n }\n }\n }\n\n if (adjustSliders !== undefined && adjustSliders === true) {\n var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)), 10),\n minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)), 10),\n secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)), 10),\n millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)), 10),\n microsecMax = parseInt((this._defaults.microsecMax - ((this._defaults.microsecMax - this._defaults.microsecMin) % this._defaults.stepMicrosec)), 10);\n\n if (this.hour_slider) {\n this.control.options(this, this.hour_slider, 'hour', { min: this._defaults.hourMin, max: hourMax, step: this._defaults.stepHour });\n this.control.value(this, this.hour_slider, 'hour', this.hour - (this.hour % this._defaults.stepHour));\n }\n if (this.minute_slider) {\n this.control.options(this, this.minute_slider, 'minute', { min: this._defaults.minuteMin, max: minMax, step: this._defaults.stepMinute });\n this.control.value(this, this.minute_slider, 'minute', this.minute - (this.minute % this._defaults.stepMinute));\n }\n if (this.second_slider) {\n this.control.options(this, this.second_slider, 'second', { min: this._defaults.secondMin, max: secMax, step: this._defaults.stepSecond });\n this.control.value(this, this.second_slider, 'second', this.second - (this.second % this._defaults.stepSecond));\n }\n if (this.millisec_slider) {\n this.control.options(this, this.millisec_slider, 'millisec', { min: this._defaults.millisecMin, max: millisecMax, step: this._defaults.stepMillisec });\n this.control.value(this, this.millisec_slider, 'millisec', this.millisec - (this.millisec % this._defaults.stepMillisec));\n }\n if (this.microsec_slider) {\n this.control.options(this, this.microsec_slider, 'microsec', { min: this._defaults.microsecMin, max: microsecMax, step: this._defaults.stepMicrosec });\n this.control.value(this, this.microsec_slider, 'microsec', this.microsec - (this.microsec % this._defaults.stepMicrosec));\n }\n }\n\n },\n\n /*\n * when a slider moves, set the internal time...\n * on time change is also called when the time is updated in the text field\n */\n _onTimeChange: function () {\n if (!this._defaults.showTimepicker) {\n return;\n }\n var hour = (this.hour_slider) ? this.control.value(this, this.hour_slider, 'hour') : false,\n minute = (this.minute_slider) ? this.control.value(this, this.minute_slider, 'minute') : false,\n second = (this.second_slider) ? this.control.value(this, this.second_slider, 'second') : false,\n millisec = (this.millisec_slider) ? this.control.value(this, this.millisec_slider, 'millisec') : false,\n microsec = (this.microsec_slider) ? this.control.value(this, this.microsec_slider, 'microsec') : false,\n timezone = (this.timezone_select) ? this.timezone_select.val() : false,\n o = this._defaults,\n pickerTimeFormat = o.pickerTimeFormat || o.timeFormat,\n pickerTimeSuffix = o.pickerTimeSuffix || o.timeSuffix;\n\n if (typeof(hour) === 'object') {\n hour = false;\n }\n if (typeof(minute) === 'object') {\n minute = false;\n }\n if (typeof(second) === 'object') {\n second = false;\n }\n if (typeof(millisec) === 'object') {\n millisec = false;\n }\n if (typeof(microsec) === 'object') {\n microsec = false;\n }\n if (typeof(timezone) === 'object') {\n timezone = false;\n }\n\n if (hour !== false) {\n hour = parseInt(hour, 10);\n }\n if (minute !== false) {\n minute = parseInt(minute, 10);\n }\n if (second !== false) {\n second = parseInt(second, 10);\n }\n if (millisec !== false) {\n millisec = parseInt(millisec, 10);\n }\n if (microsec !== false) {\n microsec = parseInt(microsec, 10);\n }\n if (timezone !== false) {\n timezone = timezone.toString();\n }\n\n var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0];\n\n // If the update was done in the input field, the input field should not be updated.\n // If the update was done using the sliders, update the input field.\n var hasChanged = (\n hour !== parseInt(this.hour,10) || // sliders should all be numeric\n minute !== parseInt(this.minute,10) ||\n second !== parseInt(this.second,10) ||\n millisec !== parseInt(this.millisec,10) ||\n microsec !== parseInt(this.microsec,10) ||\n (this.ampm.length > 0 && (hour < 12) !== ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1)) ||\n (this.timezone !== null && timezone !== this.timezone.toString()) // could be numeric or \"EST\" format, so use toString()\n );\n\n if (hasChanged) {\n\n if (hour !== false) {\n this.hour = hour;\n }\n if (minute !== false) {\n this.minute = minute;\n }\n if (second !== false) {\n this.second = second;\n }\n if (millisec !== false) {\n this.millisec = millisec;\n }\n if (microsec !== false) {\n this.microsec = microsec;\n }\n if (timezone !== false) {\n this.timezone = timezone;\n }\n\n if (!this.inst) {\n this.inst = $.datepicker._getInst(this.$input[0]);\n }\n\n this._limitMinMaxDateTime(this.inst, true);\n }\n if (this.support.ampm) {\n this.ampm = ampm;\n }\n\n // Updates the time within the timepicker\n this.formattedTime = $.datepicker.formatTime(o.timeFormat, this, o);\n if (this.$timeObj) {\n if (pickerTimeFormat === o.timeFormat) {\n this.$timeObj.val(this.formattedTime + pickerTimeSuffix);\n }\n else {\n this.$timeObj.val($.datepicker.formatTime(pickerTimeFormat, this, o) + pickerTimeSuffix);\n }\n if (this.$timeObj[0].setSelectionRange) {\n var sPos = this.$timeObj[0].selectionStart;\n var ePos = this.$timeObj[0].selectionEnd;\n this.$timeObj[0].setSelectionRange(sPos, ePos);\n }\n }\n\n this.timeDefined = true;\n if (hasChanged) {\n this._updateDateTime();\n //this.$input.focus(); // may automatically open the picker on setDate\n }\n },\n\n /*\n * call custom onSelect.\n * bind to sliders slidestop, and grid click.\n */\n _onSelectHandler: function () {\n var onSelect = this._defaults.onSelect || this.inst.settings.onSelect;\n var inputEl = this.$input ? this.$input[0] : null;\n if (onSelect && inputEl) {\n onSelect.apply(inputEl, [this.formattedDateTime, this]);\n }\n },\n\n /*\n * update our input with the new date time..\n */\n _updateDateTime: function (dp_inst) {\n dp_inst = this.inst || dp_inst;\n var dtTmp = (dp_inst.currentYear > 0?\n new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay) :\n new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),\n dt = $.datepicker._daylightSavingAdjust(dtTmp),\n //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),\n //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay)),\n dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),\n formatCfg = $.datepicker._getFormatConfig(dp_inst),\n timeAvailable = dt !== null && this.timeDefined;\n this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);\n var formattedDateTime = this.formattedDate;\n\n // if a slider was changed but datepicker doesn't have a value yet, set it\n if (dp_inst.lastVal === \"\") {\n dp_inst.currentYear = dp_inst.selectedYear;\n dp_inst.currentMonth = dp_inst.selectedMonth;\n dp_inst.currentDay = dp_inst.selectedDay;\n }\n\n /*\n * remove following lines to force every changes in date picker to change the input value\n * Bug descriptions: when an input field has a default value, and click on the field to pop up the date picker.\n * If the user manually empty the value in the input field, the date picker will never change selected value.\n */\n //if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) {\n //\treturn;\n //}\n\n if (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === false) {\n formattedDateTime = this.formattedTime;\n } else if ((this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) || (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === true)) {\n formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix;\n }\n\n this.formattedDateTime = formattedDateTime;\n\n if (!this._defaults.showTimepicker) {\n this.$input.val(this.formattedDate);\n } else if (this.$altInput && this._defaults.timeOnly === false && this._defaults.altFieldTimeOnly === true) {\n this.$altInput.val(this.formattedTime);\n this.$input.val(this.formattedDate);\n } else if (this.$altInput) {\n this.$input.val(formattedDateTime);\n var altFormattedDateTime = '',\n altSeparator = this._defaults.altSeparator !== null ? this._defaults.altSeparator : this._defaults.separator,\n altTimeSuffix = this._defaults.altTimeSuffix !== null ? this._defaults.altTimeSuffix : this._defaults.timeSuffix;\n\n if (!this._defaults.timeOnly) {\n if (this._defaults.altFormat) {\n altFormattedDateTime = $.datepicker.formatDate(this._defaults.altFormat, (dt === null ? new Date() : dt), formatCfg);\n }\n else {\n altFormattedDateTime = this.formattedDate;\n }\n\n if (altFormattedDateTime) {\n altFormattedDateTime += altSeparator;\n }\n }\n\n if (this._defaults.altTimeFormat !== null) {\n altFormattedDateTime += $.datepicker.formatTime(this._defaults.altTimeFormat, this, this._defaults) + altTimeSuffix;\n }\n else {\n altFormattedDateTime += this.formattedTime + altTimeSuffix;\n }\n this.$altInput.val(altFormattedDateTime);\n } else {\n this.$input.val(formattedDateTime);\n }\n\n this.$input.trigger(\"change\");\n },\n\n _onFocus: function () {\n if (!this.$input.val() && this._defaults.defaultValue) {\n this.$input.val(this._defaults.defaultValue);\n var inst = $.datepicker._getInst(this.$input.get(0)),\n tp_inst = $.datepicker._get(inst, 'timepicker');\n if (tp_inst) {\n if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {\n try {\n $.datepicker._updateDatepicker(inst);\n } catch (err) {\n $.timepicker.log(err);\n }\n }\n }\n }\n },\n\n /*\n * Small abstraction to control types\n * We can add more, just be sure to follow the pattern: create, options, value\n */\n _controls: {\n // slider methods\n slider: {\n create: function (tp_inst, obj, unit, val, min, max, step) {\n var rtl = tp_inst._defaults.isRTL; // if rtl go -60->0 instead of 0->60\n return obj.prop('slide', null).slider({\n orientation: \"horizontal\",\n value: rtl ? val * -1 : val,\n min: rtl ? max * -1 : min,\n max: rtl ? min * -1 : max,\n step: step,\n slide: function (event, ui) {\n tp_inst.control.value(tp_inst, $(this), unit, rtl ? ui.value * -1 : ui.value);\n tp_inst._onTimeChange();\n },\n stop: function (event, ui) {\n tp_inst._onSelectHandler();\n }\n });\n },\n options: function (tp_inst, obj, unit, opts, val) {\n if (tp_inst._defaults.isRTL) {\n if (typeof(opts) === 'string') {\n if (opts === 'min' || opts === 'max') {\n if (val !== undefined) {\n return obj.slider(opts, val * -1);\n }\n return Math.abs(obj.slider(opts));\n }\n return obj.slider(opts);\n }\n var min = opts.min,\n max = opts.max;\n opts.min = opts.max = null;\n if (min !== undefined) {\n opts.max = min * -1;\n }\n if (max !== undefined) {\n opts.min = max * -1;\n }\n return obj.slider(opts);\n }\n if (typeof(opts) === 'string' && val !== undefined) {\n return obj.slider(opts, val);\n }\n return obj.slider(opts);\n },\n value: function (tp_inst, obj, unit, val) {\n if (tp_inst._defaults.isRTL) {\n if (val !== undefined) {\n return obj.slider('value', val * -1);\n }\n return Math.abs(obj.slider('value'));\n }\n if (val !== undefined) {\n return obj.slider('value', val);\n }\n return obj.slider('value');\n }\n },\n // select methods\n select: {\n create: function (tp_inst, obj, unit, val, min, max, step) {\n var sel = '<select class=\"ui-timepicker-select ui-state-default ui-corner-all\" data-unit=\"' + unit + '\" data-min=\"' + min + '\" data-max=\"' + max + '\" data-step=\"' + step + '\">',\n format = tp_inst._defaults.pickerTimeFormat || tp_inst._defaults.timeFormat;\n\n for (var i = min; i <= max; i += step) {\n sel += '<option value=\"' + i + '\"' + (i === val ? ' selected' : '') + '>';\n if (unit === 'hour') {\n sel += $.datepicker.formatTime($.trim(format.replace(/[^ht ]/ig, '')), {hour: i}, tp_inst._defaults);\n }\n else if (unit === 'millisec' || unit === 'microsec' || i >= 10) { sel += i; }\n else {sel += '0' + i.toString(); }\n sel += '</option>';\n }\n sel += '</select>';\n\n obj.children('select').remove();\n\n $(sel).appendTo(obj).change(function (e) {\n tp_inst._onTimeChange();\n tp_inst._onSelectHandler();\n tp_inst._afterInject();\n });\n\n return obj;\n },\n options: function (tp_inst, obj, unit, opts, val) {\n var o = {},\n $t = obj.children('select');\n if (typeof(opts) === 'string') {\n if (val === undefined) {\n return $t.data(opts);\n }\n o[opts] = val;\n }\n else { o = opts; }\n return tp_inst.control.create(tp_inst, obj, $t.data('unit'), $t.val(), o.min>=0 ? o.min : $t.data('min'), o.max || $t.data('max'), o.step || $t.data('step'));\n },\n value: function (tp_inst, obj, unit, val) {\n var $t = obj.children('select');\n if (val !== undefined) {\n return $t.val(val);\n }\n return $t.val();\n }\n }\n } // end _controls\n\n });\n\n $.fn.extend({\n /*\n * shorthand just to use timepicker.\n */\n timepicker: function (o) {\n o = o || {};\n var tmp_args = Array.prototype.slice.call(arguments);\n\n if (typeof o === 'object') {\n tmp_args[0] = $.extend(o, {\n timeOnly: true\n });\n }\n\n return $(this).each(function () {\n $.fn.datetimepicker.apply($(this), tmp_args);\n });\n },\n\n /*\n * extend timepicker to datepicker\n */\n datetimepicker: function (o) {\n o = o || {};\n var tmp_args = arguments;\n\n if (typeof(o) === 'string') {\n if (o === 'getDate' || (o === 'option' && tmp_args.length === 2 && typeof (tmp_args[1]) === 'string')) {\n return $.fn.datepicker.apply($(this[0]), tmp_args);\n } else {\n return this.each(function () {\n var $t = $(this);\n $t.datepicker.apply($t, tmp_args);\n });\n }\n } else {\n return this.each(function () {\n var $t = $(this);\n $t.datepicker($.timepicker._newInst($t, o)._defaults);\n });\n }\n }\n });\n\n /*\n * Public Utility to parse date and time\n */\n $.datepicker.parseDateTime = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {\n var parseRes = parseDateTimeInternal(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings);\n if (parseRes.timeObj) {\n var t = parseRes.timeObj;\n parseRes.date.setHours(t.hour, t.minute, t.second, t.millisec);\n parseRes.date.setMicroseconds(t.microsec);\n }\n\n return parseRes.date;\n };\n\n /*\n * Public utility to parse time\n */\n $.datepicker.parseTime = function (timeFormat, timeString, options) {\n var o = extendRemove(extendRemove({}, $.timepicker._defaults), options || {}),\n iso8601 = (timeFormat.replace(/\\'.*?\\'/g, '').indexOf('Z') !== -1);\n\n // Strict parse requires the timeString to match the timeFormat exactly\n var strictParse = function (f, s, o) {\n\n // pattern for standard and localized AM/PM markers\n var getPatternAmpm = function (amNames, pmNames) {\n var markers = [];\n if (amNames) {\n $.merge(markers, amNames);\n }\n if (pmNames) {\n $.merge(markers, pmNames);\n }\n markers = $.map(markers, function (val) {\n return val.replace(/[.*+?|()\\[\\]{}\\\\]/g, '\\\\$&');\n });\n return '(' + markers.join('|') + ')?';\n };\n\n // figure out position of time elements.. cause js cant do named captures\n var getFormatPositions = function (timeFormat) {\n var finds = timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|c{1}|t{1,2}|z|'.*?')/g),\n orders = {\n h: -1,\n m: -1,\n s: -1,\n l: -1,\n c: -1,\n t: -1,\n z: -1\n };\n\n if (finds) {\n for (var i = 0; i < finds.length; i++) {\n if (orders[finds[i].toString().charAt(0)] === -1) {\n orders[finds[i].toString().charAt(0)] = i + 1;\n }\n }\n }\n return orders;\n };\n\n var regstr = '^' + f.toString()\n .replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {\n var ml = match.length;\n switch (match.charAt(0).toLowerCase()) {\n case 'h':\n return ml === 1 ? '(\\\\d?\\\\d)' : '(\\\\d{' + ml + '})';\n case 'm':\n return ml === 1 ? '(\\\\d?\\\\d)' : '(\\\\d{' + ml + '})';\n case 's':\n return ml === 1 ? '(\\\\d?\\\\d)' : '(\\\\d{' + ml + '})';\n case 'l':\n return '(\\\\d?\\\\d?\\\\d)';\n case 'c':\n return '(\\\\d?\\\\d?\\\\d)';\n case 'z':\n return '(z|[-+]\\\\d\\\\d:?\\\\d\\\\d|\\\\S+)?';\n case 't':\n return getPatternAmpm(o.amNames, o.pmNames);\n default: // literal escaped in quotes\n return '(' + match.replace(/\\'/g, \"\").replace(/(\\.|\\$|\\^|\\\\|\\/|\\(|\\)|\\[|\\]|\\?|\\+|\\*)/g, function (m) { return \"\\\\\" + m; }) + ')?';\n }\n })\n .replace(/\\s/g, '\\\\s?') +\n o.timeSuffix + '$',\n order = getFormatPositions(f),\n ampm = '',\n treg;\n\n treg = s.match(new RegExp(regstr, 'i'));\n\n var resTime = {\n hour: 0,\n minute: 0,\n second: 0,\n millisec: 0,\n microsec: 0\n };\n\n if (treg) {\n if (order.t !== -1) {\n if (treg[order.t] === undefined || treg[order.t].length === 0) {\n ampm = '';\n resTime.ampm = '';\n } else {\n ampm = $.inArray(treg[order.t].toUpperCase(), $.map(o.amNames, function (x,i) { return x.toUpperCase(); })) !== -1 ? 'AM' : 'PM';\n resTime.ampm = o[ampm === 'AM' ? 'amNames' : 'pmNames'][0];\n }\n }\n\n if (order.h !== -1) {\n if (ampm === 'AM' && treg[order.h] === '12') {\n resTime.hour = 0; // 12am = 0 hour\n } else {\n if (ampm === 'PM' && treg[order.h] !== '12') {\n resTime.hour = parseInt(treg[order.h], 10) + 12; // 12pm = 12 hour, any other pm = hour + 12\n } else {\n resTime.hour = Number(treg[order.h]);\n }\n }\n }\n\n if (order.m !== -1) {\n resTime.minute = Number(treg[order.m]);\n }\n if (order.s !== -1) {\n resTime.second = Number(treg[order.s]);\n }\n if (order.l !== -1) {\n resTime.millisec = Number(treg[order.l]);\n }\n if (order.c !== -1) {\n resTime.microsec = Number(treg[order.c]);\n }\n if (order.z !== -1 && treg[order.z] !== undefined) {\n resTime.timezone = $.timepicker.timezoneOffsetNumber(treg[order.z]);\n }\n\n\n return resTime;\n }\n return false;\n };// end strictParse\n\n // First try JS Date, if that fails, use strictParse\n var looseParse = function (f, s, o) {\n try {\n var d = new Date('2012-01-01 ' + s);\n if (isNaN(d.getTime())) {\n d = new Date('2012-01-01T' + s);\n if (isNaN(d.getTime())) {\n d = new Date('01/01/2012 ' + s);\n if (isNaN(d.getTime())) {\n throw \"Unable to parse time with native Date: \" + s;\n }\n }\n }\n\n return {\n hour: d.getHours(),\n minute: d.getMinutes(),\n second: d.getSeconds(),\n millisec: d.getMilliseconds(),\n microsec: d.getMicroseconds(),\n timezone: d.getTimezoneOffset() * -1\n };\n }\n catch (err) {\n try {\n return strictParse(f, s, o);\n }\n catch (err2) {\n $.timepicker.log(\"Unable to parse \\ntimeString: \" + s + \"\\ntimeFormat: \" + f);\n }\n }\n return false;\n }; // end looseParse\n\n if (typeof o.parse === \"function\") {\n return o.parse(timeFormat, timeString, o);\n }\n if (o.parse === 'loose') {\n return looseParse(timeFormat, timeString, o);\n }\n return strictParse(timeFormat, timeString, o);\n };\n\n /**\n * Public utility to format the time\n * @param {string} format format of the time\n * @param {Object} time Object not a Date for timezones\n * @param {Object} [options] essentially the regional[].. amNames, pmNames, ampm\n * @returns {string} the formatted time\n */\n $.datepicker.formatTime = function (format, time, options) {\n options = options || {};\n options = $.extend({}, $.timepicker._defaults, options);\n time = $.extend({\n hour: 0,\n minute: 0,\n second: 0,\n millisec: 0,\n microsec: 0,\n timezone: null\n }, time);\n\n var tmptime = format,\n ampmName = options.amNames[0],\n hour = parseInt(time.hour, 10);\n\n if (hour > 11) {\n ampmName = options.pmNames[0];\n }\n\n tmptime = tmptime.replace(/(?:HH?|hh?|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {\n switch (match) {\n case 'HH':\n return ('0' + hour).slice(-2);\n case 'H':\n return hour;\n case 'hh':\n return ('0' + convert24to12(hour)).slice(-2);\n case 'h':\n return convert24to12(hour);\n case 'mm':\n return ('0' + time.minute).slice(-2);\n case 'm':\n return time.minute;\n case 'ss':\n return ('0' + time.second).slice(-2);\n case 's':\n return time.second;\n case 'l':\n return ('00' + time.millisec).slice(-3);\n case 'c':\n return ('00' + time.microsec).slice(-3);\n case 'z':\n return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, false);\n case 'Z':\n return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, true);\n case 'T':\n return ampmName.charAt(0).toUpperCase();\n case 'TT':\n return ampmName.toUpperCase();\n case 't':\n return ampmName.charAt(0).toLowerCase();\n case 'tt':\n return ampmName.toLowerCase();\n default:\n return match.replace(/'/g, \"\");\n }\n });\n\n return tmptime;\n };\n\n /*\n * the bad hack :/ override datepicker so it doesn't close on select\n // inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378\n */\n $.datepicker._base_selectDate = $.datepicker._selectDate;\n $.datepicker._selectDate = function (id, dateStr) {\n var inst = this._getInst($(id)[0]),\n tp_inst = this._get(inst, 'timepicker'),\n was_inline;\n\n if (tp_inst && inst.settings.showTimepicker) {\n tp_inst._limitMinMaxDateTime(inst, true);\n was_inline = inst.inline;\n inst.inline = inst.stay_open = true;\n //This way the onSelect handler called from calendarpicker get the full dateTime\n this._base_selectDate(id, dateStr);\n inst.inline = was_inline;\n inst.stay_open = false;\n this._notifyChange(inst);\n this._updateDatepicker(inst);\n } else {\n this._base_selectDate(id, dateStr);\n }\n };\n\n /*\n * second bad hack :/ override datepicker so it triggers an event when changing the input field\n * and does not redraw the datepicker on every selectDate event\n */\n $.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;\n $.datepicker._updateDatepicker = function (inst) {\n\n // don't popup the datepicker if there is another instance already opened\n var input = inst.input[0];\n if ($.datepicker._curInst && $.datepicker._curInst !== inst && $.datepicker._datepickerShowing && $.datepicker._lastInput !== input) {\n return;\n }\n\n if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {\n\n this._base_updateDatepicker(inst);\n\n // Reload the time control when changing something in the input text field.\n var tp_inst = this._get(inst, 'timepicker');\n if (tp_inst) {\n tp_inst._addTimePicker(inst);\n }\n }\n };\n\n /*\n * third bad hack :/ override datepicker so it allows spaces and colon in the input field\n */\n $.datepicker._base_doKeyPress = $.datepicker._doKeyPress;\n $.datepicker._doKeyPress = function (event) {\n var inst = $.datepicker._getInst(event.target),\n tp_inst = $.datepicker._get(inst, 'timepicker');\n\n if (tp_inst) {\n if ($.datepicker._get(inst, 'constrainInput')) {\n var ampm = tp_inst.support.ampm,\n tz = tp_inst._defaults.showTimezone !== null ? tp_inst._defaults.showTimezone : tp_inst.support.timezone,\n dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),\n datetimeChars = tp_inst._defaults.timeFormat.toString()\n .replace(/[hms]/g, '')\n .replace(/TT/g, ampm ? 'APM' : '')\n .replace(/Tt/g, ampm ? 'AaPpMm' : '')\n .replace(/tT/g, ampm ? 'AaPpMm' : '')\n .replace(/T/g, ampm ? 'AP' : '')\n .replace(/tt/g, ampm ? 'apm' : '')\n .replace(/t/g, ampm ? 'ap' : '') +\n \" \" + tp_inst._defaults.separator +\n tp_inst._defaults.timeSuffix +\n (tz ? tp_inst._defaults.timezoneList.join('') : '') +\n (tp_inst._defaults.amNames.join('')) + (tp_inst._defaults.pmNames.join('')) +\n dateChars,\n chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);\n return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1);\n }\n }\n\n return $.datepicker._base_doKeyPress(event);\n };\n\n /*\n * Fourth bad hack :/ override _updateAlternate function used in inline mode to init altField\n * Update any alternate field to synchronise with the main field.\n */\n $.datepicker._base_updateAlternate = $.datepicker._updateAlternate;\n $.datepicker._updateAlternate = function (inst) {\n var tp_inst = this._get(inst, 'timepicker');\n if (tp_inst) {\n var altField = tp_inst._defaults.altField;\n if (altField) { // update alternate field too\n var altFormat = tp_inst._defaults.altFormat || tp_inst._defaults.dateFormat,\n date = this._getDate(inst),\n formatCfg = $.datepicker._getFormatConfig(inst),\n altFormattedDateTime = '',\n altSeparator = tp_inst._defaults.altSeparator ? tp_inst._defaults.altSeparator : tp_inst._defaults.separator,\n altTimeSuffix = tp_inst._defaults.altTimeSuffix ? tp_inst._defaults.altTimeSuffix : tp_inst._defaults.timeSuffix,\n altTimeFormat = tp_inst._defaults.altTimeFormat !== null ? tp_inst._defaults.altTimeFormat : tp_inst._defaults.timeFormat;\n\n altFormattedDateTime += $.datepicker.formatTime(altTimeFormat, tp_inst, tp_inst._defaults) + altTimeSuffix;\n if (!tp_inst._defaults.timeOnly && !tp_inst._defaults.altFieldTimeOnly && date !== null) {\n if (tp_inst._defaults.altFormat) {\n altFormattedDateTime = $.datepicker.formatDate(tp_inst._defaults.altFormat, date, formatCfg) + altSeparator + altFormattedDateTime;\n }\n else {\n altFormattedDateTime = tp_inst.formattedDate + altSeparator + altFormattedDateTime;\n }\n }\n $(altField).val( inst.input.val() ? altFormattedDateTime : \"\");\n }\n }\n else {\n $.datepicker._base_updateAlternate(inst);\n }\n };\n\n /*\n * Override key up event to sync manual input changes.\n */\n $.datepicker._base_doKeyUp = $.datepicker._doKeyUp;\n $.datepicker._doKeyUp = function (event) {\n var inst = $.datepicker._getInst(event.target),\n tp_inst = $.datepicker._get(inst, 'timepicker');\n\n if (tp_inst) {\n if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {\n try {\n $.datepicker._updateDatepicker(inst);\n } catch (err) {\n $.timepicker.log(err);\n }\n }\n }\n\n return $.datepicker._base_doKeyUp(event);\n };\n\n /*\n * override \"Today\" button to also grab the time and set it to input field.\n */\n $.datepicker._base_gotoToday = $.datepicker._gotoToday;\n $.datepicker._gotoToday = function (id) {\n var inst = this._getInst($(id)[0]);\n this._base_gotoToday(id);\n var tp_inst = this._get(inst, 'timepicker');\n if (!tp_inst) {\n return;\n }\n\n var tzoffset = $.timepicker.timezoneOffsetNumber(tp_inst.timezone);\n var now = new Date();\n now.setMinutes(now.getMinutes() + now.getTimezoneOffset() + parseInt(tzoffset, 10));\n this._setTime(inst, now);\n this._setDate(inst, now);\n tp_inst._onSelectHandler();\n };\n\n /*\n * Disable & enable the Time in the datetimepicker\n */\n $.datepicker._disableTimepickerDatepicker = function (target) {\n var inst = this._getInst(target);\n if (!inst) {\n return;\n }\n\n var tp_inst = this._get(inst, 'timepicker');\n $(target).datepicker('getDate'); // Init selected[Year|Month|Day]\n if (tp_inst) {\n inst.settings.showTimepicker = false;\n tp_inst._defaults.showTimepicker = false;\n tp_inst._updateDateTime(inst);\n }\n };\n\n $.datepicker._enableTimepickerDatepicker = function (target) {\n var inst = this._getInst(target);\n if (!inst) {\n return;\n }\n\n var tp_inst = this._get(inst, 'timepicker');\n $(target).datepicker('getDate'); // Init selected[Year|Month|Day]\n if (tp_inst) {\n inst.settings.showTimepicker = true;\n tp_inst._defaults.showTimepicker = true;\n tp_inst._addTimePicker(inst); // Could be disabled on page load\n tp_inst._updateDateTime(inst);\n }\n };\n\n /*\n * Create our own set time function\n */\n $.datepicker._setTime = function (inst, date) {\n var tp_inst = this._get(inst, 'timepicker');\n if (tp_inst) {\n var defaults = tp_inst._defaults;\n\n // calling _setTime with no date sets time to defaults\n tp_inst.hour = date ? date.getHours() : defaults.hour;\n tp_inst.minute = date ? date.getMinutes() : defaults.minute;\n tp_inst.second = date ? date.getSeconds() : defaults.second;\n tp_inst.millisec = date ? date.getMilliseconds() : defaults.millisec;\n tp_inst.microsec = date ? date.getMicroseconds() : defaults.microsec;\n\n //check if within min/max times..\n tp_inst._limitMinMaxDateTime(inst, true);\n\n tp_inst._onTimeChange();\n tp_inst._updateDateTime(inst);\n }\n };\n\n /*\n * Create new public method to set only time, callable as $().datepicker('setTime', date)\n */\n $.datepicker._setTimeDatepicker = function (target, date, withDate) {\n var inst = this._getInst(target);\n if (!inst) {\n return;\n }\n\n var tp_inst = this._get(inst, 'timepicker');\n\n if (tp_inst) {\n this._setDateFromField(inst);\n var tp_date;\n if (date) {\n if (typeof date === \"string\") {\n tp_inst._parseTime(date, withDate);\n tp_date = new Date();\n tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);\n tp_date.setMicroseconds(tp_inst.microsec);\n } else {\n tp_date = new Date(date.getTime());\n tp_date.setMicroseconds(date.getMicroseconds());\n }\n if (tp_date.toString() === 'Invalid Date') {\n tp_date = undefined;\n }\n this._setTime(inst, tp_date);\n }\n }\n\n };\n\n /*\n * override setDate() to allow setting time too within Date object\n */\n $.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;\n $.datepicker._setDateDatepicker = function (target, _date) {\n var inst = this._getInst(target);\n var date = _date;\n if (!inst) {\n return;\n }\n\n if (typeof(_date) === 'string') {\n date = new Date(_date);\n if (!date.getTime()) {\n this._base_setDateDatepicker.apply(this, arguments);\n date = $(target).datepicker('getDate');\n }\n }\n\n var tp_inst = this._get(inst, 'timepicker');\n var tp_date;\n if (date instanceof Date) {\n tp_date = new Date(date.getTime());\n tp_date.setMicroseconds(date.getMicroseconds());\n } else {\n tp_date = date;\n }\n\n // This is important if you are using the timezone option, javascript's Date\n // object will only return the timezone offset for the current locale, so we\n // adjust it accordingly. If not using timezone option this won't matter..\n // If a timezone is different in tp, keep the timezone as is\n if (tp_inst && tp_date) {\n // look out for DST if tz wasn't specified\n if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {\n tp_inst.timezone = tp_date.getTimezoneOffset() * -1;\n }\n date = $.timepicker.timezoneAdjust(date, $.timepicker.timezoneOffsetString(-date.getTimezoneOffset()), tp_inst.timezone);\n tp_date = $.timepicker.timezoneAdjust(tp_date, $.timepicker.timezoneOffsetString(-tp_date.getTimezoneOffset()), tp_inst.timezone);\n }\n\n this._updateDatepicker(inst);\n this._base_setDateDatepicker.apply(this, arguments);\n this._setTimeDatepicker(target, tp_date, true);\n };\n\n /*\n * override getDate() to allow getting time too within Date object\n */\n $.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;\n $.datepicker._getDateDatepicker = function (target, noDefault) {\n var inst = this._getInst(target);\n if (!inst) {\n return;\n }\n\n var tp_inst = this._get(inst, 'timepicker');\n\n if (tp_inst) {\n // if it hasn't yet been defined, grab from field\n if (inst.lastVal === undefined) {\n this._setDateFromField(inst, noDefault);\n }\n\n var date = this._getDate(inst);\n\n var currDT = null;\n\n if (tp_inst.$altInput && tp_inst._defaults.altFieldTimeOnly) {\n currDT = tp_inst.$input.val() + ' ' + tp_inst.$altInput.val();\n }\n else if (tp_inst.$input.get(0).tagName !== 'INPUT' && tp_inst.$altInput) {\n /**\n * in case the datetimepicker has been applied to a non-input tag for inline UI,\n * and the user has not configured the plugin to display only time in altInput,\n * pick current date time from the altInput (and hope for the best, for now, until \"ER1\" is applied)\n *\n * @todo ER1. Since altInput can have a totally difference format, convert it to standard format by reading input format from \"altFormat\" and \"altTimeFormat\" option values\n */\n currDT = tp_inst.$altInput.val();\n }\n else {\n currDT = tp_inst.$input.val();\n }\n\n if (date && tp_inst._parseTime(currDT, !inst.settings.timeOnly)) {\n date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);\n date.setMicroseconds(tp_inst.microsec);\n\n // This is important if you are using the timezone option, javascript's Date\n // object will only return the timezone offset for the current locale, so we\n // adjust it accordingly. If not using timezone option this won't matter..\n if (tp_inst.timezone != null) {\n // look out for DST if tz wasn't specified\n if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {\n tp_inst.timezone = date.getTimezoneOffset() * -1;\n }\n date = $.timepicker.timezoneAdjust(date, tp_inst.timezone, $.timepicker.timezoneOffsetString(-date.getTimezoneOffset()));\n }\n }\n return date;\n }\n return this._base_getDateDatepicker(target, noDefault);\n };\n\n /*\n * override parseDate() because UI 1.8.14 throws an error about \"Extra characters\"\n * An option in datapicker to ignore extra format characters would be nicer.\n */\n $.datepicker._base_parseDate = $.datepicker.parseDate;\n $.datepicker.parseDate = function (format, value, settings) {\n var date;\n try {\n date = this._base_parseDate(format, value, settings);\n } catch (err) {\n // Hack! The error message ends with a colon, a space, and\n // the \"extra\" characters. We rely on that instead of\n // attempting to perfectly reproduce the parsing algorithm.\n if (err.indexOf(\":\") >= 0) {\n date = this._base_parseDate(format, value.substring(0, value.length - (err.length - err.indexOf(':') - 2)), settings);\n $.timepicker.log(\"Error parsing the date string: \" + err + \"\\ndate string = \" + value + \"\\ndate format = \" + format);\n } else {\n throw err;\n }\n }\n return date;\n };\n\n /*\n * override formatDate to set date with time to the input\n */\n $.datepicker._base_formatDate = $.datepicker._formatDate;\n $.datepicker._formatDate = function (inst, day, month, year) {\n var tp_inst = this._get(inst, 'timepicker');\n if (tp_inst) {\n tp_inst._updateDateTime(inst);\n return tp_inst.$input.val();\n }\n return this._base_formatDate(inst);\n };\n\n /*\n * override options setter to add time to maxDate(Time) and minDate(Time). MaxDate\n */\n $.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker;\n $.datepicker._optionDatepicker = function (target, name, value) {\n var inst = this._getInst(target),\n name_clone;\n if (!inst) {\n return null;\n }\n\n var tp_inst = this._get(inst, 'timepicker');\n if (tp_inst) {\n var min = null,\n max = null,\n onselect = null,\n overrides = tp_inst._defaults.evnts,\n fns = {},\n prop,\n ret,\n oldVal,\n $target;\n if (typeof name === 'string') { // if min/max was set with the string\n if (name === 'minDate' || name === 'minDateTime') {\n min = value;\n } else if (name === 'maxDate' || name === 'maxDateTime') {\n max = value;\n } else if (name === 'onSelect') {\n onselect = value;\n } else if (overrides.hasOwnProperty(name)) {\n if (typeof (value) === 'undefined') {\n return overrides[name];\n }\n fns[name] = value;\n name_clone = {}; //empty results in exiting function after overrides updated\n }\n } else if (typeof name === 'object') { //if min/max was set with the JSON\n if (name.minDate) {\n min = name.minDate;\n } else if (name.minDateTime) {\n min = name.minDateTime;\n } else if (name.maxDate) {\n max = name.maxDate;\n } else if (name.maxDateTime) {\n max = name.maxDateTime;\n }\n for (prop in overrides) {\n if (overrides.hasOwnProperty(prop) && name[prop]) {\n fns[prop] = name[prop];\n }\n }\n }\n for (prop in fns) {\n if (fns.hasOwnProperty(prop)) {\n overrides[prop] = fns[prop];\n if (!name_clone) { name_clone = $.extend({}, name); }\n delete name_clone[prop];\n }\n }\n if (name_clone && isEmptyObject(name_clone)) { return; }\n if (min) { //if min was set\n if (min === 0) {\n min = new Date();\n } else {\n min = new Date(min);\n }\n tp_inst._defaults.minDate = min;\n tp_inst._defaults.minDateTime = min;\n } else if (max) { //if max was set\n if (max === 0) {\n max = new Date();\n } else {\n max = new Date(max);\n }\n tp_inst._defaults.maxDate = max;\n tp_inst._defaults.maxDateTime = max;\n } else if (onselect) {\n tp_inst._defaults.onSelect = onselect;\n }\n\n // Datepicker will override our date when we call _base_optionDatepicker when\n // calling minDate/maxDate, so we will first grab the value, call\n // _base_optionDatepicker, then set our value back.\n if(min || max){\n $target = $(target);\n oldVal = $target.datetimepicker('getDate');\n ret = this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);\n $target.datetimepicker('setDate', oldVal);\n return ret;\n }\n }\n if (value === undefined) {\n return this._base_optionDatepicker.call($.datepicker, target, name);\n }\n return this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);\n };\n\n /*\n * jQuery isEmptyObject does not check hasOwnProperty - if someone has added to the object prototype,\n * it will return false for all objects\n */\n var isEmptyObject = function (obj) {\n var prop;\n for (prop in obj) {\n if (obj.hasOwnProperty(prop)) {\n return false;\n }\n }\n return true;\n };\n\n /*\n * jQuery extend now ignores nulls!\n */\n var extendRemove = function (target, props) {\n $.extend(target, props);\n for (var name in props) {\n if (props[name] === null || props[name] === undefined) {\n target[name] = props[name];\n }\n }\n return target;\n };\n\n /*\n * Determine by the time format which units are supported\n * Returns an object of booleans for each unit\n */\n var detectSupport = function (timeFormat) {\n var tf = timeFormat.replace(/'.*?'/g, '').toLowerCase(), // removes literals\n isIn = function (f, t) { // does the format contain the token?\n return f.indexOf(t) !== -1 ? true : false;\n };\n return {\n hour: isIn(tf, 'h'),\n minute: isIn(tf, 'm'),\n second: isIn(tf, 's'),\n millisec: isIn(tf, 'l'),\n microsec: isIn(tf, 'c'),\n timezone: isIn(tf, 'z'),\n ampm: isIn(tf, 't') && isIn(timeFormat, 'h'),\n iso8601: isIn(timeFormat, 'Z')\n };\n };\n\n /*\n * Converts 24 hour format into 12 hour\n * Returns 12 hour without leading 0\n */\n var convert24to12 = function (hour) {\n hour %= 12;\n\n if (hour === 0) {\n hour = 12;\n }\n\n return String(hour);\n };\n\n var computeEffectiveSetting = function (settings, property) {\n return settings && settings[property] ? settings[property] : $.timepicker._defaults[property];\n };\n\n /*\n * Splits datetime string into date and time substrings.\n * Throws exception when date can't be parsed\n * Returns {dateString: dateString, timeString: timeString}\n */\n var splitDateTime = function (dateTimeString, timeSettings) {\n // The idea is to get the number separator occurrences in datetime and the time format requested (since time has\n // fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split.\n var separator = computeEffectiveSetting(timeSettings, 'separator'),\n format = computeEffectiveSetting(timeSettings, 'timeFormat'),\n timeParts = format.split(separator), // how many occurrences of separator may be in our format?\n timePartsLen = timeParts.length,\n allParts = dateTimeString.split(separator),\n allPartsLen = allParts.length;\n\n if (allPartsLen > 1) {\n return {\n dateString: allParts.splice(0, allPartsLen - timePartsLen).join(separator),\n timeString: allParts.splice(0, timePartsLen).join(separator)\n };\n }\n\n return {\n dateString: dateTimeString,\n timeString: ''\n };\n };\n\n /*\n * Internal function to parse datetime interval\n * Returns: {date: Date, timeObj: Object}, where\n * date - parsed date without time (type Date)\n * timeObj = {hour: , minute: , second: , millisec: , microsec: } - parsed time. Optional\n */\n var parseDateTimeInternal = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {\n var date,\n parts,\n parsedTime;\n\n parts = splitDateTime(dateTimeString, timeSettings);\n date = $.datepicker._base_parseDate(dateFormat, parts.dateString, dateSettings);\n\n if (parts.timeString === '') {\n return {\n date: date\n };\n }\n\n parsedTime = $.datepicker.parseTime(timeFormat, parts.timeString, timeSettings);\n\n if (!parsedTime) {\n throw 'Wrong time format';\n }\n\n return {\n date: date,\n timeObj: parsedTime\n };\n };\n\n /*\n * Internal function to set timezone_select to the local timezone\n */\n var selectLocalTimezone = function (tp_inst, date) {\n if (tp_inst && tp_inst.timezone_select) {\n var now = date || new Date();\n tp_inst.timezone_select.val(-now.getTimezoneOffset());\n }\n };\n\n /*\n * Create a Singleton Instance\n */\n $.timepicker = new Timepicker();\n\n /**\n * Get the timezone offset as string from a date object (eg '+0530' for UTC+5.5)\n * @param {number} tzMinutes if not a number, less than -720 (-1200), or greater than 840 (+1400) this value is returned\n * @param {boolean} iso8601 if true formats in accordance to iso8601 \"+12:45\"\n * @return {string}\n */\n $.timepicker.timezoneOffsetString = function (tzMinutes, iso8601) {\n if (isNaN(tzMinutes) || tzMinutes > 840 || tzMinutes < -720) {\n return tzMinutes;\n }\n\n var off = tzMinutes,\n minutes = off % 60,\n hours = (off - minutes) / 60,\n iso = iso8601 ? ':' : '',\n tz = (off >= 0 ? '+' : '-') + ('0' + Math.abs(hours)).slice(-2) + iso + ('0' + Math.abs(minutes)).slice(-2);\n\n if (tz === '+00:00') {\n return 'Z';\n }\n return tz;\n };\n\n /**\n * Get the number in minutes that represents a timezone string\n * @param {string} tzString formatted like \"+0500\", \"-1245\", \"Z\"\n * @return {number} the offset minutes or the original string if it doesn't match expectations\n */\n $.timepicker.timezoneOffsetNumber = function (tzString) {\n var normalized = tzString.toString().replace(':', ''); // excuse any iso8601, end up with \"+1245\"\n\n if (normalized.toUpperCase() === 'Z') { // if iso8601 with Z, its 0 minute offset\n return 0;\n }\n\n if (!/^(\\-|\\+)\\d{4}$/.test(normalized)) { // possibly a user defined tz, so just give it back\n return parseInt(tzString, 10);\n }\n\n return ((normalized.substr(0, 1) === '-' ? -1 : 1) * // plus or minus\n ((parseInt(normalized.substr(1, 2), 10) * 60) + // hours (converted to minutes)\n parseInt(normalized.substr(3, 2), 10))); // minutes\n };\n\n /**\n * No way to set timezone in js Date, so we must adjust the minutes to compensate. (think setDate, getDate)\n * @param {Date} date\n * @param {string} fromTimezone formatted like \"+0500\", \"-1245\"\n * @param {string} toTimezone formatted like \"+0500\", \"-1245\"\n * @return {Date}\n */\n $.timepicker.timezoneAdjust = function (date, fromTimezone, toTimezone) {\n var fromTz = $.timepicker.timezoneOffsetNumber(fromTimezone);\n var toTz = $.timepicker.timezoneOffsetNumber(toTimezone);\n if (!isNaN(toTz)) {\n date.setMinutes(date.getMinutes() + (-fromTz) - (-toTz));\n }\n return date;\n };\n\n /**\n * Calls `timepicker()` on the `startTime` and `endTime` elements, and configures them to\n * enforce date range limits.\n * n.b. The input value must be correctly formatted (reformatting is not supported)\n * @param {Element} startTime\n * @param {Element} endTime\n * @param {Object} options Options for the timepicker() call\n * @return {jQuery}\n */\n $.timepicker.timeRange = function (startTime, endTime, options) {\n return $.timepicker.handleRange('timepicker', startTime, endTime, options);\n };\n\n /**\n * Calls `datetimepicker` on the `startTime` and `endTime` elements, and configures them to\n * enforce date range limits.\n * @param {Element} startTime\n * @param {Element} endTime\n * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,\n * a boolean value that can be used to reformat the input values to the `dateFormat`.\n * @param {string} method Can be used to specify the type of picker to be added\n * @return {jQuery}\n */\n $.timepicker.datetimeRange = function (startTime, endTime, options) {\n $.timepicker.handleRange('datetimepicker', startTime, endTime, options);\n };\n\n /**\n * Calls `datepicker` on the `startTime` and `endTime` elements, and configures them to\n * enforce date range limits.\n * @param {Element} startTime\n * @param {Element} endTime\n * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,\n * a boolean value that can be used to reformat the input values to the `dateFormat`.\n * @return {jQuery}\n */\n $.timepicker.dateRange = function (startTime, endTime, options) {\n $.timepicker.handleRange('datepicker', startTime, endTime, options);\n };\n\n /**\n * Calls `method` on the `startTime` and `endTime` elements, and configures them to\n * enforce date range limits.\n * @param {string} method Can be used to specify the type of picker to be added\n * @param {Element} startTime\n * @param {Element} endTime\n * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,\n * a boolean value that can be used to reformat the input values to the `dateFormat`.\n * @return {jQuery}\n */\n $.timepicker.handleRange = function (method, startTime, endTime, options) {\n options = $.extend({}, {\n minInterval: 0, // min allowed interval in milliseconds\n maxInterval: 0, // max allowed interval in milliseconds\n start: {}, // options for start picker\n end: {} // options for end picker\n }, options);\n\n // for the mean time this fixes an issue with calling getDate with timepicker()\n var timeOnly = false;\n if(method === 'timepicker'){\n timeOnly = true;\n method = 'datetimepicker';\n }\n\n function checkDates(changed, other) {\n var startdt = startTime[method]('getDate'),\n enddt = endTime[method]('getDate'),\n changeddt = changed[method]('getDate');\n\n if (startdt !== null) {\n var minDate = new Date(startdt.getTime()),\n maxDate = new Date(startdt.getTime());\n\n minDate.setMilliseconds(minDate.getMilliseconds() + options.minInterval);\n maxDate.setMilliseconds(maxDate.getMilliseconds() + options.maxInterval);\n\n if (options.minInterval > 0 && minDate > enddt) { // minInterval check\n endTime[method]('setDate', minDate);\n }\n else if (options.maxInterval > 0 && maxDate < enddt) { // max interval check\n endTime[method]('setDate', maxDate);\n }\n else if (startdt > enddt) {\n other[method]('setDate', changeddt);\n }\n }\n }\n\n function selected(changed, other, option) {\n if (!changed.val()) {\n return;\n }\n var date = changed[method].call(changed, 'getDate');\n if (date !== null && options.minInterval > 0) {\n if (option === 'minDate') {\n date.setMilliseconds(date.getMilliseconds() + options.minInterval);\n }\n if (option === 'maxDate') {\n date.setMilliseconds(date.getMilliseconds() - options.minInterval);\n }\n }\n\n if (date.getTime) {\n other[method].call(other, 'option', option, date);\n }\n }\n\n $.fn[method].call(startTime, $.extend({\n timeOnly: timeOnly,\n onClose: function (dateText, inst) {\n checkDates($(this), endTime);\n },\n onSelect: function (selectedDateTime) {\n selected($(this), endTime, 'minDate');\n }\n }, options, options.start));\n $.fn[method].call(endTime, $.extend({\n timeOnly: timeOnly,\n onClose: function (dateText, inst) {\n checkDates($(this), startTime);\n },\n onSelect: function (selectedDateTime) {\n selected($(this), startTime, 'maxDate');\n }\n }, options, options.end));\n\n checkDates(startTime, endTime);\n\n selected(startTime, endTime, 'minDate');\n selected(endTime, startTime, 'maxDate');\n\n return $([startTime.get(0), endTime.get(0)]);\n };\n\n /**\n * Log error or data to the console during error or debugging\n * @param {Object} err pass any type object to log to the console during error or debugging\n * @return {void}\n */\n $.timepicker.log = function () {\n // Older IE (9, maybe 10) throw error on accessing `window.console.log.apply`, so check first.\n if (window.console && window.console.log && window.console.log.apply) {\n window.console.log.apply(window.console, Array.prototype.slice.call(arguments));\n }\n };\n\n /*\n * Add util object to allow access to private methods for testability.\n */\n $.timepicker._util = {\n _extendRemove: extendRemove,\n _isEmptyObject: isEmptyObject,\n _convert24to12: convert24to12,\n _detectSupport: detectSupport,\n _selectLocalTimezone: selectLocalTimezone,\n _computeEffectiveSetting: computeEffectiveSetting,\n _splitDateTime: splitDateTime,\n _parseDateTimeInternal: parseDateTimeInternal\n };\n\n /*\n * Microsecond support\n */\n if (!Date.prototype.getMicroseconds) {\n Date.prototype.microseconds = 0;\n Date.prototype.getMicroseconds = function () { return this.microseconds; };\n Date.prototype.setMicroseconds = function (m) {\n this.setMilliseconds(this.getMilliseconds() + Math.floor(m / 1000));\n this.microseconds = m % 1000;\n return this;\n };\n }\n\n /*\n * Keep up with the version\n */\n $.timepicker.version = \"1.6.3\";\n\n}));\n","jquery/jquery-ui-timepicker-addon.js":"/*! jQuery Timepicker Addon - v1.6.3 - 2016-04-20\n* http://trentrichardson.com/examples/timepicker\n* Copyright (c) 2016 Trent Richardson; Licensed MIT */\n(function (factory) {\n if (typeof define === 'function' && define.amd) {\n define(['jquery', 'jquery/ui'], factory);\n } else {\n factory(jQuery);\n }\n}(function ($) {\n\n /*\n * Lets not redefine timepicker, Prevent \"Uncaught RangeError: Maximum call stack size exceeded\"\n */\n $.ui.timepicker = $.ui.timepicker || {};\n if ($.ui.timepicker.version) {\n return;\n }\n\n /*\n * Extend jQueryUI, get it started with our version number\n */\n $.extend($.ui, {\n timepicker: {\n version: \"1.6.3\"\n }\n });\n\n /*\n * Timepicker manager.\n * Use the singleton instance of this class, $.timepicker, to interact with the time picker.\n * Settings for (groups of) time pickers are maintained in an instance object,\n * allowing multiple different settings on the same page.\n */\n var Timepicker = function () {\n this.regional = []; // Available regional settings, indexed by language code\n this.regional[''] = { // Default regional settings\n currentText: 'Now',\n closeText: 'Done',\n amNames: ['AM', 'A'],\n pmNames: ['PM', 'P'],\n timeFormat: 'HH:mm',\n timeSuffix: '',\n timeOnlyTitle: 'Choose Time',\n timeText: 'Time',\n hourText: 'Hour',\n minuteText: 'Minute',\n secondText: 'Second',\n millisecText: 'Millisecond',\n microsecText: 'Microsecond',\n timezoneText: 'Time Zone',\n isRTL: false\n };\n this._defaults = { // Global defaults for all the datetime picker instances\n showButtonPanel: true,\n timeOnly: false,\n timeOnlyShowDate: false,\n showHour: null,\n showMinute: null,\n showSecond: null,\n showMillisec: null,\n showMicrosec: null,\n showTimezone: null,\n showTime: true,\n stepHour: 1,\n stepMinute: 1,\n stepSecond: 1,\n stepMillisec: 1,\n stepMicrosec: 1,\n hour: 0,\n minute: 0,\n second: 0,\n millisec: 0,\n microsec: 0,\n timezone: null,\n hourMin: 0,\n minuteMin: 0,\n secondMin: 0,\n millisecMin: 0,\n microsecMin: 0,\n hourMax: 23,\n minuteMax: 59,\n secondMax: 59,\n millisecMax: 999,\n microsecMax: 999,\n minDateTime: null,\n maxDateTime: null,\n maxTime: null,\n minTime: null,\n onSelect: null,\n hourGrid: 0,\n minuteGrid: 0,\n secondGrid: 0,\n millisecGrid: 0,\n microsecGrid: 0,\n alwaysSetTime: true,\n separator: ' ',\n altFieldTimeOnly: true,\n altTimeFormat: null,\n altSeparator: null,\n altTimeSuffix: null,\n altRedirectFocus: true,\n pickerTimeFormat: null,\n pickerTimeSuffix: null,\n showTimepicker: true,\n timezoneList: null,\n addSliderAccess: false,\n sliderAccessArgs: null,\n controlType: 'slider',\n oneLine: false,\n defaultValue: null,\n parse: 'strict',\n afterInject: null\n };\n $.extend(this._defaults, this.regional['']);\n };\n\n $.extend(Timepicker.prototype, {\n $input: null,\n $altInput: null,\n $timeObj: null,\n inst: null,\n hour_slider: null,\n minute_slider: null,\n second_slider: null,\n millisec_slider: null,\n microsec_slider: null,\n timezone_select: null,\n maxTime: null,\n minTime: null,\n hour: 0,\n minute: 0,\n second: 0,\n millisec: 0,\n microsec: 0,\n timezone: null,\n hourMinOriginal: null,\n minuteMinOriginal: null,\n secondMinOriginal: null,\n millisecMinOriginal: null,\n microsecMinOriginal: null,\n hourMaxOriginal: null,\n minuteMaxOriginal: null,\n secondMaxOriginal: null,\n millisecMaxOriginal: null,\n microsecMaxOriginal: null,\n ampm: '',\n formattedDate: '',\n formattedTime: '',\n formattedDateTime: '',\n timezoneList: null,\n units: ['hour', 'minute', 'second', 'millisec', 'microsec'],\n support: {},\n control: null,\n\n /*\n * Override the default settings for all instances of the time picker.\n * @param {Object} settings object - the new settings to use as defaults (anonymous object)\n * @return {Object} the manager object\n */\n setDefaults: function (settings) {\n extendRemove(this._defaults, settings || {});\n return this;\n },\n\n /*\n * Create a new Timepicker instance\n */\n _newInst: function ($input, opts) {\n var tp_inst = new Timepicker(),\n inlineSettings = {},\n fns = {},\n overrides, i;\n\n for (var attrName in this._defaults) {\n if (this._defaults.hasOwnProperty(attrName)) {\n var attrValue = $input.attr('time:' + attrName);\n if (attrValue) {\n try {\n inlineSettings[attrName] = eval(attrValue);\n } catch (err) {\n inlineSettings[attrName] = attrValue;\n }\n }\n }\n }\n\n overrides = {\n beforeShow: function (input, dp_inst) {\n if ($.isFunction(tp_inst._defaults.evnts.beforeShow)) {\n return tp_inst._defaults.evnts.beforeShow.call($input[0], input, dp_inst, tp_inst);\n }\n },\n onChangeMonthYear: function (year, month, dp_inst) {\n // Update the time as well : this prevents the time from disappearing from the $input field.\n // tp_inst._updateDateTime(dp_inst);\n if ($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)) {\n tp_inst._defaults.evnts.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst);\n }\n },\n onClose: function (dateText, dp_inst) {\n if (tp_inst.timeDefined === true && $input.val() !== '') {\n tp_inst._updateDateTime(dp_inst);\n }\n if ($.isFunction(tp_inst._defaults.evnts.onClose)) {\n tp_inst._defaults.evnts.onClose.call($input[0], dateText, dp_inst, tp_inst);\n }\n }\n };\n for (i in overrides) {\n if (overrides.hasOwnProperty(i)) {\n fns[i] = opts[i] || this._defaults[i] || null;\n }\n }\n\n tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, opts, overrides, {\n evnts: fns,\n timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');\n });\n tp_inst.amNames = $.map(tp_inst._defaults.amNames, function (val) {\n return val.toUpperCase();\n });\n tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function (val) {\n return val.toUpperCase();\n });\n\n // detect which units are supported\n tp_inst.support = detectSupport(\n tp_inst._defaults.timeFormat +\n (tp_inst._defaults.pickerTimeFormat ? tp_inst._defaults.pickerTimeFormat : '') +\n (tp_inst._defaults.altTimeFormat ? tp_inst._defaults.altTimeFormat : ''));\n\n // controlType is string - key to our this._controls\n if (typeof(tp_inst._defaults.controlType) === 'string') {\n if (tp_inst._defaults.controlType === 'slider' && typeof($.ui.slider) === 'undefined') {\n tp_inst._defaults.controlType = 'select';\n }\n tp_inst.control = tp_inst._controls[tp_inst._defaults.controlType];\n }\n // controlType is an object and must implement create, options, value methods\n else {\n tp_inst.control = tp_inst._defaults.controlType;\n }\n\n // prep the timezone options\n var timezoneList = [-720, -660, -600, -570, -540, -480, -420, -360, -300, -270, -240, -210, -180, -120, -60,\n 0, 60, 120, 180, 210, 240, 270, 300, 330, 345, 360, 390, 420, 480, 525, 540, 570, 600, 630, 660, 690, 720, 765, 780, 840];\n if (tp_inst._defaults.timezoneList !== null) {\n timezoneList = tp_inst._defaults.timezoneList;\n }\n var tzl = timezoneList.length, tzi = 0, tzv = null;\n if (tzl > 0 && typeof timezoneList[0] !== 'object') {\n for (; tzi < tzl; tzi++) {\n tzv = timezoneList[tzi];\n timezoneList[tzi] = { value: tzv, label: $.timepicker.timezoneOffsetString(tzv, tp_inst.support.iso8601) };\n }\n }\n tp_inst._defaults.timezoneList = timezoneList;\n\n // set the default units\n tp_inst.timezone = tp_inst._defaults.timezone !== null ? $.timepicker.timezoneOffsetNumber(tp_inst._defaults.timezone) :\n ((new Date()).getTimezoneOffset() * -1);\n tp_inst.hour = tp_inst._defaults.hour < tp_inst._defaults.hourMin ? tp_inst._defaults.hourMin :\n tp_inst._defaults.hour > tp_inst._defaults.hourMax ? tp_inst._defaults.hourMax : tp_inst._defaults.hour;\n tp_inst.minute = tp_inst._defaults.minute < tp_inst._defaults.minuteMin ? tp_inst._defaults.minuteMin :\n tp_inst._defaults.minute > tp_inst._defaults.minuteMax ? tp_inst._defaults.minuteMax : tp_inst._defaults.minute;\n tp_inst.second = tp_inst._defaults.second < tp_inst._defaults.secondMin ? tp_inst._defaults.secondMin :\n tp_inst._defaults.second > tp_inst._defaults.secondMax ? tp_inst._defaults.secondMax : tp_inst._defaults.second;\n tp_inst.millisec = tp_inst._defaults.millisec < tp_inst._defaults.millisecMin ? tp_inst._defaults.millisecMin :\n tp_inst._defaults.millisec > tp_inst._defaults.millisecMax ? tp_inst._defaults.millisecMax : tp_inst._defaults.millisec;\n tp_inst.microsec = tp_inst._defaults.microsec < tp_inst._defaults.microsecMin ? tp_inst._defaults.microsecMin :\n tp_inst._defaults.microsec > tp_inst._defaults.microsecMax ? tp_inst._defaults.microsecMax : tp_inst._defaults.microsec;\n tp_inst.ampm = '';\n tp_inst.$input = $input;\n\n if (tp_inst._defaults.altField) {\n tp_inst.$altInput = $(tp_inst._defaults.altField);\n if (tp_inst._defaults.altRedirectFocus === true) {\n tp_inst.$altInput.css({\n cursor: 'pointer'\n }).focus(function () {\n $input.trigger(\"focus\");\n });\n }\n }\n\n if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) {\n tp_inst._defaults.minDate = new Date();\n }\n if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) {\n tp_inst._defaults.maxDate = new Date();\n }\n\n // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime..\n if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) {\n tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime());\n }\n if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) {\n tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());\n }\n if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) {\n tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime());\n }\n if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) {\n tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());\n }\n tp_inst.$input.bind('focus', function () {\n tp_inst._onFocus();\n });\n\n return tp_inst;\n },\n\n /*\n * add our sliders to the calendar\n */\n _addTimePicker: function (dp_inst) {\n var currDT = $.trim((this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val());\n\n this.timeDefined = this._parseTime(currDT);\n this._limitMinMaxDateTime(dp_inst, false);\n this._injectTimePicker();\n this._afterInject();\n },\n\n /*\n * parse the time string from input value or _setTime\n */\n _parseTime: function (timeString, withDate) {\n if (!this.inst) {\n this.inst = $.datepicker._getInst(this.$input[0]);\n }\n\n if (withDate || !this._defaults.timeOnly) {\n var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');\n try {\n var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults);\n if (!parseRes.timeObj) {\n return false;\n }\n $.extend(this, parseRes.timeObj);\n } catch (err) {\n $.timepicker.log(\"Error parsing the date/time string: \" + err +\n \"\\ndate/time string = \" + timeString +\n \"\\ntimeFormat = \" + this._defaults.timeFormat +\n \"\\ndateFormat = \" + dp_dateFormat);\n return false;\n }\n return true;\n } else {\n var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults);\n if (!timeObj) {\n return false;\n }\n $.extend(this, timeObj);\n return true;\n }\n },\n\n /*\n * Handle callback option after injecting timepicker\n */\n _afterInject: function() {\n var o = this.inst.settings;\n if ($.isFunction(o.afterInject)) {\n o.afterInject.call(this);\n }\n },\n\n /*\n * generate and inject html for timepicker into ui datepicker\n */\n _injectTimePicker: function () {\n var $dp = this.inst.dpDiv,\n o = this.inst.settings,\n tp_inst = this,\n litem = '',\n uitem = '',\n show = null,\n max = {},\n gridSize = {},\n size = null,\n i = 0,\n l = 0;\n\n // Prevent displaying twice\n if ($dp.find(\"div.ui-timepicker-div\").length === 0 && o.showTimepicker) {\n var noDisplay = ' ui_tpicker_unit_hide',\n html = '<div class=\"ui-timepicker-div' + (o.isRTL ? ' ui-timepicker-rtl' : '') + (o.oneLine && o.controlType === 'select' ? ' ui-timepicker-oneLine' : '') + '\"><dl>' + '<dt class=\"ui_tpicker_time_label' + ((o.showTime) ? '' : noDisplay) + '\">' + o.timeText + '</dt>' +\n '<dd class=\"ui_tpicker_time '+ ((o.showTime) ? '' : noDisplay) + '\"><input class=\"ui_tpicker_time_input\" ' + (o.timeInput ? '' : 'disabled') + '/></dd>';\n\n // Create the markup\n for (i = 0, l = this.units.length; i < l; i++) {\n litem = this.units[i];\n uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);\n show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];\n\n // Added by Peter Medeiros:\n // - Figure out what the hour/minute/second max should be based on the step values.\n // - Example: if stepMinute is 15, then minMax is 45.\n max[litem] = parseInt((o[litem + 'Max'] - ((o[litem + 'Max'] - o[litem + 'Min']) % o['step' + uitem])), 10);\n gridSize[litem] = 0;\n\n html += '<dt class=\"ui_tpicker_' + litem + '_label' + (show ? '' : noDisplay) + '\">' + o[litem + 'Text'] + '</dt>' +\n '<dd class=\"ui_tpicker_' + litem + (show ? '' : noDisplay) + '\"><div class=\"ui_tpicker_' + litem + '_slider' + (show ? '' : noDisplay) + '\"></div>';\n\n if (show && o[litem + 'Grid'] > 0) {\n html += '<div style=\"padding-left: 1px\"><table class=\"ui-tpicker-grid-label\"><tr>';\n\n if (litem === 'hour') {\n for (var h = o[litem + 'Min']; h <= max[litem]; h += parseInt(o[litem + 'Grid'], 10)) {\n gridSize[litem]++;\n var tmph = $.datepicker.formatTime(this.support.ampm ? 'hht' : 'HH', {hour: h}, o);\n html += '<td data-for=\"' + litem + '\">' + tmph + '</td>';\n }\n }\n else {\n for (var m = o[litem + 'Min']; m <= max[litem]; m += parseInt(o[litem + 'Grid'], 10)) {\n gridSize[litem]++;\n html += '<td data-for=\"' + litem + '\">' + ((m < 10) ? '0' : '') + m + '</td>';\n }\n }\n\n html += '</tr></table></div>';\n }\n html += '</dd>';\n }\n\n // Timezone\n var showTz = o.showTimezone !== null ? o.showTimezone : this.support.timezone;\n html += '<dt class=\"ui_tpicker_timezone_label' + (showTz ? '' : noDisplay) + '\">' + o.timezoneText + '</dt>';\n html += '<dd class=\"ui_tpicker_timezone' + (showTz ? '' : noDisplay) + '\"></dd>';\n\n // Create the elements from string\n html += '</dl></div>';\n var $tp = $(html);\n\n // if we only want time picker...\n if (o.timeOnly === true) {\n $tp.prepend('<div class=\"ui-widget-header ui-helper-clearfix ui-corner-all\">' + '<div class=\"ui-datepicker-title\">' + o.timeOnlyTitle + '</div>' + '</div>');\n $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide();\n }\n\n // add sliders, adjust grids, add events\n for (i = 0, l = tp_inst.units.length; i < l; i++) {\n litem = tp_inst.units[i];\n uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);\n show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];\n\n // add the slider\n tp_inst[litem + '_slider'] = tp_inst.control.create(tp_inst, $tp.find('.ui_tpicker_' + litem + '_slider'), litem, tp_inst[litem], o[litem + 'Min'], max[litem], o['step' + uitem]);\n\n // adjust the grid and add click event\n if (show && o[litem + 'Grid'] > 0) {\n size = 100 * gridSize[litem] * o[litem + 'Grid'] / (max[litem] - o[litem + 'Min']);\n $tp.find('.ui_tpicker_' + litem + ' table').css({\n width: size + \"%\",\n marginLeft: o.isRTL ? '0' : ((size / (-2 * gridSize[litem])) + \"%\"),\n marginRight: o.isRTL ? ((size / (-2 * gridSize[litem])) + \"%\") : '0',\n borderCollapse: 'collapse'\n }).find(\"td\").click(function (e) {\n var $t = $(this),\n h = $t.html(),\n n = parseInt(h.replace(/[^0-9]/g), 10),\n ap = h.replace(/[^apm]/ig),\n f = $t.data('for'); // loses scope, so we use data-for\n\n if (f === 'hour') {\n if (ap.indexOf('p') !== -1 && n < 12) {\n n += 12;\n }\n else {\n if (ap.indexOf('a') !== -1 && n === 12) {\n n = 0;\n }\n }\n }\n\n tp_inst.control.value(tp_inst, tp_inst[f + '_slider'], litem, n);\n\n tp_inst._onTimeChange();\n tp_inst._onSelectHandler();\n }).css({\n cursor: 'pointer',\n width: (100 / gridSize[litem]) + '%',\n textAlign: 'center',\n overflow: 'hidden'\n });\n } // end if grid > 0\n } // end for loop\n\n // Add timezone options\n this.timezone_select = $tp.find('.ui_tpicker_timezone').append('<select></select>').find(\"select\");\n $.fn.append.apply(this.timezone_select,\n $.map(o.timezoneList, function (val, idx) {\n return $(\"<option />\").val(typeof val === \"object\" ? val.value : val).text(typeof val === \"object\" ? val.label : val);\n }));\n if (typeof(this.timezone) !== \"undefined\" && this.timezone !== null && this.timezone !== \"\") {\n var local_timezone = (new Date(this.inst.selectedYear, this.inst.selectedMonth, this.inst.selectedDay, 12)).getTimezoneOffset() * -1;\n if (local_timezone === this.timezone) {\n selectLocalTimezone(tp_inst);\n } else {\n this.timezone_select.val(this.timezone);\n }\n } else {\n if (typeof(this.hour) !== \"undefined\" && this.hour !== null && this.hour !== \"\") {\n this.timezone_select.val(o.timezone);\n } else {\n selectLocalTimezone(tp_inst);\n }\n }\n this.timezone_select.change(function () {\n tp_inst._onTimeChange();\n tp_inst._onSelectHandler();\n tp_inst._afterInject();\n });\n // End timezone options\n\n // inject timepicker into datepicker\n var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');\n if ($buttonPanel.length) {\n $buttonPanel.before($tp);\n } else {\n $dp.append($tp);\n }\n\n this.$timeObj = $tp.find('.ui_tpicker_time_input');\n this.$timeObj.change(function () {\n var timeFormat = tp_inst.inst.settings.timeFormat;\n var parsedTime = $.datepicker.parseTime(timeFormat, this.value);\n var update = new Date();\n if (parsedTime) {\n update.setHours(parsedTime.hour);\n update.setMinutes(parsedTime.minute);\n update.setSeconds(parsedTime.second);\n $.datepicker._setTime(tp_inst.inst, update);\n } else {\n this.value = tp_inst.formattedTime;\n this.blur();\n }\n });\n\n if (this.inst !== null) {\n var timeDefined = this.timeDefined;\n this._onTimeChange();\n this.timeDefined = timeDefined;\n }\n\n // slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/\n if (this._defaults.addSliderAccess) {\n var sliderAccessArgs = this._defaults.sliderAccessArgs,\n rtl = this._defaults.isRTL;\n sliderAccessArgs.isRTL = rtl;\n\n setTimeout(function () { // fix for inline mode\n if ($tp.find('.ui-slider-access').length === 0) {\n $tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs);\n\n // fix any grids since sliders are shorter\n var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true);\n if (sliderAccessWidth) {\n $tp.find('table:visible').each(function () {\n var $g = $(this),\n oldWidth = $g.outerWidth(),\n oldMarginLeft = $g.css(rtl ? 'marginRight' : 'marginLeft').toString().replace('%', ''),\n newWidth = oldWidth - sliderAccessWidth,\n newMarginLeft = ((oldMarginLeft * newWidth) / oldWidth) + '%',\n css = { width: newWidth, marginRight: 0, marginLeft: 0 };\n css[rtl ? 'marginRight' : 'marginLeft'] = newMarginLeft;\n $g.css(css);\n });\n }\n }\n }, 10);\n }\n // end slideAccess integration\n\n tp_inst._limitMinMaxDateTime(this.inst, true);\n }\n },\n\n /*\n * This function tries to limit the ability to go outside the\n * min/max date range\n */\n _limitMinMaxDateTime: function (dp_inst, adjustSliders) {\n var o = this._defaults,\n dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);\n\n if (!this._defaults.showTimepicker) {\n return;\n } // No time so nothing to check here\n\n if ($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date) {\n var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'),\n minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);\n\n if (this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null || this.microsecMinOriginal === null) {\n this.hourMinOriginal = o.hourMin;\n this.minuteMinOriginal = o.minuteMin;\n this.secondMinOriginal = o.secondMin;\n this.millisecMinOriginal = o.millisecMin;\n this.microsecMinOriginal = o.microsecMin;\n }\n\n if (dp_inst.settings.timeOnly || minDateTimeDate.getTime() === dp_date.getTime()) {\n this._defaults.hourMin = minDateTime.getHours();\n if (this.hour <= this._defaults.hourMin) {\n this.hour = this._defaults.hourMin;\n this._defaults.minuteMin = minDateTime.getMinutes();\n if (this.minute <= this._defaults.minuteMin) {\n this.minute = this._defaults.minuteMin;\n this._defaults.secondMin = minDateTime.getSeconds();\n if (this.second <= this._defaults.secondMin) {\n this.second = this._defaults.secondMin;\n this._defaults.millisecMin = minDateTime.getMilliseconds();\n if (this.millisec <= this._defaults.millisecMin) {\n this.millisec = this._defaults.millisecMin;\n this._defaults.microsecMin = minDateTime.getMicroseconds();\n } else {\n if (this.microsec < this._defaults.microsecMin) {\n this.microsec = this._defaults.microsecMin;\n }\n this._defaults.microsecMin = this.microsecMinOriginal;\n }\n } else {\n this._defaults.millisecMin = this.millisecMinOriginal;\n this._defaults.microsecMin = this.microsecMinOriginal;\n }\n } else {\n this._defaults.secondMin = this.secondMinOriginal;\n this._defaults.millisecMin = this.millisecMinOriginal;\n this._defaults.microsecMin = this.microsecMinOriginal;\n }\n } else {\n this._defaults.minuteMin = this.minuteMinOriginal;\n this._defaults.secondMin = this.secondMinOriginal;\n this._defaults.millisecMin = this.millisecMinOriginal;\n this._defaults.microsecMin = this.microsecMinOriginal;\n }\n } else {\n this._defaults.hourMin = this.hourMinOriginal;\n this._defaults.minuteMin = this.minuteMinOriginal;\n this._defaults.secondMin = this.secondMinOriginal;\n this._defaults.millisecMin = this.millisecMinOriginal;\n this._defaults.microsecMin = this.microsecMinOriginal;\n }\n }\n\n if ($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date) {\n var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'),\n maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);\n\n if (this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null || this.millisecMaxOriginal === null) {\n this.hourMaxOriginal = o.hourMax;\n this.minuteMaxOriginal = o.minuteMax;\n this.secondMaxOriginal = o.secondMax;\n this.millisecMaxOriginal = o.millisecMax;\n this.microsecMaxOriginal = o.microsecMax;\n }\n\n if (dp_inst.settings.timeOnly || maxDateTimeDate.getTime() === dp_date.getTime()) {\n this._defaults.hourMax = maxDateTime.getHours();\n if (this.hour >= this._defaults.hourMax) {\n this.hour = this._defaults.hourMax;\n this._defaults.minuteMax = maxDateTime.getMinutes();\n if (this.minute >= this._defaults.minuteMax) {\n this.minute = this._defaults.minuteMax;\n this._defaults.secondMax = maxDateTime.getSeconds();\n if (this.second >= this._defaults.secondMax) {\n this.second = this._defaults.secondMax;\n this._defaults.millisecMax = maxDateTime.getMilliseconds();\n if (this.millisec >= this._defaults.millisecMax) {\n this.millisec = this._defaults.millisecMax;\n this._defaults.microsecMax = maxDateTime.getMicroseconds();\n } else {\n if (this.microsec > this._defaults.microsecMax) {\n this.microsec = this._defaults.microsecMax;\n }\n this._defaults.microsecMax = this.microsecMaxOriginal;\n }\n } else {\n this._defaults.millisecMax = this.millisecMaxOriginal;\n this._defaults.microsecMax = this.microsecMaxOriginal;\n }\n } else {\n this._defaults.secondMax = this.secondMaxOriginal;\n this._defaults.millisecMax = this.millisecMaxOriginal;\n this._defaults.microsecMax = this.microsecMaxOriginal;\n }\n } else {\n this._defaults.minuteMax = this.minuteMaxOriginal;\n this._defaults.secondMax = this.secondMaxOriginal;\n this._defaults.millisecMax = this.millisecMaxOriginal;\n this._defaults.microsecMax = this.microsecMaxOriginal;\n }\n } else {\n this._defaults.hourMax = this.hourMaxOriginal;\n this._defaults.minuteMax = this.minuteMaxOriginal;\n this._defaults.secondMax = this.secondMaxOriginal;\n this._defaults.millisecMax = this.millisecMaxOriginal;\n this._defaults.microsecMax = this.microsecMaxOriginal;\n }\n }\n\n if (dp_inst.settings.minTime!==null) {\n var tempMinTime=new Date(\"01/01/1970 \" + dp_inst.settings.minTime);\n if (this.hour<tempMinTime.getHours()) {\n this.hour=this._defaults.hourMin=tempMinTime.getHours();\n this.minute=this._defaults.minuteMin=tempMinTime.getMinutes();\n } else if (this.hour===tempMinTime.getHours() && this.minute<tempMinTime.getMinutes()) {\n this.minute=this._defaults.minuteMin=tempMinTime.getMinutes();\n } else {\n if (this._defaults.hourMin<tempMinTime.getHours()) {\n this._defaults.hourMin=tempMinTime.getHours();\n this._defaults.minuteMin=tempMinTime.getMinutes();\n } else if (this._defaults.hourMin===tempMinTime.getHours()===this.hour && this._defaults.minuteMin<tempMinTime.getMinutes()) {\n this._defaults.minuteMin=tempMinTime.getMinutes();\n } else {\n this._defaults.minuteMin=0;\n }\n }\n }\n\n if (dp_inst.settings.maxTime!==null) {\n var tempMaxTime=new Date(\"01/01/1970 \" + dp_inst.settings.maxTime);\n if (this.hour>tempMaxTime.getHours()) {\n this.hour=this._defaults.hourMax=tempMaxTime.getHours();\n this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes();\n } else if (this.hour===tempMaxTime.getHours() && this.minute>tempMaxTime.getMinutes()) {\n this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes();\n } else {\n if (this._defaults.hourMax>tempMaxTime.getHours()) {\n this._defaults.hourMax=tempMaxTime.getHours();\n this._defaults.minuteMax=tempMaxTime.getMinutes();\n } else if (this._defaults.hourMax===tempMaxTime.getHours()===this.hour && this._defaults.minuteMax>tempMaxTime.getMinutes()) {\n this._defaults.minuteMax=tempMaxTime.getMinutes();\n } else {\n this._defaults.minuteMax=59;\n }\n }\n }\n\n if (adjustSliders !== undefined && adjustSliders === true) {\n var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)), 10),\n minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)), 10),\n secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)), 10),\n millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)), 10),\n microsecMax = parseInt((this._defaults.microsecMax - ((this._defaults.microsecMax - this._defaults.microsecMin) % this._defaults.stepMicrosec)), 10);\n\n if (this.hour_slider) {\n this.control.options(this, this.hour_slider, 'hour', { min: this._defaults.hourMin, max: hourMax, step: this._defaults.stepHour });\n this.control.value(this, this.hour_slider, 'hour', this.hour - (this.hour % this._defaults.stepHour));\n }\n if (this.minute_slider) {\n this.control.options(this, this.minute_slider, 'minute', { min: this._defaults.minuteMin, max: minMax, step: this._defaults.stepMinute });\n this.control.value(this, this.minute_slider, 'minute', this.minute - (this.minute % this._defaults.stepMinute));\n }\n if (this.second_slider) {\n this.control.options(this, this.second_slider, 'second', { min: this._defaults.secondMin, max: secMax, step: this._defaults.stepSecond });\n this.control.value(this, this.second_slider, 'second', this.second - (this.second % this._defaults.stepSecond));\n }\n if (this.millisec_slider) {\n this.control.options(this, this.millisec_slider, 'millisec', { min: this._defaults.millisecMin, max: millisecMax, step: this._defaults.stepMillisec });\n this.control.value(this, this.millisec_slider, 'millisec', this.millisec - (this.millisec % this._defaults.stepMillisec));\n }\n if (this.microsec_slider) {\n this.control.options(this, this.microsec_slider, 'microsec', { min: this._defaults.microsecMin, max: microsecMax, step: this._defaults.stepMicrosec });\n this.control.value(this, this.microsec_slider, 'microsec', this.microsec - (this.microsec % this._defaults.stepMicrosec));\n }\n }\n\n },\n\n /*\n * when a slider moves, set the internal time...\n * on time change is also called when the time is updated in the text field\n */\n _onTimeChange: function () {\n if (!this._defaults.showTimepicker) {\n return;\n }\n var hour = (this.hour_slider) ? this.control.value(this, this.hour_slider, 'hour') : false,\n minute = (this.minute_slider) ? this.control.value(this, this.minute_slider, 'minute') : false,\n second = (this.second_slider) ? this.control.value(this, this.second_slider, 'second') : false,\n millisec = (this.millisec_slider) ? this.control.value(this, this.millisec_slider, 'millisec') : false,\n microsec = (this.microsec_slider) ? this.control.value(this, this.microsec_slider, 'microsec') : false,\n timezone = (this.timezone_select) ? this.timezone_select.val() : false,\n o = this._defaults,\n pickerTimeFormat = o.pickerTimeFormat || o.timeFormat,\n pickerTimeSuffix = o.pickerTimeSuffix || o.timeSuffix;\n\n if (typeof(hour) === 'object') {\n hour = false;\n }\n if (typeof(minute) === 'object') {\n minute = false;\n }\n if (typeof(second) === 'object') {\n second = false;\n }\n if (typeof(millisec) === 'object') {\n millisec = false;\n }\n if (typeof(microsec) === 'object') {\n microsec = false;\n }\n if (typeof(timezone) === 'object') {\n timezone = false;\n }\n\n if (hour !== false) {\n hour = parseInt(hour, 10);\n }\n if (minute !== false) {\n minute = parseInt(minute, 10);\n }\n if (second !== false) {\n second = parseInt(second, 10);\n }\n if (millisec !== false) {\n millisec = parseInt(millisec, 10);\n }\n if (microsec !== false) {\n microsec = parseInt(microsec, 10);\n }\n if (timezone !== false) {\n timezone = timezone.toString();\n }\n\n var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0];\n\n // If the update was done in the input field, the input field should not be updated.\n // If the update was done using the sliders, update the input field.\n var hasChanged = (\n hour !== parseInt(this.hour,10) || // sliders should all be numeric\n minute !== parseInt(this.minute,10) ||\n second !== parseInt(this.second,10) ||\n millisec !== parseInt(this.millisec,10) ||\n microsec !== parseInt(this.microsec,10) ||\n (this.ampm.length > 0 && (hour < 12) !== ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1)) ||\n (this.timezone !== null && timezone !== this.timezone.toString()) // could be numeric or \"EST\" format, so use toString()\n );\n\n if (hasChanged) {\n\n if (hour !== false) {\n this.hour = hour;\n }\n if (minute !== false) {\n this.minute = minute;\n }\n if (second !== false) {\n this.second = second;\n }\n if (millisec !== false) {\n this.millisec = millisec;\n }\n if (microsec !== false) {\n this.microsec = microsec;\n }\n if (timezone !== false) {\n this.timezone = timezone;\n }\n\n if (!this.inst) {\n this.inst = $.datepicker._getInst(this.$input[0]);\n }\n\n this._limitMinMaxDateTime(this.inst, true);\n }\n if (this.support.ampm) {\n this.ampm = ampm;\n }\n\n // Updates the time within the timepicker\n this.formattedTime = $.datepicker.formatTime(o.timeFormat, this, o);\n if (this.$timeObj) {\n if (pickerTimeFormat === o.timeFormat) {\n this.$timeObj.val(this.formattedTime + pickerTimeSuffix);\n }\n else {\n this.$timeObj.val($.datepicker.formatTime(pickerTimeFormat, this, o) + pickerTimeSuffix);\n }\n if (this.$timeObj[0].setSelectionRange) {\n var sPos = this.$timeObj[0].selectionStart;\n var ePos = this.$timeObj[0].selectionEnd;\n this.$timeObj[0].setSelectionRange(sPos, ePos);\n }\n }\n\n this.timeDefined = true;\n if (hasChanged) {\n this._updateDateTime();\n //this.$input.focus(); // may automatically open the picker on setDate\n }\n },\n\n /*\n * call custom onSelect.\n * bind to sliders slidestop, and grid click.\n */\n _onSelectHandler: function () {\n var onSelect = this._defaults.onSelect || this.inst.settings.onSelect;\n var inputEl = this.$input ? this.$input[0] : null;\n if (onSelect && inputEl) {\n onSelect.apply(inputEl, [this.formattedDateTime, this]);\n }\n },\n\n /*\n * update our input with the new date time..\n */\n _updateDateTime: function (dp_inst) {\n dp_inst = this.inst || dp_inst;\n var dtTmp = (dp_inst.currentYear > 0?\n new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay) :\n new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),\n dt = $.datepicker._daylightSavingAdjust(dtTmp),\n //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),\n //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay)),\n dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),\n formatCfg = $.datepicker._getFormatConfig(dp_inst),\n timeAvailable = dt !== null && this.timeDefined;\n this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);\n var formattedDateTime = this.formattedDate;\n\n // if a slider was changed but datepicker doesn't have a value yet, set it\n if (dp_inst.lastVal === \"\") {\n dp_inst.currentYear = dp_inst.selectedYear;\n dp_inst.currentMonth = dp_inst.selectedMonth;\n dp_inst.currentDay = dp_inst.selectedDay;\n }\n\n /*\n * remove following lines to force every changes in date picker to change the input value\n * Bug descriptions: when an input field has a default value, and click on the field to pop up the date picker.\n * If the user manually empty the value in the input field, the date picker will never change selected value.\n */\n //if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) {\n //\treturn;\n //}\n\n if (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === false) {\n formattedDateTime = this.formattedTime;\n } else if ((this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) || (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === true)) {\n formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix;\n }\n\n this.formattedDateTime = formattedDateTime;\n\n if (!this._defaults.showTimepicker) {\n this.$input.val(this.formattedDate);\n } else if (this.$altInput && this._defaults.timeOnly === false && this._defaults.altFieldTimeOnly === true) {\n this.$altInput.val(this.formattedTime);\n this.$input.val(this.formattedDate);\n } else if (this.$altInput) {\n this.$input.val(formattedDateTime);\n var altFormattedDateTime = '',\n altSeparator = this._defaults.altSeparator !== null ? this._defaults.altSeparator : this._defaults.separator,\n altTimeSuffix = this._defaults.altTimeSuffix !== null ? this._defaults.altTimeSuffix : this._defaults.timeSuffix;\n\n if (!this._defaults.timeOnly) {\n if (this._defaults.altFormat) {\n altFormattedDateTime = $.datepicker.formatDate(this._defaults.altFormat, (dt === null ? new Date() : dt), formatCfg);\n }\n else {\n altFormattedDateTime = this.formattedDate;\n }\n\n if (altFormattedDateTime) {\n altFormattedDateTime += altSeparator;\n }\n }\n\n if (this._defaults.altTimeFormat !== null) {\n altFormattedDateTime += $.datepicker.formatTime(this._defaults.altTimeFormat, this, this._defaults) + altTimeSuffix;\n }\n else {\n altFormattedDateTime += this.formattedTime + altTimeSuffix;\n }\n this.$altInput.val(altFormattedDateTime);\n } else {\n this.$input.val(formattedDateTime);\n }\n\n this.$input.trigger(\"change\");\n },\n\n _onFocus: function () {\n if (!this.$input.val() && this._defaults.defaultValue) {\n this.$input.val(this._defaults.defaultValue);\n var inst = $.datepicker._getInst(this.$input.get(0)),\n tp_inst = $.datepicker._get(inst, 'timepicker');\n if (tp_inst) {\n if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {\n try {\n $.datepicker._updateDatepicker(inst);\n } catch (err) {\n $.timepicker.log(err);\n }\n }\n }\n }\n },\n\n /*\n * Small abstraction to control types\n * We can add more, just be sure to follow the pattern: create, options, value\n */\n _controls: {\n // slider methods\n slider: {\n create: function (tp_inst, obj, unit, val, min, max, step) {\n var rtl = tp_inst._defaults.isRTL; // if rtl go -60->0 instead of 0->60\n return obj.prop('slide', null).slider({\n orientation: \"horizontal\",\n value: rtl ? val * -1 : val,\n min: rtl ? max * -1 : min,\n max: rtl ? min * -1 : max,\n step: step,\n slide: function (event, ui) {\n tp_inst.control.value(tp_inst, $(this), unit, rtl ? ui.value * -1 : ui.value);\n tp_inst._onTimeChange();\n },\n stop: function (event, ui) {\n tp_inst._onSelectHandler();\n }\n });\n },\n options: function (tp_inst, obj, unit, opts, val) {\n if (tp_inst._defaults.isRTL) {\n if (typeof(opts) === 'string') {\n if (opts === 'min' || opts === 'max') {\n if (val !== undefined) {\n return obj.slider(opts, val * -1);\n }\n return Math.abs(obj.slider(opts));\n }\n return obj.slider(opts);\n }\n var min = opts.min,\n max = opts.max;\n opts.min = opts.max = null;\n if (min !== undefined) {\n opts.max = min * -1;\n }\n if (max !== undefined) {\n opts.min = max * -1;\n }\n return obj.slider(opts);\n }\n if (typeof(opts) === 'string' && val !== undefined) {\n return obj.slider(opts, val);\n }\n return obj.slider(opts);\n },\n value: function (tp_inst, obj, unit, val) {\n if (tp_inst._defaults.isRTL) {\n if (val !== undefined) {\n return obj.slider('value', val * -1);\n }\n return Math.abs(obj.slider('value'));\n }\n if (val !== undefined) {\n return obj.slider('value', val);\n }\n return obj.slider('value');\n }\n },\n // select methods\n select: {\n create: function (tp_inst, obj, unit, val, min, max, step) {\n var sel = '<select class=\"ui-timepicker-select ui-state-default ui-corner-all\" data-unit=\"' + unit + '\" data-min=\"' + min + '\" data-max=\"' + max + '\" data-step=\"' + step + '\">',\n format = tp_inst._defaults.pickerTimeFormat || tp_inst._defaults.timeFormat;\n\n for (var i = min; i <= max; i += step) {\n sel += '<option value=\"' + i + '\"' + (i === val ? ' selected' : '') + '>';\n if (unit === 'hour') {\n sel += $.datepicker.formatTime($.trim(format.replace(/[^ht ]/ig, '')), {hour: i}, tp_inst._defaults);\n }\n else if (unit === 'millisec' || unit === 'microsec' || i >= 10) { sel += i; }\n else {sel += '0' + i.toString(); }\n sel += '</option>';\n }\n sel += '</select>';\n\n obj.children('select').remove();\n\n $(sel).appendTo(obj).change(function (e) {\n tp_inst._onTimeChange();\n tp_inst._onSelectHandler();\n tp_inst._afterInject();\n });\n\n return obj;\n },\n options: function (tp_inst, obj, unit, opts, val) {\n var o = {},\n $t = obj.children('select');\n if (typeof(opts) === 'string') {\n if (val === undefined) {\n return $t.data(opts);\n }\n o[opts] = val;\n }\n else { o = opts; }\n return tp_inst.control.create(tp_inst, obj, $t.data('unit'), $t.val(), o.min>=0 ? o.min : $t.data('min'), o.max || $t.data('max'), o.step || $t.data('step'));\n },\n value: function (tp_inst, obj, unit, val) {\n var $t = obj.children('select');\n if (val !== undefined) {\n return $t.val(val);\n }\n return $t.val();\n }\n }\n } // end _controls\n\n });\n\n $.fn.extend({\n /*\n * shorthand just to use timepicker.\n */\n timepicker: function (o) {\n o = o || {};\n var tmp_args = Array.prototype.slice.call(arguments);\n\n if (typeof o === 'object') {\n tmp_args[0] = $.extend(o, {\n timeOnly: true\n });\n }\n\n return $(this).each(function () {\n $.fn.datetimepicker.apply($(this), tmp_args);\n });\n },\n\n /*\n * extend timepicker to datepicker\n */\n datetimepicker: function (o) {\n o = o || {};\n var tmp_args = arguments;\n\n if (typeof(o) === 'string') {\n if (o === 'getDate' || (o === 'option' && tmp_args.length === 2 && typeof (tmp_args[1]) === 'string')) {\n return $.fn.datepicker.apply($(this[0]), tmp_args);\n } else {\n return this.each(function () {\n var $t = $(this);\n $t.datepicker.apply($t, tmp_args);\n });\n }\n } else {\n return this.each(function () {\n var $t = $(this);\n $t.datepicker($.timepicker._newInst($t, o)._defaults);\n });\n }\n }\n });\n\n /*\n * Public Utility to parse date and time\n */\n $.datepicker.parseDateTime = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {\n var parseRes = parseDateTimeInternal(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings);\n if (parseRes.timeObj) {\n var t = parseRes.timeObj;\n parseRes.date.setHours(t.hour, t.minute, t.second, t.millisec);\n parseRes.date.setMicroseconds(t.microsec);\n }\n\n return parseRes.date;\n };\n\n /*\n * Public utility to parse time\n */\n $.datepicker.parseTime = function (timeFormat, timeString, options) {\n var o = extendRemove(extendRemove({}, $.timepicker._defaults), options || {}),\n iso8601 = (timeFormat.replace(/\\'.*?\\'/g, '').indexOf('Z') !== -1);\n\n // Strict parse requires the timeString to match the timeFormat exactly\n var strictParse = function (f, s, o) {\n\n // pattern for standard and localized AM/PM markers\n var getPatternAmpm = function (amNames, pmNames) {\n var markers = [];\n if (amNames) {\n $.merge(markers, amNames);\n }\n if (pmNames) {\n $.merge(markers, pmNames);\n }\n markers = $.map(markers, function (val) {\n return val.replace(/[.*+?|()\\[\\]{}\\\\]/g, '\\\\$&');\n });\n return '(' + markers.join('|') + ')?';\n };\n\n // figure out position of time elements.. cause js cant do named captures\n var getFormatPositions = function (timeFormat) {\n var finds = timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|c{1}|t{1,2}|z|'.*?')/g),\n orders = {\n h: -1,\n m: -1,\n s: -1,\n l: -1,\n c: -1,\n t: -1,\n z: -1\n };\n\n if (finds) {\n for (var i = 0; i < finds.length; i++) {\n if (orders[finds[i].toString().charAt(0)] === -1) {\n orders[finds[i].toString().charAt(0)] = i + 1;\n }\n }\n }\n return orders;\n };\n\n var regstr = '^' + f.toString()\n .replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {\n var ml = match.length;\n switch (match.charAt(0).toLowerCase()) {\n case 'h':\n return ml === 1 ? '(\\\\d?\\\\d)' : '(\\\\d{' + ml + '})';\n case 'm':\n return ml === 1 ? '(\\\\d?\\\\d)' : '(\\\\d{' + ml + '})';\n case 's':\n return ml === 1 ? '(\\\\d?\\\\d)' : '(\\\\d{' + ml + '})';\n case 'l':\n return '(\\\\d?\\\\d?\\\\d)';\n case 'c':\n return '(\\\\d?\\\\d?\\\\d)';\n case 'z':\n return '(z|[-+]\\\\d\\\\d:?\\\\d\\\\d|\\\\S+)?';\n case 't':\n return getPatternAmpm(o.amNames, o.pmNames);\n default: // literal escaped in quotes\n return '(' + match.replace(/\\'/g, \"\").replace(/(\\.|\\$|\\^|\\\\|\\/|\\(|\\)|\\[|\\]|\\?|\\+|\\*)/g, function (m) { return \"\\\\\" + m; }) + ')?';\n }\n })\n .replace(/\\s/g, '\\\\s?') +\n o.timeSuffix + '$',\n order = getFormatPositions(f),\n ampm = '',\n treg;\n\n treg = s.match(new RegExp(regstr, 'i'));\n\n var resTime = {\n hour: 0,\n minute: 0,\n second: 0,\n millisec: 0,\n microsec: 0\n };\n\n if (treg) {\n if (order.t !== -1) {\n if (treg[order.t] === undefined || treg[order.t].length === 0) {\n ampm = '';\n resTime.ampm = '';\n } else {\n ampm = $.inArray(treg[order.t].toUpperCase(), $.map(o.amNames, function (x,i) { return x.toUpperCase(); })) !== -1 ? 'AM' : 'PM';\n resTime.ampm = o[ampm === 'AM' ? 'amNames' : 'pmNames'][0];\n }\n }\n\n if (order.h !== -1) {\n if (ampm === 'AM' && treg[order.h] === '12') {\n resTime.hour = 0; // 12am = 0 hour\n } else {\n if (ampm === 'PM' && treg[order.h] !== '12') {\n resTime.hour = parseInt(treg[order.h], 10) + 12; // 12pm = 12 hour, any other pm = hour + 12\n } else {\n resTime.hour = Number(treg[order.h]);\n }\n }\n }\n\n if (order.m !== -1) {\n resTime.minute = Number(treg[order.m]);\n }\n if (order.s !== -1) {\n resTime.second = Number(treg[order.s]);\n }\n if (order.l !== -1) {\n resTime.millisec = Number(treg[order.l]);\n }\n if (order.c !== -1) {\n resTime.microsec = Number(treg[order.c]);\n }\n if (order.z !== -1 && treg[order.z] !== undefined) {\n resTime.timezone = $.timepicker.timezoneOffsetNumber(treg[order.z]);\n }\n\n\n return resTime;\n }\n return false;\n };// end strictParse\n\n // First try JS Date, if that fails, use strictParse\n var looseParse = function (f, s, o) {\n try {\n var d = new Date('2012-01-01 ' + s);\n if (isNaN(d.getTime())) {\n d = new Date('2012-01-01T' + s);\n if (isNaN(d.getTime())) {\n d = new Date('01/01/2012 ' + s);\n if (isNaN(d.getTime())) {\n throw \"Unable to parse time with native Date: \" + s;\n }\n }\n }\n\n return {\n hour: d.getHours(),\n minute: d.getMinutes(),\n second: d.getSeconds(),\n millisec: d.getMilliseconds(),\n microsec: d.getMicroseconds(),\n timezone: d.getTimezoneOffset() * -1\n };\n }\n catch (err) {\n try {\n return strictParse(f, s, o);\n }\n catch (err2) {\n $.timepicker.log(\"Unable to parse \\ntimeString: \" + s + \"\\ntimeFormat: \" + f);\n }\n }\n return false;\n }; // end looseParse\n\n if (typeof o.parse === \"function\") {\n return o.parse(timeFormat, timeString, o);\n }\n if (o.parse === 'loose') {\n return looseParse(timeFormat, timeString, o);\n }\n return strictParse(timeFormat, timeString, o);\n };\n\n /**\n * Public utility to format the time\n * @param {string} format format of the time\n * @param {Object} time Object not a Date for timezones\n * @param {Object} [options] essentially the regional[].. amNames, pmNames, ampm\n * @returns {string} the formatted time\n */\n $.datepicker.formatTime = function (format, time, options) {\n options = options || {};\n options = $.extend({}, $.timepicker._defaults, options);\n time = $.extend({\n hour: 0,\n minute: 0,\n second: 0,\n millisec: 0,\n microsec: 0,\n timezone: null\n }, time);\n\n var tmptime = format,\n ampmName = options.amNames[0],\n hour = parseInt(time.hour, 10);\n\n if (hour > 11) {\n ampmName = options.pmNames[0];\n }\n\n tmptime = tmptime.replace(/(?:HH?|hh?|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {\n switch (match) {\n case 'HH':\n return ('0' + hour).slice(-2);\n case 'H':\n return hour;\n case 'hh':\n return ('0' + convert24to12(hour)).slice(-2);\n case 'h':\n return convert24to12(hour);\n case 'mm':\n return ('0' + time.minute).slice(-2);\n case 'm':\n return time.minute;\n case 'ss':\n return ('0' + time.second).slice(-2);\n case 's':\n return time.second;\n case 'l':\n return ('00' + time.millisec).slice(-3);\n case 'c':\n return ('00' + time.microsec).slice(-3);\n case 'z':\n return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, false);\n case 'Z':\n return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, true);\n case 'T':\n return ampmName.charAt(0).toUpperCase();\n case 'TT':\n return ampmName.toUpperCase();\n case 't':\n return ampmName.charAt(0).toLowerCase();\n case 'tt':\n return ampmName.toLowerCase();\n default:\n return match.replace(/'/g, \"\");\n }\n });\n\n return tmptime;\n };\n\n /*\n * the bad hack :/ override datepicker so it doesn't close on select\n // inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378\n */\n $.datepicker._base_selectDate = $.datepicker._selectDate;\n $.datepicker._selectDate = function (id, dateStr) {\n var inst = this._getInst($(id)[0]),\n tp_inst = this._get(inst, 'timepicker'),\n was_inline;\n\n if (tp_inst && inst.settings.showTimepicker) {\n tp_inst._limitMinMaxDateTime(inst, true);\n was_inline = inst.inline;\n inst.inline = inst.stay_open = true;\n //This way the onSelect handler called from calendarpicker get the full dateTime\n this._base_selectDate(id, dateStr);\n inst.inline = was_inline;\n inst.stay_open = false;\n this._notifyChange(inst);\n this._updateDatepicker(inst);\n } else {\n this._base_selectDate(id, dateStr);\n }\n };\n\n /*\n * second bad hack :/ override datepicker so it triggers an event when changing the input field\n * and does not redraw the datepicker on every selectDate event\n */\n $.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;\n $.datepicker._updateDatepicker = function (inst) {\n\n // don't popup the datepicker if there is another instance already opened\n var input = inst.input[0];\n if ($.datepicker._curInst && $.datepicker._curInst !== inst && $.datepicker._datepickerShowing && $.datepicker._lastInput !== input) {\n return;\n }\n\n if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {\n\n this._base_updateDatepicker(inst);\n\n // Reload the time control when changing something in the input text field.\n var tp_inst = this._get(inst, 'timepicker');\n if (tp_inst) {\n tp_inst._addTimePicker(inst);\n }\n }\n };\n\n /*\n * third bad hack :/ override datepicker so it allows spaces and colon in the input field\n */\n $.datepicker._base_doKeyPress = $.datepicker._doKeyPress;\n $.datepicker._doKeyPress = function (event) {\n var inst = $.datepicker._getInst(event.target),\n tp_inst = $.datepicker._get(inst, 'timepicker');\n\n if (tp_inst) {\n if ($.datepicker._get(inst, 'constrainInput')) {\n var ampm = tp_inst.support.ampm,\n tz = tp_inst._defaults.showTimezone !== null ? tp_inst._defaults.showTimezone : tp_inst.support.timezone,\n dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),\n datetimeChars = tp_inst._defaults.timeFormat.toString()\n .replace(/[hms]/g, '')\n .replace(/TT/g, ampm ? 'APM' : '')\n .replace(/Tt/g, ampm ? 'AaPpMm' : '')\n .replace(/tT/g, ampm ? 'AaPpMm' : '')\n .replace(/T/g, ampm ? 'AP' : '')\n .replace(/tt/g, ampm ? 'apm' : '')\n .replace(/t/g, ampm ? 'ap' : '') +\n \" \" + tp_inst._defaults.separator +\n tp_inst._defaults.timeSuffix +\n (tz ? tp_inst._defaults.timezoneList.join('') : '') +\n (tp_inst._defaults.amNames.join('')) + (tp_inst._defaults.pmNames.join('')) +\n dateChars,\n chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);\n return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1);\n }\n }\n\n return $.datepicker._base_doKeyPress(event);\n };\n\n /*\n * Fourth bad hack :/ override _updateAlternate function used in inline mode to init altField\n * Update any alternate field to synchronise with the main field.\n */\n $.datepicker._base_updateAlternate = $.datepicker._updateAlternate;\n $.datepicker._updateAlternate = function (inst) {\n var tp_inst = this._get(inst, 'timepicker');\n if (tp_inst) {\n var altField = tp_inst._defaults.altField;\n if (altField) { // update alternate field too\n var altFormat = tp_inst._defaults.altFormat || tp_inst._defaults.dateFormat,\n date = this._getDate(inst),\n formatCfg = $.datepicker._getFormatConfig(inst),\n altFormattedDateTime = '',\n altSeparator = tp_inst._defaults.altSeparator ? tp_inst._defaults.altSeparator : tp_inst._defaults.separator,\n altTimeSuffix = tp_inst._defaults.altTimeSuffix ? tp_inst._defaults.altTimeSuffix : tp_inst._defaults.timeSuffix,\n altTimeFormat = tp_inst._defaults.altTimeFormat !== null ? tp_inst._defaults.altTimeFormat : tp_inst._defaults.timeFormat;\n\n altFormattedDateTime += $.datepicker.formatTime(altTimeFormat, tp_inst, tp_inst._defaults) + altTimeSuffix;\n if (!tp_inst._defaults.timeOnly && !tp_inst._defaults.altFieldTimeOnly && date !== null) {\n if (tp_inst._defaults.altFormat) {\n altFormattedDateTime = $.datepicker.formatDate(tp_inst._defaults.altFormat, date, formatCfg) + altSeparator + altFormattedDateTime;\n }\n else {\n altFormattedDateTime = tp_inst.formattedDate + altSeparator + altFormattedDateTime;\n }\n }\n $(altField).val( inst.input.val() ? altFormattedDateTime : \"\");\n }\n }\n else {\n $.datepicker._base_updateAlternate(inst);\n }\n };\n\n /*\n * Override key up event to sync manual input changes.\n */\n $.datepicker._base_doKeyUp = $.datepicker._doKeyUp;\n $.datepicker._doKeyUp = function (event) {\n var inst = $.datepicker._getInst(event.target),\n tp_inst = $.datepicker._get(inst, 'timepicker');\n\n if (tp_inst) {\n if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {\n try {\n $.datepicker._updateDatepicker(inst);\n } catch (err) {\n $.timepicker.log(err);\n }\n }\n }\n\n return $.datepicker._base_doKeyUp(event);\n };\n\n /*\n * override \"Today\" button to also grab the time and set it to input field.\n */\n $.datepicker._base_gotoToday = $.datepicker._gotoToday;\n $.datepicker._gotoToday = function (id) {\n var inst = this._getInst($(id)[0]);\n this._base_gotoToday(id);\n var tp_inst = this._get(inst, 'timepicker');\n if (!tp_inst) {\n return;\n }\n\n var tzoffset = $.timepicker.timezoneOffsetNumber(tp_inst.timezone);\n var now = new Date();\n now.setMinutes(now.getMinutes() + now.getTimezoneOffset() + parseInt(tzoffset, 10));\n this._setTime(inst, now);\n this._setDate(inst, now);\n tp_inst._onSelectHandler();\n };\n\n /*\n * Disable & enable the Time in the datetimepicker\n */\n $.datepicker._disableTimepickerDatepicker = function (target) {\n var inst = this._getInst(target);\n if (!inst) {\n return;\n }\n\n var tp_inst = this._get(inst, 'timepicker');\n $(target).datepicker('getDate'); // Init selected[Year|Month|Day]\n if (tp_inst) {\n inst.settings.showTimepicker = false;\n tp_inst._defaults.showTimepicker = false;\n tp_inst._updateDateTime(inst);\n }\n };\n\n $.datepicker._enableTimepickerDatepicker = function (target) {\n var inst = this._getInst(target);\n if (!inst) {\n return;\n }\n\n var tp_inst = this._get(inst, 'timepicker');\n $(target).datepicker('getDate'); // Init selected[Year|Month|Day]\n if (tp_inst) {\n inst.settings.showTimepicker = true;\n tp_inst._defaults.showTimepicker = true;\n tp_inst._addTimePicker(inst); // Could be disabled on page load\n tp_inst._updateDateTime(inst);\n }\n };\n\n /*\n * Create our own set time function\n */\n $.datepicker._setTime = function (inst, date) {\n var tp_inst = this._get(inst, 'timepicker');\n if (tp_inst) {\n var defaults = tp_inst._defaults;\n\n // calling _setTime with no date sets time to defaults\n tp_inst.hour = date ? date.getHours() : defaults.hour;\n tp_inst.minute = date ? date.getMinutes() : defaults.minute;\n tp_inst.second = date ? date.getSeconds() : defaults.second;\n tp_inst.millisec = date ? date.getMilliseconds() : defaults.millisec;\n tp_inst.microsec = date ? date.getMicroseconds() : defaults.microsec;\n\n //check if within min/max times..\n tp_inst._limitMinMaxDateTime(inst, true);\n\n tp_inst._onTimeChange();\n tp_inst._updateDateTime(inst);\n }\n };\n\n /*\n * Create new public method to set only time, callable as $().datepicker('setTime', date)\n */\n $.datepicker._setTimeDatepicker = function (target, date, withDate) {\n var inst = this._getInst(target);\n if (!inst) {\n return;\n }\n\n var tp_inst = this._get(inst, 'timepicker');\n\n if (tp_inst) {\n this._setDateFromField(inst);\n var tp_date;\n if (date) {\n if (typeof date === \"string\") {\n tp_inst._parseTime(date, withDate);\n tp_date = new Date();\n tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);\n tp_date.setMicroseconds(tp_inst.microsec);\n } else {\n tp_date = new Date(date.getTime());\n tp_date.setMicroseconds(date.getMicroseconds());\n }\n if (tp_date.toString() === 'Invalid Date') {\n tp_date = undefined;\n }\n this._setTime(inst, tp_date);\n }\n }\n\n };\n\n /*\n * override setDate() to allow setting time too within Date object\n */\n $.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;\n $.datepicker._setDateDatepicker = function (target, _date) {\n var inst = this._getInst(target);\n var date = _date;\n if (!inst) {\n return;\n }\n\n if (typeof(_date) === 'string') {\n date = new Date(_date);\n if (!date.getTime()) {\n this._base_setDateDatepicker.apply(this, arguments);\n date = $(target).datepicker('getDate');\n }\n }\n\n var tp_inst = this._get(inst, 'timepicker');\n var tp_date;\n if (date instanceof Date) {\n tp_date = new Date(date.getTime());\n tp_date.setMicroseconds(date.getMicroseconds());\n } else {\n tp_date = date;\n }\n\n // This is important if you are using the timezone option, javascript's Date\n // object will only return the timezone offset for the current locale, so we\n // adjust it accordingly. If not using timezone option this won't matter..\n // If a timezone is different in tp, keep the timezone as is\n if (tp_inst && tp_date) {\n // look out for DST if tz wasn't specified\n if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {\n tp_inst.timezone = tp_date.getTimezoneOffset() * -1;\n }\n date = $.timepicker.timezoneAdjust(date, $.timepicker.timezoneOffsetString(-date.getTimezoneOffset()), tp_inst.timezone);\n tp_date = $.timepicker.timezoneAdjust(tp_date, $.timepicker.timezoneOffsetString(-tp_date.getTimezoneOffset()), tp_inst.timezone);\n }\n\n this._updateDatepicker(inst);\n this._base_setDateDatepicker.apply(this, arguments);\n this._setTimeDatepicker(target, tp_date, true);\n };\n\n /*\n * override getDate() to allow getting time too within Date object\n */\n $.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;\n $.datepicker._getDateDatepicker = function (target, noDefault) {\n var inst = this._getInst(target);\n if (!inst) {\n return;\n }\n\n var tp_inst = this._get(inst, 'timepicker');\n\n if (tp_inst) {\n // if it hasn't yet been defined, grab from field\n if (inst.lastVal === undefined) {\n this._setDateFromField(inst, noDefault);\n }\n\n var date = this._getDate(inst);\n\n var currDT = null;\n\n if (tp_inst.$altInput && tp_inst._defaults.altFieldTimeOnly) {\n currDT = tp_inst.$input.val() + ' ' + tp_inst.$altInput.val();\n }\n else if (tp_inst.$input.get(0).tagName !== 'INPUT' && tp_inst.$altInput) {\n /**\n * in case the datetimepicker has been applied to a non-input tag for inline UI,\n * and the user has not configured the plugin to display only time in altInput,\n * pick current date time from the altInput (and hope for the best, for now, until \"ER1\" is applied)\n *\n * @todo ER1. Since altInput can have a totally difference format, convert it to standard format by reading input format from \"altFormat\" and \"altTimeFormat\" option values\n */\n currDT = tp_inst.$altInput.val();\n }\n else {\n currDT = tp_inst.$input.val();\n }\n\n if (date && tp_inst._parseTime(currDT, !inst.settings.timeOnly)) {\n date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);\n date.setMicroseconds(tp_inst.microsec);\n\n // This is important if you are using the timezone option, javascript's Date\n // object will only return the timezone offset for the current locale, so we\n // adjust it accordingly. If not using timezone option this won't matter..\n if (tp_inst.timezone != null) {\n // look out for DST if tz wasn't specified\n if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {\n tp_inst.timezone = date.getTimezoneOffset() * -1;\n }\n date = $.timepicker.timezoneAdjust(date, tp_inst.timezone, $.timepicker.timezoneOffsetString(-date.getTimezoneOffset()));\n }\n }\n return date;\n }\n return this._base_getDateDatepicker(target, noDefault);\n };\n\n /*\n * override parseDate() because UI 1.8.14 throws an error about \"Extra characters\"\n * An option in datapicker to ignore extra format characters would be nicer.\n */\n $.datepicker._base_parseDate = $.datepicker.parseDate;\n $.datepicker.parseDate = function (format, value, settings) {\n var date;\n try {\n date = this._base_parseDate(format, value, settings);\n } catch (err) {\n // Hack! The error message ends with a colon, a space, and\n // the \"extra\" characters. We rely on that instead of\n // attempting to perfectly reproduce the parsing algorithm.\n if (err.indexOf(\":\") >= 0) {\n date = this._base_parseDate(format, value.substring(0, value.length - (err.length - err.indexOf(':') - 2)), settings);\n $.timepicker.log(\"Error parsing the date string: \" + err + \"\\ndate string = \" + value + \"\\ndate format = \" + format);\n } else {\n throw err;\n }\n }\n return date;\n };\n\n /*\n * override formatDate to set date with time to the input\n */\n $.datepicker._base_formatDate = $.datepicker._formatDate;\n $.datepicker._formatDate = function (inst, day, month, year) {\n var tp_inst = this._get(inst, 'timepicker');\n if (tp_inst) {\n tp_inst._updateDateTime(inst);\n return tp_inst.$input.val();\n }\n return this._base_formatDate(inst);\n };\n\n /*\n * override options setter to add time to maxDate(Time) and minDate(Time). MaxDate\n */\n $.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker;\n $.datepicker._optionDatepicker = function (target, name, value) {\n var inst = this._getInst(target),\n name_clone;\n if (!inst) {\n return null;\n }\n\n var tp_inst = this._get(inst, 'timepicker');\n if (tp_inst) {\n var min = null,\n max = null,\n onselect = null,\n overrides = tp_inst._defaults.evnts,\n fns = {},\n prop,\n ret,\n oldVal,\n $target;\n if (typeof name === 'string') { // if min/max was set with the string\n if (name === 'minDate' || name === 'minDateTime') {\n min = value;\n } else if (name === 'maxDate' || name === 'maxDateTime') {\n max = value;\n } else if (name === 'onSelect') {\n onselect = value;\n } else if (overrides.hasOwnProperty(name)) {\n if (typeof (value) === 'undefined') {\n return overrides[name];\n }\n fns[name] = value;\n name_clone = {}; //empty results in exiting function after overrides updated\n }\n } else if (typeof name === 'object') { //if min/max was set with the JSON\n if (name.minDate) {\n min = name.minDate;\n } else if (name.minDateTime) {\n min = name.minDateTime;\n } else if (name.maxDate) {\n max = name.maxDate;\n } else if (name.maxDateTime) {\n max = name.maxDateTime;\n }\n for (prop in overrides) {\n if (overrides.hasOwnProperty(prop) && name[prop]) {\n fns[prop] = name[prop];\n }\n }\n }\n for (prop in fns) {\n if (fns.hasOwnProperty(prop)) {\n overrides[prop] = fns[prop];\n if (!name_clone) { name_clone = $.extend({}, name); }\n delete name_clone[prop];\n }\n }\n if (name_clone && isEmptyObject(name_clone)) { return; }\n if (min) { //if min was set\n if (min === 0) {\n min = new Date();\n } else {\n min = new Date(min);\n }\n tp_inst._defaults.minDate = min;\n tp_inst._defaults.minDateTime = min;\n } else if (max) { //if max was set\n if (max === 0) {\n max = new Date();\n } else {\n max = new Date(max);\n }\n tp_inst._defaults.maxDate = max;\n tp_inst._defaults.maxDateTime = max;\n } else if (onselect) {\n tp_inst._defaults.onSelect = onselect;\n }\n\n // Datepicker will override our date when we call _base_optionDatepicker when\n // calling minDate/maxDate, so we will first grab the value, call\n // _base_optionDatepicker, then set our value back.\n if(min || max){\n $target = $(target);\n oldVal = $target.datetimepicker('getDate');\n ret = this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);\n $target.datetimepicker('setDate', oldVal);\n return ret;\n }\n }\n if (value === undefined) {\n return this._base_optionDatepicker.call($.datepicker, target, name);\n }\n return this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);\n };\n\n /*\n * jQuery isEmptyObject does not check hasOwnProperty - if someone has added to the object prototype,\n * it will return false for all objects\n */\n var isEmptyObject = function (obj) {\n var prop;\n for (prop in obj) {\n if (obj.hasOwnProperty(prop)) {\n return false;\n }\n }\n return true;\n };\n\n /*\n * jQuery extend now ignores nulls!\n */\n var extendRemove = function (target, props) {\n $.extend(target, props);\n for (var name in props) {\n if (props[name] === null || props[name] === undefined) {\n target[name] = props[name];\n }\n }\n return target;\n };\n\n /*\n * Determine by the time format which units are supported\n * Returns an object of booleans for each unit\n */\n var detectSupport = function (timeFormat) {\n var tf = timeFormat.replace(/'.*?'/g, '').toLowerCase(), // removes literals\n isIn = function (f, t) { // does the format contain the token?\n return f.indexOf(t) !== -1 ? true : false;\n };\n return {\n hour: isIn(tf, 'h'),\n minute: isIn(tf, 'm'),\n second: isIn(tf, 's'),\n millisec: isIn(tf, 'l'),\n microsec: isIn(tf, 'c'),\n timezone: isIn(tf, 'z'),\n ampm: isIn(tf, 't') && isIn(timeFormat, 'h'),\n iso8601: isIn(timeFormat, 'Z')\n };\n };\n\n /*\n * Converts 24 hour format into 12 hour\n * Returns 12 hour without leading 0\n */\n var convert24to12 = function (hour) {\n hour %= 12;\n\n if (hour === 0) {\n hour = 12;\n }\n\n return String(hour);\n };\n\n var computeEffectiveSetting = function (settings, property) {\n return settings && settings[property] ? settings[property] : $.timepicker._defaults[property];\n };\n\n /*\n * Splits datetime string into date and time substrings.\n * Throws exception when date can't be parsed\n * Returns {dateString: dateString, timeString: timeString}\n */\n var splitDateTime = function (dateTimeString, timeSettings) {\n // The idea is to get the number separator occurrences in datetime and the time format requested (since time has\n // fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split.\n var separator = computeEffectiveSetting(timeSettings, 'separator'),\n format = computeEffectiveSetting(timeSettings, 'timeFormat'),\n timeParts = format.split(separator), // how many occurrences of separator may be in our format?\n timePartsLen = timeParts.length,\n allParts = dateTimeString.split(separator),\n allPartsLen = allParts.length;\n\n if (allPartsLen > 1) {\n return {\n dateString: allParts.splice(0, allPartsLen - timePartsLen).join(separator),\n timeString: allParts.splice(0, timePartsLen).join(separator)\n };\n }\n\n return {\n dateString: dateTimeString,\n timeString: ''\n };\n };\n\n /*\n * Internal function to parse datetime interval\n * Returns: {date: Date, timeObj: Object}, where\n * date - parsed date without time (type Date)\n * timeObj = {hour: , minute: , second: , millisec: , microsec: } - parsed time. Optional\n */\n var parseDateTimeInternal = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {\n var date,\n parts,\n parsedTime;\n\n parts = splitDateTime(dateTimeString, timeSettings);\n date = $.datepicker._base_parseDate(dateFormat, parts.dateString, dateSettings);\n\n if (parts.timeString === '') {\n return {\n date: date\n };\n }\n\n parsedTime = $.datepicker.parseTime(timeFormat, parts.timeString, timeSettings);\n\n if (!parsedTime) {\n throw 'Wrong time format';\n }\n\n return {\n date: date,\n timeObj: parsedTime\n };\n };\n\n /*\n * Internal function to set timezone_select to the local timezone\n */\n var selectLocalTimezone = function (tp_inst, date) {\n if (tp_inst && tp_inst.timezone_select) {\n var now = date || new Date();\n tp_inst.timezone_select.val(-now.getTimezoneOffset());\n }\n };\n\n /*\n * Create a Singleton Instance\n */\n $.timepicker = new Timepicker();\n\n /**\n * Get the timezone offset as string from a date object (eg '+0530' for UTC+5.5)\n * @param {number} tzMinutes if not a number, less than -720 (-1200), or greater than 840 (+1400) this value is returned\n * @param {boolean} iso8601 if true formats in accordance to iso8601 \"+12:45\"\n * @return {string}\n */\n $.timepicker.timezoneOffsetString = function (tzMinutes, iso8601) {\n if (isNaN(tzMinutes) || tzMinutes > 840 || tzMinutes < -720) {\n return tzMinutes;\n }\n\n var off = tzMinutes,\n minutes = off % 60,\n hours = (off - minutes) / 60,\n iso = iso8601 ? ':' : '',\n tz = (off >= 0 ? '+' : '-') + ('0' + Math.abs(hours)).slice(-2) + iso + ('0' + Math.abs(minutes)).slice(-2);\n\n if (tz === '+00:00') {\n return 'Z';\n }\n return tz;\n };\n\n /**\n * Get the number in minutes that represents a timezone string\n * @param {string} tzString formatted like \"+0500\", \"-1245\", \"Z\"\n * @return {number} the offset minutes or the original string if it doesn't match expectations\n */\n $.timepicker.timezoneOffsetNumber = function (tzString) {\n var normalized = tzString.toString().replace(':', ''); // excuse any iso8601, end up with \"+1245\"\n\n if (normalized.toUpperCase() === 'Z') { // if iso8601 with Z, its 0 minute offset\n return 0;\n }\n\n if (!/^(\\-|\\+)\\d{4}$/.test(normalized)) { // possibly a user defined tz, so just give it back\n return parseInt(tzString, 10);\n }\n\n return ((normalized.substr(0, 1) === '-' ? -1 : 1) * // plus or minus\n ((parseInt(normalized.substr(1, 2), 10) * 60) + // hours (converted to minutes)\n parseInt(normalized.substr(3, 2), 10))); // minutes\n };\n\n /**\n * No way to set timezone in js Date, so we must adjust the minutes to compensate. (think setDate, getDate)\n * @param {Date} date\n * @param {string} fromTimezone formatted like \"+0500\", \"-1245\"\n * @param {string} toTimezone formatted like \"+0500\", \"-1245\"\n * @return {Date}\n */\n $.timepicker.timezoneAdjust = function (date, fromTimezone, toTimezone) {\n var fromTz = $.timepicker.timezoneOffsetNumber(fromTimezone);\n var toTz = $.timepicker.timezoneOffsetNumber(toTimezone);\n if (!isNaN(toTz)) {\n date.setMinutes(date.getMinutes() + (-fromTz) - (-toTz));\n }\n return date;\n };\n\n /**\n * Calls `timepicker()` on the `startTime` and `endTime` elements, and configures them to\n * enforce date range limits.\n * n.b. The input value must be correctly formatted (reformatting is not supported)\n * @param {Element} startTime\n * @param {Element} endTime\n * @param {Object} options Options for the timepicker() call\n * @return {jQuery}\n */\n $.timepicker.timeRange = function (startTime, endTime, options) {\n return $.timepicker.handleRange('timepicker', startTime, endTime, options);\n };\n\n /**\n * Calls `datetimepicker` on the `startTime` and `endTime` elements, and configures them to\n * enforce date range limits.\n * @param {Element} startTime\n * @param {Element} endTime\n * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,\n * a boolean value that can be used to reformat the input values to the `dateFormat`.\n * @param {string} method Can be used to specify the type of picker to be added\n * @return {jQuery}\n */\n $.timepicker.datetimeRange = function (startTime, endTime, options) {\n $.timepicker.handleRange('datetimepicker', startTime, endTime, options);\n };\n\n /**\n * Calls `datepicker` on the `startTime` and `endTime` elements, and configures them to\n * enforce date range limits.\n * @param {Element} startTime\n * @param {Element} endTime\n * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,\n * a boolean value that can be used to reformat the input values to the `dateFormat`.\n * @return {jQuery}\n */\n $.timepicker.dateRange = function (startTime, endTime, options) {\n $.timepicker.handleRange('datepicker', startTime, endTime, options);\n };\n\n /**\n * Calls `method` on the `startTime` and `endTime` elements, and configures them to\n * enforce date range limits.\n * @param {string} method Can be used to specify the type of picker to be added\n * @param {Element} startTime\n * @param {Element} endTime\n * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,\n * a boolean value that can be used to reformat the input values to the `dateFormat`.\n * @return {jQuery}\n */\n $.timepicker.handleRange = function (method, startTime, endTime, options) {\n options = $.extend({}, {\n minInterval: 0, // min allowed interval in milliseconds\n maxInterval: 0, // max allowed interval in milliseconds\n start: {}, // options for start picker\n end: {} // options for end picker\n }, options);\n\n // for the mean time this fixes an issue with calling getDate with timepicker()\n var timeOnly = false;\n if(method === 'timepicker'){\n timeOnly = true;\n method = 'datetimepicker';\n }\n\n function checkDates(changed, other) {\n var startdt = startTime[method]('getDate'),\n enddt = endTime[method]('getDate'),\n changeddt = changed[method]('getDate');\n\n if (startdt !== null) {\n var minDate = new Date(startdt.getTime()),\n maxDate = new Date(startdt.getTime());\n\n minDate.setMilliseconds(minDate.getMilliseconds() + options.minInterval);\n maxDate.setMilliseconds(maxDate.getMilliseconds() + options.maxInterval);\n\n if (options.minInterval > 0 && minDate > enddt) { // minInterval check\n endTime[method]('setDate', minDate);\n }\n else if (options.maxInterval > 0 && maxDate < enddt) { // max interval check\n endTime[method]('setDate', maxDate);\n }\n else if (startdt > enddt) {\n other[method]('setDate', changeddt);\n }\n }\n }\n\n function selected(changed, other, option) {\n if (!changed.val()) {\n return;\n }\n var date = changed[method].call(changed, 'getDate');\n if (date !== null && options.minInterval > 0) {\n if (option === 'minDate') {\n date.setMilliseconds(date.getMilliseconds() + options.minInterval);\n }\n if (option === 'maxDate') {\n date.setMilliseconds(date.getMilliseconds() - options.minInterval);\n }\n }\n\n if (date.getTime) {\n other[method].call(other, 'option', option, date);\n }\n }\n\n $.fn[method].call(startTime, $.extend({\n timeOnly: timeOnly,\n onClose: function (dateText, inst) {\n checkDates($(this), endTime);\n },\n onSelect: function (selectedDateTime) {\n selected($(this), endTime, 'minDate');\n }\n }, options, options.start));\n $.fn[method].call(endTime, $.extend({\n timeOnly: timeOnly,\n onClose: function (dateText, inst) {\n checkDates($(this), startTime);\n },\n onSelect: function (selectedDateTime) {\n selected($(this), startTime, 'maxDate');\n }\n }, options, options.end));\n\n checkDates(startTime, endTime);\n\n selected(startTime, endTime, 'minDate');\n selected(endTime, startTime, 'maxDate');\n\n return $([startTime.get(0), endTime.get(0)]);\n };\n\n /**\n * Log error or data to the console during error or debugging\n * @param {Object} err pass any type object to log to the console during error or debugging\n * @return {void}\n */\n $.timepicker.log = function () {\n // Older IE (9, maybe 10) throw error on accessing `window.console.log.apply`, so check first.\n if (window.console && window.console.log && window.console.log.apply) {\n window.console.log.apply(window.console, Array.prototype.slice.call(arguments));\n }\n };\n\n /*\n * Add util object to allow access to private methods for testability.\n */\n $.timepicker._util = {\n _extendRemove: extendRemove,\n _isEmptyObject: isEmptyObject,\n _convert24to12: convert24to12,\n _detectSupport: detectSupport,\n _selectLocalTimezone: selectLocalTimezone,\n _computeEffectiveSetting: computeEffectiveSetting,\n _splitDateTime: splitDateTime,\n _parseDateTimeInternal: parseDateTimeInternal\n };\n\n /*\n * Microsecond support\n */\n if (!Date.prototype.getMicroseconds) {\n Date.prototype.microseconds = 0;\n Date.prototype.getMicroseconds = function () { return this.microseconds; };\n Date.prototype.setMicroseconds = function (m) {\n this.setMilliseconds(this.getMilliseconds() + Math.floor(m / 1000));\n this.microseconds = m % 1000;\n return this;\n };\n }\n\n /*\n * Keep up with the version\n */\n $.timepicker.version = \"1.6.3\";\n\n}));\n","jquery/jquery.validate.js":"/*!\n * jQuery Validation Plugin v1.19.5\n *\n * https://jqueryvalidation.org/\n *\n * Copyright (c) 2022 J\u00f6rn Zaefferer\n * Released under the MIT license\n */\n(function( factory ) {\n if ( typeof define === \"function\" && define.amd ) {\n define( [\"jquery\", \"jquery/jquery.metadata\"], factory );\n } else if (typeof module === \"object\" && module.exports) {\n module.exports = factory( require( \"jquery\" ) );\n } else {\n factory( jQuery );\n }\n}(function( $ ) {\n\n $.extend( $.fn, {\n\n // https://jqueryvalidation.org/validate/\n validate: function( options ) {\n\n // If nothing is selected, return nothing; can't chain anyway\n if ( !this.length ) {\n if ( options && options.debug && window.console ) {\n console.warn( \"Nothing selected, can't validate, returning nothing.\" );\n }\n return;\n }\n\n // Check if a validator for this form was already created\n var validator = $.data( this[ 0 ], \"validator\" );\n if ( validator ) {\n return validator;\n }\n\n // Add novalidate tag if HTML5.\n this.attr( \"novalidate\", \"novalidate\" );\n\n validator = new $.validator( options, this[ 0 ] );\n $.data( this[ 0 ], \"validator\", validator );\n\n if ( validator.settings.onsubmit ) {\n\n this.on( \"click.validate\", \":submit\", function( event ) {\n\n // Track the used submit button to properly handle scripted\n // submits later.\n validator.submitButton = event.currentTarget;\n\n // Allow suppressing validation by adding a cancel class to the submit button\n if ( $( this ).hasClass( \"cancel\" ) ) {\n validator.cancelSubmit = true;\n }\n\n // Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button\n if ( $( this ).attr( \"formnovalidate\" ) !== undefined ) {\n validator.cancelSubmit = true;\n }\n } );\n\n // Validate the form on submit\n this.on( \"submit.validate\", function( event ) {\n if ( validator.settings.debug ) {\n\n // Prevent form submit to be able to see console output\n event.preventDefault();\n }\n\n function handle() {\n var hidden, result;\n\n // Insert a hidden input as a replacement for the missing submit button\n // The hidden input is inserted in two cases:\n // - A user defined a `submitHandler`\n // - There was a pending request due to `remote` method and `stopRequest()`\n // was called to submit the form in case it's valid\n if ( validator.submitButton && ( validator.settings.submitHandler || validator.formSubmitted ) ) {\n hidden = $( \"<input type='hidden'/>\" )\n .attr( \"name\", validator.submitButton.name )\n .val( $( validator.submitButton ).val() )\n .appendTo( validator.currentForm );\n }\n\n if ( validator.settings.submitHandler && !validator.settings.debug ) {\n result = validator.settings.submitHandler.call( validator, validator.currentForm, event );\n if ( hidden ) {\n\n // And clean up afterwards; thanks to no-block-scope, hidden can be referenced\n hidden.remove();\n }\n if ( result !== undefined ) {\n return result;\n }\n return false;\n }\n return true;\n }\n\n // Prevent submit for invalid forms or custom submit handlers\n if ( validator.cancelSubmit ) {\n validator.cancelSubmit = false;\n return handle();\n }\n if ( validator.form() ) {\n if ( validator.pendingRequest ) {\n validator.formSubmitted = true;\n return false;\n }\n return handle();\n } else {\n validator.focusInvalid();\n return false;\n }\n } );\n }\n\n return validator;\n },\n\n // https://jqueryvalidation.org/valid/\n valid: function() {\n var valid, validator, errorList;\n\n if ( $( this[ 0 ] ).is( \"form\" ) ) {\n valid = this.validate().form();\n } else {\n errorList = [];\n valid = true;\n validator = $( this[ 0 ].form ).validate();\n this.each( function() {\n valid = validator.element( this ) && valid;\n if ( !valid ) {\n errorList = errorList.concat( validator.errorList );\n }\n } );\n validator.errorList = errorList;\n }\n return valid;\n },\n\n // https://jqueryvalidation.org/rules/\n rules: function( command, argument ) {\n var element = this[ 0 ],\n isContentEditable = typeof this.attr( \"contenteditable\" ) !== \"undefined\" && this.attr( \"contenteditable\" ) !== \"false\",\n settings, staticRules, existingRules, data, param, filtered;\n\n // If nothing is selected, return empty object; can't chain anyway\n if ( element == null ) {\n return;\n }\n\n if ( !element.form && isContentEditable ) {\n element.form = this.closest( \"form\" )[ 0 ];\n element.name = this.attr( \"name\" );\n }\n\n if ( element.form == null ) {\n return;\n }\n\n if ( command ) {\n settings = $.data( element.form, \"validator\" ).settings;\n staticRules = settings.rules;\n existingRules = $.validator.staticRules( element );\n switch ( command ) {\n case \"add\":\n $.extend( existingRules, $.validator.normalizeRule( argument ) );\n\n // Remove messages from rules, but allow them to be set separately\n delete existingRules.messages;\n staticRules[ element.name ] = existingRules;\n if ( argument.messages ) {\n settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );\n }\n break;\n case \"remove\":\n if ( !argument ) {\n delete staticRules[ element.name ];\n return existingRules;\n }\n filtered = {};\n $.each( argument.split( /\\s/ ), function( index, method ) {\n filtered[ method ] = existingRules[ method ];\n delete existingRules[ method ];\n } );\n return filtered;\n }\n }\n\n data = $.validator.normalizeRules(\n $.extend(\n {},\n $.validator.metadataRules(element),\n $.validator.classRules( element ),\n $.validator.attributeRules( element ),\n $.validator.dataRules( element ),\n $.validator.staticRules( element )\n ), element );\n\n // Make sure required is at front\n if ( data.required ) {\n param = data.required;\n delete data.required;\n data = $.extend( { required: param }, data );\n }\n\n // Make sure remote is at back\n if ( data.remote ) {\n param = data.remote;\n delete data.remote;\n data = $.extend( data, { remote: param } );\n }\n\n return data;\n }\n } );\n\n// JQuery trim is deprecated, provide a trim method based on String.prototype.trim\n var trim = function( str ) {\n\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim#Polyfill\n return str.replace( /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, \"\" );\n };\n\n// Custom selectors\n $.extend( $.expr.pseudos || $.expr[ \":\" ], {\t\t// '|| $.expr[ \":\" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support\n\n // https://jqueryvalidation.org/blank-selector/\n blank: function( a ) {\n return !trim( \"\" + $( a ).val() );\n },\n\n // https://jqueryvalidation.org/filled-selector/\n filled: function( a ) {\n var val = $( a ).val();\n return val !== null && !!trim( \"\" + val );\n },\n\n // https://jqueryvalidation.org/unchecked-selector/\n unchecked: function( a ) {\n return !$( a ).prop( \"checked\" );\n }\n } );\n\n// Constructor for validator\n $.validator = function( options, form ) {\n this.settings = $.extend( true, {}, $.validator.defaults, options );\n this.currentForm = form;\n this.init();\n };\n\n// https://jqueryvalidation.org/jQuery.validator.format/\n $.validator.format = function( source, params ) {\n if ( arguments.length === 1 ) {\n return function() {\n var args = $.makeArray( arguments );\n args.unshift( source );\n return $.validator.format.apply( this, args );\n };\n }\n if ( params === undefined ) {\n return source;\n }\n if ( arguments.length > 2 && params.constructor !== Array ) {\n params = $.makeArray( arguments ).slice( 1 );\n }\n if ( params.constructor !== Array ) {\n params = [ params ];\n }\n $.each( params, function( i, n ) {\n source = source.replace( new RegExp( \"\\\\{\" + i + \"\\\\}\", \"g\" ), function() {\n return n;\n } );\n } );\n return source;\n };\n\n $.extend( $.validator, {\n\n defaults: {\n messages: {},\n groups: {},\n rules: {},\n errorClass: \"error\",\n pendingClass: \"pending\",\n validClass: \"valid\",\n errorElement: \"label\",\n focusCleanup: false,\n focusInvalid: true,\n errorContainer: $( [] ),\n errorLabelContainer: $( [] ),\n onsubmit: true,\n ignore: \":hidden\",\n ignoreTitle: false,\n onfocusin: function( element ) {\n this.lastActive = element;\n\n // Hide error label and remove error class on focus if enabled\n if ( this.settings.focusCleanup ) {\n if ( this.settings.unhighlight ) {\n this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );\n }\n this.hideThese( this.errorsFor( element ) );\n }\n },\n onfocusout: function( element ) {\n if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {\n this.element( element );\n }\n },\n onkeyup: function( element, event ) {\n\n // Avoid revalidate the field when pressing one of the following keys\n // Shift => 16\n // Ctrl => 17\n // Alt => 18\n // Caps lock => 20\n // End => 35\n // Home => 36\n // Left arrow => 37\n // Up arrow => 38\n // Right arrow => 39\n // Down arrow => 40\n // Insert => 45\n // Num lock => 144\n // AltGr key => 225\n var excludedKeys = [\n 16, 17, 18, 20, 35, 36, 37,\n 38, 39, 40, 45, 144, 225\n ];\n\n if ( event.which === 9 && this.elementValue( element ) === \"\" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {\n return;\n } else if ( element.name in this.submitted || element.name in this.invalid ) {\n this.element( element );\n }\n },\n onclick: function( element ) {\n\n // Click on selects, radiobuttons and checkboxes\n if ( element.name in this.submitted ) {\n this.element( element );\n\n // Or option elements, check parent select in that case\n } else if ( element.parentNode.name in this.submitted ) {\n this.element( element.parentNode );\n }\n },\n highlight: function( element, errorClass, validClass ) {\n if ( element.type === \"radio\" ) {\n this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );\n } else {\n $( element ).addClass( errorClass ).removeClass( validClass );\n }\n },\n unhighlight: function( element, errorClass, validClass ) {\n if ( element.type === \"radio\" ) {\n this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );\n } else {\n $( element ).removeClass( errorClass ).addClass( validClass );\n }\n }\n },\n\n // https://jqueryvalidation.org/jQuery.validator.setDefaults/\n setDefaults: function( settings ) {\n $.extend( $.validator.defaults, settings );\n },\n\n messages: {\n required: \"This field is required.\",\n remote: \"Please fix this field.\",\n email: \"Please enter a valid email address.\",\n url: \"Please enter a valid URL.\",\n date: \"Please enter a valid date.\",\n dateISO: \"Please enter a valid date (ISO).\",\n number: \"Please enter a valid number.\",\n digits: \"Please enter only digits.\",\n equalTo: \"Please enter the same value again.\",\n maxlength: $.validator.format( \"Please enter no more than {0} characters.\" ),\n minlength: $.validator.format( \"Please enter at least {0} characters.\" ),\n rangelength: $.validator.format( \"Please enter a value between {0} and {1} characters long.\" ),\n range: $.validator.format( \"Please enter a value between {0} and {1}.\" ),\n max: $.validator.format( \"Please enter a value less than or equal to {0}.\" ),\n min: $.validator.format( \"Please enter a value greater than or equal to {0}.\" ),\n step: $.validator.format( \"Please enter a multiple of {0}.\" )\n },\n\n autoCreateRanges: false,\n\n prototype: {\n\n init: function() {\n this.labelContainer = $( this.settings.errorLabelContainer );\n this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );\n this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );\n this.submitted = {};\n this.valueCache = {};\n this.pendingRequest = 0;\n this.pending = {};\n this.invalid = {};\n this.reset();\n\n var currentForm = this.currentForm,\n groups = ( this.groups = {} ),\n rules;\n $.each( this.settings.groups, function( key, value ) {\n if ( typeof value === \"string\" ) {\n value = value.split( /\\s/ );\n }\n $.each( value, function( index, name ) {\n groups[ name ] = key;\n } );\n } );\n rules = this.settings.rules;\n $.each( rules, function( key, value ) {\n rules[ key ] = $.validator.normalizeRule( value );\n } );\n\n function delegate( event ) {\n var isContentEditable = typeof $( this ).attr( \"contenteditable\" ) !== \"undefined\" && $( this ).attr( \"contenteditable\" ) !== \"false\";\n\n // Set form expando on contenteditable\n if ( !this.form && isContentEditable ) {\n this.form = $( this ).closest( \"form\" )[ 0 ];\n this.name = $( this ).attr( \"name\" );\n }\n\n // Ignore the element if it belongs to another form. This will happen mainly\n // when setting the `form` attribute of an input to the id of another form.\n if ( currentForm !== this.form ) {\n return;\n }\n\n var validator = $.data( this.form, \"validator\" ),\n eventType = \"on\" + event.type.replace( /^validate/, \"\" ),\n settings = validator.settings;\n if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {\n settings[ eventType ].call( validator, this, event );\n }\n }\n\n $( this.currentForm )\n .on( \"focusin.validate focusout.validate keyup.validate\",\n \":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], \" +\n \"[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], \" +\n \"[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], \" +\n \"[type='radio'], [type='checkbox'], [contenteditable], [type='button']\", delegate )\n\n // Support: Chrome, oldIE\n // \"select\" is provided as event.target when clicking a option\n .on( \"click.validate\", \"select, option, [type='radio'], [type='checkbox']\", delegate );\n\n if ( this.settings.invalidHandler ) {\n $( this.currentForm ).on( \"invalid-form.validate\", this.settings.invalidHandler );\n }\n },\n\n // https://jqueryvalidation.org/Validator.form/\n form: function() {\n this.checkForm();\n $.extend( this.submitted, this.errorMap );\n this.invalid = $.extend( {}, this.errorMap );\n if ( !this.valid() ) {\n $( this.currentForm ).triggerHandler( \"invalid-form\", [ this ] );\n }\n this.showErrors();\n return this.valid();\n },\n\n checkForm: function() {\n this.prepareForm();\n for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {\n this.check( elements[ i ] );\n }\n return this.valid();\n },\n\n // https://jqueryvalidation.org/Validator.element/\n element: function( element ) {\n var cleanElement = this.clean( element ),\n checkElement = this.validationTargetFor( cleanElement ),\n v = this,\n result = true,\n rs, group;\n\n if ( checkElement === undefined ) {\n delete this.invalid[ cleanElement.name ];\n } else {\n this.prepareElement( checkElement );\n this.currentElements = $( checkElement );\n\n // If this element is grouped, then validate all group elements already\n // containing a value\n group = this.groups[ checkElement.name ];\n if ( group ) {\n $.each( this.groups, function( name, testgroup ) {\n if ( testgroup === group && name !== checkElement.name ) {\n cleanElement = v.validationTargetFor( v.clean( v.findByName( name ) ) );\n if ( cleanElement && cleanElement.name in v.invalid ) {\n v.currentElements.push( cleanElement );\n result = v.check( cleanElement ) && result;\n }\n }\n } );\n }\n\n rs = this.check( checkElement ) !== false;\n result = result && rs;\n if ( rs ) {\n this.invalid[ checkElement.name ] = false;\n } else {\n this.invalid[ checkElement.name ] = true;\n }\n\n if ( !this.numberOfInvalids() ) {\n\n // Hide error containers on last error\n this.toHide = this.toHide.add( this.containers );\n }\n this.showErrors();\n\n // Add aria-invalid status for screen readers\n $( element ).attr( \"aria-invalid\", !rs );\n }\n\n return result;\n },\n\n // https://jqueryvalidation.org/Validator.showErrors/\n showErrors: function( errors ) {\n if ( errors ) {\n var validator = this;\n\n // Add items to error list and map\n $.extend( this.errorMap, errors );\n this.errorList = $.map( this.errorMap, function( message, name ) {\n return {\n message: message,\n element: validator.findByName( name )[ 0 ]\n };\n } );\n\n // Remove items from success list\n this.successList = $.grep( this.successList, function( element ) {\n return !( element.name in errors );\n } );\n }\n if ( this.settings.showErrors ) {\n this.settings.showErrors.call( this, this.errorMap, this.errorList );\n } else {\n this.defaultShowErrors();\n }\n },\n\n // https://jqueryvalidation.org/Validator.resetForm/\n resetForm: function() {\n if ( $.fn.resetForm ) {\n $( this.currentForm ).resetForm();\n }\n this.invalid = {};\n this.submitted = {};\n this.prepareForm();\n this.hideErrors();\n var elements = this.elements()\n .removeData( \"previousValue\" )\n .removeAttr( \"aria-invalid\" );\n\n this.resetElements( elements );\n },\n\n resetElements: function( elements ) {\n var i;\n\n if ( this.settings.unhighlight ) {\n for ( i = 0; elements[ i ]; i++ ) {\n this.settings.unhighlight.call( this, elements[ i ],\n this.settings.errorClass, \"\" );\n this.findByName( elements[ i ].name ).removeClass( this.settings.validClass );\n }\n } else {\n elements\n .removeClass( this.settings.errorClass )\n .removeClass( this.settings.validClass );\n }\n },\n\n numberOfInvalids: function() {\n return this.objectLength( this.invalid );\n },\n\n objectLength: function( obj ) {\n /* jshint unused: false */\n var count = 0,\n i;\n for ( i in obj ) {\n\n // This check allows counting elements with empty error\n // message as invalid elements\n if ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) {\n count++;\n }\n }\n return count;\n },\n\n hideErrors: function() {\n this.hideThese( this.toHide );\n },\n\n hideThese: function( errors ) {\n errors.not( this.containers ).text( \"\" );\n this.addWrapper( errors ).hide();\n },\n\n valid: function() {\n return this.size() === 0;\n },\n\n size: function() {\n return this.errorList.length;\n },\n\n focusInvalid: function() {\n if ( this.settings.focusInvalid ) {\n try {\n $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [] )\n .filter( \":visible\" )\n .trigger( \"focus\" )\n\n // Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find\n .trigger( \"focusin\" );\n } catch ( e ) {\n\n // Ignore IE throwing errors when focusing hidden elements\n }\n }\n },\n\n findLastActive: function() {\n var lastActive = this.lastActive;\n return lastActive && $.grep( this.errorList, function( n ) {\n return n.element.name === lastActive.name;\n } ).length === 1 && lastActive;\n },\n\n elements: function() {\n var validator = this,\n rulesCache = {};\n\n // Select all valid inputs inside the form (no submit or reset buttons)\n return $( this.currentForm )\n .find( \"input, select, textarea, [contenteditable]\" )\n .not( \":submit, :reset, :image, :disabled\" )\n .not( this.settings.ignore )\n .filter( function() {\n var name = this.name || $( this ).attr( \"name\" ); // For contenteditable\n var isContentEditable = typeof $( this ).attr( \"contenteditable\" ) !== \"undefined\" && $( this ).attr( \"contenteditable\" ) !== \"false\";\n\n if ( !name && validator.settings.debug && window.console ) {\n console.error( \"%o has no name assigned\", this );\n }\n\n // Set form expando on contenteditable\n if ( isContentEditable ) {\n this.form = $( this ).closest( \"form\" )[ 0 ];\n this.name = name;\n }\n\n // Ignore elements that belong to other/nested forms\n if ( this.form !== validator.currentForm ) {\n return false;\n }\n\n // Select only the first element for each name, and only those with rules specified\n if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {\n return false;\n }\n\n rulesCache[ name ] = true;\n return true;\n } );\n },\n\n clean: function( selector ) {\n return $( selector )[ 0 ];\n },\n\n errors: function() {\n var errorClass = this.settings.errorClass.split( \" \" ).join( \".\" );\n return $( this.settings.errorElement + \".\" + errorClass, this.errorContext );\n },\n\n resetInternals: function() {\n this.successList = [];\n this.errorList = [];\n this.errorMap = {};\n this.toShow = $( [] );\n this.toHide = $( [] );\n },\n\n reset: function() {\n this.resetInternals();\n this.currentElements = $( [] );\n },\n\n prepareForm: function() {\n this.reset();\n this.toHide = this.errors().add( this.containers );\n },\n\n prepareElement: function( element ) {\n this.reset();\n this.toHide = this.errorsFor( element );\n },\n\n elementValue: function( element ) {\n var $element = $( element ),\n type = element.type,\n isContentEditable = typeof $element.attr( \"contenteditable\" ) !== \"undefined\" && $element.attr( \"contenteditable\" ) !== \"false\",\n val, idx;\n\n if ( type === \"radio\" || type === \"checkbox\" ) {\n return this.findByName( element.name ).filter( \":checked\" ).val();\n } else if ( type === \"number\" && typeof element.validity !== \"undefined\" ) {\n return element.validity.badInput ? \"NaN\" : $element.val();\n }\n\n if ( isContentEditable ) {\n val = $element.text();\n } else {\n val = $element.val();\n }\n\n if ( type === \"file\" ) {\n\n // Modern browser (chrome & safari)\n if ( val.substr( 0, 12 ) === \"C:\\\\fakepath\\\\\" ) {\n return val.substr( 12 );\n }\n\n // Legacy browsers\n // Unix-based path\n idx = val.lastIndexOf( \"/\" );\n if ( idx >= 0 ) {\n return val.substr( idx + 1 );\n }\n\n // Windows-based path\n idx = val.lastIndexOf( \"\\\\\" );\n if ( idx >= 0 ) {\n return val.substr( idx + 1 );\n }\n\n // Just the file name\n return val;\n }\n\n if ( typeof val === \"string\" ) {\n return val.replace( /\\r/g, \"\" );\n }\n return val;\n },\n\n check: function( element ) {\n element = this.validationTargetFor( this.clean( element ) );\n\n var rules = $( element ).rules(),\n rulesCount = $.map( rules, function( n, i ) {\n return i;\n } ).length,\n dependencyMismatch = false,\n val = this.elementValue( element ),\n result, method, rule, normalizer;\n\n // Prioritize the local normalizer defined for this element over the global one\n // if the former exists, otherwise user the global one in case it exists.\n if ( typeof rules.normalizer === \"function\" ) {\n normalizer = rules.normalizer;\n } else if (\ttypeof this.settings.normalizer === \"function\" ) {\n normalizer = this.settings.normalizer;\n }\n\n // If normalizer is defined, then call it to the changed value instead\n // of using the real one.\n // Note that `this` in the normalizer is `element`.\n if ( normalizer ) {\n val = normalizer.call( element, val );\n\n // Delete the normalizer from rules to avoid treating it as a pre-defined method.\n delete rules.normalizer;\n }\n\n for ( method in rules ) {\n rule = { method: method, parameters: rules[ method ] };\n try {\n result = $.validator.methods[ method ].call( this, val, element, rule.parameters );\n\n // If a method indicates that the field is optional and therefore valid,\n // don't mark it as valid when there are no other rules\n if ( result === \"dependency-mismatch\" && rulesCount === 1 ) {\n dependencyMismatch = true;\n continue;\n }\n dependencyMismatch = false;\n\n if ( result === \"pending\" ) {\n this.toHide = this.toHide.not( this.errorsFor( element ) );\n return;\n }\n\n if ( !result ) {\n this.formatAndAdd( element, rule );\n return false;\n }\n } catch ( e ) {\n if ( this.settings.debug && window.console ) {\n console.log( \"Exception occurred when checking element \" + element.id + \", check the '\" + rule.method + \"' method.\", e );\n }\n if ( e instanceof TypeError ) {\n e.message += \". Exception occurred when checking element \" + element.id + \", check the '\" + rule.method + \"' method.\";\n }\n\n throw e;\n }\n }\n if ( dependencyMismatch ) {\n return;\n }\n if ( this.objectLength( rules ) ) {\n this.successList.push( element );\n }\n return true;\n },\n\n // Return the custom message for the given element and validation method\n // specified in the element's HTML5 data attribute\n // return the generic message if present and no method specific message is present\n customDataMessage: function( element, method ) {\n return $( element ).data( \"msg\" + method.charAt( 0 ).toUpperCase() +\n method.substring( 1 ).toLowerCase() ) || $( element ).data( \"msg\" );\n },\n\n // Return the custom message for the given element name and validation method\n customMessage: function( name, method ) {\n var m = this.settings.messages[ name ];\n return m && ( m.constructor === String ? m : m[ method ] );\n },\n\n // Return the first defined argument, allowing empty strings\n findDefined: function() {\n for ( var i = 0; i < arguments.length; i++ ) {\n if ( arguments[ i ] !== undefined ) {\n return arguments[ i ];\n }\n }\n return undefined;\n },\n\n // The second parameter 'rule' used to be a string, and extended to an object literal\n // of the following form:\n // rule = {\n // method: \"method name\",\n // parameters: \"the given method parameters\"\n // }\n //\n // The old behavior still supported, kept to maintain backward compatibility with\n // old code, and will be removed in the next major release.\n defaultMessage: function( element, rule ) {\n if ( typeof rule === \"string\" ) {\n rule = { method: rule };\n }\n\n var message = this.findDefined(\n this.customMessage( element.name, rule.method ),\n this.customDataMessage( element, rule.method ),\n\n // 'title' is never undefined, so handle empty string as undefined\n !this.settings.ignoreTitle && element.title || undefined,\n $.validator.messages[ rule.method ],\n \"<strong>Warning: No message defined for \" + element.name + \"</strong>\"\n ),\n theregex = /\\$?\\{(\\d+)\\}/g;\n if ( typeof message === \"function\" ) {\n message = message.call( this, rule.parameters, element );\n } else if ( theregex.test( message ) ) {\n message = $.validator.format( message.replace( theregex, \"{$1}\" ), rule.parameters );\n }\n\n return message;\n },\n\n formatAndAdd: function( element, rule ) {\n var message = this.defaultMessage( element, rule );\n\n this.errorList.push( {\n message: message,\n element: element,\n method: rule.method\n } );\n\n this.errorMap[ element.name ] = message;\n this.submitted[ element.name ] = message;\n },\n\n addWrapper: function( toToggle ) {\n if ( this.settings.wrapper ) {\n toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );\n }\n return toToggle;\n },\n\n defaultShowErrors: function() {\n var i, elements, error;\n for ( i = 0; this.errorList[ i ]; i++ ) {\n error = this.errorList[ i ];\n if ( this.settings.highlight ) {\n this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );\n }\n this.showLabel( error.element, error.message );\n }\n if ( this.errorList.length ) {\n this.toShow = this.toShow.add( this.containers );\n }\n if ( this.settings.success ) {\n for ( i = 0; this.successList[ i ]; i++ ) {\n this.showLabel( this.successList[ i ] );\n }\n }\n if ( this.settings.unhighlight ) {\n for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {\n this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );\n }\n }\n this.toHide = this.toHide.not( this.toShow );\n this.hideErrors();\n this.addWrapper( this.toShow ).show();\n },\n\n validElements: function() {\n return this.currentElements.not( this.invalidElements() );\n },\n\n invalidElements: function() {\n return $( this.errorList ).map( function() {\n return this.element;\n } );\n },\n\n showLabel: function( element, message ) {\n var place, group, errorID, v,\n error = this.errorsFor( element ),\n elementID = this.idOrName( element ),\n describedBy = $( element ).attr( \"aria-describedby\" );\n\n if ( error.length ) {\n\n // Refresh error/success class\n error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );\n\n // Replace message on existing label\n error.html( message );\n } else {\n\n // Create error element\n error = $( \"<\" + this.settings.errorElement + \">\" )\n .attr( \"id\", elementID + \"-error\" )\n .addClass( this.settings.errorClass )\n .html( message || \"\" );\n\n // Maintain reference to the element to be placed into the DOM\n place = error;\n if ( this.settings.wrapper ) {\n\n // Make sure the element is visible, even in IE\n // actually showing the wrapped element is handled elsewhere\n place = error.hide().show().wrap( \"<\" + this.settings.wrapper + \"/>\" ).parent();\n }\n if ( this.labelContainer.length ) {\n this.labelContainer.append( place );\n } else if ( this.settings.errorPlacement ) {\n this.settings.errorPlacement.call( this, place, $( element ) );\n } else {\n place.insertAfter( element );\n }\n\n // Link error back to the element\n if ( error.is( \"label\" ) ) {\n\n // If the error is a label, then associate using 'for'\n error.attr( \"for\", elementID );\n\n // If the element is not a child of an associated label, then it's necessary\n // to explicitly apply aria-describedby\n } else if ( error.parents( \"label[for='\" + this.escapeCssMeta( elementID ) + \"']\" ).length === 0 ) {\n errorID = error.attr( \"id\" );\n\n // Respect existing non-error aria-describedby\n if ( !describedBy ) {\n describedBy = errorID;\n } else if ( !describedBy.match( new RegExp( \"\\\\b\" + this.escapeCssMeta( errorID ) + \"\\\\b\" ) ) ) {\n\n // Add to end of list if not already present\n describedBy += \" \" + errorID;\n }\n $( element ).attr( \"aria-describedby\", describedBy );\n\n // If this element is grouped, then assign to all elements in the same group\n group = this.groups[ element.name ];\n if ( group ) {\n v = this;\n $.each( v.groups, function( name, testgroup ) {\n if ( testgroup === group ) {\n $( \"[name='\" + v.escapeCssMeta( name ) + \"']\", v.currentForm )\n .attr( \"aria-describedby\", error.attr( \"id\" ) );\n }\n } );\n }\n }\n }\n if ( !message && this.settings.success ) {\n error.text( \"\" );\n if ( typeof this.settings.success === \"string\" ) {\n error.addClass( this.settings.success );\n } else {\n this.settings.success( error, element );\n }\n }\n this.toShow = this.toShow.add( error );\n },\n\n errorsFor: function( element ) {\n var name = this.escapeCssMeta( this.idOrName( element ) ),\n describer = $( element ).attr( \"aria-describedby\" ),\n selector = \"label[for='\" + name + \"'], label[for='\" + name + \"'] *\";\n\n // 'aria-describedby' should directly reference the error element\n if ( describer ) {\n selector = selector + \", #\" + this.escapeCssMeta( describer )\n .replace( /\\s+/g, \", #\" ) + \":visible\";\n }\n\n return this\n .errors()\n .filter( selector );\n },\n\n // See https://api.jquery.com/category/selectors/, for CSS\n // meta-characters that should be escaped in order to be used with JQuery\n // as a literal part of a name/id or any selector.\n escapeCssMeta: function( string ) {\n if ( string === undefined ) {\n return \"\";\n }\n\n return string.replace( /([\\\\!\"#$%&'()*+,./:;<=>?@\\[\\]^`{|}~])/g, \"\\\\$1\" );\n },\n\n idOrName: function( element ) {\n return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );\n },\n\n validationTargetFor: function( element ) {\n\n // If radio/checkbox, validate first element in group instead\n if ( this.checkable( element ) ) {\n element = this.findByName( element.name );\n }\n\n // Always apply ignore filter\n return $( element ).not( this.settings.ignore )[ 0 ];\n },\n\n checkable: function( element ) {\n return ( /radio|checkbox/i ).test( element.type );\n },\n\n findByName: function( name ) {\n return $( this.currentForm ).find( \"[name='\" + this.escapeCssMeta( name ) + \"']\" );\n },\n\n getLength: function( value, element ) {\n switch ( element.nodeName.toLowerCase() ) {\n case \"select\":\n return $( \"option:selected\", element ).length;\n case \"input\":\n if ( this.checkable( element ) ) {\n return this.findByName( element.name ).filter( \":checked\" ).length;\n }\n }\n return value.length;\n },\n\n depend: function( param, element ) {\n return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ]( param, element ) : true;\n },\n\n dependTypes: {\n \"boolean\": function( param ) {\n return param;\n },\n \"string\": function( param, element ) {\n return !!$( param, element.form ).length;\n },\n \"function\": function( param, element ) {\n return param( element );\n }\n },\n\n optional: function( element ) {\n var val = this.elementValue( element );\n return !$.validator.methods.required.call( this, val, element ) && \"dependency-mismatch\";\n },\n\n startRequest: function( element ) {\n if ( !this.pending[ element.name ] ) {\n this.pendingRequest++;\n $( element ).addClass( this.settings.pendingClass );\n this.pending[ element.name ] = true;\n }\n },\n\n stopRequest: function( element, valid ) {\n this.pendingRequest--;\n\n // Sometimes synchronization fails, make sure pendingRequest is never < 0\n if ( this.pendingRequest < 0 ) {\n this.pendingRequest = 0;\n }\n delete this.pending[ element.name ];\n $( element ).removeClass( this.settings.pendingClass );\n if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() && this.pendingRequest === 0 ) {\n $( this.currentForm ).trigger( \"submit\" );\n\n // Remove the hidden input that was used as a replacement for the\n // missing submit button. The hidden input is added by `handle()`\n // to ensure that the value of the used submit button is passed on\n // for scripted submits triggered by this method\n if ( this.submitButton ) {\n $( \"input:hidden[name='\" + this.submitButton.name + \"']\", this.currentForm ).remove();\n }\n\n this.formSubmitted = false;\n } else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) {\n $( this.currentForm ).triggerHandler( \"invalid-form\", [ this ] );\n this.formSubmitted = false;\n }\n },\n\n previousValue: function( element, method ) {\n method = typeof method === \"string\" && method || \"remote\";\n\n return $.data( element, \"previousValue\" ) || $.data( element, \"previousValue\", {\n old: null,\n valid: true,\n message: this.defaultMessage( element, { method: method } )\n } );\n },\n\n // Cleans up all forms and elements, removes validator-specific events\n destroy: function() {\n this.resetForm();\n\n $( this.currentForm )\n .off( \".validate\" )\n .removeData( \"validator\" )\n .find( \".validate-equalTo-blur\" )\n .off( \".validate-equalTo\" )\n .removeClass( \"validate-equalTo-blur\" )\n .find( \".validate-lessThan-blur\" )\n .off( \".validate-lessThan\" )\n .removeClass( \"validate-lessThan-blur\" )\n .find( \".validate-lessThanEqual-blur\" )\n .off( \".validate-lessThanEqual\" )\n .removeClass( \"validate-lessThanEqual-blur\" )\n .find( \".validate-greaterThanEqual-blur\" )\n .off( \".validate-greaterThanEqual\" )\n .removeClass( \"validate-greaterThanEqual-blur\" )\n .find( \".validate-greaterThan-blur\" )\n .off( \".validate-greaterThan\" )\n .removeClass( \"validate-greaterThan-blur\" );\n }\n\n },\n\n classRuleSettings: {\n required: { required: true },\n email: { email: true },\n url: { url: true },\n date: { date: true },\n dateISO: { dateISO: true },\n number: { number: true },\n digits: { digits: true },\n creditcard: { creditcard: true }\n },\n\n addClassRules: function( className, rules ) {\n if ( className.constructor === String ) {\n this.classRuleSettings[ className ] = rules;\n } else {\n $.extend( this.classRuleSettings, className );\n }\n },\n\n classRules: function( element ) {\n var rules = {},\n classes = $( element ).attr( \"class\" );\n\n if ( classes ) {\n $.each( classes.split( \" \" ), function() {\n if ( this in $.validator.classRuleSettings ) {\n $.extend( rules, $.validator.classRuleSettings[ this ] );\n }\n } );\n }\n return rules;\n },\n\n normalizeAttributeRule: function( rules, type, method, value ) {\n\n // Convert the value to a number for number inputs, and for text for backwards compability\n // allows type=\"date\" and others to be compared as strings\n if ( /min|max|step/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {\n value = Number( value );\n\n // Support Opera Mini, which returns NaN for undefined minlength\n if ( isNaN( value ) ) {\n value = undefined;\n }\n }\n\n if ( value || value === 0 ) {\n rules[ method ] = value;\n } else if ( type === method && type !== \"range\" ) {\n\n // Exception: the jquery validate 'range' method\n // does not test for the html5 'range' type\n rules[ type === \"date\" ? \"dateISO\" : method ] = true;\n }\n },\n\n attributeRules: function( element ) {\n var rules = {},\n $element = $( element ),\n type = element.getAttribute( \"type\" ),\n method, value;\n\n for ( method in $.validator.methods ) {\n\n // Support for <input required> in both html5 and older browsers\n if ( method === \"required\" ) {\n value = element.getAttribute( method );\n\n // Some browsers return an empty string for the required attribute\n // and non-HTML5 browsers might have required=\"\" markup\n if ( value === \"\" ) {\n value = true;\n }\n\n // Force non-HTML5 browsers to return bool\n value = !!value;\n } else {\n value = $element.attr( method );\n }\n\n this.normalizeAttributeRule( rules, type, method, value );\n }\n\n // 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs\n if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {\n delete rules.maxlength;\n }\n\n return rules;\n },\n\n metadataRules: function (element) {\n if (!$.metadata) {\n return {};\n }\n\n var meta = $.data(element.form, 'validator').settings.meta;\n return meta ?\n $(element).metadata()[meta] :\n $(element).metadata();\n },\n\n dataRules: function( element ) {\n var rules = {},\n $element = $( element ),\n type = element.getAttribute( \"type\" ),\n method, value;\n\n for ( method in $.validator.methods ) {\n value = $element.data( \"rule\" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );\n\n // Cast empty attributes like `data-rule-required` to `true`\n if ( value === \"\" ) {\n value = true;\n }\n\n this.normalizeAttributeRule( rules, type, method, value );\n }\n return rules;\n },\n\n staticRules: function( element ) {\n var rules = {},\n validator = $.data( element.form, \"validator\" );\n\n if ( validator.settings.rules ) {\n rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};\n }\n return rules;\n },\n\n normalizeRules: function( rules, element ) {\n\n // Handle dependency check\n $.each( rules, function( prop, val ) {\n\n // Ignore rule when param is explicitly false, eg. required:false\n if ( val === false ) {\n delete rules[ prop ];\n return;\n }\n if ( val.param || val.depends ) {\n var keepRule = true;\n switch ( typeof val.depends ) {\n case \"string\":\n keepRule = !!$( val.depends, element.form ).length;\n break;\n case \"function\":\n keepRule = val.depends.call( element, element );\n break;\n }\n if ( keepRule ) {\n rules[ prop ] = val.param !== undefined ? val.param : true;\n } else {\n $.data( element.form, \"validator\" ).resetElements( $( element ) );\n delete rules[ prop ];\n }\n }\n } );\n\n // Evaluate parameters\n $.each( rules, function( rule, parameter ) {\n rules[ rule ] = typeof parameter === \"function\" && rule !== \"normalizer\" ? parameter( element ) : parameter;\n } );\n\n // Clean number parameters\n $.each( [ \"minlength\", \"maxlength\" ], function() {\n if ( rules[ this ] ) {\n rules[ this ] = Number( rules[ this ] );\n }\n } );\n $.each( [ \"rangelength\", \"range\" ], function() {\n var parts;\n if ( rules[ this ] ) {\n if ( Array.isArray( rules[ this ] ) ) {\n rules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ];\n } else if ( typeof rules[ this ] === \"string\" ) {\n parts = rules[ this ].replace( /[\\[\\]]/g, \"\" ).split( /[\\s,]+/ );\n rules[ this ] = [ Number( parts[ 0 ] ), Number( parts[ 1 ] ) ];\n }\n }\n } );\n\n if ( $.validator.autoCreateRanges ) {\n\n // Auto-create ranges\n if ( rules.min != null && rules.max != null ) {\n rules.range = [ rules.min, rules.max ];\n delete rules.min;\n delete rules.max;\n }\n if ( rules.minlength != null && rules.maxlength != null ) {\n rules.rangelength = [ rules.minlength, rules.maxlength ];\n delete rules.minlength;\n delete rules.maxlength;\n }\n }\n\n return rules;\n },\n\n // Converts a simple string to a {string: true} rule, e.g., \"required\" to {required:true}\n normalizeRule: function( data ) {\n if ( typeof data === \"string\" ) {\n var transformed = {};\n $.each( data.split( /\\s/ ), function() {\n transformed[ this ] = true;\n } );\n data = transformed;\n }\n return data;\n },\n\n // https://jqueryvalidation.org/jQuery.validator.addMethod/\n addMethod: function( name, method, message ) {\n $.validator.methods[ name ] = method;\n $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];\n if ( method.length < 3 ) {\n $.validator.addClassRules( name, $.validator.normalizeRule( name ) );\n }\n },\n\n // https://jqueryvalidation.org/jQuery.validator.methods/\n methods: {\n\n // https://jqueryvalidation.org/required-method/\n required: function( value, element, param ) {\n\n // Check if dependency is met\n if ( !this.depend( param, element ) ) {\n return \"dependency-mismatch\";\n }\n if ( element.nodeName.toLowerCase() === \"select\" ) {\n\n // Could be an array for select-multiple or a string, both are fine this way\n var val = $( element ).val();\n return val && val.length > 0;\n }\n if ( this.checkable( element ) ) {\n return this.getLength( value, element ) > 0;\n }\n return value !== undefined && value !== null && value.length > 0;\n },\n\n // https://jqueryvalidation.org/email-method/\n email: function( value, element ) {\n\n // From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address\n // Retrieved 2014-01-14\n // If you have a problem with this implementation, report a bug against the above spec\n // Or use custom methods to implement your own email validation\n return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );\n },\n\n // https://jqueryvalidation.org/url-method/\n url: function( value, element ) {\n\n // Copyright (c) 2010-2013 Diego Perini, MIT licensed\n // https://gist.github.com/dperini/729294\n // see also https://mathiasbynens.be/demo/url-regex\n // modified to allow protocol-relative URLs\n return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\\/\\/)(?:(?:[^\\]\\[?\\/<~#`!@$^&*()+=}|:\";',>{ ]|%[0-9A-Fa-f]{2})+(?::(?:[^\\]\\[?\\/<~#`!@$^&*()+=}|:\";',>{ ]|%[0-9A-Fa-f]{2})*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z0-9\\u00a1-\\uffff][a-z0-9\\u00a1-\\uffff_-]{0,62})?[a-z0-9\\u00a1-\\uffff]\\.)+(?:[a-z\\u00a1-\\uffff]{2,}\\.?))(?::\\d{2,5})?(?:[/?#]\\S*)?$/i.test( value );\n },\n\n // https://jqueryvalidation.org/date-method/\n date: ( function() {\n var called = false;\n\n return function( value, element ) {\n if ( !called ) {\n called = true;\n if ( this.settings.debug && window.console ) {\n console.warn(\n \"The `date` method is deprecated and will be removed in version '2.0.0'.\\n\" +\n \"Please don't use it, since it relies on the Date constructor, which\\n\" +\n \"behaves very differently across browsers and locales. Use `dateISO`\\n\" +\n \"instead or one of the locale specific methods in `localizations/`\\n\" +\n \"and `additional-methods.js`.\"\n );\n }\n }\n\n return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );\n };\n }() ),\n\n // https://jqueryvalidation.org/dateISO-method/\n dateISO: function( value, element ) {\n return this.optional( element ) || /^\\d{4}[\\/\\-](0?[1-9]|1[012])[\\/\\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );\n },\n\n // https://jqueryvalidation.org/number-method/\n number: function( value, element ) {\n return this.optional( element ) || /^(?:-?\\d+|-?\\d{1,3}(?:,\\d{3})+)?(?:\\.\\d+)?$/.test( value );\n },\n\n // https://jqueryvalidation.org/digits-method/\n digits: function( value, element ) {\n return this.optional( element ) || /^\\d+$/.test( value );\n },\n\n // https://jqueryvalidation.org/minlength-method/\n minlength: function( value, element, param ) {\n var length = Array.isArray( value ) ? value.length : this.getLength( value, element );\n return this.optional( element ) || length >= param;\n },\n\n // https://jqueryvalidation.org/maxlength-method/\n maxlength: function( value, element, param ) {\n var length = Array.isArray( value ) ? value.length : this.getLength( value, element );\n return this.optional( element ) || length <= param;\n },\n\n // https://jqueryvalidation.org/rangelength-method/\n rangelength: function( value, element, param ) {\n var length = Array.isArray( value ) ? value.length : this.getLength( value, element );\n return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );\n },\n\n // https://jqueryvalidation.org/min-method/\n min: function( value, element, param ) {\n return this.optional( element ) || value >= param;\n },\n\n // https://jqueryvalidation.org/max-method/\n max: function( value, element, param ) {\n return this.optional( element ) || value <= param;\n },\n\n // https://jqueryvalidation.org/range-method/\n range: function( value, element, param ) {\n return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );\n },\n\n // https://jqueryvalidation.org/step-method/\n step: function( value, element, param ) {\n var type = $( element ).attr( \"type\" ),\n errorMessage = \"Step attribute on input type \" + type + \" is not supported.\",\n supportedTypes = [ \"text\", \"number\", \"range\" ],\n re = new RegExp( \"\\\\b\" + type + \"\\\\b\" ),\n notSupported = type && !re.test( supportedTypes.join() ),\n decimalPlaces = function( num ) {\n var match = ( \"\" + num ).match( /(?:\\.(\\d+))?$/ );\n if ( !match ) {\n return 0;\n }\n\n // Number of digits right of decimal point.\n return match[ 1 ] ? match[ 1 ].length : 0;\n },\n toInt = function( num ) {\n return Math.round( num * Math.pow( 10, decimals ) );\n },\n valid = true,\n decimals;\n\n // Works only for text, number and range input types\n // TODO find a way to support input types date, datetime, datetime-local, month, time and week\n if ( notSupported ) {\n throw new Error( errorMessage );\n }\n\n decimals = decimalPlaces( param );\n\n // Value can't have too many decimals\n if ( decimalPlaces( value ) > decimals || toInt( value ) % toInt( param ) !== 0 ) {\n valid = false;\n }\n\n return this.optional( element ) || valid;\n },\n\n // https://jqueryvalidation.org/equalTo-method/\n equalTo: function( value, element, param ) {\n\n // Bind to the blur event of the target in order to revalidate whenever the target field is updated\n var target = $( param );\n if ( this.settings.onfocusout && target.not( \".validate-equalTo-blur\" ).length ) {\n target.addClass( \"validate-equalTo-blur\" ).on( \"blur.validate-equalTo\", function() {\n $( element ).valid();\n } );\n }\n return value === target.val();\n },\n\n // https://jqueryvalidation.org/remote-method/\n remote: function( value, element, param, method ) {\n if ( this.optional( element ) ) {\n return \"dependency-mismatch\";\n }\n\n method = typeof method === \"string\" && method || \"remote\";\n\n var previous = this.previousValue( element, method ),\n validator, data, optionDataString;\n\n if ( !this.settings.messages[ element.name ] ) {\n this.settings.messages[ element.name ] = {};\n }\n previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ];\n this.settings.messages[ element.name ][ method ] = previous.message;\n\n param = typeof param === \"string\" && { url: param } || param;\n optionDataString = $.param( $.extend( { data: value }, param.data ) );\n if ( previous.old === optionDataString ) {\n return previous.valid;\n }\n\n previous.old = optionDataString;\n validator = this;\n this.startRequest( element );\n data = {};\n data[ element.name ] = value;\n $.ajax( $.extend( true, {\n mode: \"abort\",\n port: \"validate\" + element.name,\n dataType: \"json\",\n data: data,\n context: validator.currentForm,\n success: function( response ) {\n var valid = response === true || response === \"true\",\n errors, message, submitted;\n\n validator.settings.messages[ element.name ][ method ] = previous.originalMessage;\n if ( valid ) {\n submitted = validator.formSubmitted;\n validator.resetInternals();\n validator.toHide = validator.errorsFor( element );\n validator.formSubmitted = submitted;\n validator.successList.push( element );\n validator.invalid[ element.name ] = false;\n validator.showErrors();\n } else {\n errors = {};\n message = response || validator.defaultMessage( element, { method: method, parameters: value } );\n errors[ element.name ] = previous.message = message;\n validator.invalid[ element.name ] = true;\n validator.showErrors( errors );\n }\n previous.valid = valid;\n validator.stopRequest( element, valid );\n }\n }, param ) );\n return \"pending\";\n }\n }\n\n } );\n\n// Ajax mode: abort\n// usage: $.ajax({ mode: \"abort\"[, port: \"uniqueport\"]});\n// if mode:\"abort\" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()\n\n var pendingRequests = {},\n ajax;\n\n// Use a prefilter if available (1.5+)\n if ( $.ajaxPrefilter ) {\n $.ajaxPrefilter( function( settings, _, xhr ) {\n var port = settings.port;\n if ( settings.mode === \"abort\" ) {\n if ( pendingRequests[ port ] ) {\n pendingRequests[ port ].abort();\n }\n pendingRequests[ port ] = xhr;\n }\n } );\n } else {\n\n // Proxy ajax\n ajax = $.ajax;\n $.ajax = function( settings ) {\n var mode = ( \"mode\" in settings ? settings : $.ajaxSettings ).mode,\n port = ( \"port\" in settings ? settings : $.ajaxSettings ).port;\n if ( mode === \"abort\" ) {\n if ( pendingRequests[ port ] ) {\n pendingRequests[ port ].abort();\n }\n pendingRequests[ port ] = ajax.apply( this, arguments );\n return pendingRequests[ port ];\n }\n return ajax.apply( this, arguments );\n };\n }\n return $;\n}));\n","jquery/z-index.js":"/*!\n * zIndex plugin from jQuery UI Core - v1.10.4\n * http://jqueryui.com\n *\n * Copyright 2014 jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/category/ui-core/\n */\ndefine([\n 'jquery'\n], function ($, undefined) {\n\n// plugins\n $.fn.extend({\n zIndex: function (zIndex) {\n if (zIndex !== undefined) {\n return this.css(\"zIndex\", zIndex);\n }\n\n if (this.length) {\n var elem = $(this[0]), position, value;\n while (elem.length && elem[0] !== document) {\n // Ignore z-index if position is set to a value where z-index is ignored by the browser\n // This makes behavior of this function consistent across browsers\n // WebKit always returns auto if the element is positioned\n position = elem.css(\"position\");\n if (position === \"absolute\" || position === \"relative\" || position === \"fixed\") {\n // IE returns 0 when zIndex is not specified\n // other browsers return a string\n // we ignore the case of nested elements with an explicit value of 0\n // <div style=\"z-index: -10;\"><div style=\"z-index: 0;\"></div></div>\n value = parseInt(elem.css(\"zIndex\"), 10);\n if (!isNaN(value) && value !== 0) {\n return value;\n }\n }\n elem = elem.parent();\n }\n }\n\n return 0;\n }\n });\n});\n","jquery/jquery.tabs.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n \"jquery\",\n \"jquery/bootstrap/tab\",\n \"jquery/bootstrap/collapse\",\n], function () {\n\n});\n","jquery/jquery.metadata.js":"/*\n * Metadata - jQuery plugin for parsing metadata from elements\n *\n * Copyright (c) 2006 John Resig, Yehuda Katz, J\u00ef\u00bf\u00bd\u00c3\u00b6rn Zaefferer, Paul McLanahan\n *\n * Dual licensed under the MIT and GPL licenses:\n * http://www.opensource.org/licenses/mit-license.php\n * http://www.gnu.org/licenses/gpl.html\n *\n * Revision: $Id: jquery.metadata.js 3640 2007-10-11 18:34:38Z pmclanahan $\n *\n */\n\n/**\n * Sets the type of metadata to use. Metadata is encoded in JSON, and each property\n * in the JSON will become a property of the element itself.\n *\n * There are four supported types of metadata storage:\n *\n * attr: Inside an attribute. The name parameter indicates *which* attribute.\n *\n * class: Inside the class attribute, wrapped in curly braces: { }\n *\n * elem: Inside a child element (e.g. a script tag). The\n * name parameter indicates *which* element.\n * html5: Values are stored in data-* attributes.\n *\n * The metadata for an element is loaded the first time the element is accessed via jQuery.\n *\n * As a result, you can define the metadata type, use $(expr) to load the metadata into the elements\n * matched by expr, then redefine the metadata type and run another $(expr) for other elements.\n *\n * @name $.metadata.setType\n *\n * @example <p id=\"one\" class=\"some_class {item_id: 1, item_label: 'Label'}\">This is a p</p>\n * @before $.metadata.setType(\"class\")\n * @after $(\"#one\").metadata().item_id == 1; $(\"#one\").metadata().item_label == \"Label\"\n * @desc Reads metadata from the class attribute\n *\n * @example <p id=\"one\" class=\"some_class\" data=\"{item_id: 1, item_label: 'Label'}\">This is a p</p>\n * @before $.metadata.setType(\"attr\", \"data\")\n * @after $(\"#one\").metadata().item_id == 1; $(\"#one\").metadata().item_label == \"Label\"\n * @desc Reads metadata from a \"data\" attribute\n *\n * @example <p id=\"one\" class=\"some_class\"><script>{item_id: 1, item_label: 'Label'}</script>This is a p</p>\n * @before $.metadata.setType(\"elem\", \"script\")\n * @after $(\"#one\").metadata().item_id == 1; $(\"#one\").metadata().item_label == \"Label\"\n * @desc Reads metadata from a nested script element\n *\n * @example <p id=\"one\" class=\"some_class\" data-item_id=\"1\" data-item_label=\"Label\">This is a p</p>\n * @before $.metadata.setType(\"html5\")\n * @after $(\"#one\").metadata().item_id == 1; $(\"#one\").metadata().item_label == \"Label\"\n * @desc Reads metadata from a series of data-* attributes\n *\n * @param String type The encoding type\n * @param String name The name of the attribute to be used to get metadata (optional)\n * @cat Plugins/Metadata\n * @descr Sets the type of encoding to be used when loading metadata for the first time\n * @type undefined\n * @see metadata()\n */\n(function (factory) {\n if (typeof define === 'function' && define.amd) {\n define([\"jquery\"], factory);\n } else {\n factory(jQuery);\n }\n}(function ($) {\n\n\n $.extend({\n metadata : {\n defaults : {\n type: 'class',\n name: 'metadata',\n cre: /({.*})/,\n single: 'metadata',\n meta:'validate'\n },\n setType: function( type, name ){\n this.defaults.type = type;\n this.defaults.name = name;\n },\n get: function( elem, opts ){\n var settings = $.extend({},this.defaults,opts);\n // check for empty string in single property\n if (!settings.single.length) {\n settings.single = 'metadata';\n }\n if (!settings.meta.length) {\n settings.meta = 'validate';\n }\n\n var data = $.data(elem, settings.single);\n // returned cached data if it already exists\n if ( data ) return data;\n\n data = \"{}\";\n\n var getData = function(data) {\n if(typeof data != \"string\") return data;\n\n if( data.indexOf('{') < 0 ) {\n data = eval(\"(\" + data + \")\");\n }\n }\n\n var getObject = function(data) {\n if(typeof data != \"string\") return data;\n\n data = eval(\"(\" + data + \")\");\n return data;\n }\n\n if ( settings.type == \"html5\" ) {\n var object = {};\n $( elem.attributes ).each(function() {\n var name = this.nodeName;\n if (name.indexOf('data-' + settings.meta) === 0) {\n name = name.replace(/^data-/, '');\n }\n else {\n return true;\n }\n object[name] = getObject(this.value);\n });\n } else {\n if ( settings.type == \"class\" ) {\n var m = settings.cre.exec( elem.className );\n if ( m )\n data = m[1];\n } else if ( settings.type == \"elem\" ) {\n if( !elem.getElementsByTagName ) return;\n var e = elem.getElementsByTagName(settings.name);\n if ( e.length )\n data = $.trim(e[0].innerHTML);\n } else if ( elem.getAttribute != undefined ) {\n var attr = elem.getAttribute( settings.name );\n if ( attr )\n data = attr;\n }\n object = getObject(data.indexOf(\"{\") < 0 ? \"{\" + data + \"}\" : data);\n }\n\n $.data( elem, settings.single, object );\n return object;\n }\n }\n });\n\n /**\n * Returns the metadata object for the first member of the jQuery object.\n *\n * @name metadata\n * @descr Returns element's metadata object\n * @param Object opts An object contianing settings to override the defaults\n * @type jQuery\n * @cat Plugins/Metadata\n */\n $.fn.metadata = function( opts ){\n return $.metadata.get( this[0], opts );\n };\n\n}));","jquery/jquery.cookie.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'js-cookie/cookie-wrapper'\n], function () {\n\n});\n"} }});