| Current Path : /proc/thread-self/cwd/static/frontend/Magento/forst-trento/it_IT/js/bundle/ |
| Current File : //proc/thread-self/cwd/static/frontend/Magento/forst-trento/it_IT/js/bundle/bundle9.js |
require.config({"config": {
"jsbuild":{"mage/decorate.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 'mage/translate'\n], function ($) {\n var methods = {\n /**\n * Decorate a list (e.g. a <ul> containing <li>) recursively if specified.\n * @param {Boolean} isRecursive\n */\n list: function (isRecursive) {\n return this.each(function () {\n var list = $(this),\n items;\n\n if (list.length > 0) {\n items = typeof isRecursive === 'undefined' || isRecursive ?\n list.find('li') :\n list.children();\n items.decorate('generic', ['odd', 'even', 'last']);\n }\n });\n },\n\n /**\n * Annotate a set of DOM elements with decorator classes.\n * @param {Array} decoratorParams\n */\n generic: function (decoratorParams) {\n var elements = $(this),\n allSupportedParams;\n\n if (elements) {\n allSupportedParams = {\n even: 'odd', // Flip jQuery odd/even so that index 0 is odd.\n odd: 'even',\n last: 'last',\n first: 'first'\n };\n\n decoratorParams = decoratorParams || allSupportedParams;\n\n $.each(decoratorParams, function (index, param) {\n if (param === 'even' || param === 'odd') {\n elements.filter(':' + param).removeClass('odd even').addClass(allSupportedParams[param]);\n } else {\n elements.filter(':' + param).addClass(allSupportedParams[param]);\n }\n });\n }\n\n return this;\n },\n\n /**\n * Decorate DOM elements in an HTML table with specified classes.\n * @param {Object} instanceOptions\n */\n table: function (instanceOptions) {\n return this.each(function () {\n var table = $(this),\n options;\n\n if (table.length > 0) {\n options = {\n 'tbody': false,\n 'tbody tr': ['odd', 'even', 'first', 'last'],\n 'thead tr': ['first', 'last'],\n 'tfoot tr': ['first', 'last'],\n 'tr td': ['last']\n };\n\n $.extend(options, instanceOptions || {});\n\n $.each(options, function (key, value) {\n if (options[key]) {\n if (key === 'tr td') {\n $.each(table.find('tr'), function () {\n $(this).find('td').decorate('generic', options['tr td']);\n });\n } else {\n table.find(key).decorate('generic', value);\n }\n }\n });\n }\n });\n },\n\n /**\n * Annotate data list elements with CSS classes.\n */\n dataList: function () {\n return this.each(function () {\n var list = $(this);\n\n if (list) {\n list.find('dt').decorate('generic', ['odd', 'even', 'last']);\n list.find('dd').decorate('generic', ['odd', 'even', 'last']);\n }\n });\n }\n };\n\n /**\n * @param {String} method\n * @return {*}\n */\n $.fn.decorate = function (method) {\n var message;\n\n if (methods[method]) {\n return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));\n } else if (typeof method === 'object' || !method) {\n return methods.init.apply(this, arguments);\n }\n\n message = $.mage.__('Method %s does not exist on jQuery.decorate');\n // eslint-disable-next-line jquery-no-event-shorthand\n $.error(message.replace('%s', method));\n };\n});\n","mage/dropdowns.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery'\n], function ($) {\n 'use strict';\n\n /**\n * @param {Object} options\n */\n $.fn.dropdown = function (options) {\n var defaults = {\n parent: null,\n autoclose: true,\n btnArrow: '.arrow',\n menu: '[data-target=\"dropdown\"]',\n activeClass: 'active'\n },\n actionElem = $(this),\n self = this;\n\n options = $.extend(defaults, options);\n actionElem = $(this);\n self = this;\n\n /**\n * @param {HTMLElement} elem\n */\n this.openDropdown = function (elem) {\n elem\n .addClass(options.activeClass)\n .attr('aria-expanded', true)\n .parent()\n .addClass(options.activeClass);\n\n elem.parent()\n .find(options.menu)\n .attr('aria-hidden', false);\n\n $(options.btnArrow, elem).text('-');\n };\n\n /**\n * @param {HTMLElement} elem\n */\n this.closeDropdown = function (elem) {\n elem.removeClass(options.activeClass)\n .attr('aria-expanded', false)\n .parent()\n .removeClass(options.activeClass);\n\n elem.parent()\n .find(options.menu)\n .attr('aria-hidden', true);\n\n $(options.btnArrow, elem).text('+');\n };\n\n /**\n * Reset all dropdowns.\n *\n * @param {Object} param\n */\n this.reset = function (param) {\n var params = param || {},\n dropdowns = params.elems || actionElem;\n\n dropdowns.each(function (index, elem) {\n self.closeDropdown($(elem));\n });\n };\n\n /* document Event bindings */\n if (options.autoclose === true) {\n $(document).on('click.hideDropdown', this.reset);\n $(document).on('keyup.hideDropdown', function (e) {\n var ESC_CODE = '27';\n\n if (e.keyCode == ESC_CODE) { //eslint-disable-line eqeqeq\n self.reset();\n }\n });\n }\n\n if (options.events) {\n $.each(options.events, function (index, event) {\n $(document).on(event.name, event.selector, event.action);\n });\n }\n\n return this.each(function () {\n var elem = $(this),\n parent = $(options.parent).length > 0 ? $(options.parent) : elem.parent(),\n menu = $(options.menu, parent) || $('.dropdown-menu', parent);\n\n // ARIA (adding aria attributes)\n if (menu.length) {\n elem.attr('aria-haspopup', true);\n }\n\n if (!elem.hasClass(options.activeClass)) {\n elem.attr('aria-expanded', false);\n menu.attr('aria-hidden', true);\n } else {\n elem.attr('aria-expanded', true);\n menu.attr('aria-hidden', false);\n }\n\n if (!elem.is('a, button')) {\n elem.attr('role', 'button');\n elem.attr('tabindex', 0);\n }\n\n if (elem.attr('data-trigger-keypress-button')) {\n elem.on('keypress', function (e) {\n var keyCode = e.keyCode || e.which,\n ENTER_CODE = 13;\n\n if (keyCode === ENTER_CODE) {\n e.preventDefault();\n elem.trigger('click.toggleDropdown');\n }\n });\n }\n\n elem.on('click.toggleDropdown', function () {\n var el = actionElem;\n\n if (options.autoclose === true) {\n actionElem = $();\n $(document).trigger('click.hideDropdown');\n actionElem = el;\n }\n\n self[el.hasClass(options.activeClass) ? 'closeDropdown' : 'openDropdown'](elem);\n\n return false;\n });\n });\n };\n\n return function (data, el) {\n $(el).dropdown(data);\n };\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/mage.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], function ($, mage) {\n 'use strict';\n\n /**\n * Main namespace for Magento extensions\n * @type {Object}\n */\n $.mage = $.mage || {};\n\n /**\n * Plugin mage, initialize components on elements\n * @param {String} name - Components' path.\n * @param {Object} config - Components' config.\n * @returns {JQuery} Chainable.\n */\n $.fn.mage = function (name, config) {\n config = config || {};\n\n this.each(function (index, el) {\n mage.applyFor(el, config, name);\n });\n\n return this;\n };\n\n $.extend($.mage, {\n /**\n * Handle all components declared via data attribute\n * @return {Object} $.mage\n */\n init: function () {\n mage.apply();\n\n return this;\n },\n\n /**\n * Method handling redirects and page refresh\n * @param {String} url - redirect URL\n * @param {(undefined|String)} type - 'assign', 'reload', 'replace'\n * @param {(undefined|Number)} timeout - timeout in milliseconds before processing the redirect or reload\n * @param {(undefined|Boolean)} forced - true|false used for 'reload' only\n */\n redirect: function (url, type, timeout, forced) {\n var _redirect;\n\n forced = !!forced;\n timeout = timeout || 0;\n type = type || 'assign';\n\n /**\n * @private\n */\n _redirect = function () {\n window.location[type](type === 'reload' ? forced : url);\n };\n\n timeout ? setTimeout(_redirect, timeout) : _redirect();\n },\n\n /**\n * Checks if provided string is a valid selector.\n * @param {String} selector - Selector to check.\n * @returns {Boolean}\n */\n isValidSelector: function (selector) {\n try {\n document.querySelector(selector);\n\n return true;\n } catch (e) {\n return false;\n }\n }\n });\n\n /**\n * Init components inside of dynamically updated elements\n */\n $(document).on('contentUpdated', 'body', function () {\n if (mage) {\n mage.apply();\n }\n });\n\n return $.mage;\n});\n","mage/edit-trigger.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 */\ndefine([\n 'jquery',\n 'mage/template',\n 'jquery-ui-modules/widget'\n], function ($, mageTemplate) {\n 'use strict';\n\n var editTriggerPrototype;\n\n $.widget('mage.editTrigger', {\n options: {\n img: '',\n alt: '[TR]',\n template: '#translate-inline-icon',\n zIndex: 2000,\n editSelector: '[data-translate]',\n delay: 2000,\n offsetTop: -3,\n singleElement: true\n },\n\n /**\n * editTriger creation\n * @protected\n */\n _create: function () {\n this.tmpl = mageTemplate(this.options.template);\n this._initTrigger();\n this._bind();\n },\n\n /**\n * @return {Object}\n * @private\n */\n _getCss: function () {\n return {\n position: 'absolute',\n cursor: 'pointer',\n display: 'none',\n 'z-index': this.options.zIndex\n };\n },\n\n /**\n * @param {*} appendTo\n * @return {*|jQuery}\n * @private\n */\n _createTrigger: function (appendTo) {\n var tmpl = this.tmpl({\n data: this.options\n });\n\n return $(tmpl)\n .css(this._getCss())\n .data('role', 'edit-trigger-element')\n .appendTo(appendTo);\n },\n\n /**\n * @private\n */\n _initTrigger: function () {\n this.trigger = this._createTrigger($('body'));\n },\n\n /**\n * Bind on mousemove event\n * @protected\n */\n _bind: function () {\n this.trigger.on('click.' + this.widgetName, $.proxy(this._onClick, this));\n this.element.on('mousemove.' + this.widgetName, $.proxy(this._onMouseMove, this));\n },\n\n /**\n * Show editTriger\n */\n show: function () {\n if (this.trigger.is(':hidden')) {\n this.trigger.show();\n }\n },\n\n /**\n * Hide editTriger\n */\n hide: function () {\n this.currentTarget = null;\n\n if (this.trigger && this.trigger.is(':visible')) {\n this.trigger.hide();\n }\n },\n\n /**\n * Set editTriger position\n * @protected\n */\n _setPosition: function (el) {\n var offset = el.offset();\n\n this.trigger.css({\n top: offset.top + el.outerHeight() + this.options.offsetTop,\n left: offset.left\n });\n },\n\n /**\n * Show/hide trigger on mouse move.\n *\n * @param {jQuery.Event} e\n * @protected\n */\n _onMouseMove: function (e) {\n var target = $(e.target),\n inner = target.find(this.options.editSelector);\n\n if ($(e.target).is('button') && inner.length) {\n target = inner;\n } else if (!target.is(this.trigger) && !target.is(this.options.editSelector)) {\n target = target.parents(this.options.editSelector).first();\n }\n\n if (target.length) {\n if (!target.is(this.trigger)) {\n this._setPosition(target);\n this.currentTarget = target;\n }\n this.show();\n } else {\n this.hide();\n }\n },\n\n /**\n * Trigger event \"edit\" on element for translate.\n *\n * @param {jQuery.Event} e\n * @protected\n */\n _onClick: function (e) {\n e.preventDefault();\n e.stopImmediatePropagation();\n $(this.currentTarget).trigger('edit.' + this.widgetName);\n this.hide(true);\n },\n\n /**\n * Destroy editTriger\n */\n destroy: function () {\n this.trigger.remove();\n this.element.off('.' + this.widgetName);\n\n return $.Widget.prototype.destroy.call(this);\n }\n });\n\n /**\n * Extention for widget editTrigger - hide trigger with delay\n */\n editTriggerPrototype = $.mage.editTrigger.prototype;\n\n $.widget('mage.editTrigger', $.extend({}, editTriggerPrototype, {\n /**\n * Added clear timeout on trigger show\n */\n show: function () {\n editTriggerPrototype.show.apply(this, arguments);\n\n if (this.options.delay) {\n this._clearTimer();\n }\n },\n\n /**\n * Added setTimeout on trigger hide\n */\n hide: function (immediate) {\n if (!immediate && this.options.delay) {\n if (!this.timer) {\n this.timer = setTimeout($.proxy(function () {\n editTriggerPrototype.hide.apply(this, arguments);\n this._clearTimer();\n }, this), this.options.delay);\n }\n } else {\n editTriggerPrototype.hide.apply(this, arguments);\n }\n },\n\n /**\n * Clear timer\n * @protected\n */\n _clearTimer: function () {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n }));\n\n return $.mage.editTrigger;\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/url.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* eslint-disable strict */\ndefine([], function () {\n var baseUrl = '';\n\n return {\n /**\n * @param {String} url\n */\n setBaseUrl: function (url) {\n baseUrl = url;\n },\n\n /**\n * @param {String} path\n * @return {*}\n */\n build: function (path) {\n if (path.indexOf(baseUrl) !== -1) {\n return path;\n }\n\n return baseUrl + path;\n }\n };\n});\n","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/sticky.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.sticky', {\n options: {\n /**\n * Element selector, who's height will be used to restrict the\n * maximum offsetTop position of the stuck element.\n * Default uses document body.\n * @type {String}\n */\n container: '',\n\n /**\n * Spacing in pixels above the stuck element\n * @type {Number|Function} Number or Function that will return a Number\n */\n spacingTop: 0,\n\n /**\n * Allows postponing sticking, until element will go out of the\n * screen for the number of pixels.\n * @type {Number|Function} Number or Function that will return a Number\n */\n stickAfter: 0,\n\n /**\n * CSS class for active sticky state\n * @type {String}\n */\n stickyClass: '_sticky'\n },\n\n /**\n * Retrieve option value\n * @param {String} option\n * @return {*}\n * @private\n */\n _getOptionValue: function (option) {\n var value = this.options[option] || 0;\n\n if (typeof value === 'function') {\n value = this.options[option]();\n }\n\n return value;\n },\n\n /**\n * Bind handlers to scroll event\n * @private\n */\n _create: function () {\n $(window).on({\n 'scroll': $.proxy(this._stick, this),\n 'resize': $.proxy(this.reset, this)\n });\n\n this.element.on('dimensionsChanged', $.proxy(this.reset, this));\n\n this.reset();\n\n // Application of the workaround for IE11 and Edge\n this.normalizeIE11AndEdgeScroll();\n },\n\n /**\n * float Block on windowScroll\n * @private\n */\n _stick: function () {\n var offset,\n isStatic,\n stuck,\n stickAfter;\n\n isStatic = this.element.css('position') === 'static';\n\n if (!isStatic && this.element.is(':visible')) {\n offset = $(document).scrollTop() -\n this.parentOffset +\n this._getOptionValue('spacingTop');\n\n offset = Math.max(0, Math.min(offset, this.maxOffset));\n\n stuck = this.element.hasClass(this.options.stickyClass);\n stickAfter = this._getOptionValue('stickAfter');\n\n if (offset && !stuck && offset < stickAfter) {\n offset = 0;\n }\n\n this.element\n .toggleClass(this.options.stickyClass, offset > 0)\n .css('top', offset);\n }\n },\n\n /**\n * Defines maximum offset value of the element.\n * @private\n */\n _calculateDimens: function () {\n var $parent = this.element.parent(),\n topMargin = parseInt(this.element.css('margin-top'), 10),\n parentHeight = $parent.height() - topMargin,\n height = this.element.innerHeight(),\n maxScroll = document.body.offsetHeight - window.innerHeight;\n\n if (this.options.container.length > 0) {\n maxScroll = $(this.options.container).height();\n }\n\n this.parentOffset = $parent.offset().top + topMargin;\n this.maxOffset = maxScroll - this.parentOffset;\n\n if (this.maxOffset + height >= parentHeight) {\n this.maxOffset = parentHeight - height;\n }\n\n return this;\n },\n\n /**\n * Facade method that places sticky element where it should be.\n */\n reset: function () {\n this._calculateDimens()\n ._stick();\n },\n\n /**\n * Workaround for IE11 and Edge that solves the IE known rendering issue\n * that prevents sticky element from jumpy movement on scrolling the page.\n *\n * Alternatively, undesired jumpy movement can be eliminated by changing the setting in IE:\n * Settings > Internet options > Advanced tab > inside 'Browsing' item > set 'Use smooth scrolling' to False\n */\n normalizeIE11AndEdgeScroll: function () {\n if (navigator.userAgent.match(/Trident.*rv[ :]*11\\.|Edge\\//)) {\n document.body.addEventListener('mousewheel', function () {\n event.preventDefault();\n window.scrollTo(0, window.pageYOffset - event.wheelDelta);\n });\n }\n }\n });\n\n return $.mage.sticky;\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/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/deletable-item.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 */\ndefine([\n 'jquery',\n 'jquery-ui-modules/widget'\n], function ($) {\n 'use strict';\n\n /**\n * This widget is used to tag a DOM element as deletable. By default, it will use the click event on the item with a\n * data role of delete to trigger the deletion.\n */\n $.widget('mage.deletableItem', {\n options: {\n deleteEvent: 'click',\n deleteSelector: '[data-role=\"delete\"]',\n hiddenClass: 'no-display'\n },\n\n /**\n * This method binds elements found in this widget.\n */\n _bind: function () {\n var handlers = {};\n\n // since the first handler is dynamic, generate the object using array notation\n handlers[this.options.deleteEvent + ' ' + this.options.deleteSelector] = '_onDeleteClicked';\n handlers.hideDelete = '_onHideDelete';\n handlers.showDelete = '_onShowDelete';\n\n this._on(handlers);\n },\n\n /**\n * This method constructs a new widget.\n */\n _create: function () {\n this._bind();\n },\n\n /**\n * This method is to initialize the control\n * @private\n */\n _init: function () {\n this._onHideDelete(); // by default, hide the control\n },\n\n /**\n * This method removes the entity from the DOM.\n * @private\n */\n _onDeleteClicked: function (e) {\n e.stopPropagation();\n this.element.trigger('deleteItem');\n },\n\n /**\n * This method hides the delete capability of this item (i.e. making it not deletable)\n * @private\n */\n _onHideDelete: function () {\n this.element.find(this.options.deleteSelector).addClass(this.options.hiddenClass);\n },\n\n /**\n * This method shows the delete capability of this item (i.e. making it deletable)\n * @private\n */\n _onShowDelete: function () {\n this.element.find(this.options.deleteSelector).removeClass(this.options.hiddenClass);\n }\n });\n\n return $.mage.deletableItem;\n});\n","mage/cookies.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 'js-cookie/cookie-wrapper'\n], function ($) {\n 'use strict';\n\n /**\n * Helper for cookies manipulation\n * @returns {CookieHelper}\n * @constructor\n */\n var CookieHelper = function () {\n\n /**\n * Cookie default values.\n * @type {Object}\n */\n this.defaults = {\n expires: null,\n path: '/',\n domain: null,\n secure: false,\n lifetime: null,\n samesite: 'lax'\n };\n\n /**\n * Calculate cookie expiration date based on its lifetime.\n * @param {Object} options - Cookie option values\n * @return {Date|null} Calculated cookie expiration date or null if no lifetime provided.\n * @private\n */\n function lifetimeToExpires(options, defaults) {\n var expires,\n lifetime;\n\n lifetime = options.lifetime || defaults.lifetime;\n\n if (lifetime && lifetime > 0) {\n expires = options.expires || new Date();\n\n return new Date(expires.getTime() + lifetime * 1000);\n }\n\n return null;\n }\n\n /**\n * Set a cookie's value by cookie name based on optional cookie options.\n * @param {String} name - The name of the cookie.\n * @param {String} value - The cookie's value.\n * @param {Object} options - Optional options (e.g. lifetime, expires, path, etc.)\n */\n this.set = function (name, value, options) {\n var expires,\n path,\n domain,\n secure,\n samesite;\n\n options = $.extend({}, this.defaults, options || {});\n expires = lifetimeToExpires(options, this.defaults) || options.expires;\n path = options.path;\n domain = options.domain;\n secure = options.secure;\n samesite = options.samesite;\n\n document.cookie = name + '=' + encodeURIComponent(value) +\n (expires ? '; expires=' + expires.toUTCString() : '') +\n (path ? '; path=' + path : '') +\n (domain ? '; domain=' + domain : '') +\n (secure ? '; secure' : '') +\n '; samesite=' + (samesite ? samesite : 'lax');\n };\n\n /**\n * Get a cookie's value by cookie name.\n * @param {String} name - The name of the cookie.\n * @return {(null|String)}\n */\n this.get = function (name) {\n var arg = name + '=',\n aLength = arg.length,\n cookie = document.cookie,\n cLength = cookie.length,\n i = 0,\n j = 0;\n\n while (i < cLength) {\n j = i + aLength;\n\n if (cookie.substring(i, j) === arg) {\n return this.getCookieVal(j);\n }\n i = cookie.indexOf(' ', i) + 1;\n\n if (i === 0) {\n break;\n }\n }\n\n return null;\n };\n\n /**\n * Clear a cookie's value by name.\n * @param {String} name - The name of the cookie being cleared.\n */\n this.clear = function (name) {\n if (this.get(name)) {\n this.set(name, '', {\n expires: new Date('Jan 01 1970 00:00:01 GMT')\n });\n }\n };\n\n /**\n * Return URI decoded cookie component value (e.g. expires, path, etc.) based on a\n * numeric offset in the document's cookie value.\n * @param {Number} offset - Offset into the document's cookie value.\n * @return {String}\n */\n this.getCookieVal = function (offset) {\n var cookie = document.cookie,\n endstr = cookie.indexOf(';', offset);\n\n if (endstr === -1) {\n endstr = cookie.length;\n }\n\n return decodeURIComponent(cookie.substring(offset, endstr));\n };\n\n return this;\n };\n\n $.extend(true, $, {\n mage: {\n cookies: new CookieHelper()\n }\n });\n\n return function (pageOptions) {\n $.extend($.mage.cookies.defaults, pageOptions);\n $.extend($.cookie.defaults, $.mage.cookies.defaults);\n };\n});\n","mage/touch-slider.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'underscore',\n 'jquery-ui-modules/slider'\n], function ($, _) {\n 'use strict';\n\n /**\n * Adds support for touch events for regular jQuery UI slider.\n */\n $.widget('mage.touchSlider', $.ui.slider, {\n\n /**\n * Creates instance of widget.\n *\n * @override\n */\n _create: function () {\n _.bindAll(\n this,\n '_mouseDown',\n '_mouseMove',\n '_onTouchEnd'\n );\n\n return this._superApply(arguments);\n },\n\n /**\n * Initializes mouse events on element.\n * @override\n */\n _mouseInit: function () {\n var result = this._superApply(arguments);\n\n this.element\n .off('mousedown.' + this.widgetName)\n .on('touchstart.' + this.widgetName, this._mouseDown);\n\n return result;\n },\n\n /**\n * Elements' 'mousedown' event handler polyfill.\n * @override\n */\n _mouseDown: function (event) {\n var prevDelegate = this._mouseMoveDelegate,\n result;\n\n event = this._touchToMouse(event);\n result = this._super(event);\n\n if (prevDelegate === this._mouseMoveDelegate) {\n return result;\n }\n\n $(document)\n .off('mousemove.' + this.widgetName)\n .off('mouseup.' + this.widgetName);\n\n $(document)\n .on('touchmove.' + this.widgetName, this._mouseMove)\n .on('touchend.' + this.widgetName, this._onTouchEnd)\n .on('tochleave.' + this.widgetName, this._onTouchEnd);\n\n return result;\n },\n\n /**\n * Documents' 'mousemove' event handler polyfill.\n *\n * @override\n * @param {Event} event - Touch event object.\n */\n _mouseMove: function (event) {\n event = this._touchToMouse(event);\n\n return this._super(event);\n },\n\n /**\n * Documents' 'touchend' event handler.\n */\n _onTouchEnd: function (event) {\n $(document).trigger('mouseup');\n\n return this._mouseUp(event);\n },\n\n /**\n * Removes previously assigned touch handlers.\n *\n * @override\n */\n _mouseUp: function () {\n this._removeTouchHandlers();\n\n return this._superApply(arguments);\n },\n\n /**\n * Removes previously assigned touch handlers.\n *\n * @override\n */\n _mouseDestroy: function () {\n this._removeTouchHandlers();\n\n return this._superApply(arguments);\n },\n\n /**\n * Removes touch events from document object.\n */\n _removeTouchHandlers: function () {\n $(document)\n .off('touchmove.' + this.widgetName)\n .off('touchend.' + this.widgetName)\n .off('touchleave.' + this.widgetName);\n },\n\n /**\n * Adds properties to the touch event to mimic mouse event.\n *\n * @param {Event} event - Touch event object.\n * @returns {Event}\n */\n _touchToMouse: function (event) {\n var orig = event.originalEvent,\n touch = orig.touches[0];\n\n return _.extend(event, {\n which: 1,\n pageX: touch.pageX,\n pageY: touch.pageY,\n clientX: touch.clientX,\n clientY: touch.clientY,\n screenX: touch.screenX,\n screenY: touch.screenY\n });\n }\n });\n\n return $.mage.touchSlider;\n});\n","mage/smart-keyboard-handler.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 * @return {Object}\n * @constructor\n */\n function KeyboardHandler() {\n var body = $('body'),\n focusState = false,\n tabFocusClass = '_keyfocus',\n productsGrid = '[data-container=\"product-grid\"]',\n catalogProductsGrid = $(productsGrid),\n CODE_TAB = 9;\n\n /**\n * Handle logic, when onTabKeyPress fired at first.\n * Then it changes state.\n */\n function onFocusInHandler() {\n focusState = true;\n body.addClass(tabFocusClass)\n .off('focusin.keyboardHandler', onFocusInHandler);\n }\n\n /**\n * Handle logic to remove state after onTabKeyPress to normal.\n */\n function onClickHandler() {\n focusState = false;\n body.removeClass(tabFocusClass)\n .off('click', onClickHandler);\n }\n\n /**\n * Tab key onKeypress handler. Apply main logic:\n * - call differ actions onTabKeyPress and onClick\n */\n function smartKeyboardFocus() {\n $(document).on('keydown keypress', function (event) {\n if (event.which === CODE_TAB && !focusState) {\n body\n .on('focusin.keyboardHandler', onFocusInHandler)\n .on('click', onClickHandler);\n }\n });\n\n // ARIA support for catalog grid products\n if (catalogProductsGrid.length) {\n body.on('focusin.gridProducts', productsGrid, function () {\n if (body.hasClass(tabFocusClass)) {\n $(this).addClass('active');\n }\n });\n body.on('focusout.gridProducts', productsGrid, function () {\n $(this).removeClass('active');\n });\n }\n }\n\n /**\n * Attach smart focus on specific element.\n * @param {jQuery} element\n */\n function handleFocus(element) {\n element.on('focusin.emulateTabFocus', function () {\n focusState = true;\n body.addClass(tabFocusClass);\n element.off();\n });\n\n element.on('focusout.emulateTabFocus', function () {\n focusState = false;\n body.removeClass(tabFocusClass);\n element.off();\n });\n }\n\n return {\n apply: smartKeyboardFocus,\n focus: handleFocus\n };\n }\n\n return new KeyboardHandler;\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/common.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'domReady!'\n], function ($) {\n 'use strict';\n\n /* Form with auto submit feature */\n $('form[data-auto-submit=\"true\"]').trigger('submit');\n\n //Add form keys.\n $(document).on(\n 'submit',\n 'form',\n function (e) {\n var formKeyElement,\n existingFormKeyElement,\n isKeyPresentInForm,\n isActionExternal,\n baseUrl = window.BASE_URL,\n form = $(e.target),\n formKey = $('input[name=\"form_key\"]').val(),\n formMethod = form.prop('method'),\n formAction = form.prop('action');\n\n isActionExternal = formAction.indexOf(baseUrl) !== 0;\n\n existingFormKeyElement = form.find('input[name=\"form_key\"]');\n isKeyPresentInForm = existingFormKeyElement.length;\n\n /* Verifies that existing auto-added form key is a direct form child element,\n protection from a case when one form contains another form. */\n if (isKeyPresentInForm && existingFormKeyElement.attr('auto-added-form-key') === '1') {\n isKeyPresentInForm = form.find('> input[name=\"form_key\"]').length;\n }\n\n if (formKey && !isKeyPresentInForm && !isActionExternal && formMethod !== 'get') {\n formKeyElement = document.createElement('input');\n formKeyElement.setAttribute('type', 'hidden');\n formKeyElement.setAttribute('name', 'form_key');\n formKeyElement.setAttribute('value', formKey);\n formKeyElement.setAttribute('auto-added-form-key', '1');\n form.get(0).appendChild(formKeyElement);\n }\n }\n );\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/storage.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['jquery', 'mage/url'], function ($, urlBuilder) {\n 'use strict';\n\n return {\n /**\n * Perform asynchronous GET request to server.\n * @param {String} url\n * @param {Boolean} global\n * @param {String} contentType\n * @param {Object} headers\n * @returns {Deferred}\n */\n get: function (url, global, contentType, headers) {\n headers = headers || {};\n global = global === undefined ? true : global;\n contentType = contentType || 'application/json';\n\n return $.ajax({\n url: urlBuilder.build(url),\n type: 'GET',\n global: global,\n contentType: contentType,\n headers: headers\n });\n },\n\n /**\n * Perform asynchronous POST request to server.\n * @param {String} url\n * @param {String} data\n * @param {Boolean} global\n * @param {String} contentType\n * @param {Object} headers\n * @param {Boolean} async\n * @returns {Deferred}\n */\n post: function (url, data, global, contentType, headers, async) {\n headers = headers || {};\n global = global === undefined ? true : global;\n contentType = contentType || 'application/json';\n async = async === undefined ? true : async;\n\n return $.ajax({\n url: urlBuilder.build(url),\n type: 'POST',\n data: data,\n global: global,\n contentType: contentType,\n headers: headers,\n async: async\n });\n },\n\n /**\n * Perform asynchronous PUT request to server.\n * @param {String} url\n * @param {String} data\n * @param {Boolean} global\n * @param {String} contentType\n * @param {Object} headers\n * @returns {Deferred}\n */\n put: function (url, data, global, contentType, headers) {\n var ajaxSettings = {};\n\n headers = headers || {};\n global = global === undefined ? true : global;\n contentType = contentType || 'application/json';\n ajaxSettings.url = urlBuilder.build(url);\n ajaxSettings.type = 'PUT';\n ajaxSettings.data = data;\n ajaxSettings.global = global;\n ajaxSettings.contentType = contentType;\n ajaxSettings.headers = headers;\n\n return $.ajax(ajaxSettings);\n },\n\n /**\n * Perform asynchronous DELETE request to server.\n * @param {String} url\n * @param {Boolean} global\n * @param {String} contentType\n * @param {Object} headers\n * @returns {Deferred}\n */\n delete: function (url, global, contentType, headers) {\n headers = headers || {};\n global = global === undefined ? true : global;\n contentType = contentType || 'application/json';\n\n return $.ajax({\n url: urlBuilder.build(url),\n type: 'DELETE',\n global: global,\n contentType: contentType,\n headers: headers\n });\n }\n };\n});\n","mage/item-table.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 */\ndefine([\n 'jquery',\n 'mage/template',\n 'jquery-ui-modules/widget'\n], function ($, mageTemplate) {\n 'use strict';\n\n $.widget('mage.itemTable', {\n options: {\n addBlock: '[data-template=\"add-block\"]',\n addBlockData: {},\n addEvent: 'click',\n addSelector: '[data-role=\"add\"]',\n itemsSelector: '[data-container=\"items\"]',\n keepLastRow: true\n },\n\n /**\n * This method adds a new instance of the block to the items.\n * @private\n */\n _add: function () {\n var hideShowDelete,\n deletableItems,\n addedBlock;\n\n // adding a new row, so increment the count to give each row a unique index\n this.rowIndex++;\n\n // make sure the block data has the rowIndex\n this.options.addBlockData.rowIndex = this.rowIndex;\n\n // render the form\n addedBlock = $(this.addBlockTmpl({\n data: this.options.addBlockData\n }));\n\n // add the row to the item block\n this.element.find(this.options.itemsSelector).append(addedBlock);\n\n // initialize all mage content\n addedBlock.trigger('contentUpdated');\n\n // determine all existing items in the collection\n deletableItems = this._getDeletableItems();\n\n // for the most part, show the delete mechanism, except in the case where there is only one it should not\n // be deleted\n hideShowDelete = 'showDelete';\n\n if (this.options.keepLastRow && deletableItems.length === 1) {\n hideShowDelete = 'hideDelete';\n }\n\n // loop through each control and perform that action on the deletable item\n $.each(deletableItems, function (index) {\n $(deletableItems[index]).trigger(hideShowDelete);\n });\n },\n\n /**\n * This method binds elements found in this widget.\n * @private\n */\n _bind: function () {\n var handlers = {};\n\n // since the first handler is dynamic, generate the object using array notation\n handlers[this.options.addEvent + ' ' + this.options.addSelector] = '_add';\n handlers.deleteItem = '_onDeleteItem';\n\n this._on(handlers);\n },\n\n /**\n * This method constructs a new widget.\n * @private\n */\n _create: function () {\n this._bind();\n\n this.addBlockTmpl = mageTemplate(this.options.addBlock);\n\n // nothing in the table, so indicate that\n this.rowIndex = -1;\n\n // make sure the block data is an object\n if (this.options.addBlockData == null || typeof this.options.addBlockData !== 'object') {\n // reset the block data to an empty object\n this.options.addBlockData = {};\n }\n\n // add the first row to the table\n this._add();\n },\n\n /**\n * This method returns the list of widgets associated with deletable items from the container (direct children\n * only).\n * @private\n */\n _getDeletableItems: function () {\n return this.element.find(this.options.itemsSelector + '> .deletableItem');\n },\n\n /**\n * This method removes the item associated with the message.\n * @private\n */\n _onDeleteItem: function (e) {\n var deletableItems;\n\n // parent elements don't need to see this event\n e.stopPropagation();\n\n // remove the deletable item\n $(e.target).remove();\n\n if (this.options.keepLastRow) {\n // determine if there is only one element remaining, in which case, disable the delete mechanism on it\n deletableItems = this._getDeletableItems();\n\n if (deletableItems.length === 1) {\n $(deletableItems[0]).trigger('hideDelete');\n }\n }\n }\n });\n\n return $.mage.itemTable;\n});\n","mage/menu.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'matchMedia',\n 'jquery-ui-modules/menu',\n 'mage/translate'\n], function ($, mediaCheck) {\n 'use strict';\n\n /**\n * Menu Widget - this widget is a wrapper for the jQuery UI Menu\n */\n $.widget('mage.menu', $.ui.menu, {\n options: {\n categoryLayoutClass: 'catalog-product-view',\n responsive: false,\n expanded: false,\n showDelay: 42,\n hideDelay: 300,\n delay: 0,\n mediaBreakpoint: '(max-width: 768px)'\n },\n\n /**\n * @private\n */\n _create: function () {\n var self = this;\n\n this.delay = this.options.delay;\n\n this._super();\n $(window).on('resize', function () {\n self.element.find('.submenu-reverse').removeClass('submenu-reverse');\n });\n },\n\n /**\n * @private\n */\n _init: function () {\n this._super();\n\n if (this.options.expanded === true) {\n this.isExpanded();\n }\n\n if (this.options.responsive === true) {\n mediaCheck({\n media: this.options.mediaBreakpoint,\n entry: $.proxy(function () {\n this._toggleMobileMode();\n }, this),\n exit: $.proxy(function () {\n this._toggleDesktopMode();\n }, this)\n });\n }\n\n this._assignControls()._listen();\n this._setActiveMenu();\n },\n\n /**\n * @return {Object}\n * @private\n */\n _assignControls: function () {\n this.controls = {\n toggleBtn: $('[data-action=\"toggle-nav\"]')\n };\n\n return this;\n },\n\n /**\n * @private\n */\n _listen: function () {\n var controls = this.controls,\n toggle = this.toggle;\n\n controls.toggleBtn.off('click');\n controls.toggleBtn.on('click', toggle.bind(this));\n },\n\n /**\n * Toggle.\n */\n toggle: function () {\n var html = $('html');\n\n if (html.hasClass('nav-open')) {\n html.removeClass('nav-open');\n setTimeout(function () {\n html.removeClass('nav-before-open');\n }, this.options.hideDelay);\n } else {\n html.addClass('nav-before-open');\n setTimeout(function () {\n html.addClass('nav-open');\n }, this.options.showDelay);\n }\n },\n\n /**\n * Tries to figure out the active category for current page and add appropriate classes:\n * - 'active' class for active category\n * - 'has-active' class for all parents of active category\n *\n * First, checks whether current URL is URL of category page,\n * otherwise tries to retrieve category URL in case of current URL is product view page URL\n * which has category tree path in it.\n *\n * @return void\n * @private\n */\n _setActiveMenu: function () {\n var currentUrl = window.location.href.split('?')[0];\n\n if (!this._setActiveMenuForCategory(currentUrl)) {\n this._setActiveMenuForProduct(currentUrl);\n }\n },\n\n /**\n * Looks for category with provided URL and adds 'active' CSS class to it if it was not set before.\n * If menu item has parent categories, sets 'has-active' class to all af them.\n *\n * @param {String} url - possible category URL\n * @returns {Boolean} - true if active category was founded by provided URL, otherwise return false\n * @private\n */\n _setActiveMenuForCategory: function (url) {\n var activeCategoryLink = this.element.find('a[href=\"' + url + '\"]'),\n classes,\n classNav;\n\n if (!activeCategoryLink || !activeCategoryLink.hasClass('ui-menu-item-wrapper')) {\n\n //category was not found by provided URL\n return false;\n } else if (!activeCategoryLink.parent().hasClass('active')) {\n activeCategoryLink.parent().addClass('active');\n classes = activeCategoryLink.parent().attr('class');\n classNav = classes.match(/(nav\\-)[0-9]+(\\-[0-9]+)+/gi);\n\n if (classNav) {\n this._setActiveParent(classNav[0]);\n }\n }\n\n return true;\n },\n\n /**\n * Sets 'has-active' CSS class to all parent categories which have part of provided class in childClassName\n *\n * @example\n * childClassName - 'nav-1-2-3'\n * CSS class 'has-active' will be added to categories have 'nav-1-2' and 'nav-1' classes\n *\n * @param {String} childClassName - Class name of active category <li> element\n * @return void\n * @private\n */\n _setActiveParent: function (childClassName) {\n var parentElement,\n parentClass = childClassName.substr(0, childClassName.lastIndexOf('-'));\n\n if (parentClass.lastIndexOf('-') !== -1) {\n parentElement = this.element.find('.' + parentClass);\n\n if (parentElement) {\n parentElement.addClass('has-active');\n }\n this._setActiveParent(parentClass);\n }\n },\n\n /**\n * Extracts the URL extension from the given URL.\n * It identifies the last segment of the URL after the last slash ('/') and returns the substring after the last dot ('.')\n * If there's no dot in the last segment, it returns an empty string.\n *\n * @param {String} url - The URL from which to extract the extension.\n * @return {String} The extracted URL extension or an empty string if no extension is found.\n * @private\n */\n _getUrlExtension: function (url) {\n var lastSegment = url.slice(url.lastIndexOf('/') + 1);\n return lastSegment.includes('.') ? lastSegment.slice(lastSegment.lastIndexOf('.')) : '';\n },\n\n /**\n * Determines if the current page is a product page.\n * It checks the catalog product view related class in the body tag of the document.\n *\n * @return {Boolean} True if the current page is a product page, false otherwise.\n * @private\n */\n _isProductPage: function () {\n return document.body.classList.contains(this.options.categoryLayoutClass);\n },\n\n /**\n * Sets the active state in the menu for a product page. Determines the category URL from either\n * the referrer URL or the current URL, using the URL extension to identify the category.\n * Sets the corresponding category as active in the menu if a valid category URL is found.\n * Clears the active state if no valid category URL is found or if it's not a product page.\n *\n * @param {String} currentUrl - The current page URL without parameters.\n * @return void\n * @private\n */\n _setActiveMenuForProduct: function (currentUrl) {\n var firstCategoryUrl = this.element.find('> li a').attr('href');\n\n if (!firstCategoryUrl) {\n this._clearActiveState();\n return;\n }\n\n var categoryUrlExtension = this._getUrlExtension(firstCategoryUrl);\n var categoryUrl;\n var isProductPage = this._isProductPage();\n\n if (isProductPage) {\n var currentHostname = window.location.hostname;\n\n if (document.referrer.includes(currentHostname) && document.referrer.endsWith(categoryUrlExtension)) {\n categoryUrl = document.referrer.split('?')[0];\n } else {\n categoryUrl = currentUrl.substring(0, currentUrl.lastIndexOf('/')) + categoryUrlExtension;\n }\n\n this._setActiveMenuForCategory(categoryUrl);\n } else {\n this._clearActiveState();\n }\n },\n\n /**\n * Clears the active state from all menu items within the navigation element.\n * It removes 'active' and 'has-active' classes from all list items (li elements),\n * which are used to indicate the currently selected or parent of a selected item.\n *\n * @return void\n * @private\n */\n _clearActiveState: function () {\n this.element.find('li').removeClass('active has-active');\n },\n\n /**\n * Add class for expanded option.\n */\n isExpanded: function () {\n var subMenus = this.element.find(this.options.menus),\n expandedMenus = subMenus.find(this.options.menus);\n\n expandedMenus.addClass('expanded');\n },\n\n /**\n * @param {jQuery.Event} event\n * @private\n */\n _activate: function (event) {\n window.location.href = this.active.find('> a').attr('href');\n this.collapseAll(event);\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 /* eslint-disable max-depth */\n /**\n * @param {String} value\n */\n function escape(value) {\n return value.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, '\\\\$&');\n }\n\n if (this.active.closest(this.options.menus).attr('aria-expanded') != 'true') { //eslint-disable-line eqeqeq\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 if (this.active && !this.active.is('.ui-state-disabled')) {\n this.expand(event);\n }\n break;\n\n case $.ui.keyCode.LEFT:\n this.previous(event);\n break;\n\n case $.ui.keyCode.RIGHT:\n this.next(event);\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 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) {\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 } else {\n switch (event.keyCode) {\n case $.ui.keyCode.DOWN:\n this.next(event);\n break;\n\n case $.ui.keyCode.UP:\n this.previous(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.LEFT:\n case $.ui.keyCode.ESCAPE:\n this.collapse(event);\n break;\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) {\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\n /* eslint-enable max-depth */\n if (preventDefault) {\n event.preventDefault();\n }\n },\n\n /**\n * @private\n */\n _toggleMobileMode: function () {\n var subMenus;\n\n $(this.element).off('mouseenter mouseleave');\n this._on({\n\n /**\n * @param {jQuery.Event} event\n */\n 'click .ui-menu-item:has(a)': function (event) {\n var target;\n\n event.preventDefault();\n target = $(event.target).closest('.ui-menu-item');\n target.get(0).scrollIntoView();\n\n // Open submenu on click\n if (target.has('.ui-menu').length) {\n this.expand(event);\n } else if (!this.element.is(':focus') &&\n $(this.document[0].activeElement).closest('.ui-menu').length\n ) {\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 if (!target.hasClass('level-top') || !target.has('.ui-menu').length) {\n window.location.href = target.find('> a').attr('href');\n }\n },\n\n /**\n * @param {jQuery.Event} event\n */\n 'click .ui-menu-item:has(.ui-state-active)': function (event) {\n this.collapseAll(event, true);\n }\n });\n\n subMenus = this.element.find('.level-top');\n $.each(subMenus, $.proxy(function (index, item) {\n var category = $(item).find('> a span').not('.ui-menu-icon').text(),\n categoryUrl = $(item).find('> a').attr('href'),\n menu = $(item).find('> .ui-menu');\n\n this.categoryLink = $('<a>')\n .attr('href', categoryUrl)\n .text($.mage.__('All %1').replace('%1', category));\n\n this.categoryParent = $('<li>')\n .addClass('ui-menu-item all-category')\n .html(this.categoryLink);\n\n if (menu.find('.all-category').length === 0) {\n menu.prepend(this.categoryParent);\n }\n\n }, this));\n },\n\n /**\n * @private\n */\n _toggleDesktopMode: function () {\n var categoryParent, html;\n\n $(this.element).off('click mousedown mouseenter mouseleave');\n this._on({\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 '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 {jQuer.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.select(event);\n\n // Only set the mouseHandled flag if the event will bubble, see #9469.\n if (!event.isPropagationStopped()) {\n this.mouseHandled = true;\n }\n\n // Open submenu on click\n if (target.has('.ui-menu').length) {\n this.expand(event);\n } else if (!this.element.is(':focus') &&\n $(this.document[0].activeElement).closest('.ui-menu').length\n ) {\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 submenu = this.options.menus,\n ulElement,\n ulElementWidth,\n width,\n targetPageX,\n rightBound;\n\n if (target.has(submenu)) {\n ulElement = target.find(submenu);\n ulElementWidth = ulElement.outerWidth(true);\n width = target.outerWidth() * 2;\n targetPageX = target.offset().left;\n rightBound = $(window).width();\n\n if (ulElementWidth + width + targetPageX > rightBound) {\n ulElement.addClass('submenu-reverse');\n }\n\n if (targetPageX - ulElementWidth < 0) {\n ulElement.removeClass('submenu-reverse');\n }\n }\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\n /**\n * @param {jQuery.Event} event\n */\n 'mouseleave': function (event) {\n this.collapseAll(event, true);\n },\n\n /**\n * Mouse leave.\n */\n 'mouseleave .ui-menu': 'collapseAll'\n });\n\n categoryParent = this.element.find('.all-category');\n html = $('html');\n\n categoryParent.remove();\n\n if (html.hasClass('nav-open')) {\n html.removeClass('nav-open');\n setTimeout(function () {\n html.removeClass('nav-before-open');\n }, this.options.hideDelay);\n }\n },\n\n /**\n * @param {*} handler\n * @param {Number} delay\n * @return {Number}\n * @private\n */\n _delay: function (handler, delay) {\n var instance = this,\n\n /**\n * @return {*}\n */\n handlerProxy = function () {\n return (typeof handler === 'string' ? instance[handler] : handler).apply(instance, arguments);\n };\n\n return setTimeout(handlerProxy, delay || 0);\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 if (newItem.closest('.ui-menu').is(':visible') &&\n newItem.closest('.ui-menu').has('.all-categories')\n ) {\n return;\n }\n\n // remove the active state class from the siblings\n this.active.siblings().children('.ui-state-active').removeClass('ui-state-active');\n\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 select: function (event) {\n var ui;\n\n this.active = this.active || $(event.target).closest('.ui-menu-item');\n\n if (this.active.is('.all-category')) {\n this.active = $(event.target).closest('.ui-menu-item');\n }\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 $.widget('mage.navigation', $.mage.menu, {\n options: {\n responsiveAction: 'wrap', //option for responsive handling\n maxItems: null, //option to set max number of menu items\n container: '#menu', //container to check against navigation length\n moreText: $.mage.__('more'),\n breakpoint: 768\n },\n\n /**\n * @private\n */\n _init: function () {\n var that, responsive;\n\n this._super();\n\n that = this;\n responsive = this.options.responsiveAction;\n\n this.element\n .addClass('ui-menu-responsive')\n .attr('responsive', 'main');\n\n this.setupMoreMenu();\n this.setMaxItems();\n\n //check responsive option\n if (responsive == 'onResize') { //eslint-disable-line eqeqeq\n $(window).on('resize', function () {\n if ($(window).width() > that.options.breakpoint) {\n that._responsive();\n $('[responsive=more]').show();\n } else {\n that.element.children().show();\n $('[responsive=more]').hide();\n }\n });\n } else if (responsive == 'onReload') { //eslint-disable-line eqeqeq\n this._responsive();\n }\n },\n\n /**\n * Setup more menu.\n */\n setupMoreMenu: function () {\n var moreListItems = this.element.children().clone(),\n moreLink = $('<a>' + this.options.moreText + '</a>');\n\n moreListItems.hide();\n\n moreLink.attr('href', '#');\n\n this.moreItemsList = $('<ul>')\n .append(moreListItems);\n\n this.moreListContainer = $('<li>')\n .append(moreLink)\n .append(this.moreItemsList);\n\n this.responsiveMenu = $('<ul>')\n .addClass('ui-menu-more')\n .attr('responsive', 'more')\n .append(this.moreListContainer)\n .menu({\n position: {\n my: 'right top',\n at: 'right bottom'\n }\n })\n .insertAfter(this.element);\n },\n\n /**\n * @private\n */\n _responsive: function () {\n var container = $(this.options.container),\n containerSize = container.width(),\n width = 0,\n items = this.element.children('li'),\n more = $('.ui-menu-more > li > ul > li a');\n\n items = items.map(function () {\n var item = {};\n\n item.item = $(this);\n item.itemSize = $(this).outerWidth();\n\n return item;\n });\n\n $.each(items, function (index) {\n var itemText = items[index].item\n .find('a:first')\n .text();\n\n width += parseInt(items[index].itemSize, null); //eslint-disable-line radix\n\n if (width < containerSize) {\n items[index].item.show();\n\n more.each(function () {\n var text = $(this).text();\n\n if (text === itemText) {\n $(this).parent().hide();\n }\n });\n } else if (width > containerSize) {\n items[index].item.hide();\n\n more.each(function () {\n var text = $(this).text();\n\n if (text === itemText) {\n $(this).parent().show();\n }\n });\n }\n });\n },\n\n /**\n * Set max items.\n */\n setMaxItems: function () {\n var items = this.element.children('li'),\n itemsCount = items.length,\n maxItems = this.options.maxItems,\n overflow = itemsCount - maxItems,\n overflowItems = items.slice(overflow);\n\n overflowItems.hide();\n\n overflowItems.each(function () {\n var itemText = $(this).find('a:first').text();\n\n $(this).hide();\n\n $('.ui-menu-more > li > ul > li a').each(function () {\n var text = $(this).text();\n\n if (text === itemText) {\n $(this).parent().show();\n }\n });\n });\n }\n });\n\n return {\n menu: $.mage.menu,\n navigation: $.mage.navigation\n };\n});\n","mage/translate-inline.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/utils/misc',\n 'mage/translate',\n 'jquery-ui-modules/dialog'\n], function ($, mageTemplate, miscUtils) {\n 'use strict';\n\n $.widget('mage.translateInline', $.ui.dialog, {\n options: {\n translateForm: {\n template: '#translate-form-template',\n data: {\n id: 'translate-inline-form',\n message: 'Please refresh the page to see your changes after submitting this form. ' +\n 'Note: browser cache refresh may be required'\n }\n },\n autoOpen: false,\n translateArea: null,\n modal: true,\n dialogClass: 'popup-window window-translate-inline',\n width: '75%',\n title: $.mage.__('Translate'),\n height: 470,\n position: {\n my: 'left top',\n at: 'center top',\n of: 'body'\n },\n buttons: [{\n text: $.mage.__('Submit'),\n 'class': 'action-primary',\n\n /**\n * Click\n */\n click: function () {\n $(this).translateInline('submit');\n }\n },\n {\n text: $.mage.__('Close'),\n 'class': 'action-close',\n\n /**\n * Click.\n */\n click: function () {\n $(this).translateInline('close');\n }\n }],\n\n /**\n * Open.\n */\n open: function () {\n var $uiDialog = $(this).closest('.ui-dialog'),\n topMargin = $uiDialog.children('.ui-dialog-titlebar').outerHeight() + 45;\n\n $uiDialog\n .addClass('ui-dialog-active')\n .css('margin-top', topMargin);\n },\n\n /**\n * Close.\n */\n close: function () {\n $(this).closest('.ui-dialog').removeClass('ui-dialog-active');\n }\n },\n\n /**\n * Translate Inline creation\n * @protected\n */\n _create: function () {\n var $translateArea = $(this.options.translateArea);\n\n if (!$translateArea.length) {\n $translateArea = $('body');\n }\n $translateArea.on('edit.editTrigger', $.proxy(this._onEdit, this));\n\n this.tmpl = mageTemplate(this.options.translateForm.template);\n\n this._super();\n },\n\n /**\n * @param {*} templateData\n * @return {*|jQuery|HTMLElement}\n * @private\n */\n _prepareContent: function (templateData) {\n var data = $.extend({\n items: templateData,\n escape: miscUtils.escape\n }, this.options.translateForm.data);\n\n this.data = data;\n\n return $(this.tmpl({\n data: data\n }));\n },\n\n /**\n * Render translation form and open dialog\n * @param {Object} e - object\n * @protected\n */\n _onEdit: function (e) {\n this.target = e.target;\n this.element.html(this._prepareContent($(e.target).data('translate')));\n this.open(e);\n },\n\n /**\n * Submit.\n */\n submit: function () {\n if (this.formIsSubmitted) {\n return;\n }\n this._formSubmit();\n },\n\n /**\n * Send ajax request on form submit\n * @protected\n */\n _formSubmit: function () {\n var parameters = $.param({\n area: this.options.area\n }) + '&' + $('#' + this.options.translateForm.data.id).serialize();\n\n this.formIsSubmitted = true;\n\n $.ajax({\n url: this.options.ajaxUrl,\n type: 'POST',\n data: parameters,\n loaderContext: this.element,\n showLoader: true\n }).always($.proxy(this._formSubmitComplete, this));\n },\n\n /**\n * @param {Object} response\n * @private\n */\n _formSubmitComplete: function (response) {\n var responseJSON = response.responseJSON || response;\n\n this.close();\n this.formIsSubmitted = false;\n $.mage.translate.add(responseJSON);\n this._updatePlaceholder(responseJSON[this.data.items[0].original]);\n },\n\n /**\n * @param {*} newValue\n * @private\n */\n _updatePlaceholder: function (newValue) {\n var $target = $(this.target),\n translateObject = $target.data('translate')[0];\n\n translateObject.shown = newValue;\n translateObject.translated = newValue;\n $.mage.translate.add(this.data.items[0].original, newValue);\n\n $target.html(newValue);\n },\n\n /**\n * Destroy translateInline\n */\n destroy: function () {\n this.element.off('.editTrigger');\n this._super();\n }\n });\n\n return $.mage.translateInline;\n});\n","mage/redirect-url.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.redirectUrl', {\n options: {\n event: 'click',\n url: undefined\n },\n\n /**\n * This method binds elements found in this widget.\n * @private\n */\n _bind: function () {\n var handlers = {};\n\n handlers[this.options.event] = '_onEvent';\n this._on(handlers);\n },\n\n /**\n * This method constructs a new widget.\n * @private\n */\n _create: function () {\n this._bind();\n },\n\n /**\n * This method set the url for the redirect.\n * @private\n */\n _onEvent: function () {\n if (this.options.url) {\n location.href = this.options.url;\n } else {\n location.href = this.element.val();\n }\n }\n });\n\n return $.mage.redirectUrl;\n});\n","mage/dataPost.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 'Magento_Ui/js/modal/confirm',\n 'jquery-ui-modules/widget'\n], function ($, mageTemplate, uiConfirm) {\n 'use strict';\n\n $.widget('mage.dataPost', {\n options: {\n formTemplate: '<form action=\"<%- data.action %>\" method=\"post\">' +\n '<% _.each(data.data, function(value, index) { %>' +\n '<input name=\"<%- index %>\" value=\"<%- value %>\">' +\n '<% }) %></form>',\n postTrigger: ['a[data-post]', 'button[data-post]', 'span[data-post]'],\n formKeyInputSelector: 'input[name=\"form_key\"]'\n },\n\n /** @inheritdoc */\n _create: function () {\n this._bind();\n },\n\n /** @inheritdoc */\n _bind: function () {\n var events = {};\n\n $.each(this.options.postTrigger, function (index, value) {\n events['click ' + value] = '_postDataAction';\n });\n\n this._on(events);\n },\n\n /**\n * Handler for click.\n *\n * @param {Object} e\n * @private\n */\n _postDataAction: function (e) {\n var params = $(e.currentTarget).data('post');\n\n e.preventDefault();\n this.postData(params);\n },\n\n /**\n * Data post action.\n *\n * @param {Object} params\n */\n postData: function (params) {\n var formKey = $(this.options.formKeyInputSelector).val(),\n $form, input;\n\n if (formKey) {\n params.data['form_key'] = formKey;\n }\n\n $form = $(mageTemplate(this.options.formTemplate, {\n data: params\n }));\n\n if (params.files) {\n $form[0].enctype = 'multipart/form-data';\n $.each(params.files, function (key, files) {\n if (files instanceof FileList) {\n input = document.createElement('input');\n input.type = 'file';\n input.name = key;\n input.files = files;\n $form[0].appendChild(input);\n }\n });\n }\n\n if (params.data.confirmation) {\n uiConfirm({\n content: params.data.confirmationMessage,\n actions: {\n /** @inheritdoc */\n confirm: function () {\n $form.appendTo('body').hide().trigger('submit');\n }\n }\n });\n } else {\n $form.appendTo('body').hide().trigger('submit');\n }\n }\n });\n\n $(document).dataPost();\n\n return $.mage.dataPost;\n});\n","mage/trim-input.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.trimInput', {\n options: {\n cache: {}\n },\n\n /**\n * Widget initialization\n * @private\n */\n _create: function () {\n this.options.cache.input = $(this.element);\n this._bind();\n },\n\n /**\n * Event binding, will monitor change, keyup and paste events.\n * @private\n */\n _bind: function () {\n if (this.options.cache.input.length) {\n this._on(this.options.cache.input, {\n 'change': this._trimInput,\n 'keyup': this._trimInput,\n 'paste': this._trimInput\n });\n }\n },\n\n /**\n * Trim value\n * @private\n */\n _trimInput: function () {\n // Safari caret position workaround: storing carter position\n var caretStart, caretEnd, input;\n\n caretStart = this.options.cache.input.get(0).selectionStart;\n caretEnd = this.options.cache.input.get(0).selectionEnd;\n\n input = this._getInputValue().trim();\n\n this.options.cache.input.val(input);\n\n // Safari caret position workaround: setting caret position to previously stored values\n if (caretStart !== null && caretEnd !== null) {\n this.options.cache.input.get(0).setSelectionRange(caretStart, caretEnd);\n }\n },\n\n /**\n * Get input value\n * @returns {*}\n * @private\n */\n _getInputValue: function () {\n return this.options.cache.input.val();\n }\n });\n\n return $.mage.trimInput;\n});\n","mage/collapsible.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/core',\n 'jquery/jquery-storageapi',\n 'mage/mage'\n], function ($) {\n 'use strict';\n\n var hideProps = {},\n showProps = {};\n\n hideProps.height = 'hide';\n showProps.height = 'show';\n\n $.widget('mage.collapsible', {\n options: {\n active: false,\n disabled: false,\n collapsible: true,\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 collateral: {\n element: null,\n openedState: null\n }\n },\n\n /**\n * @private\n */\n _create: function () {\n this.storage = $.localStorage;\n this.icons = false;\n\n if (typeof this.options.icons === 'string') {\n this.options.icons = JSON.parse(this.options.icons);\n }\n\n this._processPanels();\n this._processState();\n this._refresh();\n\n if (this.options.icons.header && this.options.icons.activeHeader) {\n this._createIcons();\n this.icons = true;\n }\n\n this.element.on('dimensionsChanged', function (e) {\n if (e.target && e.target.classList.contains('active')) {\n this._scrollToTopIfNotVisible();\n }\n }.bind(this));\n\n this._bind('click');\n this._trigger('created');\n },\n\n /**\n * @private\n */\n _refresh: function () {\n this.trigger.attr('tabIndex', 0);\n\n if (this.options.active && !this.options.disabled) {\n if (this.options.openedState) {\n this.element.addClass(this.options.openedState);\n }\n\n if (this.options.collateral.element && this.options.collateral.openedState) {\n $(this.options.collateral.element).addClass(this.options.collateral.openedState);\n }\n\n if (this.options.ajaxContent) {\n this._loadContent();\n }\n // ARIA (updates aria attributes)\n this.header.attr({\n 'aria-selected': false\n });\n } else if (this.options.disabled) {\n this.disable();\n } else {\n this.content.hide();\n\n if (this.options.closedState) {\n this.element.addClass(this.options.closedState);\n }\n }\n },\n\n /**\n * Processing the state:\n * If deep linking is used and the anchor is the id of the content or the content contains this id,\n * and the collapsible element is a nested one having collapsible parents, in order to see the content,\n * all the parents must be expanded.\n * @private\n */\n _processState: function () {\n var anchor = window.location.hash,\n isValid = $.mage.isValidSelector(anchor),\n urlPath = window.location.pathname.replace(/\\./g, ''),\n state;\n\n this.stateKey = encodeURIComponent(urlPath + this.element.attr('id'));\n\n if (isValid &&\n ($(this.content.find(anchor)).length > 0 || this.content.attr('id') === anchor.replace('#', ''))\n ) {\n this.element.parents('[data-collapsible=true]').collapsible('forceActivate');\n\n if (!this.options.disabled) {\n this.options.active = true;\n\n if (this.options.saveState) { //eslint-disable-line max-depth\n this.storage.set(this.stateKey, true);\n }\n }\n } else if (this.options.saveState && !this.options.disabled) {\n state = this.storage.get(this.stateKey);\n\n if (typeof state === 'undefined' || state === null) {\n this.storage.set(this.stateKey, this.options.active);\n } else if (state === true) {\n this.options.active = true;\n } else if (state === false) {\n this.options.active = false;\n }\n }\n },\n\n /**\n * @private\n */\n _createIcons: function () {\n var icons = this.options.icons;\n\n if (icons) {\n $('<span>')\n .addClass(icons.header)\n .attr('data-role', 'icons')\n .prependTo(this.header);\n\n if (this.options.active && !this.options.disabled) {\n this.header.children('[data-role=icons]')\n .removeClass(icons.header)\n .addClass(icons.activeHeader);\n }\n }\n },\n\n /**\n * @private\n */\n _destroyIcons: function () {\n this.header\n .children('[data-role=icons]')\n .remove();\n },\n\n /**\n * @private\n */\n _destroy: function () {\n var options = this.options;\n\n this.element.removeAttr('data-collapsible');\n\n this.trigger.removeAttr('tabIndex');\n\n if (options.openedState) {\n this.element.removeClass(options.openedState);\n }\n\n if (this.options.collateral.element && this.options.collateral.openedState) {\n $(this.options.collateral.element).removeClass(this.options.collateral.openedState);\n }\n\n if (options.closedState) {\n this.element.removeClass(options.closedState);\n }\n\n if (options.disabledState) {\n this.element.removeClass(options.disabledState);\n }\n\n if (this.icons) {\n this._destroyIcons();\n }\n },\n\n /**\n * @private\n */\n _processPanels: function () {\n var headers, triggers;\n\n this.element.attr('data-collapsible', 'true');\n\n if (typeof this.options.header === 'object') {\n this.header = this.options.header;\n } else {\n headers = this.element.find(this.options.header);\n\n if (headers.length > 0) {\n this.header = headers.eq(0);\n } else {\n this.header = this.element;\n }\n }\n\n if (typeof this.options.content === 'object') {\n this.content = this.options.content;\n } else {\n this.content = this.header.next(this.options.content).eq(0);\n }\n\n // ARIA (init aria attributes)\n if (this.header.attr('id')) {\n this.content.attr('aria-labelledby', this.header.attr('id'));\n }\n\n if (this.content.attr('id')) {\n this.header.attr('aria-controls', this.content.attr('id'));\n }\n\n this.header\n .attr({\n 'role': 'tab',\n 'aria-selected': this.options.active,\n 'aria-expanded': this.options.active\n });\n\n // For collapsible widget only (not tabs or accordion)\n if (this.header.parent().attr('role') !== 'presentation') {\n this.header\n .parent()\n .attr('role', 'tablist');\n }\n\n this.content.attr({\n 'role': 'tabpanel',\n 'aria-hidden': !this.options.active\n });\n\n if (typeof this.options.trigger === 'object') {\n this.trigger = this.options.trigger;\n } else {\n triggers = this.header.find(this.options.trigger);\n\n if (triggers.length > 0) {\n this.trigger = triggers.eq(0);\n } else {\n this.trigger = this.header;\n }\n }\n },\n\n /**\n * @param {jQuery.Event} event\n * @private\n */\n _keydown: function (event) {\n var keyCode;\n\n if (event.altKey || event.ctrlKey) {\n return;\n }\n\n keyCode = $.ui.keyCode;\n\n switch (event.keyCode) {\n case keyCode.SPACE:\n case keyCode.ENTER:\n this._eventHandler(event);\n break;\n }\n\n },\n\n /**\n * @param {jQuery.Event} event\n * @private\n */\n _bind: function (event) {\n var self = this;\n\n this.events = {\n keydown: '_keydown'\n };\n\n if (event) {\n $.each(event.split(' '), function (index, eventName) {\n self.events[eventName] = '_eventHandler';\n });\n }\n this._off(this.trigger);\n\n if (!this.options.disabled) {\n this._on(this.trigger, this.events);\n }\n },\n\n /**\n * Disable.\n */\n disable: function () {\n this.options.disabled = true;\n this._off(this.trigger);\n this.forceDeactivate();\n\n if (this.options.disabledState) {\n this.element.addClass(this.options.disabledState);\n }\n this.trigger.attr('tabIndex', -1);\n },\n\n /**\n * Enable.\n */\n enable: function () {\n this.options.disabled = false;\n this._on(this.trigger, this.events);\n this.forceActivate();\n\n if (this.options.disabledState) {\n this.element.removeClass(this.options.disabledState);\n }\n this.trigger.attr('tabIndex', 0);\n },\n\n /**\n * @param {jQuery.Event} event\n * @private\n */\n _eventHandler: function (event) {\n\n if (this.options.active && this.options.collapsible) {\n this.deactivate();\n } else {\n this.activate();\n\n }\n event.preventDefault();\n\n },\n\n /**\n * @param {*} prop\n * @private\n */\n _animate: function (prop) {\n var duration,\n easing,\n animate = this.options.animate;\n\n if (typeof animate === 'number') {\n duration = animate;\n }\n\n if (typeof animate === 'string') {\n animate = JSON.parse(animate);\n }\n duration = duration || animate.duration;\n easing = animate.easing;\n this.content.animate(prop, duration, easing);\n },\n\n /**\n * Deactivate.\n */\n deactivate: function () {\n if (this.options.animate) {\n this._animate(hideProps);\n } else {\n this.content.hide();\n }\n this._close();\n },\n\n /**\n * Force deactivate.\n */\n forceDeactivate: function () {\n this.content.hide();\n this._close();\n\n },\n\n /**\n * @private\n */\n _close: function () {\n this.options.active = false;\n\n if (this.options.saveState) {\n this.storage.set(this.stateKey, false);\n }\n\n if (this.options.openedState) {\n this.element.removeClass(this.options.openedState);\n }\n\n if (this.options.collateral.element && this.options.collateral.openedState) {\n $(this.options.collateral.element).removeClass(this.options.collateral.openedState);\n }\n\n if (this.options.closedState) {\n this.element.addClass(this.options.closedState);\n }\n\n if (this.icons) {\n this.header.children('[data-role=icons]')\n .removeClass(this.options.icons.activeHeader)\n .addClass(this.options.icons.header);\n }\n\n // ARIA (updates aria attributes)\n this.header.attr({\n 'aria-selected': 'false',\n 'aria-expanded': 'false'\n });\n this.content.attr({\n 'aria-hidden': 'true'\n });\n\n this.element.trigger('dimensionsChanged', {\n opened: false\n });\n },\n\n /**\n * Activate.\n *\n * @return void;\n */\n activate: function () {\n if (this.options.disabled) {\n return;\n }\n\n if (this.options.animate) {\n this._animate(showProps);\n } else {\n this.content.show();\n }\n this._open();\n },\n\n /**\n * Force activate.\n */\n forceActivate: function () {\n if (!this.options.disabled) {\n this.content.show();\n this._open();\n }\n },\n\n /**\n * @private\n */\n _open: function () {\n this.element.trigger('beforeOpen');\n this.options.active = true;\n\n if (this.options.ajaxContent) {\n this._loadContent();\n }\n\n if (this.options.saveState) {\n this.storage.set(this.stateKey, true);\n }\n\n if (this.options.openedState) {\n this.element.addClass(this.options.openedState);\n }\n\n if (this.options.collateral.element && this.options.collateral.openedState) {\n $(this.options.collateral.element).addClass(this.options.collateral.openedState);\n }\n\n if (this.options.closedState) {\n this.element.removeClass(this.options.closedState);\n }\n\n if (this.icons) {\n this.header.children('[data-role=icons]')\n .removeClass(this.options.icons.header)\n .addClass(this.options.icons.activeHeader);\n }\n\n // ARIA (updates aria attributes)\n this.header.attr({\n 'aria-selected': 'true',\n 'aria-expanded': 'true'\n });\n this.content.attr({\n 'aria-hidden': 'false'\n });\n\n this.element.trigger('dimensionsChanged', {\n opened: true\n });\n },\n\n /**\n * @private\n */\n _loadContent: function () {\n var url = this.element.find(this.options.ajaxUrlElement).attr('href'),\n that = this;\n\n if (url) {\n that.xhr = $.get({\n url: url,\n dataType: 'html'\n }, function () {\n });\n }\n\n if (that.xhr && that.xhr.statusText !== 'canceled') {\n if (that.options.loadingClass) {\n that.element.addClass(that.options.loadingClass);\n }\n that.content.attr('aria-busy', 'true');\n that.xhr.done(function (response) {\n setTimeout(function () {\n that.content.html(response);\n }, 1);\n });\n that.xhr.always(function (jqXHR, status) {\n setTimeout(function () {\n if (status === 'abort') {\n that.content.stop(false, true);\n }\n\n if (that.options.loadingClass) {\n that.element.removeClass(that.options.loadingClass);\n }\n that.content.removeAttr('aria-busy');\n\n if (jqXHR === that.xhr) {\n delete that.xhr;\n }\n }, 1);\n });\n }\n },\n\n /**\n * @private\n */\n _scrollToTopIfNotVisible: function () {\n if (this._isElementOutOfViewport()) {\n this.header[0].scrollIntoView();\n }\n },\n\n /**\n * @private\n * @return {Boolean}\n */\n _isElementOutOfViewport: function () {\n var headerRect = this.header[0].getBoundingClientRect(),\n contentRect = this.content.get().length ? this.content[0].getBoundingClientRect() : false,\n headerOut,\n contentOut;\n\n headerOut = headerRect.bottom - headerRect.height < 0 ||\n headerRect.right - headerRect.width < 0 ||\n headerRect.left + headerRect.width > window.innerWidth ||\n headerRect.top + headerRect.height > window.innerHeight;\n\n contentOut = contentRect ? contentRect.bottom - contentRect.height < 0 ||\n contentRect.right - contentRect.width < 0 ||\n contentRect.left + contentRect.width > window.innerWidth ||\n contentRect.top + contentRect.height > window.innerHeight : false;\n\n return headerOut ? headerOut : contentOut;\n }\n });\n\n return $.mage.collapsible;\n});\n","mage/terms.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 */\ndefine([\n 'jquery'\n], function ($) {\n 'use strict';\n\n /**\n * @param {*} args\n */\n $.fn.terms = function (args) {\n\n // default\n var defaults = {\n start: 0,\n wrapper: '',\n showAnchor: '',\n effects: 'slide'\n },\n options = $.extend(defaults, args);\n\n this.each(function () {\n var obj = $(this),\n wrapper = options.wrapper !== '' ? '> ' + options.wrapper : '',\n switches = $(wrapper + '> [data-section=\"title\"] > [data-toggle=\"switch\"]', obj),\n terms = $(wrapper + '> [data-section=\"content\"]', obj),\n t = switches.length,\n marginTop = $(switches[0]).closest('[data-section=\"title\"]').css('position') == 'absolute' ? 0 : null, //eslint-disable-line\n title,\n current,\n\n /**\n * @param {*} item\n */\n showItem = function (item) {\n if (item != current && !$(switches[item]).closest('[data-section=\"title\"]').hasClass('disabled')) { //eslint-disable-line\n $(switches).closest('[data-section=\"title\"]').removeClass('active');\n\n if (options.wrapper !== '') {\n $(switches).parent().parent().removeClass('active');\n }\n $(terms).removeClass('active');\n $(switches[item]).closest('[data-section=\"title\"]').addClass('active');\n\n if (options.wrapper !== '') {\n $(switches[current]).parent().parent().addClass('active');\n }\n $(terms[item]).addClass('active');\n current = item;\n } else if (\n // Check if this is accordion width as criteria for now\n (obj.attr('data-sections') == 'accordion' || $(switches[item]).closest('[data-section=\"title\"]').css('width') == obj.css('width')) && //eslint-disable-line\n item == current && !$(switches[item]).closest('[data-section=\"title\"]').hasClass('disabled') //eslint-disable-line\n ) {\n $(switches).closest('[data-section=\"title\"]').removeClass('active');\n\n if (options.wrapper !== '') {\n $(switches).parent().parent().removeClass('active');\n }\n $(terms).removeClass('active');\n current = -1;\n }\n },\n\n /**\n * Init.\n */\n init = function () {\n var linksList, i, classes, dataSection, itemHref, itemClass, fromUrl;\n\n if (t > 0) {\n if ($(switches[0]).closest('[data-section=\"title\"]').css('display') == 'table-cell') { //eslint-disable-line\n obj.addClass('adjusted');\n\n if (obj[0].tagName == 'DL') { //eslint-disable-line eqeqeq, max-depth\n linksList = $('<dd>');\n } else {\n linksList = $('<div>');\n }\n linksList.addClass('sections-nav');\n obj.prepend(linksList);\n\n for (i = 0; i < t; i++) { //eslint-disable-line max-depth\n title = $(switches[i]).html();\n classes = $(switches[i]).closest('[data-section=\"title\"]').attr('class');\n dataSection = $(switches[i]).closest('[data-section=\"title\"]').attr('data-section');\n itemHref = $(switches[i]).attr('href');\n itemClass = $(switches[i]).attr('class');\n $(switches[i]).parent('[data-section=\"title\"]').hide();\n switches[i] = $('<a/>', {\n href: itemHref,\n 'class': itemClass,\n html: title\n }).appendTo(linksList);\n $(switches[i]).wrap(\n '<strong class=\"' + classes + '\" data-section=\"' + dataSection + '\" />'\n );\n }\n }\n $(switches).each(function (ind, el) {\n $(el).on('click', function (event) {\n event.preventDefault();\n showItem(ind);\n });\n\n if (marginTop !== null) {\n $(el).closest('[data-section=\"title\"]').css({\n 'top': marginTop + 'px'\n });\n marginTop += $(el).closest('[data-section=\"title\"]').outerHeight(true);\n obj.css({\n 'min-height': marginTop + 'px'\n });\n }\n });\n\n fromUrl = false;\n\n if (window.location.hash.length > 0) {\n $(terms).each(function (ind, el) {\n if ('#info-' + $(el).attr('id') == window.location.hash) { //eslint-disable-line eqeqeq\n showItem(ind);\n $('html, body').animate({\n scrollTop: $(switches[ind]).offset().top\n }, 700);\n fromUrl = true;\n }\n });\n }\n\n if (fromUrl === false) {\n if (options.start % 1 === 0) { //eslint-disable-line max-depth\n current = options.start + 1;\n showItem(options.start);\n } else {\n $(terms).each(function (ind, el) {\n if ($(el).attr('id') == options.start) { //eslint-disable-line eqeqeq\n current = ind + 1;\n showItem(ind);\n $('html, body').animate({\n scrollTop: $(switches[ind]).offset().top\n }, 700);\n }\n });\n }\n }\n }\n };\n\n init();\n });\n };\n\n return function (data, el) {\n $(el).terms(data);\n };\n});\n","mage/loader.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 options: {\n icon: '',\n texts: {\n loaderText: $.mage.__('Please wait...'),\n imgAlt: $.mage.__('Loading...')\n },\n template:\n '<div class=\"loading-mask\" data-role=\"loader\">' +\n '<div class=\"loader\">' +\n '<img alt=\"<%- data.texts.imgAlt %>\" src=\"<%- data.icon %>\">' +\n '<p><%- data.texts.loaderText %></p>' +\n '</div>' +\n '</div>'\n\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 {EventObject} 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 html;\n\n if (!this.spinnerTemplate) {\n this.spinnerTemplate = mageTemplate(this.options.template);\n\n html = $(this.spinnerTemplate({\n data: this.options\n }));\n\n html.prependTo(this.element);\n\n this.spinner = html;\n }\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 loadingClass: 'ajax-loading'\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 $(this.options.defaultContainer)\n .addClass(this.options.loadingClass)\n .attr({\n 'aria-busy': true\n });\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 $(this.options.defaultContainer)\n .removeClass(this.options.loadingClass)\n .attr('aria-busy', false);\n\n if (settings && settings.showLoader) {\n this._getJqueryObj(settings.loaderContext).trigger('processStop');\n }\n }\n\n });\n\n return {\n loader: $.mage.loader,\n loaderAjax: $.mage.loaderAjax\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/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/gallery/gallery.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'fotorama/fotorama',\n 'underscore',\n 'matchMedia',\n 'mage/template',\n 'text!mage/gallery/gallery.html',\n 'uiClass',\n 'mage/translate'\n], function ($, fotorama, _, mediaCheck, template, galleryTpl, Class, $t) {\n 'use strict';\n\n /**\n * Retrieves index if the main item.\n * @param {Array.<Object>} data - Set of gallery items.\n */\n var getMainImageIndex = function (data) {\n var mainIndex;\n\n if (_.every(data, function (item) {\n return _.isObject(item);\n })\n ) {\n mainIndex = _.findIndex(data, function (item) {\n return item.isMain;\n });\n }\n\n return mainIndex > 0 ? mainIndex : 0;\n },\n\n /**\n * Helper for parse translate property\n *\n * @param {Element} el - el that to parse\n * @returns {Array} - array of properties.\n */\n getTranslate = function (el) {\n var slideTransform = $(el).attr('style').split(';');\n\n slideTransform = $.map(slideTransform, function (style) {\n style = style.trim();\n\n if (style.startsWith('transform: translate3d')) {\n return style.match(/transform: translate3d\\((.+)px,(.+)px,(.+)px\\)/);\n }\n\n return false;\n });\n\n return slideTransform.filter(Boolean);\n },\n\n /**\n * @param {*} str\n * @return {*}\n * @private\n */\n _toNumber = function (str) {\n var type = typeof str;\n\n if (type === 'string') {\n return parseInt(str); //eslint-disable-line radix\n }\n\n return str;\n };\n\n return Class.extend({\n\n defaults: {\n settings: {},\n config: {},\n startConfig: {}\n },\n\n /**\n * Checks if device has touch interface.\n * @return {Boolean} The result of searching touch events on device.\n */\n isTouchEnabled: (function () {\n return 'ontouchstart' in document.documentElement;\n })(),\n\n /**\n * Initializes gallery.\n * @param {Object} config - Gallery configuration.\n * @param {String} element - String selector of gallery DOM element.\n */\n initialize: function (config, element) {\n var self = this;\n\n this._super();\n\n _.bindAll(this,\n '_focusSwitcher'\n );\n\n /*turn off arrows for touch devices*/\n if (this.isTouchEnabled) {\n config.options.arrows = false;\n\n if (config.fullscreen) {\n config.fullscreen.arrows = false;\n }\n }\n\n config.options.width = _toNumber(config.options.width);\n config.options.height = _toNumber(config.options.height);\n config.options.thumbwidth = _toNumber(config.options.thumbwidth);\n config.options.thumbheight = _toNumber(config.options.thumbheight);\n\n config.options.whiteBorders = _toNumber(config.options.whiteBorders);\n\n config.options.swipe = true;\n this.config = config;\n\n this.settings = {\n $element: $(element),\n $pageWrapper: $('.page-wrapper'),\n currentConfig: config,\n defaultConfig: _.clone(config),\n fullscreenConfig: _.clone(config.fullscreen),\n breakpoints: config.breakpoints,\n activeBreakpoint: {},\n fotoramaApi: null,\n isFullscreen: false,\n api: null,\n data: _.clone(config.data)\n };\n config.options.ratio = config.options.width / config.options.height;\n config.options.height = null;\n if (!config.options.whiteBorders) {\n config.options.height = $(element).height();\n }\n\n $.extend(true, this.startConfig, config);\n\n this.initGallery();\n this.initApi();\n this.setupBreakpoints();\n this.initFullscreenSettings();\n\n this.settings.$element.on('click', '.fotorama__stage__frame', function () {\n if (\n !$(this).parents('.fotorama__shadows--left, .fotorama__shadows--right').length &&\n !$(this).hasClass('fotorama-video-container')\n ) {\n self.openFullScreen();\n }\n });\n\n if (this.isTouchEnabled && this.settings.isFullscreen) {\n this.settings.$element.on('tap', '.fotorama__stage__frame', function () {\n var translate = getTranslate($(this).parents('.fotorama__stage__shaft'));\n\n if (translate[1] === '0' && !$(this).hasClass('fotorama-video-container')) {\n self.openFullScreen();\n self.settings.$pageWrapper.hide();\n }\n });\n }\n },\n\n /**\n * Open gallery fullscreen\n */\n openFullScreen: function () {\n this.settings.api.fotorama.requestFullScreen();\n this.settings.$fullscreenIcon.css({\n opacity: 1,\n visibility: 'visible',\n display: 'block'\n });\n },\n\n /**\n * Gallery fullscreen settings.\n */\n initFullscreenSettings: function () {\n var settings = this.settings,\n self = this;\n\n settings.$gallery = this.settings.$element.find('[data-gallery-role=\"gallery\"]');\n settings.$fullscreenIcon = this.settings.$element.find('[data-gallery-role=\"fotorama__fullscreen-icon\"]');\n settings.focusableStart = this.settings.$element.find('[data-gallery-role=\"fotorama__focusable-start\"]');\n settings.focusableEnd = this.settings.$element.find('[data-gallery-role=\"fotorama__focusable-end\"]');\n settings.closeIcon = this.settings.$element.find('[data-gallery-role=\"fotorama__fullscreen-icon\"]');\n settings.fullscreenConfig.swipe = true;\n\n settings.$gallery.on('fotorama:fullscreenenter', function () {\n settings.closeIcon.show();\n settings.focusableStart.attr('tabindex', '0');\n settings.focusableEnd.attr('tabindex', '0');\n settings.focusableStart.on('focusin', self._focusSwitcher);\n settings.focusableEnd.on('focusin', self._focusSwitcher);\n settings.api.updateOptions(settings.defaultConfig.options, true);\n settings.api.updateOptions(settings.fullscreenConfig, true);\n\n if (!_.isEqual(settings.activeBreakpoint, {}) && settings.breakpoints) {\n settings.api.updateOptions(settings.activeBreakpoint.options, true);\n }\n settings.isFullscreen = true;\n });\n\n settings.$gallery.on('fotorama:fullscreenexit', function () {\n settings.closeIcon.hide();\n settings.focusableStart.attr('tabindex', '-1');\n settings.focusableEnd.attr('tabindex', '-1');\n settings.api.updateOptions(settings.defaultConfig.options, true);\n settings.focusableStart.off('focusin', this._focusSwitcher);\n settings.focusableEnd.off('focusin', this._focusSwitcher);\n settings.closeIcon.hide();\n\n if (!_.isEqual(settings.activeBreakpoint, {}) && settings.breakpoints) {\n settings.api.updateOptions(settings.activeBreakpoint.options, true);\n }\n settings.isFullscreen = false;\n settings.$element.data('gallery').updateOptions({\n swipe: true\n });\n });\n },\n\n /**\n * Switcher focus.\n */\n _focusSwitcher: function (e) {\n var target = $(e.target),\n settings = this.settings;\n\n if (target.is(settings.focusableStart)) {\n this._setFocus('start');\n } else if (target.is(settings.focusableEnd)) {\n this._setFocus('end');\n }\n },\n\n /**\n * Set focus to element.\n * @param {String} position - can be \"start\" and \"end\"\n * positions.\n * If position is \"end\" - sets focus to first\n * focusable element in modal window scope.\n * If position is \"start\" - sets focus to last\n * focusable element in modal window scope\n */\n _setFocus: function (position) {\n var settings = this.settings,\n focusableElements,\n infelicity;\n\n if (position === 'end') {\n settings.$gallery.find(settings.closeIcon).trigger('focus');\n } else if (position === 'start') {\n infelicity = 3; //Constant for find last focusable element\n focusableElements = settings.$gallery.find(':focusable');\n focusableElements.eq(focusableElements.length - infelicity).trigger('focus');\n }\n },\n\n /**\n * Initializes gallery with configuration options.\n */\n initGallery: function () {\n var breakpoints = {},\n settings = this.settings,\n config = this.config,\n tpl = template(galleryTpl, {\n next: $t('Next'),\n previous: $t('Previous')\n }),\n mainImageIndex,\n $element = settings.$element,\n $fotoramaElement;\n\n if (settings.breakpoints) {\n _.each(_.values(settings.breakpoints), function (breakpoint) {\n var conditions;\n\n _.each(_.pairs(breakpoint.conditions), function (pair) {\n conditions = conditions ? conditions + ' and (' + pair[0] + ': ' + pair[1] + ')' :\n '(' + pair[0] + ': ' + pair[1] + ')';\n });\n breakpoints[conditions] = breakpoint.options;\n });\n settings.breakpoints = breakpoints;\n }\n\n _.extend(config, config.options,\n {\n options: undefined,\n click: false,\n breakpoints: null\n }\n );\n settings.currentConfig = config;\n\n $element\n .css('min-height', settings.$element.height())\n .append(tpl);\n\n $fotoramaElement = $element.find('[data-gallery-role=\"gallery\"]');\n\n $fotoramaElement.fotorama(config);\n $fotoramaElement.find('.fotorama__stage__frame.fotorama__active')\n .one('f:load', function () {\n $element\n .removeClass('_block-content-loading')\n .css('min-height', '');\n });\n settings.$elementF = $fotoramaElement;\n settings.fotoramaApi = $fotoramaElement.data('fotorama');\n\n $.extend(true, config, this.startConfig);\n\n mainImageIndex = getMainImageIndex(config.data);\n\n if (mainImageIndex) {\n this.settings.fotoramaApi.show({\n index: mainImageIndex,\n time: 0\n });\n }\n },\n\n /**\n * Creates breakpoints for gallery.\n */\n setupBreakpoints: function () {\n var pairs,\n settings = this.settings,\n config = this.config,\n startConfig = this.startConfig,\n isInitialized = {},\n isTouchEnabled = this.isTouchEnabled;\n\n if (_.isObject(settings.breakpoints)) {\n pairs = _.pairs(settings.breakpoints);\n _.each(pairs, function (pair) {\n var mediaQuery = pair[0];\n\n isInitialized[mediaQuery] = false;\n mediaCheck({\n media: mediaQuery,\n\n /**\n * Is triggered when breakpoint enties.\n */\n entry: function () {\n $.extend(true, config, _.clone(startConfig));\n\n settings.api.updateOptions(settings.defaultConfig.options, true);\n\n if (settings.isFullscreen) {\n settings.api.updateOptions(settings.fullscreenConfig, true);\n }\n\n if (isTouchEnabled) {\n settings.breakpoints[mediaQuery].options.arrows = false;\n\n if (settings.breakpoints[mediaQuery].options.fullscreen) {\n settings.breakpoints[mediaQuery].options.fullscreen.arrows = false;\n }\n }\n\n settings.api.updateOptions(settings.breakpoints[mediaQuery].options, true);\n $.extend(true, config, settings.breakpoints[mediaQuery]);\n settings.activeBreakpoint = settings.breakpoints[mediaQuery];\n\n isInitialized[mediaQuery] = true;\n },\n\n /**\n * Is triggered when breakpoint exits.\n */\n exit: function () {\n if (isInitialized[mediaQuery]) {\n $.extend(true, config, _.clone(startConfig));\n settings.api.updateOptions(settings.defaultConfig.options, true);\n\n if (settings.isFullscreen) {\n settings.api.updateOptions(settings.fullscreenConfig, true);\n }\n settings.activeBreakpoint = {};\n } else {\n isInitialized[mediaQuery] = true;\n }\n }\n });\n });\n }\n },\n\n /**\n * Creates gallery's API.\n */\n initApi: function () {\n var settings = this.settings,\n config = this.config,\n api = {\n\n /**\n * Contains fotorama's API methods.\n */\n fotorama: settings.fotoramaApi,\n\n /**\n * Displays the last image on preview.\n */\n last: function () {\n settings.fotoramaApi.show('>>');\n },\n\n /**\n * Displays the first image on preview.\n */\n first: function () {\n settings.fotoramaApi.show('<<');\n },\n\n /**\n * Displays previous element on preview.\n */\n prev: function () {\n settings.fotoramaApi.show('<');\n },\n\n /**\n * Displays next element on preview.\n */\n next: function () {\n settings.fotoramaApi.show('>');\n },\n\n /**\n * Displays image with appropriate count number on preview.\n * @param {Number} index - Number of image that should be displayed.\n */\n seek: function (index) {\n if (_.isNumber(index) && index !== 0) {\n\n if (index > 0) {\n index -= 1;\n }\n settings.fotoramaApi.show(index);\n }\n },\n\n /**\n * Updates gallery with new set of options.\n * @param {Object} configuration - Standart gallery configuration object.\n * @param {Boolean} isInternal - Is this function called via breakpoints.\n */\n updateOptions: function (configuration, isInternal) {\n\n var $selectable = $('a[href], area[href], input, select, ' +\n 'textarea, button, iframe, object, embed, *[tabindex], *[contenteditable]')\n .not('[tabindex=-1], [disabled], :hidden'),\n $focus = $(':focus'),\n index;\n\n if (_.isObject(configuration)) {\n\n //Saves index of focus\n $selectable.each(function (number) {\n if ($(this).is($focus)) {\n index = number;\n }\n });\n\n if (this.isTouchEnabled) {\n configuration.arrows = false;\n }\n configuration.click = false;\n configuration.breakpoints = null;\n\n if (!isInternal) {\n !_.isEqual(settings.activeBreakpoint, {} && settings.breakpoints) ?\n $.extend(true, settings.activeBreakpoint.options, configuration) :\n\n settings.isFullscreen ?\n $.extend(true, settings.fullscreenConfig, configuration) :\n $.extend(true, settings.defaultConfig.options, configuration);\n\n }\n $.extend(true, settings.currentConfig.options, configuration);\n settings.fotoramaApi.setOptions(settings.currentConfig.options);\n\n if (_.isNumber(index)) {\n $selectable.eq(index).trigger('focus');\n }\n }\n },\n\n /**\n * Updates gallery with specific set of items.\n * @param {Array.<Object>} data - Set of gallery items to update.\n */\n updateData: function (data) {\n var mainImageIndex;\n\n if (_.isArray(data)) {\n settings.fotoramaApi.load(data);\n mainImageIndex = getMainImageIndex(data);\n\n if (settings.fotoramaApi.activeIndex !== mainImageIndex) {\n settings.fotoramaApi.show({\n index: mainImageIndex,\n time: 0\n });\n }\n\n $.extend(false, settings, {\n data: data,\n defaultConfig: data\n });\n $.extend(false, config, {\n data: data\n });\n }\n },\n\n /**\n * Returns current images list\n *\n * @returns {Array}\n */\n returnCurrentImages: function () {\n var images = [];\n\n _.each(this.fotorama.data, function (item) {\n images.push(_.omit(item, '$navThumbFrame', '$navDotFrame', '$stageFrame', 'labelledby'));\n });\n\n return images;\n },\n\n /**\n * Updates gallery data partially by index\n * @param {Number} index - Index of image in data array to be updated.\n * @param {Object} item - Standart gallery image object.\n *\n */\n updateDataByIndex: function (index, item) {\n settings.fotoramaApi.spliceByIndex(index, item);\n }\n };\n\n settings.$element.data('gallery', api);\n settings.api = settings.$element.data('gallery');\n settings.$element.trigger('gallery:loaded');\n }\n });\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","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/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/validation/validation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'mage/validation',\n 'mage/translate'\n], function ($) {\n 'use strict';\n\n $.each({\n 'validate-grouped-qty': [\n function (value, element, params) {\n var result = false,\n total = 0;\n\n $(params).find('input[data-validate*=\"validate-grouped-qty\"]').each(function (i, e) {\n var val = $(e).val(),\n valInt;\n\n if (val && val.length > 0) {\n result = true;\n valInt = parseFloat(val) || 0;\n\n if (valInt >= 0) {\n total += valInt;\n } else {\n result = false;\n\n return result;\n }\n }\n });\n\n return result && total > 0;\n },\n $.mage.__('Please specify the quantity of product(s).')\n ],\n 'validate-one-checkbox-required-by-name': [\n function (value, element, params) {\n var checkedCount = 0,\n container;\n\n if (element.type === 'checkbox') {\n $('[name=\"' + element.name + '\"]').each(\n function () {\n if ($(this).is(':checked')) {\n checkedCount += 1;\n\n return false;\n }\n }\n );\n }\n container = '#' + params;\n\n if (checkedCount > 0) {\n $(container).removeClass('validation-failed');\n $(container).addClass('validation-passed');\n\n return true;\n }\n $(container).addClass('validation-failed');\n $(container).removeClass('validation-passed');\n\n return false;\n },\n $.mage.__('Please select one of the options.')\n ],\n 'validate-date-between': [\n function (value, element, params) {\n var minDate = new Date(params[0]),\n maxDate = new Date(params[1]),\n inputDate = new Date(element.value),\n message;\n\n minDate.setHours(0);\n maxDate.setHours(0);\n\n if (inputDate >= minDate && inputDate <= maxDate) {\n return true;\n }\n message = $.mage.__('Please enter a date between %min and %max.');\n this.dateBetweenErrorMessage = message.replace('%min', minDate).replace('%max', maxDate);\n\n return false;\n },\n function () {\n return this.dateBetweenErrorMessage;\n }\n ],\n 'validate-dob': [\n function (val, element, params) {\n var dob = $(element).parents('.customer-dob'),\n dayVal, monthVal, yearVal, dobLength, day, month, year, curYear,\n validYearMessage, validateDayInMonth, validDateMessage, today, dateEntered;\n\n $(dob).find('.' + this.settings.errorClass).removeClass(this.settings.errorClass);\n dayVal = $(dob).find(params[0]).find('input:text').val();\n monthVal = $(dob).find(params[1]).find('input:text').val();\n yearVal = $(dob).find(params[2]).find('input:text').val();\n dobLength = dayVal.length + monthVal.length + yearVal.length;\n\n if (params[3] && dobLength === 0) {\n this.dobErrorMessage = $.mage.__('This is a required field.');\n\n return false;\n }\n\n if (!params[3] && dobLength === 0) {\n return true;\n }\n day = parseInt(dayVal, 10) || 0;\n month = parseInt(monthVal, 10) || 0;\n year = parseInt(yearVal, 10) || 0;\n curYear = new Date().getFullYear();\n\n if (!day || !month || !year) {\n this.dobErrorMessage = $.mage.__('Please enter a valid full date.');\n\n return false;\n }\n\n if (month < 1 || month > 12) {\n this.dobErrorMessage = $.mage.__('Please enter a valid month (1-12).');\n\n return false;\n }\n\n if (year < 1900 || year > curYear) {\n validYearMessage = $.mage.__('Please enter a valid year (1900-%1).');\n this.dobErrorMessage = validYearMessage.replace('%1', curYear.toString());\n\n return false;\n }\n validateDayInMonth = new Date(year, month, 0).getDate();\n\n if (day < 1 || day > validateDayInMonth) {\n validDateMessage = $.mage.__('Please enter a valid day (1-%1).');\n this.dobErrorMessage = validDateMessage.replace('%1', validateDayInMonth.toString());\n\n return false;\n }\n today = new Date();\n dateEntered = new Date();\n dateEntered.setFullYear(year, month - 1, day);\n\n if (dateEntered > today) {\n this.dobErrorMessage = $.mage.__('Please enter a date from the past.');\n\n return false;\n }\n\n day = day % 10 === day ? '0' + day : day;\n month = month % 10 === month ? '0' + month : month;\n $(element).val(month + '/' + day + '/' + year);\n\n return true;\n },\n function () {\n return this.dobErrorMessage;\n }\n ]\n }, function (i, rule) {\n rule.unshift(i);\n $.validator.addMethod.apply($.validator, rule);\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/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/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/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/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/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/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/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/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","Magento_Variable/js/grid/columns/radioselect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'mage/translate',\n 'Magento_Ui/js/grid/columns/column',\n 'jquery'\n], function (_, $t, Column, jQuery) {\n 'use strict';\n\n return Column.extend({\n defaults: {\n bodyTmpl: 'Magento_Variable/grid/cells/radioselect',\n draggable: false,\n sortable: false,\n selectedVariableCode: null,\n selectedVariableType: null\n },\n\n /**\n * Calls 'initObservable' of parent\n *\n * @returns {Object} Chainable.\n */\n initObservable: function () {\n this._super().observe(['selectedVariableCode']);\n\n return this;\n },\n\n /**\n * Remove disable class from Insert Variable button after Variable has been chosen.\n *\n * @return {Boolean}\n */\n selectVariable: function () {\n if (jQuery('#insert_variable').hasClass('disabled')) {\n jQuery('#insert_variable').removeClass('disabled');\n }\n\n return true;\n }\n });\n});\n","Magento_Csp/js/sri.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\nrequire.config({\n onNodeCreated: function (node, config, moduleName, url) {\n 'use strict';\n if ('sriHashes' in window && url in window.sriHashes) {\n node.setAttribute('integrity', window.sriHashes[url]);\n node.setAttribute('crossorigin', 'anonymous');\n }\n }\n});\n","Amasty_Base/js/http_build_query.js":"/**\n * PHP htp_build_query() analog\n */\ndefine(\n [],\n function () {\n 'use strict';\n\n /**\n * Encodes param according to RFC3986 standard.\n *\n * @param {string} str\n * @returns {string}\n */\n function encodeComponentRaw(str)\n {\n str = (str + '');\n return encodeURIComponent(str)\n .replace(/!/g, '%21')\n .replace(/'/g, '%27')\n .replace(/\\(/g, '%28')\n .replace(/\\)/g, '%29')\n .replace(/\\*/g, '%2A');\n }\n\n /**\n * Encodes param according to RF1738 standard.\n *\n * @param {string} str\n * @returns {string}\n */\n function encodeComponent(str)\n {\n return encodeComponentRaw(str).replace(/%20/g, '+');\n }\n\n /**\n * Encode single GET param.\n *\n * @param {string} key\n * @param {string} val\n * @param {string} argSeparator\n * @param {function (string)} encodeFunc\n * @returns {string}\n */\n function buildParam(key, val, argSeparator, encodeFunc)\n {\n var result = [];\n if (val === true) {\n val = '1';\n } else if (val === false) {\n val = '0';\n }\n\n if (val !== null) {\n if (typeof val === 'object') {\n for (var index in val) {\n if (val[index] !== null) {\n result.push(buildParam(key + '[' + index + ']', val[index], argSeparator, encodeFunc));\n }\n }\n\n return result.join(argSeparator);\n } else if (typeof val !== 'function') {\n return encodeFunc(key) + '=' + encodeFunc(val);\n } else {\n throw new Error('There was an error processing for http_build_query().');\n }\n } else {\n return '';\n }\n };\n\n /**\n * Builds HTTP query in the same way as PHP htp_build_query() function.\n *\n * @param {array} formData\n * @param {string} numericPrefix\n * @param {string} argSeparator\n * @param {string} encType\n * @returns {string}\n */\n function httpBuildQuery(formData, numericPrefix, argSeparator, encType)\n {\n var result = [],\n encode = (encType == 'PHP_QUERY_RFC3986') ? encodeComponentRaw : encodeComponent;\n if (!argSeparator) {\n argSeparator = '&';\n }\n\n for (var key in formData) {\n if (numericPrefix && !isNaN(key)) {\n key = String(numericPrefix) + key;\n }\n var query = buildParam(key, formData[key], argSeparator, encode);\n if (query !== '') {\n result.push(query);\n }\n }\n\n return result.join(argSeparator);\n };\n\n return function (formData, numericPrefix, argSeparator, encType) {\n return httpBuildQuery(formData, numericPrefix, argSeparator, encType);\n }\n }\n);\n","Amasty_Base/vendor/slick/slick.min.js":"/* phpcs:ignoreFile */\n/*\n _ _ _ _\n ___| (_) ___| | __ (_)___\n/ __| | |/ __| |/ / | / __|\n\\__ \\ | | (__| < _ | \\__ \\\n|___/_|_|\\___|_|\\_(_)/ |___/\n |__/\n Version: 1.9.0\n Author: Ken Wheeler\n Website: http://kenwheeler.github.io\n Docs: http://kenwheeler.github.io/slick\n Repo: http://github.com/kenwheeler/slick\n Issues: http://github.com/kenwheeler/slick/issues\n */\n(function(i){\"use strict\";\"function\"==typeof define&&define.amd?define([\"jquery\"],i):\"undefined\"!=typeof exports?module.exports=i(require(\"jquery\")):i(jQuery)})(function(i){\"use strict\";var e=window.Slick||{};e=function(){function e(e,o){var s,n=this;n.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:i(e),appendDots:i(e),arrows:!0,asNavFor:null,prevArrow:'<button class=\"slick-prev\" aria-label=\"Previous\" type=\"button\">Previous</button>',nextArrow:'<button class=\"slick-next\" aria-label=\"Next\" type=\"button\">Next</button>',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:\"50px\",cssEase:\"ease\",customPaging:function(e,t){return i('<button type=\"button\" />').text(t+1)},dots:!1,dotsClass:\"slick-dots\",draggable:!0,easing:\"linear\",edgeFriction:.35,fade:!1,focusOnSelect:!1,focusOnChange:!1,infinite:!0,initialSlide:0,lazyLoad:\"ondemand\",mobileFirst:!1,pauseOnHover:!0,pauseOnFocus:!0,pauseOnDotsHover:!1,respondTo:\"window\",responsive:null,rows:1,rtl:!1,slide:\"\",slidesPerRow:1,slidesToShow:1,slidesToScroll:1,speed:500,swipe:!0,swipeToSlide:!1,touchMove:!0,touchThreshold:5,useCSS:!0,useTransform:!0,variableWidth:!1,vertical:!1,verticalSwiping:!1,waitForAnimate:!0,zIndex:1e3},n.initials={animating:!1,dragging:!1,autoPlayTimer:null,currentDirection:0,currentLeft:null,currentSlide:0,direction:1,$dots:null,listWidth:null,listHeight:null,loadIndex:0,$nextArrow:null,$prevArrow:null,scrolling:!1,slideCount:null,slideWidth:null,$slideTrack:null,$slides:null,sliding:!1,slideOffset:0,swipeLeft:null,swiping:!1,$list:null,touchObject:{},transformsEnabled:!1,unslicked:!1},i.extend(n,n.initials),n.activeBreakpoint=null,n.animType=null,n.animProp=null,n.breakpoints=[],n.breakpointSettings=[],n.cssTransitions=!1,n.focussed=!1,n.interrupted=!1,n.hidden=\"hidden\",n.paused=!0,n.positionProp=null,n.respondTo=null,n.rowCount=1,n.shouldClick=!0,n.$slider=i(e),n.$slidesCache=null,n.transformType=null,n.transitionType=null,n.visibilityChange=\"visibilitychange\",n.windowWidth=0,n.windowTimer=null,s=i(e).data(\"slick\")||{},n.options=i.extend({},n.defaults,o,s),n.currentSlide=n.options.initialSlide,n.originalSettings=n.options,\"undefined\"!=typeof document.mozHidden?(n.hidden=\"mozHidden\",n.visibilityChange=\"mozvisibilitychange\"):\"undefined\"!=typeof document.webkitHidden&&(n.hidden=\"webkitHidden\",n.visibilityChange=\"webkitvisibilitychange\"),n.autoPlay=i.proxy(n.autoPlay,n),n.autoPlayClear=i.proxy(n.autoPlayClear,n),n.autoPlayIterator=i.proxy(n.autoPlayIterator,n),n.changeSlide=i.proxy(n.changeSlide,n),n.clickHandler=i.proxy(n.clickHandler,n),n.selectHandler=i.proxy(n.selectHandler,n),n.setPosition=i.proxy(n.setPosition,n),n.swipeHandler=i.proxy(n.swipeHandler,n),n.dragHandler=i.proxy(n.dragHandler,n),n.keyHandler=i.proxy(n.keyHandler,n),n.instanceUid=t++,n.htmlExpr=/^(?:\\s*(<[\\w\\W]+>)[^>]*)$/,n.registerBreakpoints(),n.init(!0)}var t=0;return e}(),e.prototype.activateADA=function(){var i=this;i.$slideTrack.find(\".slick-active\").attr({\"aria-hidden\":\"false\"}).find(\"a, input, button, select\").attr({tabindex:\"0\"})},e.prototype.addSlide=e.prototype.slickAdd=function(e,t,o){var s=this;if(\"boolean\"==typeof t)o=t,t=null;else if(t<0||t>=s.slideCount)return!1;s.unload(),\"number\"==typeof t?0===t&&0===s.$slides.length?i(e).appendTo(s.$slideTrack):o?i(e).insertBefore(s.$slides.eq(t)):i(e).insertAfter(s.$slides.eq(t)):o===!0?i(e).prependTo(s.$slideTrack):i(e).appendTo(s.$slideTrack),s.$slides=s.$slideTrack.children(this.options.slide),s.$slideTrack.children(this.options.slide).detach(),s.$slideTrack.append(s.$slides),s.$slides.each(function(e,t){i(t).attr(\"data-slick-index\",e)}),s.$slidesCache=s.$slides,s.reinit()},e.prototype.animateHeight=function(){var i=this;if(1===i.options.slidesToShow&&i.options.adaptiveHeight===!0&&i.options.vertical===!1){var e=i.$slides.eq(i.currentSlide).outerHeight(!0);i.$list.animate({height:e},i.options.speed)}},e.prototype.animateSlide=function(e,t){var o={},s=this;s.animateHeight(),s.options.rtl===!0&&s.options.vertical===!1&&(e=-e),s.transformsEnabled===!1?s.options.vertical===!1?s.$slideTrack.animate({left:e},s.options.speed,s.options.easing,t):s.$slideTrack.animate({top:e},s.options.speed,s.options.easing,t):s.cssTransitions===!1?(s.options.rtl===!0&&(s.currentLeft=-s.currentLeft),i({animStart:s.currentLeft}).animate({animStart:e},{duration:s.options.speed,easing:s.options.easing,step:function(i){i=Math.ceil(i),s.options.vertical===!1?(o[s.animType]=\"translate(\"+i+\"px, 0px)\",s.$slideTrack.css(o)):(o[s.animType]=\"translate(0px,\"+i+\"px)\",s.$slideTrack.css(o))},complete:function(){t&&t.call()}})):(s.applyTransition(),e=Math.ceil(e),s.options.vertical===!1?o[s.animType]=\"translate3d(\"+e+\"px, 0px, 0px)\":o[s.animType]=\"translate3d(0px,\"+e+\"px, 0px)\",s.$slideTrack.css(o),t&&setTimeout(function(){s.disableTransition(),t.call()},s.options.speed))},e.prototype.getNavTarget=function(){var e=this,t=e.options.asNavFor;return t&&null!==t&&(t=i(t).not(e.$slider)),t},e.prototype.asNavFor=function(e){var t=this,o=t.getNavTarget();null!==o&&\"object\"==typeof o&&o.each(function(){var t=i(this).slick(\"getSlick\");t.unslicked||t.slideHandler(e,!0)})},e.prototype.applyTransition=function(i){var e=this,t={};e.options.fade===!1?t[e.transitionType]=e.transformType+\" \"+e.options.speed+\"ms \"+e.options.cssEase:t[e.transitionType]=\"opacity \"+e.options.speed+\"ms \"+e.options.cssEase,e.options.fade===!1?e.$slideTrack.css(t):e.$slides.eq(i).css(t)},e.prototype.autoPlay=function(){var i=this;i.autoPlayClear(),i.slideCount>i.options.slidesToShow&&(i.autoPlayTimer=setInterval(i.autoPlayIterator,i.options.autoplaySpeed))},e.prototype.autoPlayClear=function(){var i=this;i.autoPlayTimer&&clearInterval(i.autoPlayTimer)},e.prototype.autoPlayIterator=function(){var i=this,e=i.currentSlide+i.options.slidesToScroll;i.paused||i.interrupted||i.focussed||(i.options.infinite===!1&&(1===i.direction&&i.currentSlide+1===i.slideCount-1?i.direction=0:0===i.direction&&(e=i.currentSlide-i.options.slidesToScroll,i.currentSlide-1===0&&(i.direction=1))),i.slideHandler(e))},e.prototype.buildArrows=function(){var e=this;e.options.arrows===!0&&(e.$prevArrow=i(e.options.prevArrow).addClass(\"slick-arrow\"),e.$nextArrow=i(e.options.nextArrow).addClass(\"slick-arrow\"),e.slideCount>e.options.slidesToShow?(e.$prevArrow.removeClass(\"slick-hidden\").removeAttr(\"aria-hidden tabindex\"),e.$nextArrow.removeClass(\"slick-hidden\").removeAttr(\"aria-hidden tabindex\"),e.htmlExpr.test(e.options.prevArrow)&&e.$prevArrow.prependTo(e.options.appendArrows),e.htmlExpr.test(e.options.nextArrow)&&e.$nextArrow.appendTo(e.options.appendArrows),e.options.infinite!==!0&&e.$prevArrow.addClass(\"slick-disabled\").attr(\"aria-disabled\",\"true\")):e.$prevArrow.add(e.$nextArrow).addClass(\"slick-hidden\").attr({\"aria-disabled\":\"true\",tabindex:\"-1\"}))},e.prototype.buildDots=function(){var e,t,o=this;if(o.options.dots===!0&&o.slideCount>o.options.slidesToShow){for(o.$slider.addClass(\"slick-dotted\"),t=i(\"<ul />\").addClass(o.options.dotsClass),e=0;e<=o.getDotCount();e+=1)t.append(i(\"<li />\").append(o.options.customPaging.call(this,o,e)));o.$dots=t.appendTo(o.options.appendDots),o.$dots.find(\"li\").first().addClass(\"slick-active\")}},e.prototype.buildOut=function(){var e=this;e.$slides=e.$slider.children(e.options.slide+\":not(.slick-cloned)\").addClass(\"slick-slide\"),e.slideCount=e.$slides.length,e.$slides.each(function(e,t){i(t).attr(\"data-slick-index\",e).data(\"originalStyling\",i(t).attr(\"style\")||\"\")}),e.$slider.addClass(\"slick-slider\"),e.$slideTrack=0===e.slideCount?i('<div class=\"slick-track\"/>').appendTo(e.$slider):e.$slides.wrapAll('<div class=\"slick-track\"/>').parent(),e.$list=e.$slideTrack.wrap('<div class=\"slick-list\"/>').parent(),e.$slideTrack.css(\"opacity\",0),e.options.centerMode!==!0&&e.options.swipeToSlide!==!0||(e.options.slidesToScroll=1),i(\"img[data-lazy]\",e.$slider).not(\"[src]\").addClass(\"slick-loading\"),e.setupInfinite(),e.buildArrows(),e.buildDots(),e.updateDots(),e.setSlideClasses(\"number\"==typeof e.currentSlide?e.currentSlide:0),e.options.draggable===!0&&e.$list.addClass(\"draggable\")},e.prototype.buildRows=function(){var i,e,t,o,s,n,r,l=this;if(o=document.createDocumentFragment(),n=l.$slider.children(),l.options.rows>0){for(r=l.options.slidesPerRow*l.options.rows,s=Math.ceil(n.length/r),i=0;i<s;i++){var d=document.createElement(\"div\");for(e=0;e<l.options.rows;e++){var a=document.createElement(\"div\");for(t=0;t<l.options.slidesPerRow;t++){var c=i*r+(e*l.options.slidesPerRow+t);n.get(c)&&a.appendChild(n.get(c))}d.appendChild(a)}o.appendChild(d)}l.$slider.empty().append(o),l.$slider.children().children().children().css({width:100/l.options.slidesPerRow+\"%\",display:\"inline-block\"})}},e.prototype.checkResponsive=function(e,t){var o,s,n,r=this,l=!1,d=r.$slider.width(),a=window.innerWidth||i(window).width();if(\"window\"===r.respondTo?n=a:\"slider\"===r.respondTo?n=d:\"min\"===r.respondTo&&(n=Math.min(a,d)),r.options.responsive&&r.options.responsive.length&&null!==r.options.responsive){s=null;for(o in r.breakpoints)r.breakpoints.hasOwnProperty(o)&&(r.originalSettings.mobileFirst===!1?n<r.breakpoints[o]&&(s=r.breakpoints[o]):n>r.breakpoints[o]&&(s=r.breakpoints[o]));null!==s?null!==r.activeBreakpoint?(s!==r.activeBreakpoint||t)&&(r.activeBreakpoint=s,\"unslick\"===r.breakpointSettings[s]?r.unslick(s):(r.options=i.extend({},r.originalSettings,r.breakpointSettings[s]),e===!0&&(r.currentSlide=r.options.initialSlide),r.refresh(e)),l=s):(r.activeBreakpoint=s,\"unslick\"===r.breakpointSettings[s]?r.unslick(s):(r.options=i.extend({},r.originalSettings,r.breakpointSettings[s]),e===!0&&(r.currentSlide=r.options.initialSlide),r.refresh(e)),l=s):null!==r.activeBreakpoint&&(r.activeBreakpoint=null,r.options=r.originalSettings,e===!0&&(r.currentSlide=r.options.initialSlide),r.refresh(e),l=s),e||l===!1||r.$slider.trigger(\"breakpoint\",[r,l])}},e.prototype.changeSlide=function(e,t){var o,s,n,r=this,l=i(e.currentTarget);switch(l.is(\"a\")&&e.preventDefault(),l.is(\"li\")||(l=l.closest(\"li\")),n=r.slideCount%r.options.slidesToScroll!==0,o=n?0:(r.slideCount-r.currentSlide)%r.options.slidesToScroll,e.data.message){case\"previous\":s=0===o?r.options.slidesToScroll:r.options.slidesToShow-o,r.slideCount>r.options.slidesToShow&&r.slideHandler(r.currentSlide-s,!1,t);break;case\"next\":s=0===o?r.options.slidesToScroll:o,r.slideCount>r.options.slidesToShow&&r.slideHandler(r.currentSlide+s,!1,t);break;case\"index\":var d=0===e.data.index?0:e.data.index||l.index()*r.options.slidesToScroll;r.slideHandler(r.checkNavigable(d),!1,t),l.children().trigger(\"focus\");break;default:return}},e.prototype.checkNavigable=function(i){var e,t,o=this;if(e=o.getNavigableIndexes(),t=0,i>e[e.length-1])i=e[e.length-1];else for(var s in e){if(i<e[s]){i=t;break}t=e[s]}return i},e.prototype.cleanUpEvents=function(){var e=this;e.options.dots&&null!==e.$dots&&(i(\"li\",e.$dots).off(\"click.slick\",e.changeSlide).off(\"mouseenter.slick\",i.proxy(e.interrupt,e,!0)).off(\"mouseleave.slick\",i.proxy(e.interrupt,e,!1)),e.options.accessibility===!0&&e.$dots.off(\"keydown.slick\",e.keyHandler)),e.$slider.off(\"focus.slick blur.slick\"),e.options.arrows===!0&&e.slideCount>e.options.slidesToShow&&(e.$prevArrow&&e.$prevArrow.off(\"click.slick\",e.changeSlide),e.$nextArrow&&e.$nextArrow.off(\"click.slick\",e.changeSlide),e.options.accessibility===!0&&(e.$prevArrow&&e.$prevArrow.off(\"keydown.slick\",e.keyHandler),e.$nextArrow&&e.$nextArrow.off(\"keydown.slick\",e.keyHandler))),e.$list.off(\"touchstart.slick mousedown.slick\",e.swipeHandler),e.$list.off(\"touchmove.slick mousemove.slick\",e.swipeHandler),e.$list.off(\"touchend.slick mouseup.slick\",e.swipeHandler),e.$list.off(\"touchcancel.slick mouseleave.slick\",e.swipeHandler),e.$list.off(\"click.slick\",e.clickHandler),i(document).off(e.visibilityChange,e.visibility),e.cleanUpSlideEvents(),e.options.accessibility===!0&&e.$list.off(\"keydown.slick\",e.keyHandler),e.options.focusOnSelect===!0&&i(e.$slideTrack).children().off(\"click.slick\",e.selectHandler),i(window).off(\"orientationchange.slick.slick-\"+e.instanceUid,e.orientationChange),i(window).off(\"resize.slick.slick-\"+e.instanceUid,e.resize),i(\"[draggable!=true]\",e.$slideTrack).off(\"dragstart\",e.preventDefault),i(window).off(\"load.slick.slick-\"+e.instanceUid,e.setPosition)},e.prototype.cleanUpSlideEvents=function(){var e=this;e.$list.off(\"mouseenter.slick\",i.proxy(e.interrupt,e,!0)),e.$list.off(\"mouseleave.slick\",i.proxy(e.interrupt,e,!1))},e.prototype.cleanUpRows=function(){var i,e=this;e.options.rows>0&&(i=e.$slides.children().children(),i.removeAttr(\"style\"),e.$slider.empty().append(i))},e.prototype.clickHandler=function(i){var e=this;e.shouldClick===!1&&(i.stopImmediatePropagation(),i.stopPropagation(),i.preventDefault())},e.prototype.destroy=function(e){var t=this;t.autoPlayClear(),t.touchObject={},t.cleanUpEvents(),i(\".slick-cloned\",t.$slider).detach(),t.$dots&&t.$dots.remove(),t.$prevArrow&&t.$prevArrow.length&&(t.$prevArrow.removeClass(\"slick-disabled slick-arrow slick-hidden\").removeAttr(\"aria-hidden aria-disabled tabindex\").css(\"display\",\"\"),t.htmlExpr.test(t.options.prevArrow)&&t.$prevArrow.remove()),t.$nextArrow&&t.$nextArrow.length&&(t.$nextArrow.removeClass(\"slick-disabled slick-arrow slick-hidden\").removeAttr(\"aria-hidden aria-disabled tabindex\").css(\"display\",\"\"),t.htmlExpr.test(t.options.nextArrow)&&t.$nextArrow.remove()),t.$slides&&(t.$slides.removeClass(\"slick-slide slick-active slick-center slick-visible slick-current\").removeAttr(\"aria-hidden\").removeAttr(\"data-slick-index\").each(function(){i(this).attr(\"style\",i(this).data(\"originalStyling\"))}),t.$slideTrack.children(this.options.slide).detach(),t.$slideTrack.detach(),t.$list.detach(),t.$slider.append(t.$slides)),t.cleanUpRows(),t.$slider.removeClass(\"slick-slider\"),t.$slider.removeClass(\"slick-initialized\"),t.$slider.removeClass(\"slick-dotted\"),t.unslicked=!0,e||t.$slider.trigger(\"destroy\",[t])},e.prototype.disableTransition=function(i){var e=this,t={};t[e.transitionType]=\"\",e.options.fade===!1?e.$slideTrack.css(t):e.$slides.eq(i).css(t)},e.prototype.fadeSlide=function(i,e){var t=this;t.cssTransitions===!1?(t.$slides.eq(i).css({zIndex:t.options.zIndex}),t.$slides.eq(i).animate({opacity:1},t.options.speed,t.options.easing,e)):(t.applyTransition(i),t.$slides.eq(i).css({opacity:1,zIndex:t.options.zIndex}),e&&setTimeout(function(){t.disableTransition(i),e.call()},t.options.speed))},e.prototype.fadeSlideOut=function(i){var e=this;e.cssTransitions===!1?e.$slides.eq(i).animate({opacity:0,zIndex:e.options.zIndex-2},e.options.speed,e.options.easing):(e.applyTransition(i),e.$slides.eq(i).css({opacity:0,zIndex:e.options.zIndex-2}))},e.prototype.filterSlides=e.prototype.slickFilter=function(i){var e=this;null!==i&&(e.$slidesCache=e.$slides,e.unload(),e.$slideTrack.children(this.options.slide).detach(),e.$slidesCache.filter(i).appendTo(e.$slideTrack),e.reinit())},e.prototype.focusHandler=function(){var e=this;e.$slider.off(\"focus.slick blur.slick\").on(\"focus.slick\",\"*\",function(t){var o=i(this);setTimeout(function(){e.options.pauseOnFocus&&o.is(\":focus\")&&(e.focussed=!0,e.autoPlay())},0)}).on(\"blur.slick\",\"*\",function(t){i(this);e.options.pauseOnFocus&&(e.focussed=!1,e.autoPlay())})},e.prototype.getCurrent=e.prototype.slickCurrentSlide=function(){var i=this;return i.currentSlide},e.prototype.getDotCount=function(){var i=this,e=0,t=0,o=0;if(i.options.infinite===!0)if(i.slideCount<=i.options.slidesToShow)++o;else for(;e<i.slideCount;)++o,e=t+i.options.slidesToScroll,t+=i.options.slidesToScroll<=i.options.slidesToShow?i.options.slidesToScroll:i.options.slidesToShow;else if(i.options.centerMode===!0)o=i.slideCount;else if(i.options.asNavFor)for(;e<i.slideCount;)++o,e=t+i.options.slidesToScroll,t+=i.options.slidesToScroll<=i.options.slidesToShow?i.options.slidesToScroll:i.options.slidesToShow;else o=1+Math.ceil((i.slideCount-i.options.slidesToShow)/i.options.slidesToScroll);return o-1},e.prototype.getLeft=function(i){var e,t,o,s,n=this,r=0;return n.slideOffset=0,t=n.$slides.first().outerHeight(!0),n.options.infinite===!0?(n.slideCount>n.options.slidesToShow&&(n.slideOffset=n.slideWidth*n.options.slidesToShow*-1,s=-1,n.options.vertical===!0&&n.options.centerMode===!0&&(2===n.options.slidesToShow?s=-1.5:1===n.options.slidesToShow&&(s=-2)),r=t*n.options.slidesToShow*s),n.slideCount%n.options.slidesToScroll!==0&&i+n.options.slidesToScroll>n.slideCount&&n.slideCount>n.options.slidesToShow&&(i>n.slideCount?(n.slideOffset=(n.options.slidesToShow-(i-n.slideCount))*n.slideWidth*-1,r=(n.options.slidesToShow-(i-n.slideCount))*t*-1):(n.slideOffset=n.slideCount%n.options.slidesToScroll*n.slideWidth*-1,r=n.slideCount%n.options.slidesToScroll*t*-1))):i+n.options.slidesToShow>n.slideCount&&(n.slideOffset=(i+n.options.slidesToShow-n.slideCount)*n.slideWidth,r=(i+n.options.slidesToShow-n.slideCount)*t),n.slideCount<=n.options.slidesToShow&&(n.slideOffset=0,r=0),n.options.centerMode===!0&&n.slideCount<=n.options.slidesToShow?n.slideOffset=n.slideWidth*Math.floor(n.options.slidesToShow)/2-n.slideWidth*n.slideCount/2:n.options.centerMode===!0&&n.options.infinite===!0?n.slideOffset+=n.slideWidth*Math.floor(n.options.slidesToShow/2)-n.slideWidth:n.options.centerMode===!0&&(n.slideOffset=0,n.slideOffset+=n.slideWidth*Math.floor(n.options.slidesToShow/2)),e=n.options.vertical===!1?i*n.slideWidth*-1+n.slideOffset:i*t*-1+r,n.options.variableWidth===!0&&(o=n.slideCount<=n.options.slidesToShow||n.options.infinite===!1?n.$slideTrack.children(\".slick-slide\").eq(i):n.$slideTrack.children(\".slick-slide\").eq(i+n.options.slidesToShow),e=n.options.rtl===!0?o[0]?(n.$slideTrack.width()-o[0].offsetLeft-o.width())*-1:0:o[0]?o[0].offsetLeft*-1:0,n.options.centerMode===!0&&(o=n.slideCount<=n.options.slidesToShow||n.options.infinite===!1?n.$slideTrack.children(\".slick-slide\").eq(i):n.$slideTrack.children(\".slick-slide\").eq(i+n.options.slidesToShow+1),e=n.options.rtl===!0?o[0]?(n.$slideTrack.width()-o[0].offsetLeft-o.width())*-1:0:o[0]?o[0].offsetLeft*-1:0,e+=(n.$list.width()-o.outerWidth())/2)),e},e.prototype.getOption=e.prototype.slickGetOption=function(i){var e=this;return e.options[i]},e.prototype.getNavigableIndexes=function(){var i,e=this,t=0,o=0,s=[];for(e.options.infinite===!1?i=e.slideCount:(t=e.options.slidesToScroll*-1,o=e.options.slidesToScroll*-1,i=2*e.slideCount);t<i;)s.push(t),t=o+e.options.slidesToScroll,o+=e.options.slidesToScroll<=e.options.slidesToShow?e.options.slidesToScroll:e.options.slidesToShow;return s},e.prototype.getSlick=function(){return this},e.prototype.getSlideCount=function(){var e,t,o,s,n=this;return s=n.options.centerMode===!0?Math.floor(n.$list.width()/2):0,o=n.swipeLeft*-1+s,n.options.swipeToSlide===!0?(n.$slideTrack.find(\".slick-slide\").each(function(e,s){var r,l,d;if(r=i(s).outerWidth(),l=s.offsetLeft,n.options.centerMode!==!0&&(l+=r/2),d=l+r,o<d)return t=s,!1}),e=Math.abs(i(t).attr(\"data-slick-index\")-n.currentSlide)||1):n.options.slidesToScroll},e.prototype.goTo=e.prototype.slickGoTo=function(i,e){var t=this;t.changeSlide({data:{message:\"index\",index:parseInt(i)}},e)},e.prototype.init=function(e){var t=this;i(t.$slider).hasClass(\"slick-initialized\")||(i(t.$slider).addClass(\"slick-initialized\"),t.buildRows(),t.buildOut(),t.setProps(),t.startLoad(),t.loadSlider(),t.initializeEvents(),t.updateArrows(),t.updateDots(),t.checkResponsive(!0),t.focusHandler()),e&&t.$slider.trigger(\"init\",[t]),t.options.accessibility===!0&&t.initADA(),t.options.autoplay&&(t.paused=!1,t.autoPlay())},e.prototype.initADA=function(){var e=this,t=Math.ceil(e.slideCount/e.options.slidesToShow),o=e.getNavigableIndexes().filter(function(i){return i>=0&&i<e.slideCount});e.$slides.add(e.$slideTrack.find(\".slick-cloned\")).attr({\"aria-hidden\":\"true\",tabindex:\"-1\"}).find(\"a, input, button, select\").attr({tabindex:\"-1\"}),null!==e.$dots&&(e.$slides.not(e.$slideTrack.find(\".slick-cloned\")).each(function(t){var s=o.indexOf(t);if(i(this).attr({role:\"tabpanel\",id:\"slick-slide\"+e.instanceUid+t,tabindex:-1}),s!==-1){var n=\"slick-slide-control\"+e.instanceUid+s;i(\"#\"+n).length&&i(this).attr({\"aria-describedby\":n})}}),e.$dots.attr(\"role\",\"tablist\").find(\"li\").each(function(s){var n=o[s];i(this).attr({role:\"presentation\"}),i(this).find(\"button\").first().attr({role:\"tab\",id:\"slick-slide-control\"+e.instanceUid+s,\"aria-controls\":\"slick-slide\"+e.instanceUid+n,\"aria-label\":s+1+\" of \"+t,\"aria-selected\":null,tabindex:\"-1\"})}).eq(e.currentSlide).find(\"button\").attr({\"aria-selected\":\"true\",tabindex:\"0\"}).end());for(var s=e.currentSlide,n=s+e.options.slidesToShow;s<n;s++)e.options.focusOnChange?e.$slides.eq(s).attr({tabindex:\"0\"}):e.$slides.eq(s).removeAttr(\"tabindex\");e.activateADA()},e.prototype.initArrowEvents=function(){var i=this;i.options.arrows===!0&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.off(\"click.slick\").on(\"click.slick\",{message:\"previous\"},i.changeSlide),i.$nextArrow.off(\"click.slick\").on(\"click.slick\",{message:\"next\"},i.changeSlide),i.options.accessibility===!0&&(i.$prevArrow.on(\"keydown.slick\",i.keyHandler),i.$nextArrow.on(\"keydown.slick\",i.keyHandler)))},e.prototype.initDotEvents=function(){var e=this;e.options.dots===!0&&e.slideCount>e.options.slidesToShow&&(i(\"li\",e.$dots).on(\"click.slick\",{message:\"index\"},e.changeSlide),e.options.accessibility===!0&&e.$dots.on(\"keydown.slick\",e.keyHandler)),e.options.dots===!0&&e.options.pauseOnDotsHover===!0&&e.slideCount>e.options.slidesToShow&&i(\"li\",e.$dots).on(\"mouseenter.slick\",i.proxy(e.interrupt,e,!0)).on(\"mouseleave.slick\",i.proxy(e.interrupt,e,!1))},e.prototype.initSlideEvents=function(){var e=this;e.options.pauseOnHover&&(e.$list.on(\"mouseenter.slick\",i.proxy(e.interrupt,e,!0)),e.$list.on(\"mouseleave.slick\",i.proxy(e.interrupt,e,!1)))},e.prototype.initializeEvents=function(){var e=this;e.initArrowEvents(),e.initDotEvents(),e.initSlideEvents(),e.$list.on(\"touchstart.slick mousedown.slick\",{action:\"start\"},e.swipeHandler),e.$list.on(\"touchmove.slick mousemove.slick\",{action:\"move\"},e.swipeHandler),e.$list.on(\"touchend.slick mouseup.slick\",{action:\"end\"},e.swipeHandler),e.$list.on(\"touchcancel.slick mouseleave.slick\",{action:\"end\"},e.swipeHandler),e.$list.on(\"click.slick\",e.clickHandler),i(document).on(e.visibilityChange,i.proxy(e.visibility,e)),e.options.accessibility===!0&&e.$list.on(\"keydown.slick\",e.keyHandler),e.options.focusOnSelect===!0&&i(e.$slideTrack).children().on(\"click.slick\",e.selectHandler),i(window).on(\"orientationchange.slick.slick-\"+e.instanceUid,i.proxy(e.orientationChange,e)),i(window).on(\"resize.slick.slick-\"+e.instanceUid,i.proxy(e.resize,e)),i(\"[draggable!=true]\",e.$slideTrack).on(\"dragstart\",e.preventDefault),i(window).on(\"load.slick.slick-\"+e.instanceUid,e.setPosition),i(e.setPosition)},e.prototype.initUI=function(){var i=this;i.options.arrows===!0&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.show(),i.$nextArrow.show()),i.options.dots===!0&&i.slideCount>i.options.slidesToShow&&i.$dots.show()},e.prototype.keyHandler=function(i){var e=this;i.target.tagName.match(\"TEXTAREA|INPUT|SELECT\")||(37===i.keyCode&&e.options.accessibility===!0?e.changeSlide({data:{message:e.options.rtl===!0?\"next\":\"previous\"}}):39===i.keyCode&&e.options.accessibility===!0&&e.changeSlide({data:{message:e.options.rtl===!0?\"previous\":\"next\"}}))},e.prototype.lazyLoad=function(){function e(e){i(\"img[data-lazy]\",e).each(function(){var e=i(this),t=i(this).attr(\"data-lazy\"),o=i(this).attr(\"data-srcset\"),s=i(this).attr(\"data-sizes\")||r.$slider.attr(\"data-sizes\"),n=document.createElement(\"img\");n.onload=function(){e.animate({opacity:0},100,function(){o&&(e.attr(\"srcset\",o),s&&e.attr(\"sizes\",s)),e.attr(\"src\",t).animate({opacity:1},200,function(){e.removeAttr(\"data-lazy data-srcset data-sizes\").removeClass(\"slick-loading\")}),r.$slider.trigger(\"lazyLoaded\",[r,e,t])})},n.onerror=function(){e.removeAttr(\"data-lazy\").removeClass(\"slick-loading\").addClass(\"slick-lazyload-error\"),r.$slider.trigger(\"lazyLoadError\",[r,e,t])},n.src=t})}var t,o,s,n,r=this;if(r.options.centerMode===!0?r.options.infinite===!0?(s=r.currentSlide+(r.options.slidesToShow/2+1),n=s+r.options.slidesToShow+2):(s=Math.max(0,r.currentSlide-(r.options.slidesToShow/2+1)),n=2+(r.options.slidesToShow/2+1)+r.currentSlide):(s=r.options.infinite?r.options.slidesToShow+r.currentSlide:r.currentSlide,n=Math.ceil(s+r.options.slidesToShow),r.options.fade===!0&&(s>0&&s--,n<=r.slideCount&&n++)),t=r.$slider.find(\".slick-slide\").slice(s,n),\"anticipated\"===r.options.lazyLoad)for(var l=s-1,d=n,a=r.$slider.find(\".slick-slide\"),c=0;c<r.options.slidesToScroll;c++)l<0&&(l=r.slideCount-1),t=t.add(a.eq(l)),t=t.add(a.eq(d)),l--,d++;e(t),r.slideCount<=r.options.slidesToShow?(o=r.$slider.find(\".slick-slide\"),e(o)):r.currentSlide>=r.slideCount-r.options.slidesToShow?(o=r.$slider.find(\".slick-cloned\").slice(0,r.options.slidesToShow),e(o)):0===r.currentSlide&&(o=r.$slider.find(\".slick-cloned\").slice(r.options.slidesToShow*-1),e(o))},e.prototype.loadSlider=function(){var i=this;i.setPosition(),i.$slideTrack.css({opacity:1}),i.$slider.removeClass(\"slick-loading\"),i.initUI(),\"progressive\"===i.options.lazyLoad&&i.progressiveLazyLoad()},e.prototype.next=e.prototype.slickNext=function(){var i=this;i.changeSlide({data:{message:\"next\"}})},e.prototype.orientationChange=function(){var i=this;i.checkResponsive(),i.setPosition()},e.prototype.pause=e.prototype.slickPause=function(){var i=this;i.autoPlayClear(),i.paused=!0},e.prototype.play=e.prototype.slickPlay=function(){var i=this;i.autoPlay(),i.options.autoplay=!0,i.paused=!1,i.focussed=!1,i.interrupted=!1},e.prototype.postSlide=function(e){var t=this;if(!t.unslicked&&(t.$slider.trigger(\"afterChange\",[t,e]),t.animating=!1,t.slideCount>t.options.slidesToShow&&t.setPosition(),t.swipeLeft=null,t.options.autoplay&&t.autoPlay(),t.options.accessibility===!0&&(t.initADA(),t.options.focusOnChange))){var o=i(t.$slides.get(t.currentSlide));o.attr(\"tabindex\",0).focus()}},e.prototype.prev=e.prototype.slickPrev=function(){var i=this;i.changeSlide({data:{message:\"previous\"}})},e.prototype.preventDefault=function(i){i.preventDefault()},e.prototype.progressiveLazyLoad=function(e){e=e||1;var t,o,s,n,r,l=this,d=i(\"img[data-lazy]\",l.$slider);d.length?(t=d.first(),o=t.attr(\"data-lazy\"),s=t.attr(\"data-srcset\"),n=t.attr(\"data-sizes\")||l.$slider.attr(\"data-sizes\"),r=document.createElement(\"img\"),r.onload=function(){s&&(t.attr(\"srcset\",s),n&&t.attr(\"sizes\",n)),t.attr(\"src\",o).removeAttr(\"data-lazy data-srcset data-sizes\").removeClass(\"slick-loading\"),l.options.adaptiveHeight===!0&&l.setPosition(),l.$slider.trigger(\"lazyLoaded\",[l,t,o]),l.progressiveLazyLoad()},r.onerror=function(){e<3?setTimeout(function(){l.progressiveLazyLoad(e+1)},500):(t.removeAttr(\"data-lazy\").removeClass(\"slick-loading\").addClass(\"slick-lazyload-error\"),l.$slider.trigger(\"lazyLoadError\",[l,t,o]),l.progressiveLazyLoad())},r.src=o):l.$slider.trigger(\"allImagesLoaded\",[l])},e.prototype.refresh=function(e){var t,o,s=this;o=s.slideCount-s.options.slidesToShow,!s.options.infinite&&s.currentSlide>o&&(s.currentSlide=o),s.slideCount<=s.options.slidesToShow&&(s.currentSlide=0),t=s.currentSlide,s.destroy(!0),i.extend(s,s.initials,{currentSlide:t}),s.init(),e||s.changeSlide({data:{message:\"index\",index:t}},!1)},e.prototype.registerBreakpoints=function(){var e,t,o,s=this,n=s.options.responsive||null;if(\"array\"===i.type(n)&&n.length){s.respondTo=s.options.respondTo||\"window\";for(e in n)if(o=s.breakpoints.length-1,n.hasOwnProperty(e)){for(t=n[e].breakpoint;o>=0;)s.breakpoints[o]&&s.breakpoints[o]===t&&s.breakpoints.splice(o,1),o--;s.breakpoints.push(t),s.breakpointSettings[t]=n[e].settings}s.breakpoints.sort(function(i,e){return s.options.mobileFirst?i-e:e-i})}},e.prototype.reinit=function(){var e=this;e.$slides=e.$slideTrack.children(e.options.slide).addClass(\"slick-slide\"),e.slideCount=e.$slides.length,e.currentSlide>=e.slideCount&&0!==e.currentSlide&&(e.currentSlide=e.currentSlide-e.options.slidesToScroll),e.slideCount<=e.options.slidesToShow&&(e.currentSlide=0),e.registerBreakpoints(),e.setProps(),e.setupInfinite(),e.buildArrows(),e.updateArrows(),e.initArrowEvents(),e.buildDots(),e.updateDots(),e.initDotEvents(),e.cleanUpSlideEvents(),e.initSlideEvents(),e.checkResponsive(!1,!0),e.options.focusOnSelect===!0&&i(e.$slideTrack).children().on(\"click.slick\",e.selectHandler),e.setSlideClasses(\"number\"==typeof e.currentSlide?e.currentSlide:0),e.setPosition(),e.focusHandler(),e.paused=!e.options.autoplay,e.autoPlay(),e.$slider.trigger(\"reInit\",[e])},e.prototype.resize=function(){var e=this;i(window).width()!==e.windowWidth&&(clearTimeout(e.windowDelay),e.windowDelay=window.setTimeout(function(){e.windowWidth=i(window).width(),e.checkResponsive(),e.unslicked||e.setPosition()},50))},e.prototype.removeSlide=e.prototype.slickRemove=function(i,e,t){var o=this;return\"boolean\"==typeof i?(e=i,i=e===!0?0:o.slideCount-1):i=e===!0?--i:i,!(o.slideCount<1||i<0||i>o.slideCount-1)&&(o.unload(),t===!0?o.$slideTrack.children().remove():o.$slideTrack.children(this.options.slide).eq(i).remove(),o.$slides=o.$slideTrack.children(this.options.slide),o.$slideTrack.children(this.options.slide).detach(),o.$slideTrack.append(o.$slides),o.$slidesCache=o.$slides,void o.reinit())},e.prototype.setCSS=function(i){var e,t,o=this,s={};o.options.rtl===!0&&(i=-i),e=\"left\"==o.positionProp?Math.ceil(i)+\"px\":\"0px\",t=\"top\"==o.positionProp?Math.ceil(i)+\"px\":\"0px\",s[o.positionProp]=i,o.transformsEnabled===!1?o.$slideTrack.css(s):(s={},o.cssTransitions===!1?(s[o.animType]=\"translate(\"+e+\", \"+t+\")\",o.$slideTrack.css(s)):(s[o.animType]=\"translate3d(\"+e+\", \"+t+\", 0px)\",o.$slideTrack.css(s)))},e.prototype.setDimensions=function(){var i=this;i.options.vertical===!1?i.options.centerMode===!0&&i.$list.css({padding:\"0px \"+i.options.centerPadding}):(i.$list.height(i.$slides.first().outerHeight(!0)*i.options.slidesToShow),i.options.centerMode===!0&&i.$list.css({padding:i.options.centerPadding+\" 0px\"})),i.listWidth=i.$list.width(),i.listHeight=i.$list.height(),i.options.vertical===!1&&i.options.variableWidth===!1?(i.slideWidth=Math.ceil(i.listWidth/i.options.slidesToShow),i.$slideTrack.width(Math.ceil(i.slideWidth*i.$slideTrack.children(\".slick-slide\").length))):i.options.variableWidth===!0?i.$slideTrack.width(5e3*i.slideCount):(i.slideWidth=Math.ceil(i.listWidth),i.$slideTrack.height(Math.ceil(i.$slides.first().outerHeight(!0)*i.$slideTrack.children(\".slick-slide\").length)));var e=i.$slides.first().outerWidth(!0)-i.$slides.first().width();i.options.variableWidth===!1&&i.$slideTrack.children(\".slick-slide\").width(i.slideWidth-e)},e.prototype.setFade=function(){var e,t=this;t.$slides.each(function(o,s){e=t.slideWidth*o*-1,t.options.rtl===!0?i(s).css({position:\"relative\",right:e,top:0,zIndex:t.options.zIndex-2,opacity:0}):i(s).css({position:\"relative\",left:e,top:0,zIndex:t.options.zIndex-2,opacity:0})}),t.$slides.eq(t.currentSlide).css({zIndex:t.options.zIndex-1,opacity:1})},e.prototype.setHeight=function(){var i=this;if(1===i.options.slidesToShow&&i.options.adaptiveHeight===!0&&i.options.vertical===!1){var e=i.$slides.eq(i.currentSlide).outerHeight(!0);i.$list.css(\"height\",e)}},e.prototype.setOption=e.prototype.slickSetOption=function(){var e,t,o,s,n,r=this,l=!1;if(\"object\"===i.type(arguments[0])?(o=arguments[0],l=arguments[1],n=\"multiple\"):\"string\"===i.type(arguments[0])&&(o=arguments[0],s=arguments[1],l=arguments[2],\"responsive\"===arguments[0]&&\"array\"===i.type(arguments[1])?n=\"responsive\":\"undefined\"!=typeof arguments[1]&&(n=\"single\")),\"single\"===n)r.options[o]=s;else if(\"multiple\"===n)i.each(o,function(i,e){r.options[i]=e});else if(\"responsive\"===n)for(t in s)if(\"array\"!==i.type(r.options.responsive))r.options.responsive=[s[t]];else{for(e=r.options.responsive.length-1;e>=0;)r.options.responsive[e].breakpoint===s[t].breakpoint&&r.options.responsive.splice(e,1),e--;r.options.responsive.push(s[t])}l&&(r.unload(),r.reinit())},e.prototype.setPosition=function(){var i=this;i.setDimensions(),i.setHeight(),i.options.fade===!1?i.setCSS(i.getLeft(i.currentSlide)):i.setFade(),i.$slider.trigger(\"setPosition\",[i])},e.prototype.setProps=function(){var i=this,e=document.body.style;i.positionProp=i.options.vertical===!0?\"top\":\"left\",\n \"top\"===i.positionProp?i.$slider.addClass(\"slick-vertical\"):i.$slider.removeClass(\"slick-vertical\"),void 0===e.WebkitTransition&&void 0===e.MozTransition&&void 0===e.msTransition||i.options.useCSS===!0&&(i.cssTransitions=!0),i.options.fade&&(\"number\"==typeof i.options.zIndex?i.options.zIndex<3&&(i.options.zIndex=3):i.options.zIndex=i.defaults.zIndex),void 0!==e.OTransform&&(i.animType=\"OTransform\",i.transformType=\"-o-transform\",i.transitionType=\"OTransition\",void 0===e.perspectiveProperty&&void 0===e.webkitPerspective&&(i.animType=!1)),void 0!==e.MozTransform&&(i.animType=\"MozTransform\",i.transformType=\"-moz-transform\",i.transitionType=\"MozTransition\",void 0===e.perspectiveProperty&&void 0===e.MozPerspective&&(i.animType=!1)),void 0!==e.webkitTransform&&(i.animType=\"webkitTransform\",i.transformType=\"-webkit-transform\",i.transitionType=\"webkitTransition\",void 0===e.perspectiveProperty&&void 0===e.webkitPerspective&&(i.animType=!1)),void 0!==e.msTransform&&(i.animType=\"msTransform\",i.transformType=\"-ms-transform\",i.transitionType=\"msTransition\",void 0===e.msTransform&&(i.animType=!1)),void 0!==e.transform&&i.animType!==!1&&(i.animType=\"transform\",i.transformType=\"transform\",i.transitionType=\"transition\"),i.transformsEnabled=i.options.useTransform&&null!==i.animType&&i.animType!==!1},e.prototype.setSlideClasses=function(i){var e,t,o,s,n=this;if(t=n.$slider.find(\".slick-slide\").removeClass(\"slick-active slick-center slick-current\").attr(\"aria-hidden\",\"true\"),n.$slides.eq(i).addClass(\"slick-current\"),n.options.centerMode===!0){var r=n.options.slidesToShow%2===0?1:0;e=Math.floor(n.options.slidesToShow/2),n.options.infinite===!0&&(i>=e&&i<=n.slideCount-1-e?n.$slides.slice(i-e+r,i+e+1).addClass(\"slick-active\").attr(\"aria-hidden\",\"false\"):(o=n.options.slidesToShow+i,t.slice(o-e+1+r,o+e+2).addClass(\"slick-active\").attr(\"aria-hidden\",\"false\")),0===i?t.eq(t.length-1-n.options.slidesToShow).addClass(\"slick-center\"):i===n.slideCount-1&&t.eq(n.options.slidesToShow).addClass(\"slick-center\")),n.$slides.eq(i).addClass(\"slick-center\")}else i>=0&&i<=n.slideCount-n.options.slidesToShow?n.$slides.slice(i,i+n.options.slidesToShow).addClass(\"slick-active\").attr(\"aria-hidden\",\"false\"):t.length<=n.options.slidesToShow?t.addClass(\"slick-active\").attr(\"aria-hidden\",\"false\"):(s=n.slideCount%n.options.slidesToShow,o=n.options.infinite===!0?n.options.slidesToShow+i:i,n.options.slidesToShow==n.options.slidesToScroll&&n.slideCount-i<n.options.slidesToShow?t.slice(o-(n.options.slidesToShow-s),o+s).addClass(\"slick-active\").attr(\"aria-hidden\",\"false\"):t.slice(o,o+n.options.slidesToShow).addClass(\"slick-active\").attr(\"aria-hidden\",\"false\"));\"ondemand\"!==n.options.lazyLoad&&\"anticipated\"!==n.options.lazyLoad||n.lazyLoad()},e.prototype.setupInfinite=function(){var e,t,o,s=this;if(s.options.fade===!0&&(s.options.centerMode=!1),s.options.infinite===!0&&s.options.fade===!1&&(t=null,s.slideCount>s.options.slidesToShow)){for(o=s.options.centerMode===!0?s.options.slidesToShow+1:s.options.slidesToShow,e=s.slideCount;e>s.slideCount-o;e-=1)t=e-1,i(s.$slides[t]).clone(!0).attr(\"id\",\"\").attr(\"data-slick-index\",t-s.slideCount).prependTo(s.$slideTrack).addClass(\"slick-cloned\");for(e=0;e<o+s.slideCount;e+=1)t=e,i(s.$slides[t]).clone(!0).attr(\"id\",\"\").attr(\"data-slick-index\",t+s.slideCount).appendTo(s.$slideTrack).addClass(\"slick-cloned\");s.$slideTrack.find(\".slick-cloned\").find(\"[id]\").each(function(){i(this).attr(\"id\",\"\")})}},e.prototype.interrupt=function(i){var e=this;i||e.autoPlay(),e.interrupted=i},e.prototype.selectHandler=function(e){var t=this,o=i(e.target).is(\".slick-slide\")?i(e.target):i(e.target).parents(\".slick-slide\"),s=parseInt(o.attr(\"data-slick-index\"));return s||(s=0),t.slideCount<=t.options.slidesToShow?void t.slideHandler(s,!1,!0):void t.slideHandler(s)},e.prototype.slideHandler=function(i,e,t){var o,s,n,r,l,d=null,a=this;if(e=e||!1,!(a.animating===!0&&a.options.waitForAnimate===!0||a.options.fade===!0&&a.currentSlide===i))return e===!1&&a.asNavFor(i),o=i,d=a.getLeft(o),r=a.getLeft(a.currentSlide),a.currentLeft=null===a.swipeLeft?r:a.swipeLeft,a.options.infinite===!1&&a.options.centerMode===!1&&(i<0||i>a.getDotCount()*a.options.slidesToScroll)?void(a.options.fade===!1&&(o=a.currentSlide,t!==!0&&a.slideCount>a.options.slidesToShow?a.animateSlide(r,function(){a.postSlide(o)}):a.postSlide(o))):a.options.infinite===!1&&a.options.centerMode===!0&&(i<0||i>a.slideCount-a.options.slidesToScroll)?void(a.options.fade===!1&&(o=a.currentSlide,t!==!0&&a.slideCount>a.options.slidesToShow?a.animateSlide(r,function(){a.postSlide(o)}):a.postSlide(o))):(a.options.autoplay&&clearInterval(a.autoPlayTimer),s=o<0?a.slideCount%a.options.slidesToScroll!==0?a.slideCount-a.slideCount%a.options.slidesToScroll:a.slideCount+o:o>=a.slideCount?a.slideCount%a.options.slidesToScroll!==0?0:o-a.slideCount:o,a.animating=!0,a.$slider.trigger(\"beforeChange\",[a,a.currentSlide,s]),n=a.currentSlide,a.currentSlide=s,a.setSlideClasses(a.currentSlide),a.options.asNavFor&&(l=a.getNavTarget(),l=l.slick(\"getSlick\"),l.slideCount<=l.options.slidesToShow&&l.setSlideClasses(a.currentSlide)),a.updateDots(),a.updateArrows(),a.options.fade===!0?(t!==!0?(a.fadeSlideOut(n),a.fadeSlide(s,function(){a.postSlide(s)})):a.postSlide(s),void a.animateHeight()):void(t!==!0&&a.slideCount>a.options.slidesToShow?a.animateSlide(d,function(){a.postSlide(s)}):a.postSlide(s)))},e.prototype.startLoad=function(){var i=this;i.options.arrows===!0&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.hide(),i.$nextArrow.hide()),i.options.dots===!0&&i.slideCount>i.options.slidesToShow&&i.$dots.hide(),i.$slider.addClass(\"slick-loading\")},e.prototype.swipeDirection=function(){var i,e,t,o,s=this;return i=s.touchObject.startX-s.touchObject.curX,e=s.touchObject.startY-s.touchObject.curY,t=Math.atan2(e,i),o=Math.round(180*t/Math.PI),o<0&&(o=360-Math.abs(o)),o<=45&&o>=0?s.options.rtl===!1?\"left\":\"right\":o<=360&&o>=315?s.options.rtl===!1?\"left\":\"right\":o>=135&&o<=225?s.options.rtl===!1?\"right\":\"left\":s.options.verticalSwiping===!0?o>=35&&o<=135?\"down\":\"up\":\"vertical\"},e.prototype.swipeEnd=function(i){var e,t,o=this;if(o.dragging=!1,o.swiping=!1,o.scrolling)return o.scrolling=!1,!1;if(o.interrupted=!1,o.shouldClick=!(o.touchObject.swipeLength>10),void 0===o.touchObject.curX)return!1;if(o.touchObject.edgeHit===!0&&o.$slider.trigger(\"edge\",[o,o.swipeDirection()]),o.touchObject.swipeLength>=o.touchObject.minSwipe){switch(t=o.swipeDirection()){case\"left\":case\"down\":e=o.options.swipeToSlide?o.checkNavigable(o.currentSlide+o.getSlideCount()):o.currentSlide+o.getSlideCount(),o.currentDirection=0;break;case\"right\":case\"up\":e=o.options.swipeToSlide?o.checkNavigable(o.currentSlide-o.getSlideCount()):o.currentSlide-o.getSlideCount(),o.currentDirection=1}\"vertical\"!=t&&(o.slideHandler(e),o.touchObject={},o.$slider.trigger(\"swipe\",[o,t]))}else o.touchObject.startX!==o.touchObject.curX&&(o.slideHandler(o.currentSlide),o.touchObject={})},e.prototype.swipeHandler=function(i){var e=this;if(!(e.options.swipe===!1||\"ontouchend\"in document&&e.options.swipe===!1||e.options.draggable===!1&&i.type.indexOf(\"mouse\")!==-1))switch(e.touchObject.fingerCount=i.originalEvent&&void 0!==i.originalEvent.touches?i.originalEvent.touches.length:1,e.touchObject.minSwipe=e.listWidth/e.options.touchThreshold,e.options.verticalSwiping===!0&&(e.touchObject.minSwipe=e.listHeight/e.options.touchThreshold),i.data.action){case\"start\":e.swipeStart(i);break;case\"move\":e.swipeMove(i);break;case\"end\":e.swipeEnd(i)}},e.prototype.swipeMove=function(i){var e,t,o,s,n,r,l=this;return n=void 0!==i.originalEvent?i.originalEvent.touches:null,!(!l.dragging||l.scrolling||n&&1!==n.length)&&(e=l.getLeft(l.currentSlide),l.touchObject.curX=void 0!==n?n[0].pageX:i.clientX,l.touchObject.curY=void 0!==n?n[0].pageY:i.clientY,l.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(l.touchObject.curX-l.touchObject.startX,2))),r=Math.round(Math.sqrt(Math.pow(l.touchObject.curY-l.touchObject.startY,2))),!l.options.verticalSwiping&&!l.swiping&&r>4?(l.scrolling=!0,!1):(l.options.verticalSwiping===!0&&(l.touchObject.swipeLength=r),t=l.swipeDirection(),void 0!==i.originalEvent&&l.touchObject.swipeLength>4&&(l.swiping=!0,i.preventDefault()),s=(l.options.rtl===!1?1:-1)*(l.touchObject.curX>l.touchObject.startX?1:-1),l.options.verticalSwiping===!0&&(s=l.touchObject.curY>l.touchObject.startY?1:-1),o=l.touchObject.swipeLength,l.touchObject.edgeHit=!1,l.options.infinite===!1&&(0===l.currentSlide&&\"right\"===t||l.currentSlide>=l.getDotCount()&&\"left\"===t)&&(o=l.touchObject.swipeLength*l.options.edgeFriction,l.touchObject.edgeHit=!0),l.options.vertical===!1?l.swipeLeft=e+o*s:l.swipeLeft=e+o*(l.$list.height()/l.listWidth)*s,l.options.verticalSwiping===!0&&(l.swipeLeft=e+o*s),l.options.fade!==!0&&l.options.touchMove!==!1&&(l.animating===!0?(l.swipeLeft=null,!1):void l.setCSS(l.swipeLeft))))},e.prototype.swipeStart=function(i){var e,t=this;return t.interrupted=!0,1!==t.touchObject.fingerCount||t.slideCount<=t.options.slidesToShow?(t.touchObject={},!1):(void 0!==i.originalEvent&&void 0!==i.originalEvent.touches&&(e=i.originalEvent.touches[0]),t.touchObject.startX=t.touchObject.curX=void 0!==e?e.pageX:i.clientX,t.touchObject.startY=t.touchObject.curY=void 0!==e?e.pageY:i.clientY,void(t.dragging=!0))},e.prototype.unfilterSlides=e.prototype.slickUnfilter=function(){var i=this;null!==i.$slidesCache&&(i.unload(),i.$slideTrack.children(this.options.slide).detach(),i.$slidesCache.appendTo(i.$slideTrack),i.reinit())},e.prototype.unload=function(){var e=this;i(\".slick-cloned\",e.$slider).remove(),e.$dots&&e.$dots.remove(),e.$prevArrow&&e.htmlExpr.test(e.options.prevArrow)&&e.$prevArrow.remove(),e.$nextArrow&&e.htmlExpr.test(e.options.nextArrow)&&e.$nextArrow.remove(),e.$slides.removeClass(\"slick-slide slick-active slick-visible slick-current\").attr(\"aria-hidden\",\"true\").css(\"width\",\"\")},e.prototype.unslick=function(i){var e=this;e.$slider.trigger(\"unslick\",[e,i]),e.destroy()},e.prototype.updateArrows=function(){var i,e=this;i=Math.floor(e.options.slidesToShow/2),e.options.arrows===!0&&e.slideCount>e.options.slidesToShow&&!e.options.infinite&&(e.$prevArrow.removeClass(\"slick-disabled\").attr(\"aria-disabled\",\"false\"),e.$nextArrow.removeClass(\"slick-disabled\").attr(\"aria-disabled\",\"false\"),0===e.currentSlide?(e.$prevArrow.addClass(\"slick-disabled\").attr(\"aria-disabled\",\"true\"),e.$nextArrow.removeClass(\"slick-disabled\").attr(\"aria-disabled\",\"false\")):e.currentSlide>=e.slideCount-e.options.slidesToShow&&e.options.centerMode===!1?(e.$nextArrow.addClass(\"slick-disabled\").attr(\"aria-disabled\",\"true\"),e.$prevArrow.removeClass(\"slick-disabled\").attr(\"aria-disabled\",\"false\")):e.currentSlide>=e.slideCount-1&&e.options.centerMode===!0&&(e.$nextArrow.addClass(\"slick-disabled\").attr(\"aria-disabled\",\"true\"),e.$prevArrow.removeClass(\"slick-disabled\").attr(\"aria-disabled\",\"false\")))},e.prototype.updateDots=function(){var i=this;null!==i.$dots&&(i.$dots.find(\"li\").removeClass(\"slick-active\").end(),i.$dots.find(\"li\").eq(Math.floor(i.currentSlide/i.options.slidesToScroll)).addClass(\"slick-active\"))},e.prototype.visibility=function(){var i=this;i.options.autoplay&&(document[i.hidden]?i.interrupted=!0:i.interrupted=!1)},i.fn.slick=function(){var i,t,o=this,s=arguments[0],n=Array.prototype.slice.call(arguments,1),r=o.length;for(i=0;i<r;i++)if(\"object\"==typeof s||\"undefined\"==typeof s?o[i].slick=new e(o[i],s):t=o[i].slick[s].apply(o[i].slick,n),\"undefined\"!=typeof t)return t;return o}});\n","Magento_Vault/js/view/payment/vault.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*browser:true*/\n\n/* @api */\ndefine([\n 'underscore',\n 'uiComponent',\n 'Magento_Checkout/js/model/payment/renderer-list',\n 'uiLayout',\n 'uiRegistry'\n], function (_, Component, rendererList, layout, registry) {\n 'use strict';\n\n var vaultGroupName = 'vaultGroup';\n\n layout([{\n name: vaultGroupName,\n component: 'Magento_Checkout/js/model/payment/method-group',\n alias: 'vault',\n sortOrder: 10\n }]);\n\n registry.get(vaultGroupName, function (vaultGroup) {\n _.each(window.checkoutConfig.payment.vault, function (config, index) {\n rendererList.push(\n {\n type: index,\n config: config.config,\n component: config.component,\n group: vaultGroup,\n\n /**\n * Custom payment method types comparator\n * @param {String} typeA\n * @param {String} typeB\n * @return {Boolean}\n */\n typeComparatorCallback: function (typeA, typeB) {\n // vault token items have the same name as vault payment without index\n return typeA.substring(0, typeA.lastIndexOf('_')) === typeB;\n }\n }\n );\n });\n });\n\n /**\n * Add view logic here if needed\n */\n return Component.extend({});\n});\n","Magento_Vault/js/view/payment/vault-enabler.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*browser:true*/\n\n/* @api */\ndefine(\n [\n 'uiElement'\n ],\n function (\n Component\n ) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n isActivePaymentTokenEnabler: true\n },\n\n /**\n * @param {String} paymentCode\n */\n setPaymentCode: function (paymentCode) {\n this.paymentCode = paymentCode;\n },\n\n /**\n * @returns {Object}\n */\n initObservable: function () {\n this._super()\n .observe([\n 'isActivePaymentTokenEnabler'\n ]);\n\n return this;\n },\n\n /**\n * @param {Object} data\n */\n visitAdditionalData: function (data) {\n if (!this.isVaultEnabled()) {\n return;\n }\n\n if (!('additional_data' in data)) {\n data['additional_data'] = {};\n }\n\n data['additional_data']['is_active_payment_token_enabler'] = this.isActivePaymentTokenEnabler();\n },\n\n /**\n * @returns {Boolean}\n */\n isVaultEnabled: function () {\n return typeof window.checkoutConfig.vault[this.paymentCode] !== 'undefined' &&\n window.checkoutConfig.vault[this.paymentCode]['is_enabled'] === true;\n }\n });\n }\n);\n","Magento_Vault/js/view/payment/method-renderer/vault.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*browser:true*/\n\ndefine(\n [\n 'Magento_Checkout/js/view/payment/default',\n 'Magento_Checkout/js/action/select-payment-method',\n 'Magento_Checkout/js/checkout-data'\n ],\n function (Component, selectPaymentMethod, checkoutData) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n template: 'Magento_Vault/payment/form'\n },\n\n /**\n * @returns {exports.initObservable}\n */\n initObservable: function () {\n this._super()\n .observe([]);\n\n return this;\n },\n\n /**\n * @returns\n */\n selectPaymentMethod: function () {\n selectPaymentMethod(\n {\n method: this.getId()\n }\n );\n checkoutData.setSelectedPaymentMethod(this.getId());\n\n return true;\n },\n\n /**\n * @returns {String}\n */\n getTitle: function () {\n return '';\n },\n\n /**\n * @returns {String}\n */\n getToken: function () {\n return '';\n },\n\n /**\n * @returns {String}\n */\n getId: function () {\n return this.index;\n },\n\n /**\n * @returns {String}\n */\n getCode: function () {\n return this.code;\n },\n\n /**\n * Get last 4 digits of card\n * @returns {String}\n */\n getMaskedCard: function () {\n return '';\n },\n\n /**\n * Get expiration date\n * @returns {String}\n */\n getExpirationDate: function () {\n return '';\n },\n\n /**\n * Get card type\n * @returns {String}\n */\n getCardType: function () {\n return '';\n },\n\n /**\n * @param {String} type\n * @returns {Boolean}\n */\n getIcons: function (type) {\n return window.checkoutConfig.payment.ccform.icons.hasOwnProperty(type) ?\n window.checkoutConfig.payment.ccform.icons[type]\n : false;\n },\n\n /**\n * Return state of place order button.\n *\n * @return {Boolean}\n */\n isButtonActive: function () {\n return this.isActive() && this.isPlaceOrderActionAllowed();\n },\n\n /**\n * Check if payment is active.\n *\n * @return {Boolean}\n */\n isActive: function () {\n return this.isChecked() === this.getId();\n },\n\n /**\n * @returns {*}\n */\n getData: function () {\n var data = {\n method: this.getCode()\n };\n\n data['additional_data'] = {};\n data['additional_data']['public_hash'] = this.getToken();\n\n return data;\n }\n });\n }\n);\n","Magento_Vault/js/customer_account/deleteWidget.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'Magento_Ui/js/modal/modalToggle',\n 'mage/translate'\n], function ($, modalToggle) {\n 'use strict';\n\n return function (config, deleteButton) {\n config.buttons = [\n {\n text: $.mage.__('Cancel'),\n class: 'action secondary cancel'\n }, {\n text: $.mage.__('Delete'),\n class: 'action primary',\n\n /**\n * Default action on button click\n */\n click: function (event) { //eslint-disable-line no-unused-vars\n $(deleteButton.form).trigger('submit');\n }\n }\n ];\n\n modalToggle(config, deleteButton);\n };\n});\n","Magento_InventorySwatchesFrontendUi/js/swatch-renderer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'configurableVariationQty',\n 'jquery-ui-modules/widget'\n], function ($, configurableVariationQty) {\n 'use strict';\n\n return function (SwatchRenderer) {\n $.widget('mage.SwatchRenderer', SwatchRenderer, {\n\n /** @inheritdoc */\n _OnClick: function ($this, widget) {\n var salesChannel = this.options.jsonConfig.channel,\n salesChannelCode = this.options.jsonConfig.salesChannelCode,\n productVariationsSku = this.options.jsonConfig.sku;\n\n this._super($this, widget);\n configurableVariationQty(productVariationsSku[widget.getProductId()], salesChannel, salesChannelCode);\n }\n });\n\n return $.mage.SwatchRenderer;\n };\n});\n","Magento_Ups/js/view/shipping-rates-validation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'uiComponent',\n 'Magento_Checkout/js/model/shipping-rates-validator',\n 'Magento_Checkout/js/model/shipping-rates-validation-rules',\n 'Magento_Ups/js/model/shipping-rates-validator',\n 'Magento_Ups/js/model/shipping-rates-validation-rules'\n], function (\n Component,\n defaultShippingRatesValidator,\n defaultShippingRatesValidationRules,\n upsShippingRatesValidator,\n upsShippingRatesValidationRules\n) {\n 'use strict';\n\n defaultShippingRatesValidator.registerValidator('ups', upsShippingRatesValidator);\n defaultShippingRatesValidationRules.registerRules('ups', upsShippingRatesValidationRules);\n\n return Component;\n});\n","Magento_Ups/js/model/shipping-rates-validator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'mageUtils',\n 'Magento_Ups/js/model/shipping-rates-validation-rules',\n 'mage/translate'\n], function ($, utils, validationRules, $t) {\n 'use strict';\n\n return {\n validationErrors: [],\n\n /**\n * @param {Object} address\n * @return {Boolean}\n */\n validate: function (address) {\n var self = this;\n\n this.validationErrors = [];\n $.each(validationRules.getRules(), function (field, rule) {\n var message;\n\n if (rule.required && utils.isEmpty(address[field])) {\n message = $t('Field ') + field + $t(' is required.');\n self.validationErrors.push(message);\n }\n });\n\n return !this.validationErrors.length;\n }\n };\n});\n","Magento_Ups/js/model/shipping-rates-validation-rules.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 * @return {Object}\n */\n getRules: function () {\n return {\n 'postcode': {\n 'required': true\n },\n 'country_id': {\n 'required': true\n }\n };\n }\n };\n});\n","Magento_Search/js/form-mini.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'jquery',\n 'underscore',\n 'mage/template',\n 'matchMedia',\n 'jquery-ui-modules/widget',\n 'jquery-ui-modules/core',\n 'mage/translate'\n], function ($, _, mageTemplate, mediaCheck) {\n 'use strict';\n\n /**\n * Check whether the incoming string is not empty or if doesn't consist of spaces.\n *\n * @param {String} value - Value to check.\n * @returns {Boolean}\n */\n function isEmpty(value) {\n return value.length === 0 || value == null || /^\\s+$/.test(value);\n }\n\n $.widget('mage.quickSearch', {\n options: {\n autocomplete: 'off',\n minSearchLength: 3,\n responseFieldElements: 'ul li',\n selectClass: 'selected',\n template:\n '<li class=\"<%- data.row_class %>\" id=\"qs-option-<%- data.index %>\" role=\"option\">' +\n '<span class=\"qs-option-name\">' +\n ' <%- data.title %>' +\n '</span>' +\n '<span aria-hidden=\"true\" class=\"amount\">' +\n '<%- data.num_results %>' +\n '</span>' +\n '</li>',\n submitBtn: 'button[type=\"submit\"]',\n searchLabel: '[data-role=minisearch-label]',\n isExpandable: null,\n suggestionDelay: 300\n },\n\n /** @inheritdoc */\n _create: function () {\n this.responseList = {\n indexList: null,\n selected: null\n };\n this.autoComplete = $(this.options.destinationSelector);\n this.searchForm = $(this.options.formSelector);\n this.submitBtn = this.searchForm.find(this.options.submitBtn)[0];\n this.searchLabel = this.searchForm.find(this.options.searchLabel);\n this.isExpandable = this.options.isExpandable;\n\n _.bindAll(this, '_onKeyDown', '_onPropertyChange', '_onSubmit');\n\n this.submitBtn.disabled = true;\n\n this.element.attr('autocomplete', this.options.autocomplete);\n\n mediaCheck({\n media: '(max-width: 768px)',\n entry: function () {\n this.isExpandable = true;\n }.bind(this),\n exit: function () {\n this.isExpandable = true;\n }.bind(this)\n });\n\n this.searchLabel.on('click', function (e) {\n // allow input to lose its' focus when clicking on label\n if (this.isExpandable && this.isActive()) {\n e.preventDefault();\n }\n }.bind(this));\n\n this.element.on('blur', $.proxy(function () {\n if (!this.searchLabel.hasClass('active')) {\n return;\n }\n\n setTimeout($.proxy(function () {\n if (this.autoComplete.is(':hidden')) {\n this.setActiveState(false);\n } else {\n this.element.trigger('focus');\n }\n this.autoComplete.hide();\n this._updateAriaHasPopup(false);\n }, this), 250);\n }, this));\n\n if (this.element.get(0) === document.activeElement) {\n this.setActiveState(true);\n }\n\n this.element.on('focus', this.setActiveState.bind(this, true));\n this.element.on('keydown', this._onKeyDown);\n // Prevent spamming the server with requests by waiting till the user has stopped typing for period of time\n this.element.on('input propertychange', _.debounce(this._onPropertyChange, this.options.suggestionDelay));\n\n this.searchForm.on('submit', $.proxy(function (e) {\n this._onSubmit(e);\n this._updateAriaHasPopup(false);\n }, this));\n },\n\n /**\n * Checks if search field is active.\n *\n * @returns {Boolean}\n */\n isActive: function () {\n return this.searchLabel.hasClass('active');\n },\n\n /**\n * Sets state of the search field to provided value.\n *\n * @param {Boolean} isActive\n */\n setActiveState: function (isActive) {\n var searchValue;\n\n this.searchForm.toggleClass('active', isActive);\n this.searchLabel.toggleClass('active', isActive);\n\n if (this.isExpandable) {\n this.element.attr('aria-expanded', isActive);\n searchValue = this.element.val();\n this.element.val('');\n this.element.val(searchValue);\n }\n },\n\n /**\n * @private\n * @return {Element} The first element in the suggestion list.\n */\n _getFirstVisibleElement: function () {\n return this.responseList.indexList ? this.responseList.indexList.first() : false;\n },\n\n /**\n * @private\n * @return {Element} The last element in the suggestion list.\n */\n _getLastElement: function () {\n return this.responseList.indexList ? this.responseList.indexList.last() : false;\n },\n\n /**\n * @private\n * @param {Boolean} show - Set attribute aria-haspopup to \"true/false\" for element.\n */\n _updateAriaHasPopup: function (show) {\n if (show) {\n this.element.attr('aria-haspopup', 'true');\n } else {\n this.element.attr('aria-haspopup', 'false');\n }\n },\n\n /**\n * Clears the item selected from the suggestion list and resets the suggestion list.\n * @private\n * @param {Boolean} all - Controls whether to clear the suggestion list.\n */\n _resetResponseList: function (all) {\n this.responseList.selected = null;\n\n if (all === true) {\n this.responseList.indexList = null;\n }\n },\n\n /**\n * Executes when the search box is submitted. Sets the search input field to the\n * value of the selected item.\n * @private\n * @param {Event} e - The submit event\n */\n _onSubmit: function (e) {\n var value = this.element.val();\n\n if (isEmpty(value)) {\n e.preventDefault();\n }\n\n if (this.responseList.selected) {\n this.element.val(this.responseList.selected.find('.qs-option-name').text());\n }\n },\n\n /**\n * Executes when keys are pressed in the search input field. Performs specific actions\n * depending on which keys are pressed.\n * @private\n * @param {Event} e - The key down event\n * @return {Boolean} Default return type for any unhandled keys\n */\n _onKeyDown: function (e) {\n var keyCode = e.keyCode || e.which;\n\n switch (keyCode) {\n case $.ui.keyCode.HOME:\n if (this._getFirstVisibleElement()) {\n this._getFirstVisibleElement().addClass(this.options.selectClass);\n this.responseList.selected = this._getFirstVisibleElement();\n }\n break;\n\n case $.ui.keyCode.END:\n if (this._getLastElement()) {\n this._getLastElement().addClass(this.options.selectClass);\n this.responseList.selected = this._getLastElement();\n }\n break;\n\n case $.ui.keyCode.ESCAPE:\n this._resetResponseList(true);\n this.autoComplete.hide();\n break;\n\n case $.ui.keyCode.ENTER:\n if (this.element.val().length >= parseInt(this.options.minSearchLength, 10)) {\n this.searchForm.trigger('submit');\n e.preventDefault();\n }\n break;\n\n case $.ui.keyCode.DOWN:\n if (this.responseList.indexList) {\n if (!this.responseList.selected) { //eslint-disable-line max-depth\n this._getFirstVisibleElement().addClass(this.options.selectClass);\n this.responseList.selected = this._getFirstVisibleElement();\n } else if (!this._getLastElement().hasClass(this.options.selectClass)) {\n this.responseList.selected = this.responseList.selected\n .removeClass(this.options.selectClass).next().addClass(this.options.selectClass);\n } else {\n this.responseList.selected.removeClass(this.options.selectClass);\n this._getFirstVisibleElement().addClass(this.options.selectClass);\n this.responseList.selected = this._getFirstVisibleElement();\n }\n this.element.val(this.responseList.selected.find('.qs-option-name').text());\n this.element.attr('aria-activedescendant', this.responseList.selected.attr('id'));\n this._updateAriaHasPopup(true);\n this.autoComplete.show();\n }\n break;\n\n case $.ui.keyCode.UP:\n if (this.responseList.indexList !== null) {\n if (!this._getFirstVisibleElement().hasClass(this.options.selectClass)) {\n this.responseList.selected = this.responseList.selected\n .removeClass(this.options.selectClass).prev().addClass(this.options.selectClass);\n\n } else {\n this.responseList.selected.removeClass(this.options.selectClass);\n this._getLastElement().addClass(this.options.selectClass);\n this.responseList.selected = this._getLastElement();\n }\n this.element.val(this.responseList.selected.find('.qs-option-name').text());\n this.element.attr('aria-activedescendant', this.responseList.selected.attr('id'));\n this._updateAriaHasPopup(true);\n this.autoComplete.show();\n }\n break;\n default:\n return true;\n }\n },\n\n /**\n * Executes when the value of the search input field changes. Executes a GET request\n * to populate a suggestion list based on entered text. Handles click (select), hover,\n * and mouseout events on the populated suggestion list dropdown.\n * @private\n */\n _onPropertyChange: function () {\n var searchField = this.element,\n clonePosition = {\n position: 'absolute',\n // Removed to fix display issues\n // left: searchField.offset().left,\n // top: searchField.offset().top + searchField.outerHeight(),\n width: searchField.outerWidth()\n },\n source = this.options.template,\n template = mageTemplate(source),\n dropdown = $('<ul role=\"listbox\"></ul>'),\n value = this.element.val();\n\n this.submitBtn.disabled = true;\n\n if (value.length >= parseInt(this.options.minSearchLength, 10)) {\n this.submitBtn.disabled = false;\n\n if (this.options.url !== '') { //eslint-disable-line eqeqeq\n $.getJSON(this.options.url, {\n q: value\n }, $.proxy(function (data) {\n if (data.length) {\n $.each(data, function (index, element) {\n var html;\n\n element.index = index;\n html = template({\n data: element\n });\n dropdown.append(html);\n });\n\n this._resetResponseList(true);\n\n this.responseList.indexList = this.autoComplete.html(dropdown)\n .css(clonePosition)\n .show()\n .find(this.options.responseFieldElements + ':visible');\n\n this.element.removeAttr('aria-activedescendant');\n\n if (this.responseList.indexList.length) {\n this._updateAriaHasPopup(true);\n } else {\n this._updateAriaHasPopup(false);\n }\n\n this.responseList.indexList\n .on('click', function (e) {\n this.responseList.selected = $(e.currentTarget);\n this.searchForm.trigger('submit');\n }.bind(this))\n .on('mouseenter mouseleave', function (e) {\n this.responseList.indexList.removeClass(this.options.selectClass);\n $(e.target).addClass(this.options.selectClass);\n this.responseList.selected = $(e.target);\n this.element.attr('aria-activedescendant', $(e.target).attr('id'));\n }.bind(this))\n .on('mouseout', function (e) {\n if (!this._getLastElement() &&\n this._getLastElement().hasClass(this.options.selectClass)) {\n $(e.target).removeClass(this.options.selectClass);\n this._resetResponseList(false);\n }\n }.bind(this));\n } else {\n this._resetResponseList(true);\n this.autoComplete.hide();\n this._updateAriaHasPopup(false);\n this.element.removeAttr('aria-activedescendant');\n }\n }, this));\n }\n } else {\n this._resetResponseList(true);\n this.autoComplete.hide();\n this._updateAriaHasPopup(false);\n this.element.removeAttr('aria-activedescendant');\n }\n }\n });\n\n return $.mage.quickSearch;\n});\n","Magento_Theme/js/cookie-status.js":"define([\n 'jquery',\n 'Magento_Ui/js/modal/modal',\n 'mage/translate'\n], function ($, modal) {\n 'use strict';\n\n $.widget('mage.cookieStatus', {\n options: {\n type: 'popup',\n responsive: true,\n innerScroll: true,\n autoOpen: true,\n buttons: [{\n text: $.mage.__('Close'),\n class: 'cookie-status',\n\n /**\n * Callback for click event\n */\n click: function () {\n this.closeModal();\n }\n }]\n },\n\n /**\n * Init object\n * @private\n */\n _init: function () {\n\n if (!navigator.cookieEnabled) {\n modal(this.options, $('#cookie-status'));\n }\n }\n });\n\n return $.mage.cookieStatus;\n});\n","Magento_Theme/js/theme.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'mage/smart-keyboard-handler',\n 'mage/mage',\n 'domReady!'\n], function ($, keyboardHandler) {\n 'use strict';\n\n $('.cart-summary').mage('sticky', {\n container: '#maincontent'\n });\n\n $('.panel.header > .header.links').clone().appendTo('#store\\\\.links');\n $('#store\\\\.links li a').each(function () {\n var id = $(this).attr('id');\n\n if (id !== undefined) {\n $(this).attr('id', id + '_mobile');\n }\n });\n keyboardHandler.apply();\n});\n","Magento_Theme/js/row-builder.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * JQuery UI Widget declaration: 'mage.rowBuilder'\n *\n * @api\n */\ndefine([\n 'jquery',\n 'mage/template',\n 'jquery-ui-modules/widget'\n], function ($, mageTemplate) {\n 'use strict';\n\n $.widget('mage.rowBuilder', {\n\n /**\n * options with default values for setting up the template\n */\n options: {\n //Default template options\n rowTemplate: '#template-registrant',\n rowContainer: '#registrant-container',\n //Row index used by the template rows.\n rowIndex: 0,\n //Row count: Should not be set externally\n rowCount: 0,\n rowParentElem: '<li></li>',\n rowContainerClass: 'fields',\n addRowBtn: '#add-registrant-button',\n btnRemoveIdPrefix: 'btn-remove',\n btnRemoveSelector: '.btn-remove',\n rowIdPrefix: 'row',\n //This class is added to rows added after the first one. Adds the dotted separator\n additionalRowClass: 'add-row',\n\n /*\n This is provided during widget instantiation. eg :\n formDataPost : {\"formData\":formData,\"templateFields\":['field1-name','field2-name'] }\n -\"formData\" is the multi-dimensional array of form field values : [['a','b'],['c','b']]\n received from the server and encoded\n -\"templateFields\" are the input fields in the template with index suffixed after the field name\n eg field1-name{index}\n */\n formDataPost: null,\n //Default selectors for add element of a template\n addEventSelector: 'button',\n //Default selectors for remove markup elements of a template\n remEventSelector: 'a',\n //This option allows adding first row delete option and a row separator\n hideFirstRowAddSeparator: true,\n //Max rows - This option should be set when instantiating the widget\n maxRows: 1000,\n maxRowsMsg: '#max-registrant-message'\n },\n\n /**\n * Initialize create\n * @private\n */\n _create: function () {\n this.rowTemplate = mageTemplate(this.options.rowTemplate);\n\n this.options.rowCount = this.options.rowIndex = 0;\n\n //On document ready related tasks\n $($.proxy(this.ready, this));\n\n //Binding template-wide events handlers for adding and removing rows\n this.element.on(\n 'click',\n this.options.addEventSelector + this.options.addRowBtn,\n $.proxy(this.handleAdd, this)\n );\n this.element.on(\n 'click',\n this.options.remEventSelector + this.options.btnRemoveSelector,\n $.proxy(this.handleRemove, this)\n );\n },\n\n /**\n * Initialize template\n * @public\n */\n ready: function () {\n if (this.options.formDataPost &&\n this.options.formDataPost.formData &&\n this.options.formDataPost.formData.length\n ) {\n this.processFormDataArr(this.options.formDataPost);\n } else if (this.options.rowIndex === 0 && this.options.maxRows !== 0) {\n //If no form data , then add default row\n this.addRow(0);\n }\n },\n\n /**\n * Process and loop through all row data to create preselected values. This is used for any error on submit.\n * For complex implementations the inheriting widget can override this behavior\n * @public\n * @param {Object} formDataArr\n */\n processFormDataArr: function (formDataArr) {\n var formData = formDataArr.formData,\n templateFields = formDataArr.templateFields,\n formRow,\n i, j;\n\n for (i = this.options.rowIndex = 0; i < formData.length; this.options.rowIndex = i++) {\n this.addRow(i);\n\n formRow = formData[i];\n\n for (j = 0; j < formRow.length; j++) {\n this.setFieldById(templateFields[j] + i, formRow[j]);\n }\n }\n\n },\n\n /**\n * Initialize and create markup for template row. Add it to the parent container.\n * The template processing will substitute row index at all places marked with _index_ in the template\n * using the template\n * @public\n * @param {Number} index - current index/count of the created template. This will be used as the id\n * @return {*}\n */\n addRow: function (index) {\n var row = $(this.options.rowParentElem),\n tmpl;\n\n row.addClass(this.options.rowContainerClass).attr('id', this.options.rowIdPrefix + index);\n\n tmpl = this.rowTemplate({\n data: {\n _index_: index\n }\n });\n\n $(tmpl).appendTo(row);\n\n $(this.options.rowContainer).append(row).trigger('contentUpdated');\n\n row.addClass(this.options.additionalRowClass);\n\n //Remove 'delete' link and additionalRowClass for first row\n if (this.options.rowIndex === 0 && this.options.hideFirstRowAddSeparator) {\n $('#' + this._esc(this.options.btnRemoveIdPrefix) + '0').remove();\n $('#' + this._esc(this.options.rowIdPrefix) + '0').removeClass(this.options.additionalRowClass);\n }\n\n this.maxRowCheck(++this.options.rowCount);\n\n return row;\n },\n\n /**\n * Remove return item information row\n * @public\n * @param {*} rowIndex - return item information row index\n * @return {Boolean}\n */\n removeRow: function (rowIndex) {\n $('#' + this._esc(this.options.rowIdPrefix) + rowIndex).remove();\n this.maxRowCheck(--this.options.rowCount);\n\n return false;\n },\n\n /**\n * Function to check if maximum rows are exceeded and render/hide maxMsg and Add btn\n * @public\n * @param {Number} rowIndex\n */\n maxRowCheck: function (rowIndex) {\n var addRowBtn = $(this.options.addRowBtn),\n maxRowMsg = $(this.options.maxRowsMsg);\n\n //liIndex starts from 0\n if (rowIndex >= this.options.maxRows) {\n addRowBtn.hide();\n maxRowMsg.show();\n } else if (addRowBtn.is(':hidden')) {\n addRowBtn.show();\n maxRowMsg.hide();\n }\n },\n\n /**\n * Set the value on given element\n * @public\n * @param {String} domId\n * @param {String} value\n */\n setFieldById: function (domId, value) {\n var x = $('#' + this._esc(domId));\n\n if (x.length) {\n\n if (x.is(':checkbox')) {\n x.attr('checked', true);\n } else if (x.is('option')) {\n x.attr('selected', 'selected');\n } else {\n x.val(value);\n }\n }\n },\n\n /**\n * Delegated handler for adding a row\n * @public\n * @return {Boolean}\n */\n handleAdd: function () {\n this.addRow(++this.options.rowIndex);\n\n return false;\n },\n\n /**\n * Delegated handler for removing a selected row\n * @public\n * @param {Object} e - Native event object\n * @return {Boolean}\n */\n handleRemove: function (e) {\n this.removeRow($(e.currentTarget).closest('[id^=\"' + this.options.btnRemoveIdPrefix + '\"]')\n .attr('id').replace(this.options.btnRemoveIdPrefix, ''));\n\n return false;\n },\n\n /**\n * Utility function to add escape chars for jquery selector strings\n * @private\n * @param {String} str - String to be processed\n * @return {String}\n */\n _esc: function (str) {\n return str ? str.replace(/([ ;&,.+*~\\':\"!\\^$\\[\\]()=>|\\/@])/g, '\\\\$1') : str;\n }\n });\n\n return $.mage.rowBuilder;\n});\n","Magento_Theme/js/view/add-home-breadcrumb.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/* eslint-disable max-nested-callbacks, no-undef */\ndefine([\n 'jquery',\n 'Magento_Theme/js/model/breadcrumb-list',\n 'mage/translate'\n], function ($, breadcrumbList) {\n 'use strict';\n\n /**\n * @return {Object}\n */\n var homeCrumb = function () {\n return {\n name: 'home',\n label: $.mage.__('Home'),\n title: $.mage.__('Go to Home Page'),\n link: BASE_URL || ''\n };\n };\n\n return function (breadcrumb) {\n\n breadcrumbList.unshift(homeCrumb());\n\n return breadcrumb;\n };\n});\n","Magento_Theme/js/view/messages.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'jquery',\n 'uiComponent',\n 'Magento_Customer/js/customer-data',\n 'underscore',\n 'escaper',\n 'jquery/jquery-storageapi'\n], function ($, Component, customerData, _, escaper) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n cookieMessages: [],\n cookieMessagesObservable: [],\n messages: [],\n allowedTags: ['div', 'span', 'b', 'strong', 'i', 'em', 'u', 'a']\n },\n\n /**\n * Extends Component object by storage observable messages.\n */\n initialize: function () {\n this._super().observe(\n [\n 'cookieMessagesObservable'\n ]\n );\n\n // The \"cookieMessages\" variable is not used anymore. It exists for backward compatibility; to support\n // merchants who have overwritten \"messages.phtml\" which would still point to cookieMessages instead of the\n // observable variant (also see https://github.com/magento/magento2/pull/37309).\n this.cookieMessages = _.unique($.cookieStorage.get('mage-messages'), 'text');\n this.cookieMessagesObservable(this.cookieMessages);\n\n this.messages = customerData.get('messages').extend({\n disposableCustomerData: 'messages'\n });\n\n $.mage.cookies.set('mage-messages', '', {\n samesite: 'strict',\n domain: ''\n });\n },\n\n /**\n * Prepare the given message to be rendered as HTML\n *\n * @param {String} message\n * @return {String}\n */\n prepareMessageForHtml: function (message) {\n return escaper.escapeHtml(message, this.allowedTags);\n },\n purgeMessages: function () {\n if (!_.isEmpty(this.messages().messages)) {\n customerData.set('messages', {});\n }\n }\n });\n});\n","Magento_Theme/js/view/breadcrumbs.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 'Magento_Theme/js/model/breadcrumb-list',\n 'text!Magento_Theme/templates/breadcrumbs.html',\n 'jquery-ui-modules/widget'\n], function ($, mageTemplate, breadcrumbList, tpl) {\n 'use strict';\n\n /**\n * Breadcrumb Widget.\n */\n $.widget('mage.breadcrumbs', {\n\n /** @inheritdoc */\n _init: function () {\n this._super();\n this._render();\n },\n\n /**\n * Render breadcrumb.\n *\n * @private\n */\n _render: function () {\n var html,\n crumbs = breadcrumbList,\n template = mageTemplate(tpl);\n\n this._decorate(crumbs);\n\n html = template({\n 'breadcrumbs': crumbs\n });\n\n if (html.length) {\n $(this.element).html(html);\n }\n },\n\n /**\n * Decorate list.\n *\n * @param {Array} list\n * @private\n */\n _decorate: function (list) {\n\n if (list.length) {\n list[0].first = true;\n }\n\n if (list.length > 1) {\n list[list.length - 1].last = true;\n }\n }\n });\n\n return $.mage.breadcrumbs;\n});\n","Magento_Theme/js/model/breadcrumb-list.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"}
}});