1require.config({"config": { 2 "jsbuild":{"mage/validation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n(function (factory) {\n 'use strict';\n\n if (typeof define === 'function' && define.amd) {\n define([\n 'jquery',\n 'moment',\n 'jquery/ui',\n 'jquery/validate',\n 'mage/translate'\n ], factory);\n } else {\n factory(jQuery);\n }\n}(function ($, moment) {\n 'use strict';\n\n var creditCartTypes, rules, showLabel, originValidateDelegate;\n\n $.extend(true, $, {\n // @TODO: Move methods 'isEmpty', 'isEmptyNoTrim', 'parseNumber', 'stripHtml' in file with utility functions\n mage: {\n /**\n * Check if string is empty with trim\n * @param {String} value\n */\n isEmpty: function (value) {\n return value === '' || value === undefined ||\n value == null || value.length === 0 || /^\\s+$/.test(value);\n },\n\n /**\n * Check if string is empty no trim\n * @param {String} value\n */\n isEmptyNoTrim: function (value) {\n return value === '' || value == null || value.length === 0;\n },\n\n /**\n * Checks if {value} is between numbers {from} and {to}\n * @param {String} value\n * @param {String} from\n * @param {String} to\n * @returns {Boolean}\n */\n isBetween: function (value, from, to) {\n return ($.mage.isEmpty(from) || value >= $.mage.parseNumber(from)) &&\n ($.mage.isEmpty(to) || value <= $.mage.parseNumber(to));\n },\n\n /**\n * Parse price string\n * @param {String} value\n */\n parseNumber: function (value) {\n var isDot, isComa;\n\n if (typeof value !== 'string') {\n return parseFloat(value);\n }\n isDot = value.indexOf('.');\n isComa = value.indexOf(',');\n\n if (isDot !== -1 && isComa !== -1) {\n if (isComa > isDot) {\n value = value.replace('.', '').replace(',', '.');\n } else {\n value = value.replace(',', '');\n }\n } else if (isComa !== -1) {\n value = value.replace(',', '.');\n }\n\n return parseFloat(value);\n },\n\n /**\n * Removes HTML tags and space characters, numbers and punctuation.\n *\n * @param {String} value - Value being stripped.\n * @return {String}\n */\n stripHtml: function (value) {\n return value.replace(/<.[^<>]*?>/g, ' ').replace(/ | /gi, ' ')\n .replace(/[0-9.(),;:!?%#$'\"_+=\\/-]*/g, '');\n }\n }\n });\n\n /**\n * @param {String} name\n * @param {*} method\n * @param {*} message\n * @param {*} dontSkip\n */\n $.validator.addMethod = function (name, method, message, dontSkip) {\n $.validator.methods[name] = method;\n $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name];\n\n if (method.length < 3 || dontSkip) {\n $.validator.addClassRules(name, $.validator.normalizeRule(name));\n }\n };\n\n /**\n * Javascript object with credit card types\n * 0 - regexp for card number\n * 1 - regexp for cvn\n * 2 - check or not credit card number trough Luhn algorithm by\n */\n creditCartTypes = {\n 'SO': [\n new RegExp('^(6334[5-9]([0-9]{11}|[0-9]{13,14}))|(6767([0-9]{12}|[0-9]{14,15}))$'),\n new RegExp('^([0-9]{3}|[0-9]{4})?$'),\n true\n ],\n 'SM': [\n new RegExp('(^(5[0678])[0-9]{11,18}$)|(^(6[^05])[0-9]{11,18}$)|' +\n '(^(601)[^1][0-9]{9,16}$)|(^(6011)[0-9]{9,11}$)|(^(6011)[0-9]{13,16}$)|' +\n '(^(65)[0-9]{11,13}$)|(^(65)[0-9]{15,18}$)|(^(49030)[2-9]([0-9]{10}$|[0-9]{12,13}$))|' +\n '(^(49033)[5-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49110)[1-2]([0-9]{10}$|[0-9]{12,13}$))|' +\n '(^(49117)[4-9]([0-9]{10}$|[0-9]{12,13}$))|(^(49118)[0-2]([0-9]{10}$|[0-9]{12,13}$))|' +\n '(^(4936)([0-9]{12}$|[0-9]{14,15}$))'), new RegExp('^([0-9]{3}|[0-9]{4})?$'),\n true\n ],\n 'VI': [new RegExp('^4[0-9]{12}([0-9]{3})?$'), new RegExp('^[0-9]{3}$'), true],\n 'MC': [\n new RegExp('^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}
2|27[01][0-9]|2720)[0-9]{12}$'),\n new RegExp('^[0-9]{3}$'),\n true\n ],\n 'AE': [new RegExp('^3[47][0-9]{13}$'), new RegExp('^[0-9]{4}$'), true],\n 'DI': [new RegExp('^(6011(0|[2-4]|74|7[7-9]|8[6-9]|9)|6(4[4-9]|5))\\\\d*$'), new RegExp('^[0-9]{3}$'), true],\n 'JCB': [new RegExp('^35(2[8-9]|[3-8])\\\\d*$'), new RegExp('^[0-9]{3}$'), true],\n 'DN': [new RegExp('^(3(0[0-5]|095|6|[8-9]))\\\\d*$'), new RegExp('^[0-9]{3}$'), true],\n 'UN': [\n new RegExp('^(622(1(2[6-9]|[3-9])|[3-8]|9([[0-1]|2[0-5]))|62[4-6]|628([2-8]))\\\\d*?$'),\n new RegExp('^[0-9]{3}$'),\n true\n ],\n 'MI': [new RegExp('^(5(0|[6-9])|63|67(?!59|6770|6774))\\\\d*$'), new RegExp('^[0-9]{3}$'), true],\n 'MD': [new RegExp('^6759(?!24|38|40|6[3-9]|70|76)|676770|676774\\\\d*$'), new RegExp('^[0-9]{3}$'), true]\n };\n\n /**\n * validate credit card number using mod10\n * @param {String} s\n * @return {Boolean}\n */\n function validateCreditCard(s) {\n // remove non-numerics\n var v = '0123456789',\n w = '',\n i, j, k, m, c, a, x;\n\n for (i = 0; i < s.length; i++) {\n x = s.charAt(i);\n\n if (v.indexOf(x, 0) !== -1) {\n w += x;\n }\n }\n // validate number\n j = w.length / 2;\n k = Math.floor(j);\n m = Math.ceil(j) - k;\n c = 0;\n\n for (i = 0; i < k; i++) {\n a = w.charAt(i * 2 + m) * 2;\n c += a > 9 ? Math.floor(a / 10 + a % 10) : a;\n }\n\n for (i = 0; i < k + m; i++) {\n c += w.charAt(i * 2 + 1 - m) * 1;\n }\n\n return c % 10 === 0;\n }\n\n /**\n * validate all table required inputs at once, using single hidden input\n * @param {String} value\n * @param {HTMLElement} element\n *\n * @return {Boolean}\n */\n function tableSingleValidation(value, element) {\n var empty = $(element).closest('table')\n .find('input.required-option:visible')\n .filter(function (i, el) {\n if ($(el).is('disabled')) {\n return $.mage.isEmpty(el.value);\n }\n })\n .length;\n\n return empty === 0;\n }\n\n /**\n * Collection of validation rules including rules from additional-methods.js\n * @type {Object}\n */\n rules = {\n 'max-words': [\n function (value, element, params) {\n return this.optional(element) || $.mage.stripHtml(value).match(/\\b\\w+\\b/g).length < params;\n },\n $.mage.__('Please enter {0} words or less.')\n ],\n 'min-words': [\n function (value, element, params) {\n return this.optional(element) || $.mage.stripHtml(value).match(/\\b\\w+\\b/g).length >= params;\n },\n $.mage.__('Please enter at least {0} words.')\n ],\n 'range-words': [\n function (value, element, params) {\n return this.optional(element) ||\n $.mage.stripHtml(value).match(/\\b\\w+\\b/g).length >= params[0] &&\n value.match(/bw+b/g).length < params[1];\n },\n $.mage.__('Please enter between {0} and {1} words.')\n ],\n 'letters-with-basic-punc': [\n function (value, element) {\n return this.optional(element) || /^[a-z\\-.,()'\\\"\\s]+$/i.test(value);\n },\n $.mage.__('Letters or punctuation only please')\n ],\n 'alphanumeric': [\n function (value, element) {\n return this.optional(element) || /^\\w+$/i.test(value);\n },\n $.mage.__('Letters, numbers, spaces or underscores only please')\n ],\n 'letters-only': [\n function (value, element) {\n return this.optional(element) || /^[a-z]+$/i.test(value);\n },\n $.mage.__('Letters only please')\n ],\n 'no-whitespace': [\n function (value, element) {\n return this.optional(element) || /^\\S+$/i.test(value);\n },\n $.mage.__('No white space please')\n ],\n 'zip-range': [\n function (value, element) {\n return this.optional(element) || /^90[2-5]-\\d{2}-\\d{4}$/.test(value);\n },\n $.mage.__('Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx')\n ],\n 'integer': [\n function (value, element) {\n return this.optional(element) || /^-?\\d+$/.test(value);\n },\n $.mage.__('A positive or negative non-decimal number please')\n ],\n 'vinUS': [\n function (v) {\n var i, n, d, f, cd, cdv, LL, VL, FL, rs;\n\n /* eslint-disable max-depth */\n if (v.length !== 17) {\n return false;\n }\n\n LL = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L',\n 'M', 'N', 'P', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];\n VL = [1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9];\n FL = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2];\n rs = 0;\n\n for (i = 0; i < 17;
2 i++) {\n f = FL[i];\n d = v.slice(i, i + 1);\n\n if (i === 8) {\n cdv = d;\n }\n\n if (!isNaN(d)) {\n d *= f;\n } else {\n for (n = 0; n < LL.length; n++) {\n if (d.toUpperCase() === LL[n]) {\n d = VL[n];\n d *= f;\n\n if (isNaN(cdv) && n === 8) {\n cdv = LL[n];\n }\n break;\n }\n }\n }\n rs += d;\n }\n\n /* eslint-enable max-depth */\n cd = rs % 11;\n\n if (cd === 10) {\n cd = 'X';\n }\n\n if (cd === cdv) {\n return true;\n }\n\n return false;\n },\n $.mage.__('The specified vehicle identification number (VIN) is invali
2d.')\n ],\n 'dateITA': [\n function (value, element) {\n var check = false,\n re = /^\\d{1,2}\\/\\d{1,2}\\/\\d{4}$/,\n adata, gg, mm, aaaa, xdata;\n\n if (re.test(value)) {\n adata = value.split('/');\n gg = parseInt(adata[0], 10);\n mm = parseInt(adata[1], 10);\n aaaa = parseInt(adata[2], 10);\n xdata = new Date(aaaa, mm - 1, gg);\n\n if (xdata.getFullYear() === aaaa &&\n xdata.getMonth() === mm - 1 &&\n xdata.getDate() === gg\n ) {\n check = true;\n } else {\n check = false;\n }\n } else {\n check = false;\n }\n\n return this.optional(element) || check;\n },\n $.mage.__('Please enter a correct date')\n ],\n 'dateNL': [\n function (value, element) {\n return this.optional(element) || /^\\d\\d?[\\.\\/-]\\d\\d?[\\.\\/-]\\d\\d\\d?\\d?$/.test(value);\n },\n 'Vul hier een geldige datum in.'\n ],\n 'time': [\n function (value, element) {\n return this.optional(element) || /^([01]\\d|2[0-3])(:[0-5]\\d){0,2}$/.test(value);\n },\n $.mage.__('Please enter a valid time, between 00:00 and 23:59')\n ],\n 'time12h': [\n function (value, element) {\n return this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\\d){0,2}(\\ [AP]M))$/i.test(value);\n },\n $.mage.__('Please enter a valid time, between 00:00 am and 12:00 pm')\n ],\n 'phoneUS': [\n function (phoneNumber, element) {\n phoneNumber = phoneNumber.replace(/\\s+/g, '');\n\n return this.optional(element) || phoneNumber.length > 9 &&\n phoneNumber.match(/^(1-?)?(\\([2-9]\\d{2}\\)|[2-9]\\d{2})-?[2-9]\\d{2}-?\\d{4}$/);\n },\n $.mage.__('Please specify a valid phone number')\n ],\n 'phoneUK': [\n function (phoneNumber, element) {\n return this.optional(element) || phoneNumber.length > 9 &&\n phoneNumber.match(/^(\\(?(0|\\+44)[1-9]{1}\\d{1,4}?\\)?\\s?\\d{3,4}\\s?\\d{3,4})$/);\n },\n $.mage.__('Please specify a valid phone number')\n ],\n 'mobileUK': [\n function (phoneNumber, element) {\n return this.optional(element) || phoneNumber.length > 9 &&\n phoneNumber.match(/^((0|\\+44)7\\d{3}\\s?\\d{6})$/);\n },\n $.mage.__('Please specify a valid mobile number')\n ],\n 'stripped-min-length': [\n function (value, element, param) {\n return value.length >= param;\n },\n $.mage.__('Please enter at least {0} characters')\n ],\n\n /* detect chars that would require more than 3 bytes */\n 'validate-no-utf8mb4-characters': [\n function (value) {\n var validator = this,\n message = $.mage.__('Please remove invalid characters: {0}.'),\n matches = value.match(/(?:[\\uD800-\\uDBFF][\\uDC00-\\uDFFF])/g),\n result = matches === null;\n\n if (!result) {\n validator.charErrorMessage = message.replace('{0}', matches.join());\n }\n\n return result;\n }, function () {\n return this.charErrorMessage;\n }\n ],\n\n /* eslint-disable max-len */\n 'email2': [\n function (value, element) {\n return this.optional(element) ||\n /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$/i.test(value);\n },\n $.validator.messages.email\n ],\n 'url2': [\n function (value, element) {\n return this.optional(element) || /^(https?|ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(\\#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i.test(value);\n },\n $.validator.messages.url\n ],\n\n /* eslint-enable max-len */\n 'credit-card-types': [\n function (value, element, param) {\n var val
2idTypes;\n\n if (/[^0-9-]+/.test(value)) {\n return false;\n }\n value = value.replace(/\\D/g, '');\n\n validTypes = 0x0000;\n\n if (param.mastercard) {\n validTypes |= 0x0001;\n }\n\n if (param.visa) {\n validTypes |= 0x0002;\n }\n\n if (param.amex) {\n validTypes |= 0x0004;\n }\n\n if (param.dinersclub) {\n validTypes |= 0x0008;\n }\n\n if (param.enroute) {\n validTypes |= 0x0010;\n }\n\n if (param.discover) {\n validTypes |= 0x0020;\n }\n\n if (param.jcb) {\n validTypes |= 0x0040;\n }\n\n if (param.unknown) {\n validTypes |= 0x0080;\n }\n\n if (param.all) {\n validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;\n }\n\n if (validTypes & 0x0001 && /^(51|52|53|54|55)/.test(value)) { //mastercard\n return value.length === 16;\n }\n\n if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa\n return value.length === 16;\n }\n\n if (validTypes & 0x0004 && /^(34|37)/.test(value)) { //amex\n return value.length === 15;\n }\n\n if (validTypes & 0x0008 && /^(300|301|302|303|304|305|36|38)/.test(value)) { //dinersclub\n return value.length === 14;\n }\n\n if (validTypes & 0x0010 && /^(2014|2149)/.test(value)) { //enroute\n return value.length === 15;\n }\n\n if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover\n return value.length === 16;\n }\n\n if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb\n return value.length === 16;\n }\n\n if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb\n return value.length === 15;\n }\n\n if (validTypes & 0x0080) { //unknown\n return true;\n }\n\n return false;\n },\n $.mage.__('Please enter a valid credit card number.')\n ],\n\n /* eslint-disable max-len */\n 'ipv4': [\n function (value, element) {\n return this.optional(element) ||\n /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i.test(value);\n },\n $.mage.__('Please enter a valid IP v4 address.')\n ],\n 'ipv6': [\n function (value, element) {\n return this.optional(element) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value);\n },\n $.mage.__('Please enter a valid IP v6 address.')\n ],\n\n /* eslint-enable max-len */\n 'pattern': [\n function (value, element, param) {\n return this.optional(element) || param.test(value);\n },\n $.mage.__('Invalid format.')\n ],\n 'allow-container-className': [\n function (element) {\n if (element.type === 'radio' || element.type === 'checkbox') {\n return $(element).hasClass('change-container-classname');\n }\n },\n ''\n ],\n 'validate-no-html-tags': [\n function (value) {\n return !/<(\\/)?\\w+/.test(value);\n },\n $.mage.__('HTML tags are not allowed.')\n ],\n 'validate-select': [\n function (value) {\n return value !== 'none' && value != null && value.length !== 0;\n },\n $.mage.__('Please select an option.')\n ],\n 'validate-no-empty': [\n function (value) {\n return !$.mage.isEmpty(value);\n },\n $.mage.__('Empty Value.')\n ],\n 'validate-alphanum-with-spaces': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^[a-zA-Z0-9 ]+$/.test(v);\n },\n $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.')\n ],\n 'validate-data': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^[A-Za-z]+[A-Za-z0-9_]+$/.test(v);\n },\n $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.') //eslint-disable-line max-len\n ],\n 'validate-street': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^[ \\w]{3,}([A-Za-z]\\.)?([ \\w]*\\#\\d+)?(\\r\\n| )[ \\w]{3,}/.test(v);\n },\n $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9), spaces and \"#\" in this field.')\n ],\n 'validate-phoneStrict': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^(\\()?\\d{3}(\\))?(-|\\s)?\\d{3}(-|\\s)\\d{4}$/.test(v);\n },\n $.mage.__('Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.')\n ],\n 'validate-phoneLax': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) ||\n /^((\\d[\\-. ]?)?((\\(\\d{3}\\))|\\d{3}))?[\\-. ]?\\d{3}[\\-. ]?\\d{4}$/.test(v);\n },\n $.mage.__('Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.')\n ],\n 'validate-fax': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^(\\()?\\d{3}(\\))?(-|\\s)?\\d{3}(-|\\s)\\d{4}$/.test(v);\n },\n $.mage.__('Please enter a valid fax number (Ex: 123-456-7890).')\n ],\n 'validate-email': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*@([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*\\.(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]){2,})$/i.test(v); //eslint-disable-line max-len\n },\n $.mage.__('Please enter a valid email address (Ex: [email protected]).')\n ],\n 'validate-emailSender': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^[\\S ]+$/.test(v);\n },\n $.mage.__('Please enter a valid email address (Ex: [email protected]).')\n ],\n 'validate-password': [\n function (v) {\n var pass;\n\n if (v == null) {\n return false;\n }
2\n //strip leading and trailing spaces\n pass = $.trim(v);\n\n if (!pass.length) {\n return true;\n }\n\n return !(pass.length > 0 && pass.length < 6);\n },\n $.mage.__('Please enter 6 or more characters. Leading and trailing spaces will be ignored.')\n ],\n 'validate-admin-password': [\n function (v) {\n var pass;\n\n if (v == null) {\n return false;\n }\n pass = $.trim(v);\n // strip leading and trailing spaces\n if (pass.length === 0) {\n return true;\n }\n\n if (!/[a-z]/i.test(v) || !/[0-9]/.test(v)) {\n return false;\n }\n\n if (pass.length < 7) {\n return false;\n }\n\n return true;\n },\n $.mage.__('Please enter 7 or more characters, using both numeric and alphabetic.')\n ],\n 'validate-customer-password': [\n function (v, elm) {\n var validator = this,\n counter = 0,\n passwordMinLength = $(elm).data('password-min-length'),\n passwordMinCharacterSets = $(elm).data('password-min-character-sets'),\n pass = $.trim(v),\n result = pass.length >= passwordMinLength;\n\n if (result === false) {\n validator.passwordErrorMessage = $.mage.__('Minimum length of this field must be equal or greater than %1 symbols. Leading and trailing spaces will be ignored.').replace('%1', passwordMinLength); //eslint-disable-line max-len\n\n return result;\n }\n\n if (pass.match(/\\d+/)) {\n counter++;\n }\n\n if (pass.match(/[a-z]+/)) {\n counter++;\n }\n\n if (pass.match(/[A-Z]+/)) {\n counter++;\n }\n\n if (pass.match(/[^a-zA-Z0-9]+/)) {\n counter++;\n }\n\n if (counter < passwordMinCharacterSets) {\n result = false;\n validator.passwordErrorMessage = $.mage.__('Minimum of different classes of characters in password is %1. Classes of characters: Lower Case, Upper Case, Digits, Special Characters.').replace('%1', passwordMinCharacterSets); //eslint-disable-line max-len\n }\n\n return result;\n }, function () {\n return this.passwordErrorMessage;\n }\n ],\n 'validate-url': [\n function (v) {\n if ($.mage.isEmptyNoTrim(v)) {\n return true;\n }\n v = (v || '').replace(/^\\s+/, '').replace(/\\s+$/, '');\n\n return (/^(http|https|ftp):\\/\\/(([A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))(\\.[A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))*)(:(\\d+))?(\\/[A-Z0-9~](([A-Z0-9_~-]|\\.)*[A-Z0-9~]|))*\\/?(.*)?$/i).test(v); //eslint-disable-line max-len\n\n },\n $.mage.__('Please enter a valid URL. Protocol is required (http://, https:// or ftp://).')\n ],\n 'validate-clean-url': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^(http|https|ftp):\\/\\/(([A-Z0-9][A-Z0-9_-]*)(\\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\\d+))?\\/?/i.test(v) || /^(www)((\\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\\d+))?\\/?/i.test(v); //eslint-disable-line max-len\n\n },\n $.mage.__('Please enter a valid URL. For example http://www.example.com or www.example.com.')\n ],\n 'validate-xml-identifier': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^[A-Z][A-Z0-9_\\/-]*$/i.test(v);\n\n },\n $.mage.__('Please enter a valid XML-identifier (Ex: something_1, block5, id-4).')\n ],\n 'validate-ssn': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^\\d{3}-?\\d{2}-?\\d{4}$/.test(v);\n\n },\n $.mage.__('Please enter a valid social security number (Ex: 123-45-6789).')\n ],\n 'validate-zip-us': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /(^\\d{5}$)|(^\\d{5}-\\d{4}$)/.test(v);\n\n },\n $.mage.__('Please enter a valid zip code (Ex: 90602 or 90602-1234).')\n ],\n 'validate-date-au': [\n function (v) {\n var regex, d;\n\n if ($.mage.isEmptyNoTrim(v)) {\n return true;\n }\n regex = /^(\\d{2})\\/(\\d{2})\\/(\\d{4})$/;\n\n if ($.mage.isEmpty(v) || !regex.test(v)) {\n return false;\n }\n d = new Date(v.replace(regex, '$2/$1/$3'));
2\n\n return parseInt(RegExp.$2, 10) === 1 + d.getMonth() &&\n parseInt(RegExp.$1, 10) === d.getDate() &&\n parseInt(RegExp.$3, 10) === d.getFullYear();\n\n },\n $.mage.__('Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.')\n ],\n 'validate-currency-dollar': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^\\$?\\-?([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}\\d*(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$/.test(v); //eslint-disable-line max-len\n\n },\n $.mage.__('Please enter a valid $ amount. For example $100.00.')\n ],\n 'validate-not-negative-number': [\n function (v) {\n if ($.mage.isEmptyNoTrim(v)) {\n return true;\n }\n v = $.mage.parseNumber(v);\n\n return !isNaN(v) && v >= 0;\n\n },\n $.mage.__('Please enter a number 0 or greater in this field.')\n ],\n // validate-not-negative-number should be replaced in all places with this one and then removed\n 'validate-zero-or-greater': [\n function (v) {\n if ($.mage.isEmptyNoTrim(v)) {\n return true;\n }\n v = $.mage.parseNumber(v);\n\n return !isNaN(v) && v >= 0;\n\n },\n $.mage.__('Please enter a number 0 or greater in this field.')\n ],\n 'validate-greater-than-zero': [\n function (v) {\n if ($.mage.isEmptyNoTrim(v)) {\n return true;\n }\n v = $.mage.parseNumber(v);\n\n return !isNaN(v) && v > 0;\n },\n $.mage.__('Please enter a number greater than 0 in this field.')\n ],\n 'validate-css-length': [\n function (v) {\n if (v !== '') {\n return (/^[0-9]*\\.*[0-9]+(px|pc|pt|ex|em|mm|cm|in|%)?$/).test(v);\n }\n\n return true;\n },\n $.mage.__('Please input a valid CSS-length (Ex: 100px, 77pt, 20em, .5ex or 50%).')\n ],\n // Additional methods\n 'validate-number': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || !isNaN($.mage.parseNumber(v)) && /^\\s*-?\\d*(\\.\\d*)?\\s*$/.test(v);\n },\n $.mage.__('Please enter a valid number in this field.')\n ],\n 'required-number': [\n function (v) {\n return !!v.length;\n },\n $.mage.__('Please enter a valid number in this field.')\n ],\n 'validate-number-range': [\n function (v, elm, param) {\n var numValue, dataAttrRange, classNameRange, result, range, m, classes, ii;\n\n if ($.mage.isEmptyNoTrim(v)) {\n return true;\n }\n\n numValue = $.mage.parseNumber(v);\n\n if (isNaN(numValue)) {\n return false;\n }\n\n dataAttrRange = /^(-?[\\d.,]+)?-(-?[\\d.,]+)?$/;\n classNameRange = /^number-range-(-?[\\d.,]+)?-(-?[\\d.,]+)?$/;\n result = true;\n range = param;\n\n if (typeof range === 'string') {\n m = dataAttrRange.exec(range);\n\n if (m) {\n result = result && $.mage.isBetween(numValue, m[1], m[2]);\n } else {\n result = false;\n }\n } else if (elm && elm.className) {\n classes = elm.className.split(' ');\n ii = classes.length;\n\n while (ii--) {\n range = classes[ii];\n m = classNameRange.exec(range);\n\n if (m) { //eslint-disable-line max-depth\n result = result && $.mage.isBetween(numValue, m[1], m[2]);\n break;\n }\n }\n }\n\n return result;\n },\n $.mage.__('The value is not within the specified range.'),\n true\n ],\n 'validate-digits': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || !/[^\\d]/.test(v);\n },\n $.mage.__('Please enter a valid number in this field.')\n ],\n 'validate-forbidden-extensions': [\n function (v, elem) {\n var forbiddenExtensions = $(elem).attr('data-validation-params'),\n forbiddenExtensionsArray = forbiddenExtensions.split(','),\n extensionsArray = v.split(','),\n result = true;\n\n this.validateExtensionsMessage = $.mage.__('Forbidden extensions has been used. Avoid usage of ') +\n forbiddenExtensions;\n\n $.each(extensionsArray, function (key, extension) {\n if (forbid
2denExtensionsArray.indexOf(extension) !== -1) {\n result = false;\n }\n });\n\n return result;\n }, function () {\n return this.validateExtensionsMessage;\n }\n ],\n 'validate-digits-range': [\n function (v, elm, param) {\n var numValue, dataAttrRange, classNameRange, result, range, m, classes, ii;\n\n if ($.mage.isEmptyNoTrim(v)) {\n return true;\n }\n\n numValue = $.mage.parseNumber(v);\n\n if (isNaN(numValue)) {\n return false;\n }\n\n dataAttrRange = /^(-?\\d+)?-(-?\\d+)?$/;\n classNameRange = /^digits-range-(-?\\d+)?-(-?\\d+)?$/;\n result = true;\n range = param;\n\n if (typeof range === 'string') {\n m = dataAttrRange.exec(range);\n\n if (m) {\n result = result && $.mage.isBetween(numValue, m[1], m[2]);\n } else {\n result = false;\n }\n } else if (elm && elm.className) {\n classes = elm.className.split(' ');\n ii = classes.length;\n\n while (ii--) {\n range = classes[ii];\n m = classNameRange.exec(range);\n\n if (m) { //eslint-disable-line max-depth\n result = result && $.mage.isBetween(numValue, m[1], m[2]);\n break;\n }\n }\n }\n\n return result;\n },\n $.mage.__('The value is not within the specified range.'),\n true\n ],\n 'validate-range': [\n function (v, elm) {\n var minValue, maxValue, ranges, reRange, result, values,\n i, name, validRange, minValidRange, maxValidRange;\n\n if ($.mage.isEmptyNoTrim(v)) {\n return true;\n } else if ($.validator.methods['validate-digits'] && $.validator.methods['validate-digits'](v)) {\n minValue = maxValue = $.mage.parseNumber(v);\n } else {\n ranges = /^(-?\\d+)?-(-?\\d+)?$/.exec(v);\n\n if (ranges) {\n minValue = $.mage.parseNumber(ranges[1]);\n maxValue = $.mage.parseNumber(ranges[2]);\n\n if (minValue > maxValue) { //eslint-disable-line max-depth\n return false;\n }\n } else {\n return false;\n }\n }\n reRange = /^range-(-?\\d+)?-(-?\\d+)?$/;\n result = true;\n values = $(elm).prop('class').split(' ');\n\n for (i = values.length - 1; i >= 0; i--) {\n name = values[i];\n validRange = reRange.exec(name);\n\n if (validRange) {\n minValidRange = $.mage.parseNumber(validRange[1]);\n maxValidRange = $.mage.parseNumber(validRange[2]);\n result = result &&\n (isNaN(minValidRange) || minValue >= minValidRange) &&\n (isNaN(maxValidRange) || maxValue <= maxValidRange);\n }\n }\n\n return result;\n },\n $.mage.__('The value is not within the specified range.')\n ],\n 'validate-alpha': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^[a-zA-Z]+$/.test(v);\n },\n $.mage.__('Please use letters only (a-z or A-Z) in this field.')\n ],\n 'validate-code': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^[a-z]+[a-z0-9_]+$/.test(v);\n },\n $.mage.__('Please use only letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.') //eslint-disable-line max-len\n ],\n 'validate-alphanum': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^[a-zA-Z0-9]+$/.test(v);\n },\n $.mage.__('Please use only letters (a-z or A-Z) or numbers (0-9) in this field. No spaces or other characters are allowed.') //eslint-disable-line max-len\n ],\n 'validate-date': [\n function (value, params, additionalParams) {\n var test = moment(value, additionalParams.dateFormat);\n\n return $.mage.isEmptyNoTrim(value) || test.isValid();\n },\n $.mage.__('Please enter a valid date.')\n\n ],\n 'validate-date-range': [\n function (v, elm) {\n var m = /\\bdate-range-(\\w+)-(\\w+)\\b/.exec(elm.className),\n currentYear, normalizedTime, dependentElements;\n\n if (!m || m[2] === 'to' || $.mage.isEmptyNoTrim(v)) {\n return true;\n }\n\n currentYear = new Date().getFullYear() + '';\n\n /**\n * @param {String} vd\n * @return {Number}\n */\n normalizedTime = function (vd) {\n vd = vd.split(/[.\\/]/);\n\n if (vd[2] && vd[2].length < 4) {\n vd[2] = currentYear.substr(0, vd[2].length) + vd[2];\n }\n\n return new Date(vd.join('/')).getTime();\n };\n\n dependentElements = $(elm.form).find('.validate-date-range.date-range-' + m[1] + '-to');\n\n return !dependentElements.length || $.mage.isEmptyNoTrim(dependentElements[0].value) ||\n normalizedTime(v) <= normalizedTime(dependentElements[0].value);\n },\n $.mage.__('Make sure the To Date is later than or the same as the From Date.')\n ],\n 'validate-cpassword': [\n function () {\n var conf = $('#confirmation').length > 0 ? $('#confirmation') : $($('.validate-cpassword')[0]),\n pass = false,\n passwordElements, i, passwordElement;\n\n if ($('#password')) {\n pass = $('#password');\n }\n passwordElements = $('.validate-password');\n\n for (i = 0; i < passwordElements.length;
2 i++) {\n passwordElement = $(passwordElements[i]);\n\n if (passwordElement.closest('form').attr('id') === conf.closest('form').attr('id')) {\n pass = passwordElement;\n }\n }\n\n if ($('.validate-admin-password').length) {\n pass = $($('.validate-admin-password')[0]);\n }\n\n return pass.val() === conf.val();\n },\n $.mage.__('Please make sure your passwords match.')\n ],\n 'validate-identifier': [\n function (v) {\n return $.mage.isEmptyNoTrim(v) || /^[a-z0-9][a-z0-9_\\/-]+(\\.[a-z0-9_-]+)?$/.test(v);\n },\n $.mage.__('Please enter a valid URL Key (Ex: \"example-page\", \"example-page.html\" or \"anotherlevel/example-page\").') //eslint-disable-line max-len\n ],\n 'validate-zip-international': [\n\n /*function(v) {\n // @TODO: Cleanup\n return Validation.get('IsEmpty').test(v) ||\n /(^[A-z0-9]{2,10}([\\s]{0,1}|[\\-]{0,1})[A-z0-9]{2,10}$)/.test(v);\n }*/\n function () {\n return true;\n },\n $.mage.__('Please enter a valid zip code.')\n ],\n 'validate-one-required': [\n function (v, elm) {\n var p = $(elm).parent(),\n options = p.find('input');\n\n return options.map(function (el) {\n return $(el).val();\n }).length > 0;\n },\n $.mage.__('Please select one of the options above.')\n ],\n 'validate-state': [\n function (v) {\n return v !== 0 || v === '';\n },\n $.mage.__('Please select State/Province.')\n ],\n 'required-file': [\n function (v, elm) {\n var result = !$.mage.isEmptyNoTrim(v),\n ovId;\n\n if (!result) {\n ovId = $(elm).attr('id') + '_value';\n\n if ($(ovId)) {\n result = !$.mage.isEmptyNoTrim($(ovId).val());\n }\n }\n\n return result;\n },\n $.mage.__('Please select a file.')\n ],\n 'validate-ajax-error': [\n function (v, element) {\n element = $(element);\n element.on('change.ajaxError', function () {\n element.removeClass('validate-ajax-error');\n element.off('change.ajaxError');\n });\n\n return !element.hasClass('validate-ajax-error');\n },\n ''\n ],\n 'validate-optional-datetime': [\n function (v, elm, param) {\n var dateTimeParts = $('.datetime-picker[id^=\"options_' + param + '\"]'),\n hasWithValue = false,\n hasWithNoValue = false,\n pattern = /day_part$/i,\n i;\n\n for (i = 0; i < dateTimeParts.length; i++) {\n if (!pattern.test($(dateTimeParts[i]).attr('id'))) {\n if ($(dateTimeParts[i]).val() === 's') { //eslint-disable-line max-depth\n hasWithValue = true;\n } else {\n hasWithNoValue = true;\n }\n }\n }\n\n return hasWithValue ^ hasWithNoValue;\n },\n $.mage.__('The field isn\\'t complete.')\n ],\n 'validate-required-datetime': [\n function (v, elm, param) {\n var dateTimeParts = $('.datetime-picker[id^=\"options_' + param + '\"]'),\n i;\n\n for (i = 0; i < dateTimeParts.length; i++) {\n if (dateTimeParts[i].value === '') {\n return false;\n }\n }\n\n return true;\n },\n $.mage.__('This is a required field.')\n ],\n 'validate-one-required-by-name': [\n function (v, elm, selector) {\n var name = elm.name.replace(/([\\\\\"])/g, '\\\\$1'),\n container = this.currentForm;\n\n selector = selector === true ? 'input[name=\"' + name + '\"]:checked' : selector;\n\n return !!container.querySelectorAll(selector).length;\n },\n $.mage.__('Please select one of the options.')\n ],\n 'less-than-equals-to': [\n function (value, element, params) {\n if ($.isNumeric($(params).val()) && $.isNumeric(value)) {\n this.lteToVal = $(params).val();\n\n return parseFloat(value) <= parseFloat($(params).val());\n }\n\n return true;\n },\n function () {\n var message = $.mage.__('Please enter a value less than or equal to %s.');\n\n return message.replace('%s', this.lteToVal);\n }\n ],\n 'greater-than-equals-to': [\n function (value, element, params) {\n if ($.isNumeric($(params).val()) && $.isNumeric(value)) {\n this.gteToVal = $(params).val();\n\n return parseFloat(value) >= parseFloat($(params).val());\n }\n\n return true;\n },\n function () {\n var message = $.mage.__('Please enter a value greater than or equal to %s.');\n\n return message.replace('%s', this.gteToVal);\n }\n ],\n 'validate-emails': [\n function (value) {\n var val
2idRegexp, emails, i;\n\n if ($.mage.isEmpty(value)) {\n return true;\n }\n validRegexp = /^([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*@([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*\\.(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]){2,})$/i; //eslint-disable-line max-len\n emails = value.split(/[\\s\\n\\,]+/g);\n\n for (i = 0; i < emails.length; i++) {\n if (!validRegexp.test(emails[i].trim())) {\n return false;\n }\n }\n\n return true;\n },\n $.mage.__('Please enter valid email addresses, separated by commas. For example, [email protected], [email protected].') //eslint-disable-line max-len\n ],\n\n 'validate-cc-type-select': [\n\n /**\n * Validate credit card type matches credit card number\n * @param {*} value - select credit card type\n * @param {*} element - element contains the select box for credit card types\n * @param {*} params - selector for credit card number\n * @return {Boolean}\n */\n function (value, element, params) {\n if (value && params && creditCartTypes[value]) {\n return creditCartTypes[value][0].test($(params).val().replace(/\\s+/g, ''));\n }\n\n return false;\n },\n $.mage.__('Card type does not match credit card number.')\n ],\n 'validate-cc-number': [\n\n /**\n * Validate credit card number based on mod 10.\n *\n * @param {*} value - credit card number\n * @return {Boolean}\n */\n function (value) {\n if (value) {\n return validateCreditCard(value);\n }\n\n return false;\n },\n $.mage.__('Please enter a valid credit card number.')\n ],\n 'validate-cc-type': [\n\n /**\n * Validate credit card number is for the correct credit card type.\n *\n * @param {String} value - credit card number\n * @param {*} element - element contains credit card number\n * @param {*} params - selector for credit card type\n * @return {Boolean}\n */\n function (value, element, params) {\n var ccType;\n\n if (value && params) {\n ccType = $(params).val();\n value = value.replace(/\\s/g, '').replace(/\\-/g, '');\n\n if (creditCartTypes[ccType] && creditCartTypes[ccType][0]) {\n return creditCartTypes[ccType][0].test(value);\n } else if (creditCartTypes[ccType] && !creditCartTypes[ccType][0]) {\n return true;\n }\n }\n\n return false;\n },\n $.mage.__('Credit card number does not match credit card type.')\n ],\n 'validate-cc-exp': [\n\n /**\n * Validate credit card expiration date, make sure it's within the year and not before current month.\n *\n * @param {*} value - month\n * @param {*} element - element contains month\n * @param {*} params - year selector\n * @return {Boolean}\n */\n function (value, element, params) {\n var isValid = false,\n month, year, currentTime, currentMonth, currentYear;\n\n if (value && params) {\n month = value;\n year = $(params).val();\n currentTime = new Date();\n currentMonth = currentTime.getMonth() + 1;\n currentYear = currentTime.getFullYear();\n\n isValid = !year || year > currentYear || year == currentYear && month >= currentMonth; //eslint-disable-line\n }\n\n return isValid;\n },\n $.mage.__('Incorrect credit card expiration date.')\n ],\n 'validate-cc-cvn': [\n\n /**\n * Validate credit card cvn based on credit card type.\n *\n * @param {*} value - credit card cvn\n * @param {*} element - element contains credit card cvn\n * @param {*} params - credit card type selector\n * @return {*}\n */\n function (value, element, params) {\n var ccType;\n\n if (value && params) {\n ccType = $(params).val();
2\n\n if (creditCartTypes[ccType] && creditCartTypes[ccType][0]) {\n return creditCartTypes[ccType][1].test(value);\n }\n }\n\n return false;\n },\n $.mage.__('Please enter a valid credit card verification number.')\n ],\n 'validate-cc-ukss': [\n\n /**\n * Validate Switch/Solo/Maestro issue number and start date is filled.\n *\n * @param {*} value - input field value\n * @return {*}\n */\n function (value) {\n return value;\n },\n $.mage.__('Please enter issue number or start date for switch/solo card type.')\n ],\n 'validate-length': [\n function (v, elm) {\n var reMax = new RegExp(/^maximum-length-[0-9]+$/),\n reMin = new RegExp(/^minimum-length-[0-9]+$/),\n validator = this,\n result = true,\n length = 0;\n\n $.each(elm.className.split(' '), function (index, name) {\n if (name.match(reMax) && result) {\n length = name.split('-')[2];\n result = v.length <= length;\n validator.validateMessage =\n $.mage.__('Please enter less or equal than %1 symbols.').replace('%1', length);\n }\n\n if (name.match(reMin) && result && !$.mage.isEmpty(v)) {\n length = name.split('-')[2];\n result = v.length >= length;\n validator.validateMessage =\n $.mage.__('Please enter more or equal than %1 symbols.').replace('%1', length);\n }\n });\n\n return result;\n }, function () {\n return this.validateMessage;\n }\n ],\n 'required-entry': [\n function (value) {\n return !$.mage.isEmpty(value);\n }, $.mage.__('This is a required field.')\n ],\n 'not-negative-amount': [\n function (v) {\n if (v.length) {\n return (/^\\s*\\d+([,.]\\d+)*\\s*%?\\s*$/).test(v);\n }\n\n return true;\n },\n $.mage.__('Please enter positive number in this field.')\n ],\n 'validate-per-page-value-list': [\n function (v) {\n var isValid = !$.mage.isEmpty(v),\n values = v.split(','),\n i;\n\n for (i = 0; i < values.length; i++) {\n if (!/^[0-9]+$/.test(values[i])) {\n isValid = false;\n }\n }\n\n return isValid;\n },\n $.mage.__('Please enter a valid value, ex: 10,20,30')\n ],\n 'validate-per-page-value': [\n function (v, elm) {\n var values;\n\n if ($.mage.isEmpty(v)) {\n return false;\n }\n values = $('#' + elm.id + '_values').val().split(',');\n\n return values.indexOf(v) !== -1;\n },\n $.mage.__('Please enter a valid value from list')\n ],\n 'validate-new-password': [\n function (v) {\n if ($.validator.methods['validate-password'] && !$.validator.methods['validate-password'](v)) {\n return false;\n }\n\n if ($.mage.isEmpty(v) && v !== '') {\n return false;\n }\n\n return true;\n },\n $.mage.__('Please enter 6 or more characters. Leading and trailing spaces will be ignored.')\n ],\n 'required-if-not-specified': [\n function (value, element, params) {\n var valid = false,\n alternate = $(params),\n alternateValue;\n\n if (alternate.length > 0) {\n valid = this.check(alternate);\n // if valid, it may be blank, so check for that\n if (valid) {\n alternateValue = alternate.val();\n\n if (typeof alternateValue == 'undefined' || alternateValue.length === 0) { //eslint-disable-line\n valid = false;\n }\n }\n }\n\n if (!valid) {\n valid = !this.optional(element);\n }\n\n return valid;\n },\n $.mage.__('This is a required field.')\n ],\n 'required-if-all-sku-empty-and-file-not-loaded': [\n function (value, element, params) {\n var val
2id = false,\n alternate = $(params.specifiedId),\n alternateValue;\n\n if (alternate.length > 0) {\n valid = this.check(alternate);\n // if valid, it may be blank, so check for that\n if (valid) {\n alternateValue = alternate.val();\n\n if (typeof alternateValue == 'undefined' || alternateValue.length === 0) { //eslint-disable-line\n valid = false;\n }\n }\n }\n\n if (!valid) {\n valid = !this.optional(element);\n }\n\n $('input[' + params.dataSku + '=true]').each(function () {\n if ($(this).val() !== '') {\n valid = true;\n }\n });\n\n return valid;\n },\n $.mage.__('Please enter valid SKU key.')\n ],\n 'required-if-specified': [\n function (value, element, params) {\n var valid = true,\n dependent = $(params),\n dependentValue;\n\n if (dependent.length > 0) {\n valid = this.check(dependent);\n // if valid, it may be blank, so check for that\n if (valid) {\n dependentValue = dependent.val();\n valid = typeof dependentValue != 'undefined' && dependentValue.length > 0;\n }\n }\n\n if (valid) {\n valid = !this.optional(element);\n } else {\n valid = true; // dependent was not valid, so don't even check\n }\n\n return valid;\n },\n $.mage.__('This is a required field.')\n ],\n 'required-number-if-specified': [\n function (value, element, params) {\n var valid = true,\n dependent = $(params),\n depeValue;\n\n if (dependent.length) {\n valid = this.check(dependent);\n\n if (valid) {\n depeValue = dependent[0].value;\n valid = !!(depeValue && depeValue.length);\n }\n }\n\n return valid ? !!value.length : true;\n },\n $.mage.__('Please enter a valid number.')\n ],\n 'datetime-validation': [\n function (value, element) {\n var isValid = true;\n\n if ($(element).val().length === 0) {\n isValid = false;\n $(element).addClass('mage-error');\n }\n\n return isValid;\n },\n $.mage.__('This is required field')\n ],\n 'required-text-swatch-entry': [\n tableSingleValidation,\n $.mage.__('Admin is a required field in each row.')\n ],\n 'required-visual-swatch-entry': [\n tableSingleValidation,\n $.mage.__('Admin is a required field in each row.')\n ],\n 'required-dropdown-attribute-entry': [\n tableSingleValidation,\n $.mage.__('Admin is a required field in each row.')\n ],\n 'validate-item-quantity': [\n function (value, element, params) {\n var validator = this,\n result = false,\n // obtain values for validation\n qty = $.mage.parseNumber(value),\n isMinAllowedValid = typeof params.minAllowed === 'undefined' ||\n qty >= $.mage.parseNumber(params.minAllowed),\n isMaxAllowedValid = typeof params.maxAllowed === 'undefined' ||\n qty <= $.mage.parseNumber(params.maxAllowed),\n isQtyIncrementsValid = typeof params.qtyIncrements === 'undefined' ||\n qty % $.mage.parseNumber(params.qtyIncrements) === 0;\n\n result = qty > 0;\n\n if (result === false) {\n validator.itemQtyErrorMessage = $.mage.__('Please enter a quantity greater than 0.');//eslint-disable-line max-len\n\n return result;\n }\n\n result = isMinAllowedValid;\n\n if (result === false) {\n validator.itemQtyErrorMessage = $.mage.__('The fewest you may purchase is %1.').replace('%1', params.minAllowed);//eslint-disable-line max-len\n\n return result;\n }\n\n result = isMaxAllowedValid;\n\n if (result === false) {\n validator.itemQtyErrorMessage = $.mage.__('The maximum you may purchase is %1.').replace('%1', params.maxAllowed);//eslint-disable-line max-len\n\n return result;\n }
2\n\n result = isQtyIncrementsValid;\n\n if (result === false) {\n validator.itemQtyErrorMessage = $.mage.__('You can buy this product only in quantities of %1 at a time.').replace('%1', params.qtyIncrements);//eslint-disable-line max-len\n\n return result;\n }\n\n return result;\n }, function () {\n return this.itemQtyErrorMessage;\n }\n ],\n 'password-not-equal-to-user-name': [\n function (value, element, params) {\n if (typeof params === 'string') {\n return value.toLowerCase() !== params.toLowerCase();\n }\n\n return true;\n },\n $.mage.__('Password cannot be the same as email address.')\n ]\n };\n\n $.each(rules, function (i, rule) {\n rule.unshift(i);\n $.validator.addMethod.apply($.validator, rule);\n });\n $.validator.addClassRules({\n 'required-option': {\n required: true\n },\n 'required-options-count': {\n required: true\n },\n 'validate-both-passwords': {\n 'validate-cpassword': true\n }\n });\n $.validator.messages = $.extend($.validator.messages, {\n required: $.mage.__('This is a required field.'),\n remote: $.mage.__('Please fix this field.'),\n email: $.mage.__('Please enter a valid email address.'),\n url: $.mage.__('Please enter a valid URL.'),\n date: $.mage.__('Please enter a valid date.'),\n dateISO: $.mage.__('Please enter a valid date (ISO).'),\n number: $.mage.__('Please enter a valid number.'),\n digits: $.mage.__('Please enter only digits.'),\n creditcard: $.mage.__('Please enter a valid credit card number.'),\n equalTo: $.mage.__('Please enter the same value again.'),\n maxlength: $.validator.format($.mage.__('Please enter no more than {0} characters.')),\n minlength: $.validator.format($.mage.__('Please enter at least {0} characters.')),\n rangelength: $.validator.format($.mage.__('Please enter a value between {0} and {1} characters long.')),\n range: $.validator.format($.mage.__('Please enter a value between {0} and {1}.')),\n max: $.validator.format($.mage.__('Please enter a value less than or equal to {0}.')),\n min: $.validator.format($.mage.__('Please enter a value greater than or equal to {0}.'))\n });\n\n if ($.metadata) {\n // Setting the type as html5 to enable data-validate attribute\n $.metadata.setType('html5');\n }\n\n showLabel = $.validator.prototype.showLabel;\n $.extend(true, $.validator.prototype, {\n /**\n * @param {*} element\n * @param {*} message\n */\n showLabel: function (element, message) {\n var label, elem;\n\n showLabel.call(this, element, message);\n\n // ARIA (adding aria-invalid & aria-describedby)\n label = this.errorsFor(element);\n elem = $(element);\n\n if (!label.attr('id')) {\n label.attr('id', this.idOrName(element) + '-error');\n }\n elem.attr('aria-invalid', 'true')\n .attr('aria-describedby', label.attr('id'));\n }\n });\n\n /**\n * Validate form field without instantiating validate plug-in.\n *\n * @param {Element|String} element - DOM element or selector\n * @return {Boolean} validation result\n */\n $.validator.validateElement = function (element) {\n var form, validator, valid, classes;\n\n element = $(element);\n form = element.get(0).form;\n validator = form ? $(form).data('validator') : null;\n\n if (validator) {\n return validator.element(element.get(0));\n }\n valid = true;\n classes = element.prop('class').split(' ');\n $.each(classes, $.proxy(function (i, className) {\n if (this.methods[className] && !this.methods[className](element.val(), element.get(0))) {\n valid = false;\n\n return valid;\n }\n }, this));\n\n return valid;\n };\n\n originValidateDelegate = $.fn.validateDelegate;\n\n /**\n * @return {*}\n */\n $.fn.validateDelegate = function () {\n if (!this[0].form) {\n return this;\n }\n\n return originValidateDelegate.apply(this, arguments);\n };\n\n /**\n * Validate single element.\n *\n * @param {Element} element\n * @param {Object} config\n * @returns {*}\n */\n $.validator.validateSingleElement = function (element, config) {\n var errors = {},\n valid = true,\n validateConfig = {\n errorElement: 'label',\n ignore: '.ignore-validate'\n },\n form, validator, classes, elementValue;\n\n $.extend(validateConfig, config);\n element = $(element).not(validateConfig.ignore);\n\n if (!element.length) {\n return true;\n }\n\n form = element.get(0).form;\n validator = form ? $(form).data('validator') : null;\n\n if (validator) {\n return validator.element(element.get(0));\n }\n\n classes = element.prop('class').split(' ');\n validator = element.parent().data('validator') ||\n $.mage.validation(vali
2dateConfig, element.parent()).validate;\n\n element.removeClass(validator.settings.errorClass);\n validator.toHide = validator.toShow;\n validator.hideErrors();\n validator.toShow = validator.toHide = $([]);\n\n $.each(classes, $.proxy(function (i, className) {\n elementValue = element.val();\n\n if (element.is(':checkbox') || element.is(':radio')) {\n elementValue = element.is(':checked') || null;\n }\n\n if (this.methods[className] && !this.methods[className](elementValue, element.get(0))) {\n valid = false;\n errors[element.get(0).name] = this.messages[className];\n validator.invalid[element.get(0).name] = true;\n validator.showErrors(errors);\n\n return valid;\n }\n }, this));\n\n return valid;\n };\n\n $.widget('mage.validation', {\n options: {\n meta: 'validate',\n onfocusout: false,\n onkeyup: false,\n onclick: false,\n ignoreTitle: true,\n errorClass: 'mage-error',\n errorElement: 'div',\n\n /**\n * @param {*} error\n * @param {*} element\n */\n errorPlacement: function (error, element) {\n var errorPlacement = element,\n fieldWrapper;\n\n // logic for date-picker error placement\n if (element.hasClass('_has-datepicker')) {\n errorPlacement = element.siblings('button');\n }\n // logic for field wrapper\n fieldWrapper = element.closest('.addon');\n\n if (fieldWrapper.length) {\n errorPlacement = fieldWrapper.after(error);\n }\n //logic for checkboxes/radio\n if (element.is(':checkbox') || element.is(':radio')) {\n errorPlacement = element.parents('.control').children().last();\n\n //fallback if group does not have .control parent\n if (!errorPlacement.length) {\n errorPlacement = element.siblings('label').last();\n }\n }\n //logic for control with tooltip\n if (element.siblings('.tooltip').length) {\n errorPlacement = element.siblings('.tooltip');\n }\n errorPlacement.after(error);\n }\n },\n\n /**\n * Check if form pass validation rules without submit.\n *\n * @return boolean\n */\n isValid: function () {\n return this.element.valid();\n },\n\n /**\n * Remove validation error messages\n */\n clearError: function () {\n if (arguments.length) {\n $.each(arguments, $.proxy(function (index, item) {\n this.validate.prepareElement(item);\n this.validate.hideErrors();\n }, this));\n } else {\n this.validate.resetForm();\n }\n },\n\n /**\n * Validation creation.\n *\n * @protected\n */\n _create: function () {\n this.validate = this.element.validate(this.options);\n\n // ARIA (adding aria-required attribute)\n this.element\n .find('.field.required')\n .find('.control')\n .find('input, select, textarea')\n .attr('aria-required', 'true');\n\n this._listenFormValidate();\n },\n\n /**\n * Validation listening.\n * @protected\n */\n _listenFormValidate: function () {\n $('form').on('invalid-form.validate', this.listenFormValidateHandler);\n },\n\n /**\n * Handle form validation. Focus on first invalid form field.\n *\n * @param {jQuery.Event} event\n * @param {Object} validation\n */\n listenFormValidateHandler: function (event, validation) {\n var firstActive = $(validation.errorList[0].element || []),\n lastActive = $(validation.findLastActive() ||\n validation.errorList.length && validation.errorList[0].element || []),\n parent, windowHeight, successList;
2\n\n if (lastActive.is(':hidden')) {\n parent = lastActive.parent();\n windowHeight = $(window).height();\n $('html, body').animate({\n scrollTop: parent.offset().top - windowHeight / 2\n });\n }\n\n // ARIA (removing aria attributes if success)\n successList = validation.successList;\n\n if (successList.length) {\n $.each(successList, function () {\n $(this)\n .removeAttr('aria-describedby')\n .removeAttr('aria-invalid');\n });\n }\n\n if (firstActive.length) {\n firstActive.focus();\n }\n }\n });\n\n return $.mage.validation;\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'\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/mage.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n(function (root, factory) {\n 'use strict';\n\n if (typeof define === 'function' && define.amd) {\n define([\n 'jquery',\n 'mage/apply/main'\n ], factory);\n } else {\n factory(root.jQuery);\n }\n}(this, 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 c
2omponents 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 $('body').on('contentUpdated', function () {\n if (mage) {\n mage.apply();\n }\n });\n\n return $.mage;\n}));\n","mage/dropdown.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'jquery/ui',\n 'mage/translate'\n], function ($) {\n 'use strict';\n\n var timer = null;\n\n /**\n * Dropdown Widget - this widget is a wrapper for the jQuery UI Dialog\n */\n $.widget('mage.dropdownDialog', $.ui.dialog, {\n options: {\n triggerEvent: 'click',\n triggerClass: null,\n parentClass: null,\n triggerTarget: null,\n defaultDialogClass: 'mage-dropdown-dialog',\n dialogContentClass: null,\n shadowHinter: null,\n closeOnMouseLeave: true,\n closeOnClickOutside: true,\n minHeight: null,\n minWidth: null,\n width: null,\n modal: false,\n timeout: null,\n autoOpen: false,\n createTitleBar: false,\n autoPosition: false,\n autoSize: false,\n draggable: false,\n resizable: false,\n bodyClass: '',\n buttons: [\n {\n 'class': 'action close',\n 'text': $.mage.__('Close'),\n\n /**\n * Click action.\n */\n 'click': function () {\n $(this).dropdownDialog('close');\n }\n }\n ]\n },\n\n /**\n * extend default functionality to bind the opener for dropdown\n * @private\n */\n _create: function () {\n var _self = this;\n\n this._super();\n this.uiDialog.addClass(this.options.defaultDialogClass);\n\n if (_self.options.triggerTarget) {\n $(_self.options.triggerTarget).on(_self.options.triggerEvent, function (event) {\n event.preventDefault();\n event.stopPropagation();\n\n if (!_self._isOpen) {\n $('.' + _self.options.defaultDialogClass + ' > .ui-dialog-content').dropdownDialog('close');\n _self.open();\n } else {\n _self.close(event);\n }\n });\n }\n\n if (_self.options.shadowHinter) {\n _self.hinter = $('<
2div class=\"' + _self.options.shadowHinter + '\"/>');\n _self.element.append(_self.hinter);\n }\n },\n\n /**\n * Extend default functionality to close the dropdown\n * with custom delay on mouse out and also to close when clicking outside\n */\n open: function () {\n var _self = this;\n\n this._super();\n\n if (_self.options.dialogContentClass) {\n _self.element.addClass(_self.options.dialogContentClass);\n }\n\n if (_self.options.closeOnMouseLeave) {\n\n this._mouseEnter(_self.uiDialog);\n this._mouseLeave(_self.uiDialog);\n\n if (_self.options.triggerTarget) {\n this._mouseLeave($(_self.options.triggerTarget));\n }\n }\n\n if (_self.options.closeOnClickOutside) {\n $('body').on('click.outsideDropdown', function (event) {\n if (_self._isOpen && !$(event.target).closest('.ui-dialog').length) {\n if (timer) {\n clearTimeout(timer);\n }\n _self.close(event);\n }\n });\n }\n // adding the class on the opener and parent element for dropdown\n if (_self.options.triggerClass) {\n $(_self.options.triggerTarget).addClass(_self.options.triggerClass);\n }\n\n if (_self.options.parentClass) {\n $(_self.options.appendTo).addClass(_self.options.parentClass);\n }\n\n if (_self.options.bodyClass) {\n $('body').addClass(_self.options.bodyClass);\n }\n\n if (_self.options.shadowHinter) {\n _self._setShadowHinterPosition();\n }\n },\n\n /**\n * extend default functionality to reset the timer and remove the active class for opener\n */\n close: function () {\n this._super();\n\n if (this.options.dialogContentClass) {\n this.element.removeClass(this.options.dialogContentClass);\n }\n\n if (this.options.triggerClass) {\n $(this.options.triggerTarget).removeClass(this.options.triggerClass);\n }\n\n if (this.options.parentClass) {\n $(this.options.appendTo).removeClass(this.options.parentClass);\n }\n\n if (this.options.bodyClass) {\n $('body').removeClass(this.options.bodyClass);\n }\n\n if (timer) {\n clearTimeout(timer);\n }\n\n if (this.options.triggerTarget) {\n $(this.options.triggerTarget).off('mouseleave');\n }\n this.uiDialog.off('mouseenter');\n this.uiDialog.off('mouseleave');\n $('body').off('click.outsideDropdown');\n },\n\n /**\n * _setShadowHinterPosition\n * @private\n */\n _setShadowHinterPosition: function () {\n var _self = this,\n offset;\n\n offset = _self.options.position.of.offset().left -\n _self.element.offset().left +\n _self.options.position.of.outerWidth() / 2;\n offset = isNaN(offset) ? 0 : Math.floor(offset);\n _self.hinter.css('left', offset);\n },\n\n /**\n * @private\n */\n _position: function () {\n if (this.options.autoPosition) {\n this._super();\n }\n },\n\n /**\n * @private\n */\n _createTitlebar: function () {\n if (this.options.createTitleBar) {\n this._super();\n } else {\n // the title bar close button is referenced\n // in _focusTabbable function, so to prevent errors it must be declared\n this.uiDialogTitlebarClose = $('<
2div>');\n }\n },\n\n /**\n * @private\n */\n _size: function () {\n if (this.options.autoSize) {\n this._super();\n }\n },\n\n /**\n * @param {Object} handler\n * @private\n */\n _mouseLeave: function (handler) {\n var _self = this;\n\n handler.on('mouseleave', function (event) {\n event.stopPropagation();\n\n if (_self._isOpen) {\n if (timer) {\n clearTimeout(timer);\n }\n timer = setTimeout(function (e) {\n _self.close(e);\n }, _self.options.timeout);\n }\n });\n },\n\n /**\n * @param {Object} handler\n * @private\n */\n _mouseEnter: function (handler) {\n handler.on('mouseenter', function (event) {\n event.stopPropagation();\n\n if (timer) {\n clearTimeout(timer);\n }\n });\n },\n\n /**\n * @param {String} key\n * @param {*} value\n * @private\n */\n _setOption: function (key, value) {\n this._super(key, value);\n\n if (key === 'triggerTarget') {\n this.options.triggerTarget = value;\n }\n }\n });\n\n return $.mage.dropdownDialog;\n});\n","mage/toggle.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'jquery/ui'\n], function ($) {\n 'use strict';\n\n $.widget('mage.toggleAdvanced', {\n options: {\n baseToggleClass: 'active' // Class used to be toggled on clicked element\n },\n\n /**\n * Toggle creation\n * @private\n */\n _create: function () {\n this.beforeCreate();\n this._bindCore();\n this.afterCreate();\n },\n\n /**\n * Core bound events & setup\n * @protected\n */\n _bindCore: function () {\n var widget = this;\n\n this.element.on('click', $.proxy(function (e) {\n widget._onClick();\n e.preventDefault();\n }, this));\n },\n\n /**\n * Binding Click event\n *\n * @protected\n */\n _onClick: function () {\n this._prepareOptions();\n this._toggleSelectors();\n },\n\n /**\n * Method used to look for data attributes to override default options\n *\n * @protected\n */\n _prepareOptions: function () {\n this.options.baseToggleClass = this.element.data('base-toggle-class') ?\n this.element.data('base-toggle-class') : this.options.baseToggleClass;\n },\n\n /**\n * Method responsible for hiding and revealing specified DOM elements\n * Toggle the class on clicked element\n *\n * @protected\n */\n _toggleSelectors: function () {\n this.element.toggleClass(this.options.baseToggleClass);\n },\n\n /**\n * Method used to inject 3rd party functionality before create\n * @public\n */\n beforeCreate: function () {},\n\n /**\n * Method used to inject 3rd party functionality after create\n * @public\n */\n afterCreate: function () {}\n });\n\n // Extension for mage.toggle - Adding selectors support for other DOM elements we wish to toggle\n $.widget('mage.toggleAdvanced', $.mage.toggleAdvanced, {\n\n options: {\n selectorsToggleClass: 'hidden', // Class used to be toggled on selectors DOM elements\n toggleContainers: null\n },\n\n /**\n * Method responsible for hiding and revealing specified DOM elements\n * If data-toggle-selectors attribute is present - toggle will be done on these selectors\n * Otherwise we toggle the class on clicked element\n *\n * @protected\n * @override\n */\n _toggleSelectors: function () {\n this._super();
2\n\n if (this.options.toggleContainers) {\n $(this.options.toggleContainers).toggleClass(this.options.selectorsToggleClass);\n } else {\n this.element.toggleClass(this.options.baseToggleClass);\n }\n },\n\n /**\n * Method used to look for data attributes to override default options\n *\n * @protected\n * @override\n */\n _prepareOptions: function () {\n this.options.selectorsToggleClass = this.element.data('selectors-toggle-class') ?\n this.element.data('selectors-toggle-class') : this.options.selectorsToggleClass;\n this.options.toggleContainers = this.element.data('toggle-selectors') ?\n this.element.data('toggle-selectors') : this.options.toggleContainers;\n this._super();\n }\n });\n\n // Extension for mage.toggle - Adding label toggle\n $.widget('mage.toggleAdvanced', $.mage.toggleAdvanced, {\n\n options: {\n newLabel: null, // Text of the new label to be used on toggle\n curLabel: null, // Text of the old label to be used on toggle\n currentLabelElement: null // Current label container\n },\n\n /**\n * Binding Click event\n *\n * @protected\n * @override\n */\n _onClick: function () {\n this._super();\n this._toggleLabel();\n },\n\n /**\n * Method responsible for replacing clicked element labels\n * @protected\n */\n _toggleLabel: function () {\n var cachedLabel, currentLabelSelector;\n\n if (this.options.newLabel) {\n cachedLabel = this.options.newLabel;\n currentLabelSelector = this.options.currentLabelElement ?\n $(this.options.currentLabelElement) : this.element;\n\n this.element.data('toggle-label', this.options.curLabel);\n currentLabelSelector.html(this.options.newLabel);\n\n this.options.curLabel = this.options.newLabel;\n this.options.newLabel = cachedLabel;\n }\n },\n\n /**\n * Method used to look for data attributes to override default options\n *\n * @protected\n * @override\n */\n _prepareOptions: function () {\n this.options.newLabel = this.element.data('toggle-label') ?\n this.element.data('toggle-label') : this.options.newLabel;\n\n this.options.currentLabelElement = this.element.data('current-label-el') ?\n this.element.data('current-label-el') : this.options.currentLabelElement;\n\n if (!this.options.currentLabelElement) {\n this.options.currentLabelElement = this.element;\n }\n\n this.options.curLabel = $(this.options.currentLabelElement).html();\n\n this._super();\n }\n });\n\n return $.mage.toggleAdvanced;\n});\n","mage/multiselect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'jquery',\n 'text!mage/multiselect.html',\n 'Magento_Ui/js/modal/alert',\n 'jquery/ui',\n 'jquery/editableMultiselect/js/jquery.multiselect'\n], function (_, $, searchTemplate, alert) {\n 'use strict';\n\n $.widget('mage.multiselect2', {\n options: {\n mselectContainer: 'section.mselect-list',\n mselectItemsWrapperClass: 'mselect-items-wrapper',\n mselectCheckedClass: 'mselect-checked',\n containerClass: 'paginated',\n searchInputClass: 'admin__action-multiselect-search',\n selectedItemsCountClass: 'admin__action-multiselect-items-selected',\n currentPage: 1,\n lastAppendValue: 0,\n updateDelay: 1000,\n optionsLoaded: false\n },\n\n /** @inheritdoc */\n _create: function () {\n $.fn.multiselect.call(this.element, this.options);\n },\n\n /** @inheritdoc */\n _init: function () {\n this.domElement = this.element.get(0);\n\n this.$container = $(this.options.mselectContainer);\n this.$wrapper = this.$container.find('.' + this.options.mselectItemsWrapperClass);\n this.$item = this.$wrapper.find('div').first();\n this.selectedValues = [];\n this.values = {};\n\n this.$container.addClass(this.options.containerClass).prepend(searchTemplate);\n this.$input = this.$container.find('.' + this.options.searchInputClass);\n this.$selectedCounter = this.$container.find('.' + this.options.selectedItemsCountClass);\n this.filter = '';\n\n if (this.domElement.options.length) {\n this._setLastAppendOption(this.domElement.options[this.domElement.options.length - 1].value);\n }\n\n this._initElement();\n this._events();\n },\n\n /**\n * Leave only saved/selected options in select element.\n *\n * @private\n */\n _initElement: function () {\n this.element.empty();\n _.each(this.options.selectedValues, function (value) {\n this._createSelectedOption({\n value: value,\n label: value\n });\n }, this);\n },\n\n /**\n * Attach required events.\n *\n * @private\n */\n _events: function () {\n var onKeyUp = _.debounce(this.onKeyUp, this.options.updateDelay);\n\n _.bindAll(this, 'onScroll', 'onCheck', 'onOptionsChange');\n\n this.$wrapper.on('scroll', this.onScroll);\n this.$wrapper.on('change.mselectCheck', '[type=checkbox]', this.onCheck);\n this.$input.on('keyup', _.bind(onKeyUp, this));\n this.element.on('change.hiddenSelect', this.onOptionsChange);\n },\n\n /**\n * Behaves multiselect scroll.\n */\n onScroll: function () {\n var height = this.$wrapper.height(),\
2n scrollHeight = this.$wrapper.prop('scrollHeight'),\n scrollTop = Math.ceil(this.$wrapper.prop('scrollTop'));\n\n if (!this.options.optionsLoaded && scrollHeight - height <= scrollTop) {\n this.loadOptions();\n }\n },\n\n /**\n * Behaves keyup event on input search\n */\n onKeyUp: function () {\n if (this.getSearchCriteria() === this.filter) {\n return false;\n }\n\n this.setFilter();\n this.clearMultiselectOptions();\n this.setCurrentPage(0);\n this.loadOptions();\n },\n\n /**\n * Callback for select change event\n */\n onOptionsChange: function () {\n this.selectedValues = _.map(this.domElement.options, function (option) {\n this.values[option.value] = true;\n\n return option.value;\n }, this);\n\n this._updateSelectedCounter();\n },\n\n /**\n * Overrides native check behaviour.\n *\n * @param {Event} event\n */\n onCheck: function (event) {\n var checkbox = event.target,\n option = {\n value: checkbox.value,\n label: $(checkbox).parent('label').text()\n };\n\n checkbox.checked ? this._createSelectedOption(option) : this._removeSelectedOption(option);\n event.stopPropagation();\n },\n\n /**\n * Show error message.\n *\n * @param {String} message\n */\n onError: function (message) {\n alert({\n content: message\n });\n },\n\n /**\n * Updates current filter state.\n */\n setFilter: function () {\n this.filter = this.getSearchCriteria() || '';\n },\n\n /**\n * Reads search input value.\n *\n * @return {String}\n */\n getSearchCriteria: function () {\n return $.trim(this.$input.val());\n },\n\n /**\n * Load options data.\n */\n loadOptions: function () {\n var nextPage = this.getCurrentPage() + 1;\n\n this.$wrapper.trigger('processStart');\n this.$input.prop('disabled', true);\n\n $.get(this.options.nextPageUrl, {\n p: nextPage,\n s: this.filter\n })\n .done(function (response) {\n if (response.success) {\n this.appendOptions(response.result);\n this.setCurrentPage(nextPage);\n } else {\n this.onError(response.errorMessage);\n }\n }.bind(this))\n .always(function () {\n this.$wrapper.trigger('processStop');\n this.$input.prop('disabled', false);\n\n if (this.filter) {\n this.$input.focus();\n }\n }.bind(this));\n },\n\n /**\n * Append loaded options\n *\n * @param {Array} options\n */\n appendOptions: function (options) {\n var divOptions = [];\n\n if (!options.length) {\n return false;\n }\n\n if (this.isOptionsLoaded(options)) {\n return;\n }\n\n options.forEach(function (option) {\n if (!this.values[option.value]) {\n this.values[option.value] = true;\n option.selected = this._isOptionSelected(option);\n divOptions.push(this._createMultiSelectOption(option));\n this._setLastAppendOption(option.value);\n }\n }, this);\n\n this.$wrapper.append(divOptions);\n },\n\n /**\n * Clear multiselect options\n */\n clearMultiselectOptions: function () {\n this._setLastAppendOption(0);\n this.values = {};\n this.$wrapper.empty();\n },\n\n /**\n * Checks if all options are already loaded\n *\n * @return {Boolean}\n */\n isOptionsLoaded: function (options) {\n this.options.optionsLoaded = this.options.lastAppendValue === options[options.length - 1].value;\n\n return this.options.optionsLoaded;\n },\n\n /**\n * Setter for current page.\n *\n * @param {Number} page\n */\n setCurrentPage: function (page) {\n this.options.currentPage = page;\n },\n\n /**\n * Getter for current page.\n *\n * @return {Number}\n */\n getCurrentPage: function () {\n return this.options.currentPage;\n },\n\n /**\n * Creates new selected option for select element\n *\n * @param {Object} option - option object\n * @param {String}
2 option.value - option value\n * @param {String} option.label - option label\n * @private\n */\n _createSelectedOption: function (option) {\n var selectOption = new Option(option.label, option.value, false, true);\n\n this.element.append(selectOption);\n this.selectedValues.push(option.value);\n this._updateSelectedCounter();\n\n return selectOption;\n },\n\n /**\n * Remove passed option from select element\n *\n * @param {Object} option - option object\n * @param {String} option.value - option value\n * @param {String} option.label - option label\n * @return {Object} option\n * @private\n */\n _removeSelectedOption: function (option) {\n var unselectedOption = _.findWhere(this.domElement.options, {\n value: option.value\n });\n\n if (!_.isUndefined(unselectedOption)) {\n this.domElement.remove(unselectedOption.index);\n this.selectedValues.splice(_.indexOf(this.selectedValues, option.value), 1);\n this._updateSelectedCounter();\n }\n\n return unselectedOption;\n },\n\n /**\n * Creates new DIV option for multiselect widget\n *\n * @param {Object} option - option object\n * @param {String} option.value - option value\n * @param {String} option.label - option label\n * @param {Boolean} option.selected - is option selected\n * @private\n */\n _createMultiSelectOption: function (option) {\n var item = this.$item.clone(),\n checkbox = item.find('input'),\n isSelected = !!option.selected;\n\n checkbox.val(option.value)\n .prop('checked', isSelected)\n .toggleClass(this.options.mselectCheckedClass, isSelected);\n\n item.find('label > span').text(option.label);\n\n return item;\n },\n\n /**\n * Checks if passed option should be selected\n *\n * @param {Object} option - option object\n * @param {String} option.value - option value\n * @param {String} option.label - option label\n * @param {Boolean} option.selected - is option selected\n * @return {Boolean}\n * @private\n */\n _isOptionSelected: function (option) {\n return !!~this.selectedValues.indexOf(option.value);\n },\n\n /**\n * Saves last added option value.\n *\n * @param {Number} value\n * @private\n */\n _setLastAppendOption: function (value) {\n this.options.lastAppendValue = value;\n },\n\n /**\n * Updates counter of selected items.\n *\n * @private\n */\n _updateSelectedCounter: function () {\n this.$selectedCounter.text(this.selectedValues.length);\n }\n });\n\n return $.mage.multiselect2;\n});\n","mage/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 */\n $(mage.apply);\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'\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;\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.data.confirmation) {\n uiConfirm({\n content: params.data.confirmationMessage,\n actions: {\n /** @inheritdoc */\n confirm: function () {\n $form.appendTo('body').hide().submit();\n }\n }\n });\n } else {\n $form.appendTo('body').hide().submit();\n }\n }\n });
2\n\n $(document).dataPost();\n\n return $.mage.dataPost;\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'\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\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 palces sticky element where it should be.\n */\n reset: function () {\n this._calculateDimens()\n ._stick();\n }\n });\n\n return $.mage.sticky;\n});\n","mage/tabs.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'jquery/ui',\n 'mage/mage',\n 'mage/collapsible'\n], function ($) {\n 'use strict';\n\n $.widget('mage.tabs', {\n options: {\n active: 0,\n disabled: [],\n openOnFocus: true,\n collapsible: false,\n collapsibleElement: '[data-role=collapsible]',\n header: '[data-role=title]',\n content: '[data-role=content]',\n trigger: '[data-role=trigger]',\n closedState: null,\n openedState: null,\n disabledState: null,\n ajaxUrlElement: '[data-ajax=true]',\n ajaxContent: false,\n loadingClass: null,\n saveState: false,\n animate: false,\n icons: {\n activeHeader: null,\n header: null\n }\n },\n\n /**\n * @private\n */\n _create: function () {\n if (typeof this.options.disabled === 'string') {\n this.options.disabled = this.options.disabled.split(' ').map(function (item) {\n return parseInt(item, 10);\n });\n }\n this._processPanels();\n this._handleDeepLinking();\n this._processTabIndex();\n this._closeOthers();\n this._bind();\n },\n\n /**\n * @private\n */\n _destroy: function () {\n $.each(this.collapsibles, function () {\n $(this).collapsible('destroy');\n });\n },\n\n /**\n * If deep linking is used, all sections must be closed but the one that c
2ontains the anchor.\n * @private\n */\n _handleDeepLinking: function () {\n var self = this,\n anchor = window.location.hash,\n isValid = $.mage.isValidSelector(anchor),\n anchorId = anchor.replace('#', '');\n\n if (anchor && isValid) {\n $.each(self.contents, function (i) {\n if ($(this).attr('id') === anchorId) {\n self.collapsibles.not(self.collapsibles.eq(i)).collapsible('forceDeactivate');\n\n return false;\n }\n });\n }\n },\n\n /**\n * When the widget gets instantiated, the first tab that is not disabled receive focusable property\n * Updated: for accessibility all tabs receive tabIndex 0\n * @private\n */\n _processTabIndex: function () {\n var self = this;\n\n self.triggers.attr('tabIndex', 0);\n $.each(this.collapsibles, function (i) {\n if (!$(this).collapsible('option', 'disabled')) {\n self.triggers.eq(i).attr('tabIndex', 0);\n\n return false;\n }\n });\n $.each(this.collapsibles, function (i) {\n $(this).on('beforeOpen', function () {\n self.triggers.attr('tabIndex', 0);\n self.triggers.eq(i).attr('tabIndex', 0);\n });\n });\n },\n\n /**\n * Prepare the elements for instantiating the collapsible widget\n * @private\n */\n _processPanels: function () {\n this.contents = this.element.find(this.options.content);\n\n this.collapsibles = this.element.find(this.options.collapsibleElement);\n\n this.collapsibles\n .attr('role', 'presentation')\n .parent()\n .attr('role', 'tablist');\n\n this.headers = this.element.find(this.options.header);\n\n if (this.headers.length === 0) {\n this.headers = this.collapsibles;\n }\n this.triggers = this.element.find(this.options.trigger);\n\n if (this.triggers.length === 0) {\n this.triggers = this.headers;\n }\n this._callCollapsible();\n },\n\n /**\n * Setting the disabled and active tabs and calling instantiation of collapsible\n * @private\n */\n _callCollapsible: function () {\n var self = this,\n disabled = false,\n active = false;\n\n $.each(this.collapsibles, function (i) {\n disabled = active = false;\n\n if ($.inArray(i, self.options.disabled) !== -1) {\n disabled = true;\n }\n\n if (i === self.options.active) {\n active = true;\n }\n self._instantiateCollapsible(this, i, active, disabled);\n });\n },\n\n /**\n * Instantiate collapsible.\n *\n * @param {HTMLElement} element\n * @param {Number} index\n * @param {*} active\n * @param {*} disabled\n * @private\n */\n _instantiateCollapsible: function (element, index, active, disabled) {\n $(element).collapsible(\n $.extend({}, this.options, {\n active: active,\n disabled: disabled,\n header: this.headers.eq(index),\n content: this.contents.eq(index),\n trigger: this.triggers.eq(index)\n })\n );\n },\n\n /**\n * Adding callback to close others tabs when one gets opened\n * @private\n */\n _closeOthers: function () {\n var self = this;\n\n $.each(this.collapsibles, function () {\n $(this).on('beforeOpen', function () {\n self.collapsibles.not(this).collapsible('forceDeactivate');\n });\n });\n },\n\n /**\n * @param {*} index\n */\n activate: function (index) {\n this._toggleActivate('activate', index);\n },\n\n /**\n * @param {*} index\n */\n deactivate: function (index) {\n this._toggleActivate('deactivate', index);\n },\n\n /**\n * @param {*} action\n * @param {*} index\n * @private\n */\n _toggleActivate: function (action, index) {\n this.collapsibles.eq(index).collapsible(action);\n },\n\n /**\n * @param {*} index\n */\n disable: function (index) {\n this._toggleEnable('disable', index);\n },\n\n /**\n * @param {*} index\n */\n enable: function (index) {\n this._toggleEnable('enable', index);\n },\n\n /**\n * @param {*} action\n * @param {*} index\n * @private\n */\n _toggleEnable: function (action, index) {\n var self = this;\n\n if ($.isArray(index)) {\n $.each(index, function () {\n self.collapsibles.eq(this).collapsible(action);\n });\n } else if (index === undefined) {\n this.collapsibles.collapsible(action);\n } else {\n this.collapsibles.eq(index).collapsible(action);\n }\n },\n\n /**\n * @param {jQuery.Event} event\n * @private\n */\n _keydown: function (event) {\n var self = this,\n keyCode, toFocus, toFocusIndex, enabledTriggers, length, currentIndex, nextToFocus;\n\n if (event.altKey || event.ctrlKey) {\n return;\n }\n keyCode = $.ui.keyCode;\n toFocus = false;\n enabledTriggers = [];\n\n $.each(this.triggers, function () {\n if (!self.collapsibles.eq(self.triggers.index($(this))).collapsible('option', 'disabled')) {\n enabledTriggers.push(this);\n }\n });\n length = $(enabledTriggers).length;\n currentIndex = $(enabledTriggers).index(event.target);\n\n /**\n * @param {String} direction\n * @return {*}\n */\n nextToFocus = function (direction) {\n if (length > 0) {\n if (direction === 'right') {\n toFocusIndex = (currentIndex + 1) % length;\n } else {\n toFocusIndex = (currentIndex + length - 1) % length;\n }\n\n return enabledTriggers[toFocusIndex];\n }\n\n return event.target;\n };\n\n switch (event.keyCode) {\n case keyCode.RIGHT:\n case keyCode.DOWN:\n toFocus = nextToFocus('right');\n break;\n\n case keyCode.LEFT:\n case keyCode.UP:\n toFocus = nextToFocus('left');\n break;\n\n case keyCode.HOME:\n toFocus = enabledTriggers[
20];\n break;\n\n case keyCode.END:\n toFocus = enabledTriggers[length - 1];\n break;\n }\n\n if (toFocus) {\n toFocusIndex = this.triggers.index(toFocus);\n $(event.target).attr('tabIndex', -1);\n $(toFocus).attr('tabIndex', 0);\n toFocus.focus();\n\n if (this.options.openOnFocus) {\n this.activate(toFocusIndex);\n }\n event.preventDefault();\n }\n },\n\n /**\n * @private\n */\n _bind: function () {\n var events = {\n keydown: '_keydown'\n };\n\n this._off(this.triggers);\n this._on(this.triggers, events);\n }\n });\n\n return $.mage.tabs;\n});\n","mage/ie-class-fixer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* eslint-disable strict */\n(function () {\n var userAgent = navigator.userAgent, // user agent identifier\n html = document.documentElement, // html tag\n version = 9, // minimal supported version of IE\n gap = ''; // gap between classes\n\n if (html.className) { // check if neighbour class exist in html tag\n gap = ' ';\n } // end if\n\n for (version; version <= 10; version++) { // loop from minimal to 10 version of IE\n if (userAgent.indexOf('MSIE ' + version) > -1) { // match IE individual name\n html.className += gap + 'ie' + version;\n } // end if\n }\n\n if (userAgent.match(/Trident.*rv[ :]*11\\./)) { // Special case for IE11\n html.className += gap + 'ie11';\n } // end if\n\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], 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 var input = this._getInputValue().trim();\n\n this.options.cache.input.val(input);\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/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',\n 'jquery/jquery.mobile.custom',\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 responsive: false,\n expanded: false,\n showDelay: 42,\n hideDelay: 300,\n delay: 300,\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 }
2\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 swipeArea: $('.nav-sections')\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 this._on(controls.toggleBtn, {\n 'click': toggle\n });\n this._on(controls.swipeArea, {\n 'swipeleft': toggle\n });\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-corner-all')) {\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 * Tries to retrieve category URL from current URL and mark this category as active\n * @see _setActiveMenuForCategory(url)\n *\n * @example\n * currentUrl - http://magento.com/category1/category12/product.html,\n * category URLs has extensions .phtml - http://magento.com/category1.phtml\n * method sets active category which has URL http://magento.com/category1/category12.phtml\n *\n * @param {String} currentUrl - current page URL without parameters\n * @return void\n * @private\n */\n _setA
2ctiveMenuForProduct: function (currentUrl) {\n var categoryUrlExtension,\n lastUrlSection,\n possibleCategoryUrl,\n //retrieve first category URL to know what extension is used for category URLs\n firstCategoryUrl = this.element.find('> li a').attr('href');\n\n if (firstCategoryUrl) {\n lastUrlSection = firstCategoryUrl.substr(firstCategoryUrl.lastIndexOf('/'));\n categoryUrlExtension = lastUrlSection.lastIndexOf('.') !== -1 ?\n lastUrlSection.substr(lastUrlSection.lastIndexOf('.')) : '';\n\n possibleCategoryUrl = currentUrl.substr(0, currentUrl.lastIndexOf('/')) + categoryUrlExtension;\n this._setActiveMenuForCategory(possibleCategoryUrl);\n }\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 * @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\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 ') + 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._on({\n /**\n * Prevent focus from sticking to links inside menu after clicking\n * them (focus should always stay on UL during navigation).\n */\n 'mousedown .ui-menu-item > a': function (event) {\n event.preventDefault();\n },\n\n /**\n * Prevent focus from sticking to links inside menu after clicking\n * them (focus should always stay on UL during navigation).\n */\n 'click .ui-state-disabled > a': function (event) {\n event.preventDefault();\n },\n\n /**\n * @param {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();
2\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 setMa
2xItems: 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/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'\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/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 }
2).appendTo(linksList);\n $(switches[i]).wrap(\n '<strong class=\"' + classes + '\" data-section=\"' + dataSection + '\" />'\n );\n }\n }\n $(switches).each(function (ind, el) {\n $(el).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/decorate.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* eslint-disable strict */\n(function (factory) {\n if (typeof define === 'function' && define.amd) {\n define([\n 'jquery',\n 'mage/translate'\n ], factory);\n } else {\n factory(jQuery);\n }\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 $.error(message.replace('%s', method));\n };\n}));\n","mage/dialog.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'\n], function ($) {\n 'use strict';\n\n /**\n * Dialog Widget - this widget is a wrapper for the jQuery UI Dialog\n */\n $.widget('mage.dialog', $.ui.dialog, {});\n\n return $.mage.dialog;\n});\n","mage/translate-inline.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n(function (root, factory) {\n 'use strict';\n\n if (typeof define === 'function' && define.amd) {\n define([\n 'jquery',\n 'mage/template',\n 'jquery/ui',\n 'mage/translate'\n ], factory);\n } else {\n factory(root.jQuery, root.mageTemplate);\n }\n}(this, function ($, mageTemplate) {\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 }\n },\n autoOpen: false,\n translateArea: null,\n modal: true,\n dialogClass: 'popup-window',\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 }
2],\n\n /**\n * Open.\n */\n open: function () {\n var topMargin;\n\n $(this).closest('.ui-dialog').addClass('ui-dialog-active');\n topMargin = jQuery(this).closest('.ui-dialog').children('.ui-dialog-titlebar').outerHeight() + 45;\n jQuery(this).closest('.ui-dialog').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 this.tmpl = mageTemplate(this.options.translateForm.template);\n (this.options.translateArea && $(this.options.translateArea).length ?\n $(this.options.translateArea) :\n this.element.closest('body'))\n .on('edit.editTrigger', $.proxy(this._onEdit, this));\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: $.mage.escapeHTML\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;\n\n this.formIsSubmitted = true;\n parameters = $.param({\n area: this.options.area\n }) + '&' + $('#' + this.options.translateForm.data.id).serialize();\n\n $.ajax({\n url: this.options.ajaxUrl,\n type: 'POST',\n data: parameters,\n loaderContext: this.element,\n showLoader: true\n }).complete($.proxy(this._formSubmitComplete, this));\n },\n\n /**\n * @param {Object} response\n * @private\n */\n _formSubmitComplete: function (response) {\n this.close();\n this.formIsSubmitted = false;\n this._updatePlaceholder(response.responseJSON[this.data.items[0].original]);\n },\n\n /**\n * @param {*} newValue\n * @private\n */\n _updatePlaceholder: function (newValue) {\n var target = jQuery(this.target);\n\n target.data('translate')[0].shown = newValue;\n target.data('translate')[0].translated = newValue;\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 // @TODO move the \"escapeHTML\" method into the file with global utility functions\n $.extend(true, $, {\n mage: {\n /**\n * @param {String} str\n * @return {Boolean}\n */\n escapeHTML: function (str) {\n return str ?\n jQuery('<div/>').text(str).html().replace(/\"/g, '"') :\n false;\n }\n }\n });\n\n return $.mage.translateInline;\n}));
2\n","mage/fieldset-controls.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'\n], function ($) {\n 'use strict';\n\n /**\n * This widget will allow a control with the fieldsetResetControl widget attached to reset a set of input fields.\n * The input fields to reset are defined by the inputSelector selector. The widget will store a clone of the fields\n * on create, and on trigger of fieldsetReset event it resets the defined fields. The event is triggered by the\n * reset control widget.\n *\n * For inputs of type file, the whole dom element is replaced as changing the value is a security violation\n * For inputs of type checkbox or radio, the checked attribute is added or removed as appropriate\n * For all others the jquery .val method is used to update to value to the original.\n */\n $.widget('mage.fieldsetControls', {\n original: undefined,\n options: {\n inputSelector: '[data-reset=\"true\"]'\n },\n\n /**\n * @private\n */\n _create: function () {\n this.original = this.element.find(this.options.inputSelector).clone(true);\n this._bind();\n },\n\n /**\n * @private\n */\n _bind: function () {\n this._on({\n 'fieldsetReset': '_onReset'\n });\n },\n\n /**\n * @param {jQuery.Event} e\n * @private\n */\n _onReset: function (e) {\n var items;\n\n e.stopPropagation();\n // find all the ones we have to remove\n items = this.element.find(this.options.inputSelector);\n // loop over replacing each one.\n items.each($.proxy(function (index, item) {\n if ($(item).attr('type') == 'file') { //eslint-disable-line eqeqeq\n // Replace the current one we found with a clone of the original saved earlier\n $(item).replaceWith($(this.original[index]).clone(true));\n } else if ($(item).attr('type') == 'checkbox' || $(item).attr('type') == 'radio') { //eslint-disable-line\n // Return to original state.\n if ($(this.original[index]).attr('checked') === undefined) {\n $(item).removeAttr('checked');\n } else {\n $(item).attr('checked', $(this.original[index]).attr('checked'));\n }\n } else {\n // Replace the value with the original\n $(item).val($(this.original[index]).val());\n }\n }, this));\n }\n });\n\n $.widget('mage.fieldsetResetControl', {\n /**\n * @private\n */\n _create: function () {\n this._bind();\n },\n\n /**\n * @private\n */\n _bind: function () {\n this._on({\n click: '_onClick'\n });\n },\n\n /**\n * @param {jQuery.Event} e\n * @private\n */\n _onClick: function (e) {\n e.stopPropagation();\n $(this.element).trigger('fieldsetReset');\n }\n });\n\n return {\n fieldsetControls: $.mage.fieldsetControls,\n fieldsetResetControl: $.mage.fieldsetResetControl\n };\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 ($.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 anch
2or 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 if (!this.options.multipleCollapsible) {\n this._super();\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/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/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\"]').submit();\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 * @returns {Deferred}\n */\n get: function (url, global, contentType) {\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 });\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 * @returns {Deferred}\n */\n post: function (url, data, global, contentType) {\n global = global === undefined ? true : global;\n contentType = contentType || 'application/json';\n\n return $.ajax({\n url: urlBuilder.build(url),\n type: 'POST',\n data: data,\n global: global,\n contentType: contentType\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 * @returns {Deferred}\n */\n put: function (url, data, global, contentType) {\n global = global === undefined ? true : global;\n contentType = contentType || 'application/json';\n\n return $.ajax({\n url: urlBuilder.build(url),\n type: 'PUT',\n data: data,\n global: global,\n contentType: contentType\n });\n },\n\n /**\n * Perform asynchronous DELETE request to server.\n * @param {String} url\n * @param {Boolean} global\n * @param {String} contentType\n * @returns {Deferred}\n */\n delete: function (url, global, contentType) {\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 });\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'\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
2+\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 if ($.browser.msie) { // Hacked together for IE browsers\n centeredY = window.screenTop - 120 +\n (((document.documentElement.clientHeight + 120) / 2 - settings.height / 2));\n centeredX = window.screenLeft + (((document.body.offsetWidth + 20) / 2 - settings.width / 2));\n } else {\n centeredY = window.screenY + ((window.outerHeight / 2 - settings.height / 2));\n centeredX = window.screenX + ((window.outerWidth / 2 - settings.width / 2));\n }\n windowFeatures += ',left=' + centeredX + ',top=' + centeredY;\n } else if (settings.centerScreen) {\n centeredY = (screen.height - settings.height) / 2;\n centeredX = (screen.width - settings.width) / 2;\n windowFeatures += ',left=' + centeredX + ',top=' + centeredY;\n } else {\n windowFeatures += ',left=' + settings.left + ',top=' + settings.top;\n }\n\n window.open(settings.windowURL, settings.windowName, windowFeatures).focus();\n event.preventDefault();\n }\n });\n\n return $.mage.popupWindow;\n});\n","mage/loader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'mage/template',\n 'jquery/ui',\n '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 }
2,\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/translate.js":"define([\n 'jquery',\n 'mage/mage',\n 'mageTranslationDictionary'\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 _data[text] ? _data[text] : text;\n }\n };\n }())\n }\n });\n $.mage.__ = $.proxy($.mage.translate.translate, $.mage.translate);\n\n return $.mage.__;\n});","mage/template.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n(function (root, factory) {\n 'use strict';\n\n if (typeof define === 'function' && define.amd) {\n define([\n 'underscore'\n ], factory);\n } else {\n root.mageTemplate = factory(root._);\n }\n}(this, 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/cookies.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n(function (factory) {\n 'use strict';\n\n if (typeof define === 'function' && define.amd) {\n define([\n 'jquery',\n 'mage/mage',\n 'jquery/jquery.cookie'\n ], factory);\n } else {\n factory(jQuery);\n }\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.\
2n * @type {Object}\n */\n this.defaults = {\n expires: null,\n path: '/',\n domain: null,\n secure: false,\n lifetime: null\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\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\n document.cookie = name + '=' + encodeURIComponent(value) +\n (expires ? '; expires=' + expires.toUTCString() : '') +\n (path ? '; path=' + path : '') +\n (domain ? '; domain=' + domain : '') +\n (secure ? '; secure' : '');\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 }
2\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/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 */\n(function (root, factory) {\n 'use strict';\n\n if (typeof define === 'function' && define.amd) {\n define([\n 'jquery',\n 'mage/template',\n 'jquery/ui'\n ], factory);\n } else {\n factory(root.jQuery, root.mageTemplate);\n }\n}(this, 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)) {\
2n 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/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/validation/validation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n(function (factory) {\n 'use strict';\n\n if (typeof define === 'function' && define.amd) {\n define([\n 'jquery',\n 'mage/validation',\n 'mage/translate'\n ], factory);\n } else {\n factory(jQuery);\n }\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(function () {\n if ($(this).is(':checked')) {\n checkedCount += 1;\n\n return false;\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);
2\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/view/composite.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @deprecated since version 2.2.0\n */\n/* eslint-disable strict */\ndefine(['jquery'], function ($) {\n return function () {\n var renderedChildren = {},\n children = {};\n\n return {\n /**\n * @param {*} child\n * @param {String} key\n */\n addChild: function (child, key) {\n children[key] = child;\n },\n\n /**\n * @param {*} root\n */\n render: function (root) {\n $.each(children, function (key, child) {\n var childRoot = $('<div>');\n\n renderedChildren[key] = child.render(childRoot);\n root.append(childRoot);\n });\n }\n };\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) {\
2n 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.swipe = true;\n this.config = config;\n\n this.settings = {\n $element: $(element),\n $pageWrapper: $('body>.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\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('mouseup', '.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.bind('focusin', self._focusSwitcher);\n settings.focusableEnd.bind('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.unbind('focusin', this._focusSwitcher);\n settings.focusableEnd.unbind('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).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).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\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 config.options = undefined;\n\n config.click = false;\n config.breakpoints = null;\n settings.currentConfig = config;\n settings.$element.html(tpl);\n settings.$element.removeClass('_block-content-loading');\n settings.$elementF = $(settings.$element.children()[0]);\n settings.$elementF.fotorama(config);\n settings.fotoramaApi = settings.$elementF.data('fotorama');\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 isTouchEnabled = this.isTouchEnabled;\n\n if (_.isObject(settings.breakpoints)) {\n pairs = _.pairs(settings.breakpoints);\n _.each(pairs, function (pair) {\n mediaCheck({\n media: pair[0],\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[pair[0]].options.arrows = false;\n\n if (settings.breakpoints[pair[0]].options.fullscreen) {\n settings.breakpoints[pair[0]].options.fullscreen.arrows = false;\n }\n }\n\n settings.api.updateOptions(settings.breakpoints[pair[0]].options, true);\n $.extend(true, config, settings.breakpoints[pair[0]]);\n settings.activeBreakpoint = settings.breakpoints[pair[0]];\n },\n\n /**\n * Is triggered when breakpoint exits.\
2n */\n exit: function () {\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 }\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.brekpoints) ?\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).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) {\
2n if (_.isArray(data)) {\n settings.fotoramaApi.load(data);\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/apply/scripts.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'jquery'\n], function (_, $) {\n 'use strict';\n\n var scriptSelector = 'script[type=\"text/x-magento-init\"]',\n dataAttr = 'data-mage-init',\n virtuals = [];\n\n /**\n * Adds components to the virtual list.\n *\n * @param {Object} components\n */\n function addVirtual(components) {\n virtuals.push({\n el: false,\n data: components\n });\n }\n\n /**\n * Merges provided data with a current data\n * of a elements' \"data-mage-init\" attribute.\n *\n * @param {Object} components - Object with components and theirs configuration.\n * @param {HTMLElement} elem - Element whose data should be modified.\n */\n function setData(components, elem) {\n var data = elem.getAttribute(dataAttr);\n\n data = data ? JSON.parse(data) : {};\n _.each(components, function (obj, key) {\n if (_.has(obj, 'mixins')) {\n data[key] = data[key] || {};\n data[key].mixins = data[key].mixins || [];\n data[key].mixins = data[key].mixins.concat(obj.mixins);\n delete obj.mixins;\n }\n });\n\n data = $.extend(true, data, components);\n data = JSON.stringify(data);\n elem.setAttribute(dataAttr, data);\n }\n\n /**\n * Search for the elements by privded selector and extends theirs data.\n *\n * @param {Object} components - Object with components and theirs configuration.\n * @param {String} selector - Selector for the elements.\n */\n function processElems(components, selector) {\n var elems,\n iterator;\n\n if (selector === '*') {\n addVirtual(components);\n\n return;\n }\n\n elems = document.querySelectorAll(selector);\n iterator = setData.bind(null, components);\n\n _.toArray(elems).forEach(iterator);\n }\n\n /**\n * Parses content of a provided script node.\n * Note: node will be removed from DOM.\n *\n * @param {HTMLScriptElement} node - Node to be processed.\n * @returns {Object}\n */\n function getNodeData(node) {\n var data = node.textContent;\n\n node.parentNode.removeChild(node);\n\n return JSON.parse(data);\n }\n\n /**\n * Parses 'script' tags with a custom type attribute and moves it's data\n * to a 'data-mage-init' attribute of an element found by provided selector.\n * Note: All found script nodes will be removed from DOM.\n *\n * @returns {Array} An array of components not assigned to the specific element.\n *\n * @example Sample declaration.\n * <script type=\"text/x-magento-init\">\n * {\n * \"body\": {\n * \"path/to/component\": {\"foo\": \"bar\"}\n * }\n * }\n * </script>\n *\n * @example Providing data without selector.\n * {\n * \"*\": {\n * \"path/to/component\": {\"bar\": \"baz\"}\n * }\n * }\n */\n return function () {\n var nodes = document.querySelectorAll(scriptSelector);\n\n _.toArray(nodes)\n .map(getNodeData)\n .forEach(function (item) {\n _.each(item, processElems);\n });\n\n return virtuals.splice(0, virtuals.length);\n };\n});\n","mage/apply/main.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'jquery',\n './scripts'\n], function (_, $, processScripts) {\n 'use strict';\n\n var dataAttr = 'data-mage-init',\n nodeSelector = '[' + dataAttr + ']';\n\n /**\n * Initializes components assigned to a specified element via data-* attribute.\n *\n * @param {HTMLElement} el - Element to initialize components with.\n * @param {Object|String} config - Initial components' config.\n * @param {String} component - Components' path.\n */\n function init(el, config, component) {\n require([component], function (fn) {\n\n if (typeof fn === 'object') {\n fn = fn[component].bind(fn);\n }\n\n if (_.isFunction(fn)) {\n fn(config, el);\n } else if ($(el)[component]) {\n $(el)[component](config);\n }\n }
2, 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 () {\n var virtuals = processScripts(),\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/app/config.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @deprecated since version 2.2.0\n */\n/* eslint-disable strict */\ndefine([], function () {\n return {\n /**\n * Get base url.\n */\n getBaseUrl: function () {\n return this.values.baseUrl;\n },\n\n /**\n * Get form key.\n */\n getFormKey: function () {\n return this.values.formKey;\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 'FormData'\n], function (_, $) {\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(mage, moment);\n });\n\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}
2 attrs - Attributes that will be added to virtual form.\n */\n submit: function (options, attrs) {\n var form = document.createElement('form'),\n data = this.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) {\
2n 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 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 .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(this.serialize(data), function (val, name) {\n formData.append(name, val);\n });\n } else if (type === 'simple') {\n formData = this.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) && !value.length) {\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 symbol codes with their unescaped counterparts.\n *\n * @param {String} data\n *\n * @returns {String}
2\n */\n unescape: function (data) {\n var unescaped = _.unescape(data),\n mapCharacter = {\n ''': '\\''\n };\n\n _.each(mapCharacter, 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/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 '
2-' + symbol.toLowerCase() :\n symbol :\n symbol.toLowerCase();\n })\n .join('');\n },\n\n /**\n * Converts name-through-minus to nameThroughCamelCase\n *\n * @param {String} string\n * @returns {String}\n */\n minusToCamelCase: function minusToCamelCase(string) {\n return ('' + string)\n .split('-')\n .map(function (part, index) {\n return index ? part.charAt(0).toUpperCase() + part.slice(1) : part;\n })\n .join('');\n }\n };\n});\n","mage/utils/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);
2\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/arrays.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n './strings'\n], function (_, utils) {\n 'use strict';\n\n /**\n * Defines index of an item in a specified container.\n *\n * @param {*} item - Item whose index should be defined.\n * @param {Array} container - Container upon which to perform search.\n * @returns {Number}\n */\n function getIndex(item, container) {\n var index = container.indexOf(item);\n\n if (~index) {\n return index;\n }\n\n return _.findIndex(container, function (value) {\n return value && value.name === item;\n });\n }\n\n return {\n /**\n * Facade method to remove/add value from/to array\n * without creating a new instance.\n *\n * @param {Array} arr - Array to be modified.\n * @param {*} value - Value to add/remove.\n * @param {Boolean} add - Flag that specfies operation.\n * @returns {Utils} Chainable.\n */\n toggle: function (arr, value, add) {\n return add ?\n this.add(arr, value) :\n this.remove(arr, value);\n },\n\n /**\n * Removes the incoming value from array in case\n * without creating a new instance of it.\n *\n * @param {Array} arr - Array to be modified.\n * @param {*} value - Value to be removed.\n * @returns {Utils} Chainable.\n */\n remove: function (arr, value) {\n var index = arr.indexOf(value);\n\n if (~index) {\n arr.splice(index, 1);\n }\n\n return this;\n },\n\n /**\n * Adds the incoming value to array if\n * it's not alredy present in there.\n *\n * @param {Array} arr - Array to be modifed.\n * @param {...*} arguments - Values to be added.\n * @returns {Utils} Chainable.\n */\n add: function (arr) {\n var values = _.toArray(arguments).slice(1);\n\n values.forEach(function (value) {\n if (!~arr.indexOf(value)) {\n arr.push(value);\n }\n });\n\n return this;\n },\n\n /**\n * Inserts specified item into container at a specified position.\n *\n * @param {*} item - Item to be inserted into container.\n * @param {Array} container - Container of items.\n * @param {*} [position=-1] - Position at which item should be inserted.\n * Position can represent:\n * - specific index in container\n * - item which might already be present in container\n * - structure with one of these properties: after, before\n * @returns {Boolean|*}\n * - true if element has changed its' position\n * - false if nothing has changed\n * - inserted value if it wasn't present in container\n */\n insert: function (item, container, position) {\n var currentIndex = getIndex(item, container),\n newIndex,\n target;\n\n if (typeof position === 'undefined') {\n position = -1;\n } else if (typeof position === 'string') {\n position = isNaN(+position) ? position : +position;\n }\n\n newIndex = position;\n\n if (~currentIndex) {\n target = container.splice(currentIndex, 1)[0];\n\n if (typeof item === 'string') {\n item = target;\n }\n }\n\n if (typeof position !== 'number') {\n target = position.after || position.before || position;\n\n newIndex = getIndex(target, container);\n\n if (~newIndex && (position.after || newIndex >= currentIndex)) {\n newIndex++;\n }\n }\n\n if (newIndex < 0) {\n newIndex += container.length + 1;\n }\n\n container[newIndex] ?\n container.splice(newIndex, 0, item) :\n container[newIndex] = item;\n\n return !~currentIndex ? item : currentIndex !== newIndex;\n },\n\n /**\n * @param {Array} elems\n * @param {Number} offset\n * @return {Number|*}\n */\n formatOffset: function (elems, offset) {\n if (utils.isEmpty(offset)) {\n offset = -1;\n }\n\n offset = +offset;\n\n if (offset < 0) {\n offset += elems.length + 1;\n }\n\n return offset;\n }\n };\n});\n","mage/utils/compare.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'underscore',\n 'mage/utils/objects'\n], function (_, utils) {\n 'use strict';\n\n var result = [];\n\n /**\n * Checks if all of the provided arrays contains equal values.\
2n *\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.indexOf(value) === index;\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),
2key, '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], function (ko, $, _) {\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 _.each(data, function (node, name) {\n if (parent) {\n name = parent + separator + name;\n }
2\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' }
2\n */\n serialize: function (data) {\n var result = {};\n\n data = this.flatten(data);\n\n _.each(data, function (value, keys) {\n keys = this.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 forEac
2hRecursive: 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 {*}
2\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","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\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 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' && ~value.indexOf(opener);\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 * @returns {*} Compiled template.\n */\n function render(tmpl, data, castString) {\n var last = tmpl;\n\n while (~tmpl.indexOf(opener)) {\n tmpl = template(tmpl, data);\n\n if (tmpl === last) {\n break;\n }\n\n last = tmpl;\n }
2\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 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 list[key] = render(value, tmpl, castString);\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/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].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 > _.filter(module.depMaps, isRejected).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}
2\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/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
2= url.replace(baseUrl, ''),\n newBaseUrl,\n rewrite = module.config()[modulePath];\n\n if (!rewrite) {\n return url;\n }\n\n newBaseUrl = normalize(rewrite, baseUrl, undefined, newConfig);\n\n return newBaseUrl + modulePath;\n }\n\n /**\n * Replace original function.\n *\n * @returns {*}\n */\n ctx.nameToUrl = function () {\n return getUrl(ctx, origNameToUrl.apply(ctx, arguments));\n };\n\n /**\n * Replace original function.\n *\n * @return {*}\n */\n require.s.newContext = function () {\n var newCtx = newContextConstr.apply(require.s, arguments),\n newOrigNameToUrl = newCtx.nameToUrl;\n\n /**\n * New implementation of native function.\n *\n * @returns {String}\n */\n newCtx.nameToUrl = function () {\n return getUrl(newCtx, newOrigNameToUrl.apply(newCtx, arguments));\n };\n\n return newCtx;\n };\n});\n\nrequire(['baseUrlInterceptor'], function () {\n 'use strict';\n\n});\n","mage/requirejs/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 XMLHttpRequest, 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","Magento_Ui/js/block-loader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'jquery',\n 'Magento_Ui/js/lib/knockout/template/loader',\n 'mage/template'\n], function (ko, $, templateLoader, template) {\n 'use strict';\n\n var blockLoaderTemplatePath = 'ui/block-loader',\n blockContentLoadingClass = '_block-content-loading',\n blockLoader,\n blockLoaderClass,\n loaderImageHref;\n\n templateLoader.loadTemplate(blockLoaderTemplatePath).done(function (blockLoaderTemplate) {\n blockLoader = template($.trim(blockLoaderTemplate), {\n loaderImageHref: loaderImageHref\n });\n blockLoader = $(blockLoader);\n blockLoaderClass = '.' + blockLoader.attr('class');\n });\n\n /**\n * Helper function to check if blockContentLoading class should be applied.\n * @param {Object} element\n * @returns {Boolean}\n */\n function isLoadingClassRequired(element) {\n var position = element.css('position');\n\n if (position === 'absolute' || position === 'fixed') {\n return false;\n }\n\n return true;\n }\n\n /**\n * Add loader to block.\n * @param {Object} element\n */\n function addBlockLoader(element) {\n element.find(':focus').blur();
2\n element.find('input:disabled, select:disabled').addClass('_disabled');\n element.find('input, select').prop('disabled', true);\n\n if (isLoadingClassRequired(element)) {\n element.addClass(blockContentLoadingClass);\n }\n element.append(blockLoader.clone());\n }\n\n /**\n * Remove loader from block.\n * @param {Object} element\n */\n function removeBlockLoader(element) {\n if (!element.has(blockLoaderClass).length) {\n return;\n }\n element.find(blockLoaderClass).remove();\n element.find('input:not(\"._disabled\"), select:not(\"._disabled\")').prop('disabled', false);\n element.find('input:disabled, select:disabled').removeClass('_disabled');\n element.removeClass(blockContentLoadingClass);\n }\n\n return function (loaderHref) {\n loaderImageHref = loaderHref;\n ko.bindingHandlers.blockLoader = {\n /**\n * Process loader for block\n * @param {String} element\n * @param {Boolean} displayBlockLoader\n */\n update: function (element, displayBlockLoader) {\n element = $(element);\n\n if (ko.unwrap(displayBlockLoader())) {\n addBlockLoader(element);\n } else {\n removeBlockLoader(element);\n }\n }\n };\n };\n});\n","Magento_Ui/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 'ko',\n 'jquery',\n 'uiComponent',\n '../model/messageList'\n], function (ko, $, Component, globalMessages) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n template: 'Magento_Ui/messages',\n selector: '[data-role=checkout-messages]',\n isHidden: false,\n listens: {\n isHidden: 'onHiddenChange'\n }\n },\n\n /** @inheritdoc */\n initialize: function (config, messageContainer) {\n this._super()\n .initObservable();\n\n this.messageContainer = messageContainer || config.messageContainer || globalMessages;\n\n return this;\n },\n\n /** @inheritdoc */\n initObservable: function () {\n this._super()\n .observe('isHidden');\n\n return this;\n },\n\n /**\n * Checks visibility.\n *\n * @return {Boolean}\n */\n isVisible: function () {\n return this.isHidden(this.messageContainer.hasMessages());\n },\n\n /**\n * Remove all messages.\n */\n removeAll: function () {\n this.messageContainer.clear();\n },\n\n /**\n * @param {Boolean} isHidden\n */\n onHiddenChange: function (isHidden) {\n var self = this;\n\n // Hide message block if needed\n if (isHidden) {\n setTimeout(function () {\n $(self.selector).hide('blind', {}, 500);\n }, 5000);\n }\n }\n });\n});\n","Magento_Ui/js/model/messageList.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n './messages'\n], function (Messages) {\n 'use strict';\n\n return new Messages();\n});\n","Magento_Ui/js/model/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 'ko',\n 'uiClass'\n], function (ko, Class) {\n 'use strict';\n\n return Class.extend({\n /** @inheritdoc */\n initialize: function () {\n this._super()\n .initObservable();\n\n return this;\n },\n\n /** @inheritdoc */\n initObservable: function () {\n this.errorMessages = ko.observableArray([]);\n this.successMessages = ko.observableArray([]);\n\n return this;\n },\n\n /**\n * Add message to list.\n * @param {Object} messageObj\n * @param {Object} type\n * @returns {Boolean}\n */\n add: function (messageObj, type) {\n var expr = /([%])\\w+/g,\n message;\n\n if (!messageObj.hasOwnProperty('parameters')) {\
2n this.clear();\n type.push(messageObj.message);\n\n return true;\n }\n message = messageObj.message.replace(expr, function (varName) {\n varName = varName.substr(1);\n\n if (messageObj.parameters.hasOwnProperty(varName)) {\n return messageObj.parameters[varName];\n }\n\n return messageObj.parameters.shift();\n });\n this.clear();\n type.push(message);\n\n return true;\n },\n\n /**\n * Add success message.\n *\n * @param {Object} message\n * @return {*|Boolean}\n */\n addSuccessMessage: function (message) {\n return this.add(message, this.successMessages);\n },\n\n /**\n * Add error message.\n *\n * @param {Object} message\n * @return {*|Boolean}\n */\n addErrorMessage: function (message) {\n return this.add(message, this.errorMessages);\n },\n\n /**\n * Get error messages.\n *\n * @return {Array}\n */\n getErrorMessages: function () {\n return this.errorMessages;\n },\n\n /**\n * Get success messages.\n *\n * @return {Array}\n */\n getSuccessMessages: function () {\n return this.successMessages;\n },\n\n /**\n * Checks if an instance has stored messages.\n *\n * @return {Boolean}\n */\n hasMessages: function () {\n return this.errorMessages().length > 0 || this.successMessages().length > 0;\n },\n\n /**\n * Removes stored messages.\n */\n clear: function () {\n this.errorMessages.removeAll();\n this.successMessages.removeAll();\n }\n });\n});\n","Magento_Ui/js/modal/modalToggle.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 'Magento_Ui/js/modal/modal'\n], function ($) {\n 'use strict';\n\n return function (config, el) {\n var widget,\n content;\n\n if (config.contentSelector) {\n content = $(config.contentSelector);\n } else if (config.content) {\n content = $('<div />').html(config.content);\n } else {\n content = $('<div />');\n }\n\n widget = content.modal(config);\n\n $(el).on(config.toggleEvent, function () {\n var state = widget.data('mage-modal').options.isOpen;\n\n if (state) {\n widget.modal('closeModal');\n } else {\n widget.modal('openModal');\n }\n\n return false;\n });\n\n return widget;\n };\n});\n","Magento_Ui/js/modal/prompt.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 'text!ui/template/modal/modal-prompt-content.html',\n 'jquery/ui',\n 'Magento_Ui/js/modal/modal',\n 'mage/translate'\n], function ($, _, template, promptContentTmpl) {\n 'use strict';\n\n $.widget('mage.prompt', $.mage.modal, {\n options: {\n modalClass: 'prompt',\n promptContentTmpl: promptContentTmpl,\n promptField: '[data-role=\"promptField\"]',\n attributesForm: {},\n attributesField: {},\n value: '',\n validation: false,\n validationRules: [],\n actions: {\n\n /**\n * Callback always - called on all actions.\n */\n always: function () {},\n\n /**\n * Callback confirm.\n */\n confirm: function () {},\n\n /**\n * Callback cancel.\n */\n cancel: function () {}\n },\n buttons: [{\n text: $.mage.__('Cancel'),\n class: 'action-secondary action-dismiss',\n\n /**\n * Click handler.\n */\n click: function () {\n this.closeModal();\n }\n }, {\n text: $.mage.__('OK'),\n class: 'action-primary action-accept',\n\n /**\n * Click handler.\n */\n click: function () {\n this.closeModal(true);\n }\n }]\n },\n\n /**\n * Create widget.\n */\n _create: function () {\n this.options.focus = this.options.promptField;\n this.options.validation = this.options.validation && this.options.validationRules.length;\n this._super();\n this.modal.find(this.options.modalContent).append(this.getFormTemplate());\n this.modal.find(this.options.modalCloseBtn).off().on('click', _.bind(this.closeModal, this, false));\n\n if (this.options.validation) {\n this.setValidationClasses();\n }\n\n this.openModal();\n },\n\n /**\n * Form template getter.\n *\n * @returns {Object} Form template.\n */\n getFormTemplate: function () {\n var formTemplate,\n formAttr = '',\n inputAttr = '',\n attributeName;\n\n for (attributeName in this.options.attributesForm) {\n if (this.options.attributesForm.hasOwnProperty(attributeName)) {\
2n formAttr = formAttr + ' ' + attributeName + '=\"' +\n this.options.attributesForm[attributeName] + '\"';\n }\n }\n\n for (attributeName in this.options.attributesField) {\n if (this.options.attributesField.hasOwnProperty(attributeName)) {\n inputAttr = inputAttr + ' ' + attributeName + '=\"' +\n this.options.attributesField[attributeName] + '\"';\n }\n }\n\n formTemplate = $(template(this.options.promptContentTmpl, {\n data: this.options,\n formAttr: formAttr,\n inputAttr: inputAttr\n }));\n\n return formTemplate;\n },\n\n /**\n * Remove widget\n */\n _remove: function () {\n this.modal.remove();\n },\n\n /**\n * Validate prompt field\n */\n validate: function () {\n return $.validator.validateSingleElement(this.options.promptField);\n },\n\n /**\n * Add validation classes to prompt field\n */\n setValidationClasses: function () {\n this.modal.find(this.options.promptField).attr('class', $.proxy(function (i, val) {\n return val + ' ' + this.options.validationRules.join(' ');\n }, this));\n },\n\n /**\n * Open modal window\n */\n openModal: function () {\n this._super();\n this.modal.find(this.options.promptField).val(this.options.value);\n },\n\n /**\n * Close modal window\n */\n closeModal: function (result) {\n var value;\n\n if (result) {\n if (this.options.validation && !this.validate()) {\n return false;\n }\n\n value = this.modal.find(this.options.promptField).val();\n this.options.actions.confirm.call(this, value);\n } else {\n this.options.actions.cancel.call(this, result);\n }\n\n this.options.actions.always();\n this.element.bind('promptclosed', _.bind(this._remove, this));\n\n return this._super();\n }\n });\n\n return function (config) {\n return $('<div class=\"prompt-message\"></div>').html(config.content).prompt(config);\n };\n});\n","Magento_Ui/js/modal/modal.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 'text!ui/template/modal/modal-popup.html',\n 'text!ui/template/modal/modal-slide.html',\n 'text!ui/template/modal/modal-custom.html',\n 'Magento_Ui/js/lib/key-codes',\n 'jquery/ui',\n 'mage/translate'\n], function ($, _, template, popupTpl, slideTpl, customTpl, keyCodes) {\n 'use strict';\n\n /**\n * Detect browser transition end event.\n * @return {String|undefined} - transition event.\n */\n var transitionEvent = (function () {\n var transition,\n elementStyle = document.createElement('div').style,\n transitions = {\n 'transition': 'transitionend',\n 'OTransition': 'oTransitionEnd',\n 'MozTransition': 'transitionend',\n 'WebkitTransition': 'webkitTransitionEnd'\n };\n\n for (transition in transitions) {\n if (elementStyle[transition] !== undefined && transitions.hasOwnProperty(transition)) {\n return transitions[transition];\n }\n }\n })();\n\n /**\n * Modal Window Widget\n */\n $.widget('mage.modal', {\n options: {\n id: null,\n type: 'popup',\n title: '',\n subTitle: '',\n modalClass: '',\n focus: '[data-role=\"closeBtn\"]',\n autoOpen: false,\n clickableOverlay: true,\n popupTpl: popupTpl,\n slideTpl: slideTpl,\n customTpl: customTpl,\n modalVisibleClass: '_show',\n parentModalClass: '_has-modal',\n innerScrollClass: '_inner-scroll',\n responsive: false,\n innerScroll: false,\n modalTitle: '[data-role=\"title\"]',\n modalSubTitle: '[data-role=\"subTitle\"]',\n modalBlock: '[data-role=\"modal\"]',\n modalCloseBtn: '[data-role=\"closeBtn\"]',\n modalContent: '[data-role=\"content\"]',\n modalAction: '[data-role=\"action\"]',\n focusableScope: '[data-role=\"focusable-scope\"]',\n focusableStart: '[data-role=\"focusable-start\"]',\n focusableEnd: '[data-role=\"focusable-end\"]',\n appendTo: 'body',\n wrapperClass: 'modals-wrapper',\n overlayClass: 'modals-overlay',\n responsiveClass: 'modal
2-slide',\n trigger: '',\n modalLeftMargin: 45,\n closeText: $.mage.__('Close'),\n buttons: [{\n text: $.mage.__('Ok'),\n class: '',\n attr: {},\n\n /**\n * Default action on button click\n */\n click: function (event) {\n this.closeModal(event);\n }\n }],\n keyEventHandlers: {\n\n /**\n * Tab key press handler,\n * set focus to elements\n */\n tabKey: function () {\n if (document.activeElement === this.modal[0]) {\n this._setFocus('start');\n }\n },\n\n /**\n * Escape key press handler,\n * close modal window\n * @param {Object} event - event\n */\n escapeKey: function (event) {\n if (this.options.isOpen && this.modal.find(document.activeElement).length ||\n this.options.isOpen && this.modal[0] === document.activeElement) {\n this.closeModal(event);\n }\n }\n }\n },\n\n /**\n * Creates modal widget.\n */\n _create: function () {\n _.bindAll(\n this,\n 'keyEventSwitcher',\n '_tabSwitcher',\n 'closeModal'\n );\n\n this.options.id = this.uuid;\n this.options.transitionEvent = transitionEvent;\n this._createWrapper();\n this._renderModal();\n this._createButtons();\n $(this.options.trigger).on('click', _.bind(this.toggleModal, this));\n this._on(this.modal.find(this.options.modalCloseBtn), {\n 'click': this.options.modalCloseBtnHandler ? this.options.modalCloseBtnHandler : this.closeModal\n });\n this._on(this.element, {\n 'openModal': this.openModal,\n 'closeModal': this.closeModal\n });\n this.options.autoOpen ? this.openModal() : false;\n },\n\n /**\n * Returns element from modal node.\n * @return {Object} - element.\n */\n _getElem: function (elem) {\n return this.modal.find(elem);\n },\n\n /**\n * Gets visible modal count.\n * * @return {Number} - visible modal count.\n */\n _getVisibleCount: function () {\n var modals = this.modalWrapper.find(this.options.modalBlock);\n\n return modals.filter('.' + this.options.modalVisibleClass).length;\n },\n\n /**\n * Gets count of visible modal by slide type.\n * * @return {Number} - visible modal count.\n */\n _getVisibleSlideCount: function () {\n var elems = this.modalWrapper.find('[data-type=\"slide\"]');\n\n return elems.filter('.' + this.options.modalVisibleClass).length;\n },\n\n /**\n * Listener key events.\n * Call handler function if it exists\n */\n keyEventSwitcher: function (event) {\n var key = keyCodes[event.keyCode];\n\n if (this.options.keyEventHandlers.hasOwnProperty(key)) {\n this.options.keyEventHandlers[key].apply(this, arguments);\n }\n },\n\n /**\n * Set title for modal.\n *\n * @param {String} title\n */\n setTitle: function (title) {\n var $title = $(this.options.modalTitle),\n $subTitle = this.modal.find(this.options.modalSubTitle);\n\n $title.text(title);\n $title.append($subTitle);\n },\n\n /**\n * Set sub title for modal.\n *\n * @param {String} subTitle\n */\n setSubTitle: function (subTitle) {\n this.options.subTitle = subTitle;\n this.modal.find(this.options.modalSubTitle).html(subTitle);\n },\n\n /**\n * Toggle modal.\n * * @return {Element} - current element.\n */\n toggleModal: function () {\n if (this.options.isOpen === true) {\n this.closeModal();\n } else {\n this.openModal();\n }\n },\n\n /**\n * Open modal.\n * * @return {Element} - current element.\n */\n openModal: function () {\n this.options.isOpen = true;\n this.focussedElement = document.activeElement;\n this._createOverlay();\n this._setActive();\n this._setKeyListener();\n this.modal.one(this.options.transitionEvent, _.bind(this._setFocus, this, 'end', 'opened'));\n this.modal.one(this.options.transitionEvent, _.bind(this._trigger, this, 'opened'));\n this.modal.addClass(this.options.modalVisibleClass);\n\n if (!this.options.transitionEvent) {\n this._trigger('opened');\n }\n\n return this.element;\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 * @param {String} type - can be \"opened\" or false\n * If type is \"opened\" - looks to \"this.options.focus\"\n * property and sets focus\n */\n _setFocus: function (position, type) {\n var focusableElements,\n infelicity;\n\n if (type === 'opened' && this.options.focus) {\n this.modal.find($(this.options.focus)).focus();\n } else if (type === 'opened' && !this.options.focus) {\n this.modal.find(this.options.focusableScope).focus();\n } else if (position === 'end') {\n this.modal.find(this.options.modalCloseBtn).focus();\n } else if (position === 'start') {\n infelicity = 2; //Constant for find last focusable element\n focusableElements = this.modal.find(':focusable');\n focusableElements.eq(focusableElements.length - infelicity).focus();\n }\n },\n\n /**\n * Set events listener when modal is opened.\n */\n _setKeyListener: function () {\n this.modal.find(this.options.focusableStart).bind('focusin', this._tabSwitcher);\n this.modal.find(this.options.focusableEnd).bind('focusin', this._tabSwitcher);\n this.modal.bind('keydown', this.keyEventSwitcher);\n },\n\n /**\n * Remove events listener when modal is closed.\n */\n _removeKeyListener: function () {\n this.modal.find(this.options.focusableStart).unbind('focusin', this._tabSwitcher);\n this.modal.find(this.options.focusableEnd).unbind('focusin', this._tabSwitcher);\n this.modal.unbind('keydown', this.keyEventSwitcher);\n },\n\n /**\n * Switcher for focus event.\n * @param {Object} e - event\n */\n _tabSwitcher: function (e) {\n var target = $(e.target);\n\n if (target.is(this.options.focusableStart)) {\n this._setFocus('start');\n } else if (target.is(this.options.focusableEnd)) {\n this._setFocus('end');\n }\n },\n\n /**\n * Close modal.\n * * @return {Element} - current element.\n */\n closeModal: function () {\n var that = this;\n\n this._removeKeyListener();\n this.options.isOpen = false;\n this.modal.one(this.options.transitionEvent, function () {\n that._close();\n });\n this.modal.removeClass(this.options.modalVisibleClass);\n\n if (!this.options.transitionEvent) {\n that._close();\n }\n\n return this.element;\n },\n\n /**\n * Helper for closeModal function.\n */\n _close: function () {\n var trigger = _.bind(this._trigger, this, 'closed', this.modal);\n\n $(this.focussedElement).focus();\n this._destroyOverlay();\n this._unsetActive();\n _.defer(trigger, this);\n },\n\n /**\n * Set z-index and margin for modal and overlay.\n */\n _setA
2ctive: function () {\n var zIndex = this.modal.zIndex(),\n baseIndex = zIndex + this._getVisibleCount();\n\n this.overlay.zIndex(++baseIndex);\n this.prevOverlayIndex = this.overlay.zIndex();\n this.modal.zIndex(this.overlay.zIndex() + 1);\n\n if (this._getVisibleSlideCount()) {\n this.modal.css('marginLeft', this.options.modalLeftMargin * this._getVisibleSlideCount());\n }\n },\n\n /**\n * Unset styles for modal and set z-index for previous modal.\n */\n _unsetActive: function () {\n this.modal.removeAttr('style');\n\n if (this.overlay) {\n // In cases when one modal is closed but there is another modal open (e.g. admin notifications)\n // to avoid collisions between overlay and modal zIndexes\n // overlay zIndex is set to be less than modal one\n if (this._getVisibleCount() === 1) {\n this.overlay.zIndex(this.prevOverlayIndex - 1);\n } else {\n this.overlay.zIndex(this.prevOverlayIndex);\n }\n }\n },\n\n /**\n * Creates wrapper to hold all modals.\n */\n _createWrapper: function () {\n this.modalWrapper = $(this.options.appendTo).find('.' + this.options.wrapperClass);\n\n if (!this.modalWrapper.length) {\n this.modalWrapper = $('<div></div>')\n .addClass(this.options.wrapperClass)\n .appendTo(this.options.appendTo);\n }\n },\n\n /**\n * Compile template and append to wrapper.\n */\n _renderModal: function () {\n $(template(\n this.options[this.options.type + 'Tpl'],\n {\n data: this.options\n })).appendTo(this.modalWrapper);\n this.modal = this.modalWrapper.find(this.options.modalBlock).last(
2);\n this.element.appendTo(this._getElem(this.options.modalContent));\n\n if (this.element.is(':hidden')) {\n this.element.show();\n }\n },\n\n /**\n * Creates buttons pane.\n */\n _createButtons: function () {\n this.buttons = this._getElem(this.options.modalAction);\n _.each(this.options.buttons, function (btn, key) {\n var button = this.buttons[key];\n\n if (btn.attr) {\n $(button).attr(btn.attr);\n }\n\n if (btn.class) {\n $(button).addClass(btn.class);\n }\n\n if (!btn.click) {\n btn.click = this.closeModal;\n }\n $(button).on('click', _.bind(btn.click, this));\n }, this);\n },\n\n /**\n * Creates overlay, append it to wrapper, set previous click event on overlay.\n */\n _createOverlay: function () {\n var events,\n outerClickHandler = this.options.outerClickHandler || this.closeModal;\n\n this.overlay = $('.' + this.options.overlayClass);\n\n if (!this.overlay.length) {\n $(this.options.appendTo).addClass(this.options.parentModalClass);\n this.overlay = $('<div></div>')\n .addClass(this.options.overlayClass)\n .appendTo(this.modalWrapper);\n }\n events = $._data(this.overlay.get(0), 'events');\n events ? this.prevOverlayHandler = events.click[0].handler : false;\n this.options.clickableOverlay ? this.overlay.unbind().on('click', outerClickHandler) : false;\n },\n\n /**\n * Destroy overlay.\n */\n _destroyOverlay: function () {\n if (this._getVisibleCount()) {\n this.overlay.unbind().on('click', this.prevOverlayHandler);\n } else {\n $(this.options.appendTo).removeClass(this.options.parentModalClass);\n this.overlay.remove();\n this.overlay = null;\n }\n }\n });\n\n return $.mage.modal;\n});\n","Magento_Ui/js/modal/confirm.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/translate',\n 'jquery/ui',\n 'Magento_Ui/js/modal/modal'\n], function ($, _, $t) {\n 'use strict';\n\n $.widget('mage.confirm', $.mage.modal, {\n options: {\n modalClass: 'confirm',\n title: '',\n focus: '.action-accept',\n actions: {\n\n /**\n * Callback always - called on all actions.\n */\n always: function () {},\n\n /**\n * Callback confirm.\n */\n confirm: function () {},\n\n /**\n * Callback cancel.\n */\n cancel: function () {}\n },\n buttons: [{\n text: $t('Cancel'),\n class: 'action-secondary action-dismiss',\n\n /**\n * Click handler.\n */\n click: function (event) {\n this.closeModal(event);\n }\n }, {\n text: $t('OK'),\n class: 'action-primary action-accept',\n\n /**\n * Click handler.\n */\n click: function (event) {\n this.closeModal(event, true);\n }\n }]\n },\n\n /**\n * Create widget.\n */\n _create: function () {\n this._super();\n this.modal.find(this.options.modalCloseBtn).off().on('click', _.bind(this.closeModal, this));\n this.openModal();\n },\n\n /**\n * Remove modal window.\n */\n _remove: function () {\n this.modal.remove();\n },\n\n /**\n * Open modal window.\n */\n openModal: function () {\n return this._super();\n },\n\n /**\n * Close modal window.\n */\n closeModal: function (event, result) {\n result = result || false;\n\n if (result) {\n this.options.actions.confirm(event);\n } else {\n this.options.actions.cancel(event);\n }\n this.options.actions.always(event);\n this.element.bind('confirmclosed', _.bind(this._remove, this));\n\n return this._super();\n }\n });\n\n return function (config) {\n return $('<div></div>').html(config.content).confirm(config);\n };\n});\n","Magento_Ui/js/modal/modal-component.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'Magento_Ui/js/lib/view/utils/async',\n 'uiCollection',\n 'uiRegistry',\n 'underscore',\n './modal'\n], function ($, Collection, registry, _) {\n 'use strict';\n\n return Collection.extend({\n defaults: {\n template: 'ui/modal/modal-component',\n title: '',\n subTitle: '',\n options: {\n modalClass: '',\n title: '',\n subTitle: '',\n buttons: [],\n keyEventHandlers: {}\n },\n valid: true,\n links: {\n title: 'options.title',\n subTitle: 'options.subTitle'\n },\n listens: {\n state: 'onState',\n title: 'setTitle',\n 'options.subTitle': 'setSubTitle'\n }
2,\n modalClass: 'modal-component',\n onCancel: 'closeModal'\n },\n\n /**\n * Initializes component.\n *\n * @returns {Object} Chainable.\n */\n initialize: function () {\n this._super();\n _.bindAll(this,\n 'initModal',\n 'openModal',\n 'closeModal',\n 'toggleModal',\n 'setPrevValues',\n 'validate');\n this.initializeContent();\n\n return this;\n },\n\n /**\n * Initializes modal configuration\n *\n * @returns {Object} Chainable.\n */\n initConfig: function () {\n return this._super()\n .initSelector()\n .initModalEvents();\n },\n\n /**\n * Configure modal selector\n *\n * @returns {Object} Chainable.\n */\n initSelector: function () {\n var modalClass = this.name.replace(/\\./g, '_');\n\n this.contentSelector = '.' + this.modalClass;\n this.options.modalClass = this.options.modalClass + ' ' + modalClass;\n this.rootSelector = '.' + modalClass;\n\n return this;\n },\n\n /**\n * Configure modal keyboard handlers\n * and outer click\n *\n * @returns {Object} Chainable.\n */\n initModalEvents: function () {\n this.options.keyEventHandlers.escapeKey = this.options.outerClickHandler = this[this.onCancel].bind(this);\n\n return this;\n },\n\n /**\n * Initialize modal's content components\n */\n initializeContent: function () {\n $.async({\n component: this.name\n }, this.initModal);\n },\n\n /**\n * Init toolbar section so other components will be able to place something in it\n */\n initToolbarSection: function () {\n this.set('toolbarSection', this.modal.data('mage-modal').modal.find('header').get(0));\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Object} Chainable.\n */\n initObservable: function () {\n this._super();\n this.observe(['state', 'focused']);\n\n return this;\n },\n\n /**\n * Wrap content in a modal of certain type\n *\n * @param {HTMLElement} element\n * @returns {Object} Chainable.\n */\n initModal: function (element) {\n if (!this.modal) {\n this.overrideModalButtonCallback();\n this.options.modalCloseBtnHandler = this[this.onCancel].bind(this);\n this.modal = $(element).modal(this.options);\n this.initToolbarSection();\n\n if (this.waitCbk) {\n this.waitCbk();\n this.waitCbk = null;\n }\n }\n\n return this;\n },\n\n /**\n * Open modal\n */\n openModal: function () {\n if (this.modal) {\n this.state(true);\n } else {\n this.waitCbk = this.openModal;\n }\n },\n\n /**\n * Close modal\n */\n closeModal: function () {\n if (this.modal) {\n this.state(false);\n } else {\n this.waitCbk = this.closeModal;\n }\n },\n\n /**\n * Toggle modal\n */\n toggleModal: function () {\n if (this.modal) {\n this.state(!this.state());\n } else {\n this.waitCbk = this.toggleModal;\n }\n },\n\n /**\n * Sets title for modal\n *\n * @param {String} title\n */\n setTitle: function (title) {\n if (this.title !== title) {\n this.title = title;\n }\n\n if (this.modal) {\n this.modal.modal('setTitle', title);\n }\n },\n\n /**\n * Sets subTitle for modal\n *\n * @param {String} subTitle\n */\n setSubTitle: function (subTitle) {\n if (this.subTitle !== subTitle) {\n this.subTitle = subTitle;\n }\n\n if (this.modal) {\n this.modal.modal('setSubTitle', subTitle);\n }\n },\n\n /**\n * Wrap content in a modal of certain type\n *\n * @param {Boolean} state\n */\n onState: function (state) {\n if (state) {\n this.modal.modal('openM
2odal');\n this.applyData();\n } else {\n this.modal.modal('closeModal');\n }\n },\n\n /**\n * Validate everything validatable in modal\n */\n validate: function (elem) {\n if (typeof elem.validate === 'function') {\n this.valid = this.valid & elem.validate().valid;\n } else if (elem.elems) {\n elem.elems().forEach(this.validate, this);\n }\n },\n\n /**\n * Reset data from provider\n */\n resetData: function () {\n this.elems().forEach(this.resetValue, this);\n },\n\n /**\n * Update 'applied' property with data from modal content\n */\n applyData: function () {\n var applied = {};\n\n this.elems().forEach(this.gatherValues.bind(this, applied), this);\n this.applied = applied;\n },\n\n /**\n * Gather values from modal content\n *\n * @param {Array} applied\n * @param {HTMLElement} elem\n */\n gatherValues: function (applied, elem) {\n if (typeof elem.value === 'function') {\n applied[elem.name] = elem.value();\n }
2 else if (elem.elems) {\n elem.elems().forEach(this.gatherValues.bind(this, applied), this);\n }\n },\n\n /**\n * Set to previous values from modal content\n *\n * @param {HTMLElement} elem\n */\n setPrevValues: function (elem) {\n if (typeof elem.value === 'function') {\n this.modal.focus();\n elem.value(this.applied[elem.name]);\n } else if (elem.elems) {\n elem.elems().forEach(this.setPrevValues, this);\n }\n },\n\n /**\n * Triggers some method in every modal child elem, if this method is defined\n *\n * @param {Object} action - action configuration,\n * must contain actionName and targetName and\n * can contain params\n */\n triggerAction: function (action) {\n var targetName = action.targetName,\n params = action.params || [],\n actionName = action.actionName,\n target;\n\n target = registry.async(targetName);\n\n if (target && typeof target === 'function' && actionName) {\n params.unshift(actionName);\n target.apply(target, params);\n }\n },\n\n /**\n * Override modal buttons callback placeholders with real callbacks\n */\n overrideModalButtonCallback: function () {\n var buttons = this.options.buttons;\n\n if (buttons && buttons.length) {\n buttons.forEach(function (button) {\n button.click = this.getButtonClickHandler(button.actions);\n }, this);\n }\n },\n\n /**\n * Generate button click handler based on button's 'actions' configuration\n */\n getButtonClickHandler: function (actionsConfig) {\n var actions = actionsConfig.map(\n function (actionConfig) {\n if (_.isObject(actionConfig)) {\n return this.triggerAction.bind(this, actionConfig);\n }\n\n return this[actionConfig] ? this[actionConfig].bind(this) : function () {};\n }, this);\n\n return function () {\n actions.forEach(\n function (action) {\n action();\n }\n );\n };\n },\n\n /**\n * Cancels changes in modal:\n * returning elems values to the previous state,\n * and close modal\n */\n actionCancel: function () {\n this.elems().forEac
2h(this.setPrevValues, this);\n this.closeModal();\n },\n\n /**\n * Accept changes in modal by not preventing them.\n * Can be extended by exporting 'gatherValues' result somewhere\n */\n actionDone: function () {\n this.valid = true;\n this.elems().forEach(this.validate, this);\n\n if (this.valid) {\n this.closeModal();\n }\n }\n });\n});\n","Magento_Ui/js/modal/alert.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 'jquery/ui',\n 'Magento_Ui/js/modal/confirm',\n 'mage/translate'\n], function ($, _) {\n 'use strict';\n\n $.widget('mage.alert', $.mage.confirm, {\n options: {\n modalClass: 'confirm',\n title: $.mage.__('Attention'),\n actions: {\n\n /**\n * Callback always - called on all actions.\n */\n always: function () {}\n },\n buttons: [{\n text: $.mage.__('OK'),\n class: 'action-primary action-accept',\n\n /**\n * Click handler.\n */\n click: function () {\n this.closeModal(true);\n }\n }]\n },\n\n /**\n * Close modal window.\n */\n closeModal: function () {\n this.options.actions.always();\n this.element.bind('alertclosed', _.bind(this._remove, this));\n\n return this._super();\n }\n });\n\n return function (config) {\n return $('<div></div>').html(config.content).alert(config);\n };\n});\n","Magento_Ui/js/core/app.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n './renderer/types',\n './renderer/layout',\n '../lib/knockout/bootstrap'\n], function (types, layout) {\n 'use strict';\n\n return function (data, merge) {\n types.set(data.types);\n layout(data.components, undefined, true, merge);\n };\n});\n","Magento_Ui/js/core/renderer/types.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'mageUtils'\n], function (_, utils) {\n 'use strict';\n\n var store = {};\n\n /**\n * Flatten a nested data.\n *\n * @param {Object} data\n * @returns {Object}\n */\n function flatten(data) {\n var extender = data.extends || [],\n result = {};\n\n extender = utils.stringToArray(extender);\n\n extender.push(data);\n\n extender.forEach(function (item) {\n if (_.isString(item)) {\n item = store[item] || {};\n }\n\n utils.extend(result, item);\n });\n\n delete result.extends;\n\n return result;\n }\n\n return {\n /**\n * Set types to store object.\n *\n * @param {Object} types\n */\n set: function (types) {\n types = types || {};\n\n utils.extend(store, types);\n\n _.each(types, function (data, type) {\n store[type] = flatten(data);\n });\n },\n\n /**\n * Get type from store object.\n *\n * @param {String} type\n * @returns {*|{}}\n */\n get: function (type) {\n return store[type] || {};\n }\n };\n});\n","Magento_Ui/js/core/renderer/layout.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'underscore',\n 'jquery',\n 'mageUtils',\n 'uiRegistry',\n './types',\n '../../lib/logger/console-logger'\n], function (_, $, utils, registry, types, consoleLogger) {\n 'use strict';\n\n var templates = registry.create(),\n layout = {},\n cachedConfig = {};\n\n /**\n * Build name from parent name and node name\n *\n * @param {Object} parent\n * @param {Object} node\n * @param {String} [name]\n * @returns {String}\n */\n function getNodeName(parent, node, name) {\n var parentName = parent && parent.name;\n\n if (typeof name !== 'string') {\n name = node.name || name;\n }\n\n return utils.fullPath(parentName, name);\n }\n\n /**\n * Get node type from node or parent.\n *\n * @param {Object} parent\n * @param {Object} node\n * @returns {String}\n */\n function getNodeType(parent, node) {\n return node.type || parent && parent.childType;\n }\n\n /**\n * Get data scope based on parent data scope and n
2ode data scope.\n *\n * @param {Object} parent\n * @param {Object} node\n * @returns {String}\n */\n function getDataScope(parent, node) {\n var dataScope = node.dataScope,\n parentScope = parent && parent.dataScope;\n\n return !utils.isEmpty(parentScope) ?\n !utils.isEmpty(dataScope) ?\n parentScope + '.' + dataScope :\n parentScope :\n dataScope || '';\n }\n\n /**\n * Load node dependencies on other instances.\n *\n * @param {Object} node\n * @returns {jQueryPromise}\n */\n function loadDeps(node) {\n var loaded = $.Deferred(),\n loggerUtils = consoleLogger.utils;\n\n if (node.deps) {\n consoleLogger.utils.asyncLog(\n loaded,\n {\n data: {\n component: node.name,\n deps: node.deps\n },\n messages: loggerUtils.createMessages(\n 'depsStartRequesting',\n 'depsFinishRequesting',\n 'depsLoadingFail'\n )\n }\n );\n }\n\n registry.get(node.deps, function (deps) {\n node.provider = node.extendProvider ? deps && deps.name : node.provider;\n loaded.resolve(node);\n });\n\n return loaded.promise();\n }\n\n /**\n * Load node component file via requirejs.\n *\n * @param {Object} node\n * @returns {jQueryPromise}\n */\n function loadSource(node) {\n var loaded = $.Deferred(),\n source = node.component;\n\n consoleLogger.info('componentStartLoading', {\n component: node.component\n });\n\n require([source], function (constr) {\n consoleLogger.info('componentFinishLoading', {\n component: node.component\n });\n loaded.resolve(node, constr);\n }, function () {\n consoleLogger.error('componentLoadingFail', {\n component: node.component\n });\n });\n\n return loaded.promise();\n }\n\n /**\n * Create a new component instance and set it to the registry.\n *\n * @param {Object} node\n * @param {Function} Constr\n */\n function initComponent(node, Constr) {\n var component = new Constr(_.omit(node, 'children'));\n\n consoleLogger.info('componentStartInitialization', {\n component: node.component,\n componentName: node.name\n });\n\n registry.set(node.name, component);\n }\n\n /**\n * Application entry point.\n *\n * @param {Object} nodes\n * @param {Object} parent\n * @param {Boolean} cached\n * @param {Boolean} merge\n * @returns {Boolean|undefined}\n */\n function run(nodes, parent, cached, merge) {\n if (_.isBoolean(merge) && merge) {\n layout.merge(nodes);\n\n return false;\n }\n\n if (cached) {\n cachedConfig[_.keys(nodes)[0]] = JSON.parse(JSON.stringify(nodes));\n }\n\n _.each(nodes || [], layout.iterator.bind(layout, parent));\n }\n\n _.extend(layout, {\n /**\n * Determines if node ready to be added or process it.\n *\n * @param {Object} parent\n * @param {Object|String} node\n */\n iterator: function (parent, node) {\n var action = _.isString(node) ?\n this.addChild :\n this.process;\n\n action.apply(this, arguments);\n },\n\n /**\n * Prepare component.\n *\n * @param {Object} parent\n * @param {Object} node\n * @param {String} name\n * @returns {Object}\n */\n process: function (parent, node, name) {\n if (!parent && node.parent) {\n return this.waitParent(node, name);\n }\n\n if (node.nodeTemplate) {\n return this.waitTemplate.apply(this, arguments);\n }\n\n node = this.build.apply(this, arguments);
2\n\n if (!registry.has(node.name)) {\n this.addChild(parent, node)\n .manipulate(node)\n .initComponent(node);\n }\n\n if (node) {\n run(node.children, node);\n }\n\n return this;\n },\n\n /**\n * Detailed processing of component config.\n *\n * @param {Object} parent\n * @param {Object} node\n * @param {String} name\n * @returns {Boolean|Object}\n */\n build: function (parent, node, name) {\n var defaults = parent && parent.childDefaults || {},\n children = node.children,\n type = getNodeType(parent, node),\n dataScope = getDataScope(parent, node),\n component,\n extendDeps = true,\n nodeName;\n\n node.children = false;\n node.extendProvider = true;\n\n if (node.config && node.config.provider || node.provider) {\n node.extendProvider = false;\n }\n\n if (node.config && node.config.deps || node.deps) {\n extendDeps = false;\n }\n\n node = utils.extend({\n }, types.get(type), defaults, node);\n\n nodeName = getNodeName(parent, node, name);\n\n if (registry.has(nodeName)) {\n component = registry.get(nodeName);\n component.children = children;\n\n return component;\n }\n\n if (extendDeps && parent && parent.deps && type) {\n node.deps = parent.deps;\n }\n\n _.extend(node, node.config || {}, {\n index: node.name || name,\n name: nodeName,\n dataScope: dataScope,\n parentName: utils.getPart(nodeName, -2),\n parentScope: utils.getPart(dataScope, -2)\n });\n\n node.children = children;\n node.componentType = node.type;\n\n delete node.type;\n delete node.config;\n\n if (children) {\n node.initChildCount = _.size(children);\n }\n\n if (node.isTemplate) {\n node.isTemplate = false;\n\n templates.set(node.name, node);\n registry.get(node.parentName, function (parentComp) {\n parentComp.childTemplate = node;\n });\n\n return false;\n }\n\n if (node.componentDisabled === true) {\n return false;\n }\n\n return node;\n },\n\n /**\n * Init component.\n *\n * @param {Object} node\n * @returns {Object}\n */\n initComponent: function (node) {\n if (!node.component) {\n return this;\n }\n\n loadDeps(node)\n .then(loadSource)\n .done(initComponent);\n\n return this;\n }\n });\n\n _.extend(layout, {\n /**\n * Loading component marked as isTemplate.\n *\n * @param {Object} parent\n * @param {Object} node\n * @returns {Object}\n */\n waitTemplate: function (parent, node) {\n var args = _.toArray(arguments);\n\n templates.get(node.nodeTemplate, function () {\n this.applyTemplate.apply(this, args);\n }.bind(this));\n\n return this;\n },\n\n /**\n * Waiting for parent component and process provided component.\n *\n * @param {Object} node\n * @param {String} name\n * @returns {Object}\n */\n waitParent: function (node, name) {\n var process = this.process.bind(this);\n\n registry.get(node.parent, function (parent) {\n process(parent, node, name);\n });\n\n return this;\n },\n\n /**\n * Processing component marked as isTemplate.\n *\n * @param {Object} parent\n * @param {Object} node\n * @param {String} name\n */\n applyTemplate: function (parent, node, name) {\n var template = templates.get(node.nodeTemplate);\n\n node = utils.extend({}, template, node);\n\n delete node.nodeTemplate;\n\n this.process(parent, node, name);\n }\n });\n\n _.extend(layout, {\n /**\n * Determines inserting strategy.\n *\n * @param {Object} node\n * @returns {Object}\n */\n manipulate: function (node) {\n var name = node.name;\n\n if (node.appendTo) {\n this.insert(name, node.appendTo, -1);\n }\n\n if (node.prependTo) {\n this.insert(name, node.prependTo, 0);\n }
2\n\n if (node.insertTo) {\n this.insertTo(name, node.insertTo);\n }\n\n return this;\n },\n\n /**\n * Insert component to provide target and position.\n *\n * @param {Object|String} item\n * @param {Object} target\n * @param {Number} position\n * @returns {Object}\n */\n insert: function (item, target, position) {\n registry.get(target, function (container) {\n container.insertChild(item, position);\n });\n\n return this;\n },\n\n /**\n * Insert component into multiple targets.\n *\n * @param {Object} item\n * @param {Array} targets\n * @returns {Object}\n */\n insertTo: function (item, targets) {\n _.each(targets, function (info, target) {\n this.insert(item, target, info.position);\n }, this);\n\n return this;\n },\n\n /**\n * Add provided child to parent.\n *\n * @param {Object} parent\n * @param {Object|String} child\n * @returns {Object}\n */\n addChild: function (parent, child) {\n var name;\n\n if (parent && parent.component) {\n name = child.name || child;\n\n this.insert(name, parent.name, child.sortOrder);\n }\n\n return this;\n },\n\n /**\n * Merge components configuration with cached configuration.\n *\n * @param {Array} components\n */\n merge: function (components) {\n var cachedKey = _.keys(components)[0],\n compared = utils.compare(cachedConfig[cachedKey], components),\n remove = this.filterComponents(this.getByProperty(compared.changes, 'type', 'remove'), true),\n update = this.getByProperty(compared.changes, 'type', 'update'),\n dataSources = this.getDataSources(components),\n names, index, name, component;\n\n _.each(dataSources, function (val, key) {\n name = key.replace(/\\.children|\\.config/g, '');\n component = registry.get(name);\n\n component.cacheData();\n component.updateConfig(\n true,\n this.getFullConfig(key, components),\n this.getFullConfig(key, cachedConfig[cachedKey])\n );\n }, this);\n\n _.each(remove, function (val) {\n component = registry.get(val.path);\n\n if (component) {\n component.cleanData().destroy();\n }\n });\n\n update = _.compact(_.filter(update, function (val) {\n return !_.isEqual(val.oldValue, val.value);\n }));\n\n _.each(update, function (val) {\n names = val.path.split('.');\n index = Math.max(_.lastIndexOf(names, 'config'), _.lastIndexOf(names, 'children') + 2);\n name = _.without(names.splice(0, index), 'children', 'config').join('.');\n component = registry.get(name);\n\n if (val.name === 'sortOrder' && component) {\n registry.get(component.parentName).insertChild(component, val.value);\n } else if (component) {\n component.updateConfig(\n val.oldValue,\n val.value,\n val.path\n );\n }\n }, this);\n\n run(components, undefined, true);\n },\n\n /**\n * Recursive dataSource assignment.\n *\n * @param {Object} config\n * @param {String} parentPath\n * @returns {Object}\n */\n getDataSources: function (config, parentPath) {\n var dataSources = {},\n key, obj;\n\n /* eslint-disable no-loop-func, max-depth */\n for (key in config) {\n if (config.hasOwnProperty(key)) {\n if (\n key === 'type' &&\n config[key] === 'dataSource' &&\n config.hasOwnProperty('config')\n ) {\n dataSources[parentPath + '.config'] = config.config;\n } else if (_.isObject(config[key])) {\n obj = this.getDataSources(config[key], utils.fullPath(parentPath, key));\n\n _.each(obj, function (value, path) {\n dataSources[path] = value;\n });\n }\n }\n }\n\n /* eslint-enable no-loop-func, max-depth */\n\n return dataSources;\n },\n\n /**\n * Configuration getter.\n *\n * @param {String} path\n * @param {Object} config\n * @returns {Boolean|Object}\n */\n getFullConfig: function (path, config) {\n var index;\n\n path = path.split('.');\n index = _.lastIndexOf(path, 'config');\n\n if (!~index) {\n return false;\n }\n path = path.splice(0, index);\n\n _.each(path, function (val) {\n config = config[val];\n });\n\n return config.config;\n },\n\n /**\n * Filter data by property and value.\n *\n * @param {Object} data\n * @param {String} prop\n * @param {*} propValue\n */\n getByProperty: function (data, prop, propValue) {\n return _.filter(data, function (value) {\n return value[prop] === propValue;\n });\n },\n\n /**\n * Filter components.\n *\n * @param {Array} data\n * @param {Boolean} splitPath\n * @param {Number} index\n * @param {String} separator\n * @param {String} keyName\n * @returns {Array}\n */\n filterComponents: function (data, splitPath, index, separator, keyName) {\n var result = [],\n names, length;\n\n index = -2;\n separator = '.' || separator;\n keyName = 'children' || keyName;\n\n _.each(data, function (val) {\n names = val.path.split(separator);\n length = names.length;\n\n if (names[length + index] === keyName) {\n val.path = splitPath ? _.without(names, keyName).join(separator) : val.path;\n result.push(val);\n }\n });\n\n return result;\n }\n });\n\n return run;\n});\n","Magento_Ui/js/lib/collapsible.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'uiComponent'\n], function (Component) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n opened: false,\n collapsible: true\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Collapsible}
2 Chainable.\n */\n initObservable: function () {\n this._super()\n .observe('opened');\n\n return this;\n },\n\n /**\n * Toggles value of the 'opened' property.\n *\n * @returns {Collapsible} Chainable.\n */\n toggleOpened: function () {\n this.opened() ?\n this.close() :\n this.open();\n\n return this;\n },\n\n /**\n * Sets 'opened' flag to false.\n *\n * @returns {Collapsible} Chainable.\n */\n close: function () {\n if (this.collapsible) {\n this.opened(false);\n }\n\n return this;\n },\n\n /**\n * Sets 'opened' flag to true.\n *\n * @returns {Collapsible} Chainable.\n */\n open: function () {\n if (this.collapsible) {\n this.opened(true);\n }\n\n return this;\n }\n });\n});\n","Magento_Ui/js/lib/key-codes.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([], function () {\n 'use strict';\n\n return {\n 13: 'enterKey',\n 27: 'escapeKey',\n 40: 'pageDownKey',\n 38: 'pageUpKey',\n 32: 'spaceKey',\n 9: 'tabKey',\n 37: 'pageLeftKey',\n 39: 'pageRightKey',\n 17: 'ctrlKey',\n 18: 'altKey',\n 16: 'shiftKey'\n };\n});\n","Magento_Ui/js/lib/spinner.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 var selector = '[data-role=\"spinner\"]',\n spinner = $(selector);\n\n return {\n /**\n * Show spinner.\n */\n show: function () {\n spinner.show();\n },\n\n /**\n * Hide spinner.\n */\n hide: function () {\n spinner.hide();\n },\n\n /**\n * Get spinner by selector.\n *\n * @param {String} id\n * @return {jQuery}\n */\n get: function (id) {\n return $(selector + '[data-component=\"' + id + '\"]');\n }\n };\n});\n","Magento_Ui/js/lib/validation/utils.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine(function () {\n 'use strict';\n\n var utils = {\n /**\n * Check if string is empty with trim.\n *\n * @param {String} value\n * @return {Boolean}\n */\n isEmpty: function (value) {\n return value === '' || value == null || value.length === 0 || /^\\s+$/.test(value);\n },\n\n /**\n * Check if string is empty no trim.\n *\n * @param {String} value\n * @return {Boolean}\n */\n isEmptyNoTrim: function (value) {\n return value === '' || value == null || value.length === 0;\n },\n\n /**\n * Checks if {value} is between numbers {from} and {to}.\n *\n * @param {String} value\n * @param {String} from\n * @param {String} to\n * @return {Boolean}\n */\n isBetween: function (value, from, to) {\n return (from === null || from === '' || value >= utils.parseNumber(from)) &&\n (to === null || to === '' || value <= utils.parseNumber(to));\n },\n\n /**\n * Parse price string.\n *\n * @param {String} value\n * @return {Number}\n */\n parseNumber: function (value) {\n var isDot, isComa;\n\n if (typeof value !== 'string') {\n return parseFloat(value);\n }\n isDot = value.indexOf('.');\n isComa = value.indexOf(',');\n\n if (isDot !== -1 && isComa !== -1) {\n if (isComa > isDot) {\n value = value.replace('.', '').replace(',', '.');\n } else {\n value = value.replace(',', '');\n }\n } else if (isComa !== -1) {\n value = value.replace(',', '.');\n }\n\n return parseFloat(value);\n },\n\n /**\n * Removes HTML tags and space characters, numbers and punctuation.\n *\n * @param {String} value - Value being stripped.\n * @return {String}
2\n */\n stripHtml: function (value) {\n return value.replace(/<.[^<>]*?>/g, ' ').replace(/ | /gi, ' ')\n .replace(/[0-9.(),;:!?%#$'\"_+=\\/-]*/g, '');\n }\n };\n\n return utils;\n});\n","Magento_Ui/js/lib/validation/rules.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 './utils',\n 'moment',\n 'jquery/validate',\n 'jquery/ui',\n 'mage/translate'\n], function ($, _, utils, moment) {\n 'use strict';\n\n /**\n * validate credit card number using mod10\n * @param {String} s\n * @return {Boolean}\n */\n function validateCreditCard(s) {\n // remove non-numerics\n var v = '0123456789',\n w = '',\n i, j, k, m, c, a, x;\n\n for (i = 0; i < s.length; i++) {\n x = s.charAt(i);\n\n if (v.indexOf(x, 0) !== -1) {\n w += x;\n }\n }\n // validate number\n j = w.length / 2;\n k = Math.floor(j);\n m = Math.ceil(j) - k;\n c = 0;\n\n for (i = 0; i < k; i++) {\n a = w.charAt(i * 2 + m) * 2;\n c += a > 9 ? Math.floor(a / 10 + a % 10) : a;\n }\n\n for (i = 0; i < k + m; i++) {\n c += w.charAt(i * 2 + 1 - m) * 1;\n }\n\n return c % 10 === 0;\n }\n\n /**\n * Collection of validation rules including rules from additional-methods.js\n * @type {Object}\n */\n return _.mapObject({\n 'min_text_length': [\n function (value, params) {\n return _.isUndefined(value) || value.length === 0 || value.length >= +params;\n },\n $.mage.__('Please enter more or equal than {0} symbols.')\n ],\n 'max_text_length': [\n function (value, params) {\n return !_.isUndefined(value) && value.length <= +params;\n },\n $.mage.__('Please enter less or equal than {0} symbols.')\n ],\n 'max-words': [\n function (value, params) {\n return utils.isEmpty(value) || utils.stripHtml(value).match(/\\b\\w+\\b/g).length < params;\n },\n $.mage.__('Please enter {0} words or less.')\n ],\n 'min-words': [\n function (value, params) {\n return utils.isEmpty(value) || utils.stripHtml(value).match(/\\b\\w+\\b/g).length >= params;\n },\n $.mage.__('Please enter at least {0} words.')\n ],\n 'range-words': [\n function (value, params) {\n var match = utils.stripHtml(value).match(/\\b\\w+\\b/g) || [];\n\n return utils.isEmpty(value) || match.length >= params[0] &&\n match.length <= params[1];\n },\n $.mage.__('Please enter between {0} and {1} words.')\n ],\n 'letters-with-basic-punc': [\n function (value) {\n return utils.isEmpty(value) || /^[a-z\\-.,()\\u0027\\u0022\\s]+$/i.test(value);\n },\n $.mage.__('Letters or punctuation only please')\n ],\n 'alphanumeric': [\n function (value) {\n return utils.isEmpty(value) || /^\\w+$/i.test(value);\n },\n $.mage.__('Letters, numbers, spaces or underscores only please')\n ],\n 'letters-only': [\n function (value) {\n return utils.isEmpty(value) || /^[a-z]+$/i.test(value);\n },\n $.mage.__('Letters only please')\n ],\n 'no-whitespace': [\n function (value) {\n return utils.isEmpty(value) || /^\\S+$/i.test(value);\n },\n $.mage.__('No white space please')\n ],\n 'zip-range': [\n function (value) {\n return utils.isEmpty(value) || /^90[2-5]-\\d{2}-\\d{4}$/.test(value);\n },\n $.mage.__('Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx')\n ],\n 'integer': [\n function (value) {\n return utils.isEmpty(value) || /^-?\\d+$/.test(value);\n },\n $.mage.__('A positive or negative non-decimal number please')\n ],\n 'vinUS': [\n function (value) {\n if (utils.isEmpty(value)) {\n return true;\n }\n\n if (value.length !== 17) {\n return false;\n }\n var i, n, d, f, cd, cdv,//eslint-disable-line vars-on-top\n LL = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],//eslint-disable-line max-len\n VL = [1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9],\n FL = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2],\n rs = 0;\n\n for (i = 0; i < 17;
2 i++) {\n f = FL[i];\n d = value.slice(i, i + 1);\n\n if (i === 8) {\n cdv = d;\n }\n\n if (!isNaN(d)) {\n d *= f;\n } else {\n for (n = 0; n < LL.length; n++) {//eslint-disable-line max-depth\n if (d.toUpperCase() === LL[n]) {//eslint-disable-line max-depth\n d = VL[n];\n d *= f;\n\n if (isNaN(cdv) && n === 8) {//eslint-disable-line max-depth\n cdv = LL[n];\n }\n break;\n }\n }\n }\n rs += d;\n }\n cd = rs % 11;\n\n if (cd === 10) {\n cd = 'X';\n }\n\n if (cd === cdv) {\n return true;\n }\n\n return false;\n },\n $.mage.__('The specified vehicle identification number (VIN) is invali
2d.')\n ],\n 'dateITA': [\n function (value) {\n var check = false,\n re = /^\\d{1,2}\\/\\d{1,2}\\/\\d{4}$/,\n adata, gg, mm, aaaa, xdata;\n\n if (re.test(value)) {\n adata = value.split('/');\n gg = parseInt(adata[0], 10);\n mm = parseInt(adata[1], 10);\n aaaa = parseInt(adata[2], 10);\n xdata = new Date(aaaa, mm - 1, gg);\n\n if (xdata.getFullYear() === aaaa &&\n xdata.getMonth() === mm - 1 &&\n xdata.getDate() === gg\n ) {\n check = true;\n } else {\n check = false;\n }\n } else {\n check = false;\n }\n\n return check;\n },\n $.mage.__('Please enter a correct date')\n ],\n 'dateNL': [\n function (value) {\n return /^\\d\\d?[\\.\\/-]\\d\\d?[\\.\\/-]\\d\\d\\d?\\d?$/.test(value);\n },\n $.mage.__('Vul hier een geldige datum in.')\n ],\n 'time': [\n function (value) {\n return utils.isEmpty(value) || /^([01]\\d|2[0-3])(:[0-5]\\d){0,2}$/.test(value);\n },\n $.mage.__('Please enter a valid time, between 00:00 and 23:59')\n ],\n 'time12h': [\n function (value) {\n return utils.isEmpty(value) || /^((0?[1-9]|1[012])(:[0-5]\\d){0,2}(\\s[AP]M))$/i.test(value);\n },\n $.mage.__('Please enter a valid time, between 00:00 am and 12:00 pm')\n ],\n 'phoneUS': [\n function (value) {\n value = value.replace(/\\s+/g, '');\n\n return utils.isEmpty(value) || value.length > 9 &&\n value.match(/^(1-?)?(\\([2-9]\\d{2}\\)|[2-9]\\d{2})-?[2-9]\\d{2}-?\\d{4}$/);\n },\n $.mage.__('Please specify a valid phone number')\n ],\n 'phoneUK': [\n function (value) {\n return utils.isEmpty(value) || value.length > 9 &&\n value.match(/^(\\(?(0|\\+44)[1-9]{1}\\d{1,4}?\\)?\\s?\\d{3,4}\\s?\\d{3,4})$/);\n },\n $.mage.__('Please specify a valid phone number')\n ],\n 'mobileUK': [\n function (value) {\n return utils.isEmpty(value) || value.length > 9 && value.match(/^((0|\\+44)7\\d{3}\\s?\\d{6})$/);\n },\n $.mage.__('Please specify a valid mobile number')\n ],\n 'stripped-min-length': [\n function (value, param) {\n return _.isUndefined(value) || value.length === 0 || utils.stripHtml(value).length >= param;\n },\n $.mage.__('Please enter at least {0} characters')\n ],\n 'email2': [\n function (value) {\n return utils.isEmpty(value) || /^((([a-z]|\\d|[!#\\$%&\\u0027\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&\\u0027\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\u0022)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\u0022)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$/i.test(value);//eslint-disable-line max-len\n },\n $.validator.messages.email\n ],\n 'url2': [\n function (value) {\n return utils.isEmpty(value) || /^(https?|ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(\\#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i.test(value);//eslint-disable-line max-len\n },\n $.validator.messages.url\n ],\n 'credit-card-types': [\n function (value, param) {\n var val
2idTypes;\n\n if (utils.isEmpty(value)) {\n return true;\n }\n\n if (/[^0-9-]+/.test(value)) {\n return false;\n }\n value = value.replace(/\\D/g, '');\n validTypes = 0x0000;\n\n if (param.mastercard) {\n validTypes |= 0x0001;\n }\n\n if (param.visa) {\n validTypes |= 0x0002;\n }\n\n if (param.amex) {\n validTypes |= 0x0004;\n }\n\n if (param.dinersclub) {\n validTypes |= 0x0008;\n }\n\n if (param.enroute) {\n validTypes |= 0x0010;\n }\n\n if (param.discover) {\n validTypes |= 0x0020;\n }\n\n if (param.jcb) {\n validTypes |= 0x0040;\n }\n\n if (param.unknown) {\n validTypes |= 0x0080;\n }\n\n if (param.all) {\n validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;\n }\n\n if (validTypes & 0x0001 && /^(51|52|53|54|55)/.test(value)) { //mastercard\n return value.length === 16;\n }\n\n if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa\n return value.length === 16;\n }\n\n if (validTypes & 0x0004 && /^(34|37)/.test(value)) { //amex\n return value.length === 15;\n }\n\n if (validTypes & 0x0008 && /^(300|301|302|303|304|305|36|38)/.test(value)) { //dinersclub\n return value.length === 14;\n }\n\n if (validTypes & 0x0010 && /^(2014|2149)/.test(value)) { //enroute\n return value.length === 15;\n }\n\n if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover\n return value.length === 16;\n }\n\n if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb\n return value.length === 16;\n }\n\n if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb\n return value.length === 15;\n }\n\n if (validTypes & 0x0080) { //unknown\n return true;\n }\n\n return false;\n },\n $.mage.__('Please enter a valid credit card number.')\n ],\n 'ipv4': [\n function (value) {\n return utils.isEmpty(value) || /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i.test(value);//eslint-disable-line max-len\n },\n $.mage.__('Please enter a valid IP v4 address.')\n ],\n 'ipv6': [\n function (value) {\n return utils.isEmpty(value) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value);//eslint-disable-line max-len\n },\n $.mage.__('Please enter a valid IP v6 address.')\n ],\n 'pattern': [\n function (value, param) {\n return utils.isEmpty(value) || new RegExp(param).test(value);\n },\n $.mage.__('Invalid format.')\n ],\n 'validate-no-html-tags': [\n function (value) {\n return !/<(\\/)?\\w+/.test(value);\n },\n $.mage.__('HTML tags are not allowed.')\n ],\n 'validate-select': [\n function (value) {\n return value !== 'none' && value != null && value.length !== 0;\n },\n $.mage.__('Please select an option.')\n ],\n 'validate-no-empty': [\n function (value) {\n return !utils.isEmpty(value);\n },\n $.mage.__('Empty Value.')\n ],\n 'validate-alphanum-with-spaces': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[a-zA-Z0-9 ]+$/.test(value);\n },\n $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.')\n ],\n 'validate-data': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[A-Za-z]+[A-Za-z0-9_]+$/.test(value);\n },\n $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.')//eslint-disable-line max-len\n ],\n 'validate-street': [\n function (value) {\n return utils.isEmptyNoTrim(value) ||\n /^[ \\w]{3,}([A-Za-z]\\.)?([ \\w]*\\#\\d+)?(\\r\\n| )[ \\w]{3,}/.test(value);\n },\n $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9), spaces and \"#\" in this field.')\n ],\n 'validate-phoneStrict': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^(\\()?\\d{3}(\\))?(-|\\s)?\\d{3}(-|\\s)\\d{4}$/.test(value);\n },\n $.mage.__('Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.')\n ],\n 'validate-phoneLax': [\n function (value) {\n return utils.isEmptyNoTrim(value) ||\n /^((\\d[\\-. ]?)?((\\(\\d{3}\\))|\\d{3}))?[\\-. ]?\\d{3}[\\-. ]?\\d{4}$/.test(value);\n },\n $.mage.__('Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.')\n ],\n 'validate-fax': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^(\\()?\\d{3}(\\))?(-|\\s)?\\d{3}(-|\\s)\\d{4}$/.test(value);\n },\n $.mage.__('Please enter a valid fax number (Ex: 123-456-7890).')\n ],\n 'validate-email': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*@([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*\\.(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]){2,})$/i.test(value);//eslint-disable-line max-len\n },\n $.mage.__('Please enter a valid email address (Ex: [email protected]).')\n ],\n 'validate-emailSender': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[\\S ]+$/.test(value);\n },\n $.mage.__('Please enter a valid email address (Ex: [email protected]).')\n ],\n 'validate-password': [\n function (value) {\n var pass;\n\n if (value == null) {\n return false;\n }\n\n pass = $.trim(value);\n\n if (!pass.length) {\n return true;\n }\n\n return !(pass.length > 0 && pass.length < 6);\n },\n $.mage.__('Please enter 6 or more characters. Leading and trailing space
2s will be ignored.')\n ],\n 'validate-admin-password': [\n function (value) {\n var pass;\n\n if (value == null) {\n return false;\n }\n\n pass = $.trim(value);\n\n if (pass.length === 0) {\n return true;\n }\n\n if (!/[a-z]/i.test(value) || !/[0-9]/.test(value)) {\n return false;\n }\n\n if (pass.length < 7) {\n return false;\n }\n\n return true;\n },\n $.mage.__('Please enter 7 or more characters, using both numeric and alphabetic.')\n ],\n 'validate-customer-password': [\n function (v, elm) {\n var validator = this,\n counter = 0,\n passwordMinLength = $(elm).data('password-min-length'),\n passwordMinCharacterSets = $(elm).data('password-min-character-sets'),\n pass = $.trim(v),\n result = pass.length >= passwordMinLength;\n\n if (result === false) {\n validator.passwordErrorMessage = $.mage.__('Minimum length of this field must be equal or greater than %1 symbols. Leading and trailing spaces will be ignored.').replace('%1', passwordMinLength);//eslint-disable-line max-len\n\n return result;\n }\n\n if (pass.match(/\\d+/)) {\n counter++;\n }\n\n if (pass.match(/[a-z]+/)) {\n counter++;\n }\n\n if (pass.match(/[A-Z]+/)) {\n counter++;\n }\n\n if (pass.match(/[^a-zA-Z0-9]+/)) {\n counter++;\n }\n\n if (counter < passwordMinCharacterSets) {\n result = false;\n validator.passwordErrorMessage = $.mage.__('Minimum of different classes of characters in password is %1. Classes of characters: Lower Case, Upper Case, Digits, Special Characters.').replace('%1', passwordMinCharacterSets);//eslint-disable-line max-len\n }\n\n return result;\n }, function () {\n return this.passwordErrorMessage;\n }\n ],\n 'validate-url': [\n function (value) {\n if (utils.isEmptyNoTrim(value)) {\n return true;\n }\n value = (value || '').replace(/^\\s+/, '').replace(/\\s+$/, '');\n\n return (/^(http|https|ftp):\\/\\/(([A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))(\\.[A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))*)(:(\\d+))?(\\/[A-Z0-9~](([A-Z0-9_~-]|\\.)*[A-Z0-9~]|))*\\/?(.*)?$/i).test(value);//eslint-disable-line max-len\n\n },\n $.mage.__('Please enter a valid URL. Protocol is required (http://, https:// or ftp://).')\n ],\n 'validate-clean-url': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^(http|https|ftp):\\/\\/(([A-Z0-9][A-Z0-9_-]*)(\\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\\d+))?\\/?/i.test(value) || /^(www)((\\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\\d+))?\\/?/i.test(value);//eslint-disable-line max-len\n\n },\n $.mage.__('Please enter a valid URL. For example http://www.example.com or www.example.com.')\n ],\n 'validate-xml-identifier': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[A-Z][A-Z0-9_\\/-]*$/i.test(value);\n\n },\n $.mage.__('Please enter a valid XML-identifier (Ex: something_1, block5, id-4).')\n ],\n 'validate-ssn': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^\\d{3}-?\\d{2}-?\\d{4}$/.test(value);\n\n },\n $.mage.__('Please enter a valid social security number (Ex: 123-45-6789).')\n ],\n 'validate-zip-us': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /(^\\d{5}$)|(^\\d{5}-\\d{4}$)/.test(value);\n\n },\n $.mage.__('Please enter a valid zip code (Ex: 90602 or 90602-1234).')\n ],\n 'validate-date-au': [\n function (value) {\n var regex = /^(\\d{2})\\/(\\d{2})\\/(\\d{4})$/,\n d;\n\n if (utils.isEmptyNoTrim(value)) {\n return true;\n }\n\n if (utils.isEmpty(value) || !regex.test(value)) {\n return false;\n }\n d = new Date(value.replace(regex, '$2/$1/$3'));
2\n\n return parseInt(RegExp.$2, 10) === 1 + d.getMonth() &&\n parseInt(RegExp.$1, 10) === d.getDate() &&\n parseInt(RegExp.$3, 10) === d.getFullYear();\n\n },\n $.mage.__('Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.')\n ],\n 'validate-currency-dollar': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^\\$?\\-?([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}\\d*(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$/.test(value);//eslint-disable-line max-len\n\n },\n $.mage.__('Please enter a valid $ amount. For example $100.00.')\n ],\n 'validate-not-negative-number': [\n function (value) {\n if (utils.isEmptyNoTrim(value)) {\n return true;\n }\n value = utils.parseNumber(value);\n\n return !isNaN(value) && value >= 0;\n\n },\n $.mage.__('Please enter a number 0 or greater in this field.')\n ],\n // validate-not-negative-number should be replaced in all places with this one and then removed\n 'validate-zero-or-greater': [\n function (value) {\n if (utils.isEmptyNoTrim(value)) {\n return true;\n }\n value = utils.parseNumber(value);\n\n return !isNaN(value) && value >= 0;\n },\n $.mage.__('Please enter a number 0 or greater in this field.')\n ],\n 'validate-greater-than-zero': [\n function (value) {\n if (utils.isEmptyNoTrim(value)) {\n return true;\n }\n value = utils.parseNumber(value);\n\n return !isNaN(value) && value > 0;\n },\n $.mage.__('Please enter a number greater than 0 in this field.')\n ],\n 'validate-css-length': [\n function (value) {\n if (value !== '') {\n return (/^[0-9]*\\.*[0-9]+(px|pc|pt|ex|em|mm|cm|in|%)?$/).test(value);\n }\n\n return true;\n },\n $.mage.__('Please input a valid CSS-length (Ex: 100px, 77pt, 20em, .5ex or 50%).')\n ],\n 'validate-number': [\n function (value) {\n return utils.isEmptyNoTrim(value) ||\n !isNaN(utils.parseNumber(value)) && /^\\s*-?\\d*(,\\d*)*(\\.\\d*)?\\s*$/.test(value);\n },\n $.mage.__('Please enter a valid number in this field.')\n ],\n 'validate-integer': [\n function (value) {\n return utils.isEmptyNoTrim(value) || !isNaN(utils.parseNumber(value)) && /^\\s*-?\\d*\\s*$/.test(value);\n },\n $.mage.__('Please enter a valid integer in this field.')\n ],\n 'validate-number-range': [\n function (value, param) {\n var numValue, dataAttrRange, result, range, m;\n\n if (utils.isEmptyNoTrim(value)) {\n return true;\n }\n\n numValue = utils.parseNumber(value);\n\n if (isNaN(numValue)) {\n return false;\n }\n\n dataAttrRange = /^(-?[\\d.,]+)?-(-?[\\d.,]+)?$/;\n result = true;\n range = param;\n\n if (range) {\n m = dataAttrRange.exec(range);\n\n if (m) {\n result = result && utils.isBetween(numValue, m[1], m[2]);\n }\n }\n\n return result;\n },\n $.mage.__('The value is not within the specified range.')\n ],\n 'validate-digits': [\n function (value) {\n return utils.isEmptyNoTrim(value) || !/[^\\d]/.test(value);\n },\n $.mage.__('Please enter a valid number in this field.')\n ],\n 'validate-digits-range': [\n function (value, param) {\n var numValue, dataAttrRange, result, range, m;\n\n if (utils.isEmptyNoTrim(value)) {\n return true;\n }\n\n numValue = utils.parseNumber(value);\n\n if (isNaN(numValue)) {\n return false;\n }\n\n dataAttrRange = /^(-?\\d+)?-(-?\\d+)?$/;\n result = true;\n range = param;\n\n if (range) {\n m = dataAttrRange.exec(range);\n\n if (m) {\n result = result && utils.isBetween(numValue, m[1], m[2]);\n }\n }\n\n return result;\n },\n $.mage.__('The value is not within the specified range.')\n ],\n 'validate-range': [\n function (value) {\n var minValue, maxValue, ranges;\n\n if (utils.isEmptyNoTrim(value)) {\n return true;\n } else if ($.validator.methods['validate-digits'] && $.validator.methods['validate-digits'](value)) {\n minValue = maxValue = utils.parseNumber(value);\n } else {\n ranges = /^(-?\\d+)?-(-?\\d+)?$/.exec(value);\n\n if (ranges) {\n minValue = utils.parseNumber(ranges[1]);\n maxValue = utils.parseNumber(ranges[2]);\n\n if (minValue > maxValue) {//eslint-disable-line max-depth\n return false;\n }\n } else {\n return false;\n }\n }\n },\n $.mage.__('The value is not within the specified range.')\n ],\n 'validate-alpha': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[a-zA-Z]+$/.test(value);\n },\n $.mage.__('Please use letters only (a-z or A-Z) in this field.')\n ],\n 'validate-code': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[a-z]+[a-z0-9_]+$/.test(value);\n },\n $.mage.__('Please use only letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.')//eslint-disable-line max-len\n ],\n 'validate-alphanum': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[a-zA-Z0-9]+$/.test(value);\n },\n $.mage.__('Please use only letters (a-z or A-Z) or numbers (0-9) in this field. No spaces or other characters are allowed.')//eslint-disable-line max-len\n ],\n 'validate-not-number-first': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[^0-9-\\.].*$/.test(value.trim());\n },\n $.mage.__('First character must be letter.')\n ],\n 'validate-date': [\n function (value, params, additionalParams) {\n var test = moment(value, additionalParams.dateFormat);\n\n return utils.isEmptyNoTrim(value) || test.isValid();\n },\n $.mage.__('Please enter a valid date.')\n ],\n 'validate-identifier': [\n function (value) {\n return utils.isEmptyNoTrim(value) || /^[a-z0-9][a-z0-9_\\/-]+(\\.[a-z0-9_-]+)?$/.test(value);\n },\n $.mage.__('Please enter a valid URL Key (Ex: \"example-page\", \"example-page.html\" or \"anotherlevel/example-page\").')//eslint-disable-line max-len\n ],\n 'validate-zip-international': [\n\n /*function(v) {\n // @TODO: Cleanup\n return Validation.get('IsEmpty').test(v) || /(^[A-z0-9]{2,10}([\\s]{0,1}|[\\-]{0,1})[A-z0-9]{2,10}$)/.test(v);\n }*/\n function () {\n return true;\n },\n $.mage.__('Please enter a valid zip code.')\n ],\n 'validate-state': [\n function (value) {\n return value !== 0 || value === '';\n },\n $.mage.__('Please select State/Province.')\n ],\n 'less-than-equals-to': [\n function (value, params) {\n if ($.isNumeric(params) && $.isNumeric(value)) {\n return parseFloat(value) <= parseFloat(params);\n }\n\n return true;\n },\n $.mage.__('Please enter a value less than or equal to {0}.')\n ],\n 'greater-than-equals-to': [\n function (value, params) {\n if ($.isNumeric(params) && $.isNumeric(value)) {\n return parseFloat(value) >= parseFloat(params);\n }\n\n return true;\n },\n $.mage.__('Please enter a value greater than or equal to {0}.')\n ],\n 'validate-emails': [\n function (value) {\n var val
2idRegexp, emails, i;\n\n if (utils.isEmpty(value)) {\n return true;\n }\n validRegexp = /^[a-z0-9\\._-]{1,30}@([a-z0-9_-]{1,30}\\.){1,5}[a-z]{2,4}$/i;\n emails = value.split(/[\\s\\n\\,]+/g);\n\n for (i = 0; i < emails.length; i++) {\n if (!validRegexp.test(emails[i].strip())) {\n return false;\n }\n }\n\n return true;\n },\n $.mage.__('Please enter valid email addresses, separated by commas. For example, [email protected], [email protected].')//eslint-disable-line max-len\n ],\n 'validate-cc-number': [\n\n /**\n * Validate credit card number based on mod 10.\n *\n * @param {String} value - credit card number\n * @return {Boolean}\n */\n function (value) {\n if (value) {\n return validateCreditCard(value);\n }\n\n return true;\n },\n $.mage.__('Please enter a valid credit card number.')\n ],\n 'validate-cc-ukss': [\n\n /**\n * Validate Switch/Solo/Maestro issue number and start date is filled.\n *\n * @param {String} value - input field value\n * @return {*}\n */\n function (value) {\n return value;\n },\n $.mage.__('Please enter issue number or start date for switch/solo card type.')\n ],\n 'required-entry': [\n function (value) {\n return !utils.isEmpty(value);\n },\n $.mage.__('This is a required field.')\n ],\n 'checked': [\n function (value) {\n return value;\n },\n $.mage.__('This is a required field.')\n ],\n 'not-negative-amount': [\n function (value) {\n if (value.length) {\n return (/^\\s*\\d+([,.]\\d+)*\\s*%?\\s*$/).test(value);\n }\n\n return true;\n },\n $.mage.__('Please enter positive number in this field.')\n ],\n 'validate-per-page-value-list': [\n function (value) {\n var isValid = utils.isEmpty(value),\n values = value.split(','),\n i;\n\n if (isValid) {\n return true;\n }\n\n for (i = 0; i < values.length; i++) {\n if (!/^[0-9]+$/.test(values[i])) {\n isValid = false;\n }\n }\n\n return isValid;\n },\n $.mage.__('Please enter a valid value, ex: 10,20,30')\n ],\n 'validate-new-password': [\n function (value) {\n if ($.validator.methods['validate-password'] && !$.validator.methods['validate-password'](value)) {\n return false;\n }\n\n if (utils.isEmpty(value) && value !== '') {\n return false;\n }\n\n return true;\n },\n $.mage.__('Please enter 6 or more characters. Leading and trailing spaces will be ignored.')\n ],\n 'validate-item-quantity': [\n function (value, params) {\n var validator = this,\n result = false,\n // obtain values for validation\n qty = utils.parseNumber(value),\n isMinAllowedValid = typeof params.minAllowed === 'undefined' ||\n qty >= utils.parseNumber(params.minAllowed),\n isMaxAllowedValid = typeof params.maxAllowed === 'undefined' ||\n qty <= utils.parseNumber(params.maxAllowed),\n isQtyIncrementsValid = typeof params.qtyIncrements === 'undefined' ||\n qty % utils.parseNumber(params.qtyIncrements) === 0;\n\n result = qty > 0;\n\n if (result === false) {\n validator.itemQtyErrorMessage = $.mage.__('Please enter a quantity greater than 0.');//eslint-disable-line max-len\n\n return result;\n }\n\n result = isMinAllowedValid;\n\n if (result === false) {\n validator.itemQtyErrorMessage = $.mage.__('The fewest you may purchase is %1.').replace('%1', params.minAllowed);//eslint-disable-line max-len\n\n return result;\n }\n\n result = isMaxAllowedValid;\n\n if (result === false) {\n validator.itemQtyErrorMessage = $.mage.__('The maximum you may purchase is %1.').replace('%1', params.maxAllowed);//eslint-disable-line max-len\n\n return result;\n }
2\n\n result = isQtyIncrementsValid;\n\n if (result === false) {\n validator.itemQtyErrorMessage = $.mage.__('You can buy this product only in quantities of %1 at a time.').replace('%1', params.qtyIncrements);//eslint-disable-line max-len\n\n return result;\n }\n\n return result;\n }, function () {\n return this.itemQtyErrorMessage;\n }\n ],\n 'equalTo': [\n function (value, param) {\n return value === $(param).val();\n },\n $.validator.messages.equalTo\n ],\n 'validate-file-type': [\n function (name, types) {\n var extension = name.split('.').pop().toLowerCase();\n\n if (types && typeof types === 'string') {\n types = types.split(' ');\n }\n\n return !types || !types.length || ~types.indexOf(extension);\n },\n $.mage.__('We don\\'t recognize or support this file extension type.')\n ],\n 'validate-max-size': [\n function (size, maxSize) {\n return maxSize === false || size < maxSize;\n },\n $.mage.__('File you are trying to upload exceeds maximum file size limit.')\n ],\n 'validate-if-tag-script-exist': [\n function (value) {\n return !value || (/<script\\b[^>]*>([\\s\\S]*?)<\\/script>$/ig).test(value);\n },\n $.mage.__('Please use tag SCRIPT with SRC attribute or with proper content to include JavaScript to the document.')//eslint-disable-line max-len\n ],\n 'date_range_min': [\n function (value, minValue, params) {\n return moment.utc(value, params.dateFormat).unix() >= minValue;\n },\n $.mage.__('The date is not within the specified range.')\n ],\n 'date_range_max': [\n function (value, maxValue, params) {\n return moment.utc(value, params.dateFormat).unix() <= maxValue;\n },\n $.mage.__('The date is not within the specified range.')\n ]\n }
2, function (data) {\n return {\n handler: data[0],\n message: data[1]\n };\n });\n});\n","Magento_Ui/js/lib/validation/validator.js":"/*\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n './rules'\n], function (_, rulesList) {\n 'use strict';\n\n /**\n * Validates provided value be the specified rule.\n *\n * @param {String} id - Rule identifier.\n * @param {*} value - Value to be checked.\n * @param {*} [params]\n * @param {*} additionalParams - additional validation params set by method caller\n * @returns {Object}\n */\n function validate(id, value, params, additionalParams) {\n var rule,\n message,\n valid,\n result = {\n rule: id,\n passed: true,\n message: ''\n };\n\n if (_.isObject(params)) {\n message = params.message || '';\n }\n\n if (!rulesList[id]) {\n return result;\n }\n\n rule = rulesList[id];\n message = message || rule.message;\n valid = rule.handler(value, params, additionalParams);\n\n if (!valid) {\n params = Array.isArray(params) ?\n params :\n [params];\n\n message = params.reduce(function (msg, param, idx) {\n return msg.replace(new RegExp('\\\\{' + idx + '\\\\}', 'g'), param);\n }, message);\n\n result.passed = false;\n result.message = message;\n }\n\n return result;\n }\n\n /**\n * Validates provied value by a specfied set of rules.\n *\n * @param {(String|Object)} rules - One or many validation rules.\n * @param {*} value - Value to be checked.\n * @param {*} additionalParams - additional validation params set by method caller\n * @returns {Object}\n */\n function validator(rules, value, additionalParams) {\n var result;\n\n if (typeof rules === 'object') {\n result = {\n passed: true\n };\n\n _.every(rules, function (ruleParams, id) {\n if (ruleParams.validate || ruleParams !== false || additionalParams) {\n result = validate(id, value, ruleParams, additionalParams);\n\n return result.passed;\n }\n\n return true;\n });\n\n return result;\n }\n\n return validate.apply(null, arguments);\n }\n\n /**\n * Adds new validation rule.\n *\n * @param {String} id - Rule identifier.\n * @param {Function} handler - Validation function.\n * @param {String} message - Error message.\n */\n validator.addRule = function (id, handler, message) {\n rulesList[id] = {\n handler: handler,\n message: message\n };\n };\n\n /**\n * Returns rule object found by provided identifier.\n *\n * @param {String} id - Rule identifier.\n * @returns {Object}\n */\n validator.getRule = function (id) {\n return rulesList[id];\n };\n\n return validator;\n});\n","Magento_Ui/js/lib/view/utils/bindings.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], function (ko, $, _) {\n 'use strict';\n\n /**\n * Checks if provided value is a dom element.\n *\n * @param {*} node - Value to be checked.\n * @returns {Boolean}\n */\n function isDomElement(node) {\n return typeof node === 'object' && node.tagName && node.nodeType;\n }\n\n /**\n * Removes from the provided array all non-root nodes located inside\n * of the comment element as long as the closing comment tags.\n *\n * @param {(Array|ArrayLike)} nodes - An array of nodes to be processed.\n * @returns {Array}\n */\n function normalize(nodes) {\n var result;\n\n nodes = _.toArray(nodes);\n result = nodes.slice();
2\n\n nodes.forEach(function (node) {\n if (node.nodeType === 8) {\n result = !ko.virtualElements.hasBindingValue(node) ?\n _.without(result, node) :\n _.difference(result, ko.virtualElements.childNodes(node));\n }\n });\n\n return result;\n }\n\n /**\n * Extends binding context of each item in the collection.\n *\n * @param {...Object} extenders - Multiple extender objects to be applied to the context.\n * @returns {jQueryCollection} Chainable.\n */\n $.fn.extendCtx = function () {\n var nodes = normalize(this),\n extenders = _.toArray(arguments);\n\n nodes.forEach(function (node) {\n var ctx = ko.contextFor(node),\n data = [ctx].concat(extenders);\n\n _.extend.apply(_, data);\n });\n\n return this;\n };\n\n /**\n * Evaluates bindings specified in each DOM element of collection.\n *\n * @param {(HTMLElement|Object)} [ctx] - Context to use for bindings evaluation.\n * If not specified then current context of a collections' item will be used.\n * @returns {jQueryCollection} Chainable.\n */\n $.fn.applyBindings = function (ctx) {\n var nodes = normalize(this),\n nodeCtx;\n\n if (isDomElement(ctx)) {\n ctx = ko.contextFor(ctx);\n }\n\n nodes.forEach(function (node) {\n nodeCtx = ctx || ko.contextFor(node);\n\n ko.applyBindings(nodeCtx, node);\n });\n\n return this;\n };\n\n /**\n * Adds specfied bindings to each DOM elemenet in\n * collection and evalutes them with provided context.\n *\n * @param {(Object|Function)} data - Either bindings object or a function\n * which returns bindings data for each element in collection.\n * @param {(HTMLElement|Object)} [ctx] - Context to use for bindings evaluation.\n * If not specified then current context of a collections' item will be used.\n * @returns {jQueryCollection} Chainable.\n */\n $.fn.bindings = function (data, ctx) {\n var nodes = normalize(this),\n bindings = data,\n nodeCtx;\n\n if (isDomElement(ctx)) {\n ctx = ko.contextFor(ctx);\n }\n\n nodes.forEach(function (node) {\n nodeCtx = ctx || ko.contextFor(node);\n\n if (_.isFunction(data)) {\n bindings = data(nodeCtx, node);\n }\n\n ko.applyBindingsToNode(node, bindings, nodeCtx);\n });\n\n return this;\n };\n});\n","Magento_Ui/js/lib/view/utils/dom-observer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'underscore',\n 'MutationObserver',\n 'domReady!'\n], function ($, _) {\n 'use strict';\n\n var counter = 1,\n watchers,\n globalObserver;\n\n watchers = {\n selectors: {},\n nodes: {}\n };\n\n /**\n * Checks if node represents an element node (nodeType === 1).\n *\n * @param {HTMLElement} node\n * @returns {Boolean}\n */\n function isElementNode(node) {\n return node.nodeType === 1;\n }\n\n /**\n * Extracts all child descendant\n * elements of a specified node.\n *\n * @param {HTMLElement} node\n * @returns {Array}\n */\n function extractChildren(node) {\n var children = node.querySelectorAll('*');\n\n return _.toArray(children);\n }\n\n /**\n * Extracts node identifier. If ID is not specified,\n * then it will be created for the provided node.\n *\n * @param {HTMLElement} node\n * @returns {Number}\n */\n function getNodeId(node) {\n var id = node._observeId;\n\n if (!id) {\n id = node._observeId = counter++;\n }\n\n return id;\n }\n\n /**\n * Invokes callback passing node to it.\n *\n * @param {HTMLElement} node\n * @param {Object} data\n */\n function trigger(node, data) {\n var id = getNodeId(node),\n ids = data.invoked;\n\n if (_.contains(ids, id)) {\n return;\n }\n\n data.callback(node);\n data.invoked.push(id);\n }\n\n /**\n * Adds node to the observer list.\n *\n * @param {HTMLElement} node\n * @returns {Object}\n */\n function createNodeData(node) {\n var nodes = watchers.nodes,\n id = getNodeId(node);\n\n nodes[id] = nodes[id] || {};\n\n return nodes[id];\n }\n\n /**\n * Returns data associated with a specified node.\n *\n * @param {HTMLElement} node\n * @returns {Object|Undefined}\n */\n function getNodeData(node) {\n var nodeId = node._observeId;\n\n return watchers.nodes[nodeId];\n }\n\n /**\n * Removes data associated with a specified node.\n *\n * @param {HTMLElement} node\n */\n function removeNodeData(node) {\n var nodeId = node._observeId;\n\n delete watchers.nodes[nodeId];\n }\n\n /**\n * Adds removal listener for a specified node.\n *\n * @param {HTMLElement} node\n * @param {Object} data\n */\n function addRemovalListener(node, data) {\n var nodeData = createNodeData(node);\n\n (nodeData.remove = nodeData.remove || []).push(data);\n }\n\n /**\n * Adds listener for the nodes which matches specified selector.\n *\n * @param {String} selector - CSS selector.\n * @param {Object} data\n */\n function addSelectorListener(selector, data) {\n var storage = watchers.selectors;\n\n (storage[selector] = storage[selector] || []).push(data);\n }
2\n\n /**\n * Calls handlers assocoiated with an added node.\n * Adds listeners for the node removal.\n *\n * @param {HTMLElement} node - Added node.\n */\n function processAdded(node) {\n _.each(watchers.selectors, function (listeners, selector) {\n listeners.forEach(function (data) {\n if (!data.ctx.contains(node) || !$(node, data.ctx).is(selector)) {\n return;\n }\n\n if (data.type === 'add') {\n trigger(node, data);\n } else if (data.type === 'remove') {\n addRemovalListener(node, data);\n }\n });\n });\n }\n\n /**\n * Calls handlers assocoiated with a removed node.\n *\n * @param {HTMLElement} node - Removed node.\n */\n function processRemoved(node) {\n var nodeData = getNodeData(node),\n listeners = nodeData && nodeData.remove;\n\n if (!listeners) {\n return;\n }
2\n\n listeners.forEach(function (data) {\n trigger(node, data);\n });\n\n removeNodeData(node);\n }\n\n /**\n * Removes all non-element nodes from provided array\n * and appends to it descendant elements.\n *\n * @param {Array} nodes\n * @returns {Array}\n */\n function formNodesList(nodes) {\n var result = [],\n children;\n\n nodes = _.toArray(nodes).filter(isElementNode);\n\n nodes.forEach(function (node) {\n result.push(node);\n\n children = extractChildren(node);\n result = result.concat(children);\n });\n\n return result;\n }\n\n /**\n * Collects all removed and added nodes from\n * mutation records into separate arrays\n * while removing duplicates between both types of changes.\n *\n * @param {Array} mutations - An array of mutation records.\n * @returns {Object} Object with 'removed' and 'added' nodes arrays.\n */\n function formChangesLists(mutations) {\n var removed = [],\n added = [];\n\n mutations.forEach(function (record) {\n removed = removed.concat(_.toArray(record.removedNodes));\n added = added.concat(_.toArray(record.addedNodes));\n });\n\n removed = removed.filter(function (node) {\n var addIndex = added.indexOf(node),\n wasAdded = !!~addIndex;\n\n if (wasAdded) {\n added.splice(addIndex, 1);\n }\n\n return !wasAdded;\n });\n\n return {\n removed: formNodesList(removed),\n added: formNodesList(added)\n };\n }\n\n globalObserver = new MutationObserver(function (mutations) {\n var changes = formChangesLists(mutations);\n\n changes.removed.forEach(processRemoved);\n changes.added.forEach(processAdded);\n });\n\n globalObserver.observe(document.body, {\n subtree: true,\n childList: true\n });\n\n return {\n\n /**\n * Adds listener for the appearance of nodes that matches provided\n * selector and which are inside of the provided context. Callback will be\n * also invoked on elements which a currently present.\n *\n * @param {String} selector - CSS selector.\n * @param {Function} callback - Function that will invoked when node appears.\n * @param {HTMLElement} [ctx=document.body] - Context inside of which to search for the node.\n */\n get: function (selector, callback, ctx) {\n var data,\n nodes;\n\n data = {\n ctx: ctx || document.body,\n type: 'add',\n callback: callback,\n invoked: []\n };\n\n nodes = $(selector, data.ctx).toArray();\n\n nodes.forEach(function (node) {\n trigger(node, data);\n });\n\n addSelectorListener(selector, data);\n },\n\n /**\n * Adds listener for the nodes removal.\n *\n * @param {(jQueryObject|HTMLElement|Array|String)} selector\n * @param {Function} callback - Function that will invoked when node is removed.\n * @param {HTMLElement} [ctx=document.body] - Context inside of which to search for the node.\n */\n remove: function (selector, callback, ctx) {\n var nodes = [],\n data;\n\n data = {\n ctx: ctx || document.body,\n type: 'remove',\n callback: callback,\n invoked: []\n };\n\n if (typeof selector === 'object') {\n nodes = !_.isUndefined(selector.length) ?\n _.toArray(selector) :\n [selector];\n } else if (_.isString(selector)) {\n nodes = $(selector, ctx).toArray();\n\n addSelectorListener(selector, data);\n }
2\n\n nodes.forEach(function (node) {\n addRemovalListener(node, data);\n });\n },\n\n /**\n * Removes listeners.\n *\n * @param {String} selector\n * @param {Function} [fn]\n */\n off: function (selector, fn) {\n var selectors = watchers.selectors,\n listeners = selectors[selector];\n\n if (selector && !fn) {\n delete selectors[selector];\n } else if (listeners && fn) {\n selectors[selector] = listeners.filter(function (data) {\n return data.callback !== fn;\n });\n }\n }\n };\n});\n","Magento_Ui/js/lib/view/utils/raf.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global WeakMap */\ndefine([\n 'es6-collections'\n], function () {\n 'use strict';\n\n var processMap = new WeakMap(),\n origRaf,\n raf;\n\n origRaf = window.requestAnimationFrame ||\n window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.onRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function (callback) {\n window.setTimeout(callback, 1000 / 60);\n };\n\n /**\n * Creates new process object or extracts the\n * the existing one.\n *\n * @param {*} id - Process identifier.\n * @param {Number} fps - Required FPS count.\n * @returns {Object}\n */\n function getProcess(id, fps) {\n var process = processMap.get(id);\n\n if (!process) {\n process = {};\n processMap.set(id, process);\n }\n\n if (process.fps !== fps) {\n process.fps = fps;\n process.interval = 1000 / fps;\n process.update = Date.now();\n }\n\n return process;\n }\n\n /**\n * Proxy method which delegates call to the 'requestAnimationFrame'\n * function and optionally can keep track of the FPS with which\n * provided function is called.\n *\n * @param {Function} callback - Callback function to be passed to 'requestAnimationFrame'.\n * @param {Number} [fps] - If specified, will update FPS counter for the provided function.\n * @returns {Number|Boolean} ID of request or a flag which indicates\n * whether callback fits specified FPS.\n */\n raf = function (callback, fps) {\n var rafId = origRaf(callback);\n\n return fps ? raf.tick(callback, fps) : rafId;\n };\n\n /**\n * Updates FPS counter for the specified process\n * and returns a flag which indicates whether\n * counter value is equal or greater than the required FPS.\n *\n * @param {*} id - Process identifier.\n * @param {Number} fps - Required FPS count.\n * @returns {Boolean}\n */\n raf.tick = function (id, fps) {\n var process = getProcess(id, fps),\n now = Date.now(),\n delta = now - process.update,\n interval = process.interval;\n\n if (fps >= 60 || delta >= interval) {\n process.update = now - delta % interval;\n\n return true;\n }\n\n return false;\n };\n\n return raf;\n});\n","Magento_Ui/js/lib/view/utils/async.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'ko',\n 'jquery',\n 'underscore',\n 'uiRegistry',\n './dom-observer',\n 'Magento_Ui/js/lib/knockout/extender/bound-nodes',\n './bindings'\n], function (ko, $, _, registry, domObserver, boundedNodes) {\n 'use strict';\n\n /**\n * Checks if provided value is a dom element.\n *\n * @param {*} node - Value to be checked.\n * @returns {Boolean}\n */\n function isDomElement(node) {\n return typeof node === 'object' && node.tagName && node.nodeType;\n }\n\n /**\n * Parses provided string and extracts\n * component, context and selector data from it.\n *\n * @param {String} str - String to be processed.\n * @returns {Object} Data retrieved from string.\n *\n * @example Sample format.\n * '{{component}}:{{ctx}} -> {{selector}}'\n *\n * component - Name of component.\n * ctx - Selector of the root node upon which component is binded.\n * selector - Selector of DOM elements located\n * inside of a previously specified context.\n */\n function parseSelector(str) {\n var data = str.trim().split('->'),\n result = {},\n componentData;\n\n if (data.length === 1) {\n if (!~data[0].indexOf(':')) {\n result.selector = data[0];\n } else {\n componentData = data[0];\n }\n } else {\n componentData = data[0];\n result.selector = data[1];\n }\n\n if (componentData) {\n componentData = componentData.split(':');\n\n result.component = componentData[0];\n result.ctx = componentData[1];\n }\n\n _.each(result, function (value, key) {\n result[key] = value.trim();\n });\n\n return result;\n }\n\n /**\n * Internal method used to normalize argumnets passed\n * to 'async' module methods.\n *\n * @param {(String|Objetc)}
2 selector\n * @param {(HTMLElement|Object|String)} [ctx]\n * @returns {Object}\n */\n function parseData(selector, ctx) {\n var data = {};\n\n if (arguments.length === 2) {\n data.selector = selector;\n\n if (isDomElement(ctx)) {\n data.ctx = ctx;\n } else {\n data.component = ctx;\n data.ctx = '*';\n }\n } else {\n data = _.isString(selector) ?\n parseSelector(selector) :\n selector;\n }\n\n return data;\n }\n\n /**\n * Creates promise that will be resolved\n * when requested component is registred.\n *\n * @param {String} name - Name of component.\n * @returns {jQueryPromise}\n */\n function waitComponent(name) {\n var deffer = $.Deferred();\n\n if (_.isString(name)) {\n registry.get(name, function (component) {\n deffer.resolve(component);\n });\n } else {\n deffer.resolve(name);\n }\n\n return deffer.promise();\n }\n\n /**\n * Creates listener for the nodes binded to provided component.\n *\n * @param {Object} data - Listener data.\n * @param {Object} component - Associated with nodes component.\n */\n function setRootListener(data, component) {\n boundedNodes.get(component, function (root) {\n if (!$(root).is(data.ctx || '*')) {\n return;\n }\n\n data.selector ?\n domObserver.get(data.selector, data.fn, root) :\n data.fn(root);\n });\n }\n\n /*eslint-disable no-unused-vars*/\n /**\n * Sets listener for the appearance of elements which\n * matches specified selector data.\n *\n * @param {(String|Object)} selector - Valid css selector or a string\n * in format acceptable by 'parseSelector' method or an object with\n * 'component', 'selector' and 'ctx' properties.\n * @param {(HTMLElement|Object|String)} [ctx] - Optional context parameter\n * which might be a DOM element, component instance or components' name.\n * @param {Function} fn - Callback that will be invoked\n * when required DOM element appears.\n *\n * @example\n * Creating listener of the 'span' nodes appearance,\n * located inside of 'div' nodes, which are binded to 'cms_page_listing' component:\n *\n * $.async('cms_page_listing:div -> span', function (node) {});\n *\n * @example Another syntaxes of the previous example.\n * $.async({\n * component: 'cms_page_listing',\n * ctx: 'div',\n * selector: 'span'\n * }, function (node) {});\n *\n * @example Listens for appearance of any child node inside of specified component.\n * $.async('> *', 'cms_page_lsiting', function (node) {});\n *\n * @example Listens for appearance of 'span' nodes inside of specific context.\n * $.async('span', document.getElementById('test'), function (node) {});\n */\n $.async = function (selector, ctx, fn) {\n var args = _.toArray(arguments),\n data = parseData.apply(null, _.initial(args));\n\n data.fn = _.last(args);\n\n if (data.component) {\n waitComponent(data.component)\n .then(setRootListener.bind(null, data));\n } else {\n domObserver.get(data.selector, data.fn, data.ctx);\n }\n };\n\n /*eslint-enable no-unused-vars*/\n\n _.extend($.async, {\n\n /*eslint-disable no-unused-vars*/\n /**\n * Returns collection of elements found by provided selector data.\n *\n * @param {(String|Object)} selector - See 'async' definition.\n * @param {(HTMLElement|Object|String)} [ctx] - See 'async' definition.\n * @returns {Array} An array of DOM elements.\n */\n get: function (selector, ctx) {\n var data = parseData.apply(null, arguments),\n component = data.component,\n nodes;\n\n if (!component) {\n return $(data.selector, data.ctx).toArray();\n }
2 else if (_.isString(component)) {\n component = registry.get(component);\n }\n\n if (!component) {\n return [];\n }\n\n nodes = boundedNodes.get(component);\n nodes = $(nodes).filter(data.ctx).toArray();\n\n return data.selector ?\n $(data.selector, nodes).toArray() :\n nodes;\n },\n\n /*eslint-enable no-unused-vars*/\n\n /**\n * Sets removal listener of the specified nodes.\n *\n * @param {(HTMLElement|Array|ArrayLike)} nodes - Nodes whose removal to track.\n * @param {Function} fn - Callback that will be invoked when node is removed.\n */\n remove: function (nodes, fn) {\n domObserver.remove(nodes, fn);\n },\n\n parseSelector: parseSelector\n });\n\n return $;\n});\n","Magento_Ui/js/lib/registry/registry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n/* global WeakMap */\ndefine([\n 'jquery',\n 'underscore',\n 'es6-collections'\n], function ($, _) {\n 'use strict';\n\n var privateData = new WeakMap();\n\n /**\n * Extarcts private items storage associated\n * with a provided registry instance.\n *\n * @param {Object} container\n * @returns {Object}\n */\n function getItems(container) {\n return privateData.get(container).items;\n }\n\n /**\n * Extracts private requests array associated\n * with a provided registry instance.\n *\n * @param {Object} container\n * @returns {Array}\n */\n function getRequests(container) {\n return privateData.get(container).requests;\n }\n\n /**\n * Wrapper function used for convinient access to the elements.\n * See 'async' method for examples of usage and comparison\n * with a regular 'get' method.\n *\n * @param {(String|Object|Function)} name - Key of the requested element.\n * @param {Registry} registry - Instance of a registry\n * where to search for the element.\n * @param {(Function|String)} [method] - Optional callback function\n * or a name of the elements' method which\n * will be invoked when element is available in registry.\n * @returns {*}\n */\n function async(name, registry, method) {\n var args = _.toArray(arguments).slice(3);\n\n if (_.isString(method)) {\n registry.get(name, function (component) {\n component[method].apply(component, args);\n });\n } else if (_.isFunction(method)) {\n registry.get(name, method);\n } else if (!args.length) {\n return registry.get(name);\n }\n }\n\n /**\n * Checks that every property of the query object\n * is present and equal to the corresponding\n * property in target object.\n * Note that non-strict comparison is used.\n *\n * @param {Object} query - Query object.\n * @param {Object} target - Target object.\n * @returns {Boolean}\n */\n function compare(query, target) {\n var matches = true,\n index,\n keys,\n key;\n\n if (!_.isObject(query) || !_.isObject(target)) {\n return false;\n }\n\n keys = Object.getOwnPropertyNames(query);\n index = keys.length;\n\n while (matches && index--) {\n key = keys[index];\n\n /* eslint-disable eqeqeq */\n if (target[key] != query[key]) {\n matches = false;\n }\n\n /* eslint-enable eqeqeq */\n }\n\n return matches;\n }\n\n /**\n * Explodes incoming string into object if\n * string is defined as a set of key = value pairs.\n *\n * @param {(String|*)} query - String to be processed.\n * @returns {Object|*} Either created object or an unmodified incoming\n * value if conversion was not possible.\n * @example Sample conversions.\n * 'key = value, key2 = value2'\n * => {key: 'value', key2: 'value2'}\n */\n function explode(query) {\n var result = {},\n index,\n data;\n\n if (typeof query !== 'string' || !~query.indexOf('=')) {\n return query;\n }\n\n query = query.split(',');\n index = query.length;\n\n while (index--) {\n data = query[index].split('=');\n\n result[data[0].trim()] = data[1].trim();\n }\n\n return result;\n }\n\n /**\n * Extracts items from the provided data object\n * which matches specified search criteria.\n *\n * @param {Object} data - Data object where to perform a lookup.\n * @param {(String|Object|Function)} query - Seach criteria.\n * @param {Boolean} findAll - Flag that defines whether to\n * search for all applicable items or to stop on a first found entry.\n * @returns {Array|Object|*}\n */\n function find(data, query, findAll) {\n var iterator,\n item;\n\n query = explode(query);\n\n if (typeof query === 'string') {\n item = data[query];\n\n if (findAll) {\n return item ? [item] : [];\n }\n\n return item;\n }\n\n iterator = !_.isFunction(query) ?\n compare.bind(null, query) :\n query;\n\n return findAll ?\n _.filter(data, iterator) :\n _.find(data, iterator);\n }\n\n /**\n * @constructor\n */\n function Registry() {\n var data = {\n items: {},\n requests: []\n };\n\n this._updateRequests = _.debounce(this._updateRequests.bind(this), 10);\n privateData.set(this, data);\n }
2\n\n Registry.prototype = {\n constructor: Registry,\n\n /**\n * Retrieves item from registry which matches specified search criteria.\n *\n * @param {(Object|String|Function|Array)} query - Search condition (see examples).\n * @param {Function} [callback] - Callback that will be invoked when\n * all of the requested items are available.\n * @returns {*}\n *\n * @example Requesting item by it's name.\n * var obj = {index: 'test', sample: true};\n *\n * registry.set('first', obj);\n * registry.get('first') === obj;\n * => true\n *\n * @example Requesting item with a specific properties.\n * registry.get('sample = 1, index = test') === obj;\n * => true\n * registry.get('sample = 0, index = foo') === obj;\n * => false\n *\n * @example Declaring search criteria as an object.\n * registry.get({sample: true}) === obj;\n * => true;\n *\n * @example Providing custom search handler.\n * registry.get(function (item) { return item.sample === true; }) === obj;\n * => true\n *\n * @example Sample asynchronous request declaration.\n * registry.get('index = test', function (item) {});\n *\n * @example Requesting multiple elements.\n * registry.set('second', {index: 'test2'});\n * registry.get(['first', 'second'], function (first, second) {});\n */\n get: function (query, callback) {\n if (typeof callback !== 'function') {\n return find(getItems(this), query);\n }\n\n this._addRequest(query, callback);\n },\n\n /**\n * Sets provided item to the registry.\n *\n * @param {String} id - Item's identifier.\n * @param {*} item - Item's data.\n * returns {Registry} Chainable.\n */\n set: function (id, item) {\n getItems(this)[id] = item;\n\n this._updateRequests();\n\n return this;\n },\n\n /**\n * Removes specified item from registry.\n * Note that search query is not applicable.\n *\n * @param {String} id - Item's identifier.\n * @returns {Registry} Chainable.\n */\n remove: function (id) {\n delete getItems(this)[id];\n\n return this;\n },\n\n /**\n * Retrieves a collection of elements that match\n * provided search criteria.\n *\n * @param {(Object|String|Function)} query - Search query.\n * See 'get' method for the syntax examples.\n * @returns {Array} Found elements.\n */\n filter: function (query) {\n return find(getItems(this), query, true);\n },\n\n /**\n * Checks that at least one element in collection\n * matches provided search criteria.\n *\n * @param {(Object|String|Function)} query - Search query.\n * See 'get' method for the syntax examples.\n * @returns {Boolean}\n */\n has: function (query) {\n return !!this.get(query);\n },\n\n /**\n * Checks that registry contains a provided item.\n *\n * @param {*} item - Item to be checked.\n * @returns {Boolean}\n */\n contains: function (item) {\n return _.contains(getItems(this), item);\n },\n\n /**\n * Extracts identifier of an item if it's present in registry.\n *\n * @param {*} item - Item whose identifier will be extracted.\n * @returns {String|Undefined}\n */\n indexOf: function (item) {\n return _.findKey(getItems(this), function (elem) {\n return item === elem;\n });\n },\n\n /**\n * Same as a 'get' method except that it returns\n * a promise object instead of invoking provided callback.\n *\n * @param {(String|Function|Object|Array)} query - Search query.\n * See 'get' method for the syntax examples.\n * @returns {jQueryPromise}\n */\n promise: function (query) {\n var defer = $.Deferred(),\n callback = defer.resolve.bind(defer);\n\n this.get(query, callback);\n\n return defer.promise();\n },\n\n /**\n * Creates a wrapper function over the provided search query\n * in order to provide somehow more convinient access to the\n * registrie's items.\n *\n * @param {(String|Object|Function)} query - Search criteria.\n * See 'get' method for the syntax examples.\n * @returns {Function}\n *\n * @example Comparison with a 'get' method on retrieving items.\n * var module = registry.async('name');\n *\n * module();\n * => registry.get('name');\n *\n * @example Asynchronous request.\n * module(function (component) {});\n * => registry.get('name', function (component) {});\n *\n * @example Requesting item and invoking it's method with specified parameters.\n * module('trigger', true);\n * => registry.get('name', function (component) {\n * component.trigger(true);\n * });\n */\n async: function (query) {\n return async.bind(null, query, this);\n },\n\n /**\n * Creates new instance of a Registry.\n *\n * @returns {Registry} New instance.\n */\n create: function () {\n return new Registry;\n },\n\n /**\n * Adds new request to the queue or resolves it immediately\n * if all of the required items are available.\n *\n * @private\n * @param {(Object|String|Function|Array)} queries - Search criteria.\n * See 'get' method for the syntax examples.\n * @param {Function} callback - Callback that will be invoked when\n * all of the requested items are available.\n * @returns {Registry}\n */\n _addRequest: function (queries, callback) {\n var request;\n\n if (!Array.isArray(queries)) {\n queries = queries ? [queries] : [];\n }\n\n request = {\n queries: queries.map(explode),\n callback: callback\n };\n\n this._canResolve(request) ?\n this._resolveRequest(request) :\n getRequests(this).push(request);\n\n return this;\n },\n\n /**\n * Updates requests list resolving applicable items.\n *\n * @private\n * @returns {Registry} Chainable.\n */\n _updateRequests: function () {\n getRequests(this)\n .filter(this._canResolve, this)\n .forEach(this._resolveRequest, this);\n\n return this;\n },\n\n /**\n * Resolves provided request invoking it's callback\n * with items specified in query parameters.\n *\n * @private\n * @param {Object} request - Request object.\n * @returns {Registry} Chainable.\n */\n _resolveRequest: function (request) {\n var requests = getRequests(this),\n items = request.queries.map(this.get, this),\n index = requests.indexOf(request);\n\n request.callback.apply(null, items);\n\n if (~index) {\n requests.splice(index, 1);\n }\n\n return this;\n },\n\n /**\n * Checks if provided request can be resolved.\n *\n * @private\n * @param {Object} request - Request object.\n * @returns {Boolean}\n */\n _canResolve: function (request) {\n var queries = request.queries;\n\n return queries.every(this.has, this);\n }\n };\n\n return new Registry;\n});\n","Magento_Ui/js/lib/logger/message-pool.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 var MESSAGES = {\n templateStartLoading:\n 'The \"${ $.template }\" template requested by the \"${$.component}\" component started loading.',\n templateLoadedFromServer:\n 'The \"${ $.template }\" template requested by the \"${$.component}\" component was loaded from server.\"',\n templateLoadedFromCac
2he:\n 'The \"${ $.template }\" template requested by the \"${$.component}\" component was loaded from cache.\"',\n templateLoadingFail: 'Failed to load the \"${ $.template }\" template requested by \"${$.component}\".',\n componentStartInitialization:\n 'Component \"${$.component}\" start initialization with instance name \"${$.componentName}\".',\n componentStartLoading: ' Started loading the \"${$.component}\" component.',\n componentFinishLoading: 'The \"${$.component}\" component was loaded.',\n componentLoadingFail: 'Failed to load the \"${$.component}\" component.',\n depsLoadingFail: 'Could not get the declared \"${$.deps}\" dependency for the \"${$.component}\" instance.',\n depsStartRequesting: 'Requesting the \"${$.deps}\" dependency for the \"${$.component}\" instance.',\n depsFinishRequesting: 'The \"${$.deps}\" dependency for the \"${$.component}\" instance was received.',\n requestingComponent: 'Requesting the \"${$.component}\" component.',\n requestingComponentIsLoaded: 'The requested \"${$.component}\" component was received.',\n requestingComponentIsFailed: 'Could not get the requested \"${$.component}\" component.'\n };\n\n return {\n /**\n * Returns message that matches the provided code.\n *\n * @param {String} code - Message's identifier\n * @returns {String}\n */\n getMessage: function (code) {\n return MESSAGES[code];\n },\n\n /**\n * Adds a new message to the poll.\n *\n * @param {String} code - Message's identifier.\n * @param {String} message - Text of the message\n */\n addMessage: function (code, message) {\n MESSAGES[code] = message;\n },\n\n /**\n * Tells whether message with provide code exists in the poll.\n *\n * @param {String} code - Message's identifier.\n * @returns {Boolean}\n */\n hasMessage: function (code) {\n return MESSAGES.hasOwnProperty(code);\n }\n };\n});\n","Magento_Ui/js/lib/logger/levels-pool.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 var LEVELS,\n CODE_MAP;\n\n LEVELS = {\n NONE: 0,\n ERROR: 1,\n WARN: 2,\n INFO: 3,\n DEBUG: 4,\n ALL: 5\n };\n\n CODE_MAP = _.invert(LEVELS);\n\n return {\n /**\n * Returns the list of available log levels.\n *\n * @returns {Object}\n */\n getLevels: function () {\n return LEVELS;\n },\n\n /**\n * Returns name of the log level that matches to the provided code.\n *\n * @returns {String}\n */\n getNameByCode: function (code) {\n return CODE_MAP[code];\n }\n };\n});\n","Magento_Ui/js/lib/logger/logger.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n './levels-pool'\n], function (logLevels) {\n 'use strict';\n\n var levels = logLevels.getLevels();\n\n /**\n * @param {LogOutputHandler} outputHandler\n * @param {LogEntryFactory} entryFactory\n */\n function Logger(outputHandler, entryFactory) {\n /**\n * An array of log entries.\n *\n * @protected\n * @type {Array<LogEntry>}\n */\n this.entries_ = [];\n\n /**\n * Current display level.\n *\n * @protected\n * @type {Number}\n */\n this.displayLevel_ = levels.ERROR;\n\n /**\n * An array of display criteria.\n *\n * @protected\n * @type {Array<LogCriteria>}\n */\n this.displayCriteria_ = [];\n\n /**\n * @protected\n * @type {LogEntryFactory}\n */\n this.entryFactory_ = entryFactory;\n\n /**\n * @protected\n * @type {Array<LogOutputHandler>}\n */\n this.outputHandlers_ = [outputHandler];\n\n this.addDisplayCriteria(this.matchesLevel_);\n }\n\n /**\n * Swaps current display level with the provided one.\n *\n * @param {Number} level - Level's code.\n */\n Logger.prototype.setDisplayLevel = function (level) {\n var levelName = logLevels.getNameByCode(level);\n\n if (!levelName) {\n throw new TypeError('The provided level is not defined in the levels list.');\n }\n\n this.displayLevel_ = level;\n };\n\n /**\n * Sets up the criteria by which log entries will be filtered out from the output.\n *\n * @param {LogCriteria} criteria\n */\n Logger.prototype.addDisplayCriteria = function (criteria) {\n this.displayCriteria_.push(criteria);\n };\n\n /**\n * Removes previously defined criteria.\n *\n * @param {LogCriteria} criteria\n */\n Logger.prototype.removeDisplayCriteria = function (criteria) {\n var index = this.displayCriteria_.indexOf(criteria);\n\n if (~index) {\n this.displayCriteria_.splice(index, 1);\n }\n };\n\n /**\n * @param {String} message\n * @param {Object} [messageData]\n * @returns {LogEntry}\n */\n Logger.prototype.error = function (message, messageData) {\n return this.log_(message, levels.ERROR, messageData);\n };\n\n /**\n * @param {String} message\n * @param {Object} [messageData]\n * @returns {LogEntry}\n */\n Logger.prototype.warn = function (message, messageData) {\n return this.log_(message, levels.WARN, messageData);\n };\n\n /**\n * @param {String} message\n * @param {Object} [messageData]\n * @returns {LogEntry}\n */\n Logger.prototype.info = function (message, messageData) {\n return this.log_(message, levels.INFO, messageData);\n };\n\n /**\n * @param {String} message\n * @param {Object} [messageData]\n * @returns {LogEntry}\n */\n Logger.prototype.debug = function (message, messageData) {\n return this.log_(message, levels.DEBUG, messageData);\n };\n\n /**\n * @protected\n * @param {String} message\n * @param {Number} level\n * @param {Object} [messageData]\n * @returns {LogEntry}\n */\n Logger.prototype.log_ = function (message, level, messageData) {\n var entry = this.createEntry_(message, level, messageData);\n\n this.entries_.push(entry);\n\n if (this.matchesCriteria_(entry)) {\n this.processOutput_(entry);\n }\n\n return entry;\n };\n\n /**\n * @protected\n * @param {String} message\n * @param {Number} level\n * @param {Object} [messageData]\n * @returns {LogEntry}\n */\n Logger.prototype.createEntry_ = function (message, level, messageData) {\n return this.entryFactory_.createEntry(message, level, messageData);\n };\n\n /**\n * Returns an array of log entries that have been added to the logger.\n *\n * @param {LogCriteria} [criteria] - Optional filter criteria.\n * @returns {Array<LogEntry>}\n */\n Logger.prototype.getEntries = function (criteria) {\n if (criteria) {\n return this.entries_.filter(criteria);\n }\n\n return this.entries_;\n };\n\n /**\n * @param {LogCriteria} [criteria]\n */\n Logger.prototype.dump = function (criteria) {\n var entries;\n\n if (!criteria) {\n criteria = this.matchesCriteria_;\n }
2\n\n entries = this.entries_.filter(criteria, this);\n\n this.outputHandlers_.forEach(function (handler) {\n handler.dump(entries);\n });\n };\n\n /**\n * @protected\n * @param {LogEntry} entry\n */\n Logger.prototype.processOutput_ = function (entry) {\n this.outputHandlers_.forEach(function (handler) {\n handler.show(entry);\n });\n };\n\n /**\n * @protected\n * @param {LogEntry} entry\n * @returns {Boolean}\n */\n Logger.prototype.matchesCriteria_ = function (entry) {\n return this.displayCriteria_.every(function (criteria) {\n return criteria.call(this, entry);\n }, this);\n };\n\n /**\n * Checks that the level of provided entry passes the \"displayLevel_\" threshold.\n *\n * @protected\n * @param {LogEntry} entry - Entry to be checked.\n * @returns {Boolean}\n */\n Logger.prototype.matchesLevel_ = function (entry) {\n return entry.level <= this.displayLevel_;\n };\n\n return Logger;\n});\n","Magento_Ui/js/lib/logger/console-output-handler.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n './levels-pool'\n], function (logLevels) {\n 'use strict';\n\n var levels = logLevels.getLevels();\n\n /**\n * @param {LogFormatter} formatter\n */\n function ConsoleOutputHandler(formatter) {\n /**\n * @protected\n * @type {LogFormatter}\n */\n this.formatter_ = formatter;\n }\n\n /**\n * Display data of the provided entry to the console.\n *\n * @param {LogEntry} entry - Entry to be displayed.\n */\n ConsoleOutputHandler.prototype.show = function (entry) {\n var displayString = this.formatter_.process(entry);\n\n switch (entry.level) {\n case levels.ERROR:\n console.error(displayString);\n break;\n\n case levels.WARN:\n console.warn(displayString);\n break;\n\n case levels.INFO:\n console.info(displayString);\n break;\n\n case levels.DEBUG:\n console.log(displayString);\n break;\n }\n };\n\n /**\n * Displays the array of entries.\n *\n * @param {Array<LogEntry>} entries\n */\n ConsoleOutputHandler.prototype.dump = function (entries) {\n entries.forEach(this.show, this);\n };\n\n return ConsoleOutputHandler;\n});\n","Magento_Ui/js/lib/logger/console-logger.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n './logger',\n './entry-factory',\n './console-output-handler',\n './formatter',\n './message-pool',\n './levels-pool',\n 'Magento_Ui/js/lib/core/storage/local',\n 'underscore',\n './logger-utils'\n], function (Logger, entryFactory, ConsoleHandler, Formatter, messagePoll, levelsPoll, storage, _, LoggerUtils) {\n 'use strict';\n\n var STORAGE_NAMESPACE = 'CONSOLE_LOGGER';\n\n /**\n * Singleton Logger's sub-class instance of which is configured to display its\n * messages to the console. It also provides the support of predefined messages\n * and persists its display level.\n */\n function ConsoleLogger() {\n var formatter = new Formatter(),\n consoleHandler = new ConsoleHandler(formatter),\n savedLevel = storage.get(STORAGE_NAMESPACE),\n utils = new LoggerUtils(this);\n\n Logger.call(this, consoleHandler, entryFactory);\n\n if (savedLevel) {\n this.displayLevel_ = savedLevel;\n }\n\n this.utils = utils;\n this.messages = messagePoll;\n this.levels = levelsPoll.getLevels();\n }\n\n _.extend(ConsoleLogger, Logger);\n\n ConsoleLogger.prototype = Object.create(Logger.prototype);\n ConsoleLogger.prototype.constructor = ConsoleLogger;\n\n /**\n * Overrides parent method to save the provided display level.\n *\n * @override\n */\n ConsoleLogger.prototype.setDisplayLevel = function (level) {\n Logger.prototype.setDisplayLevel.call(this, level);\n\n storage.set(STORAGE_NAMESPACE, level);\n };\n\n /**\n * Adds the support of predefined messages.\n *\n * @protected\n * @override\n */\n ConsoleLogger.prototype.createEntry_ = function (message, level, data) {\n var code;\n\n if (messagePoll.hasMessage(message)) {\n data = data || {};\n code = message;\n message = messagePoll.getMessage(code);\n\n data.messageCode = code;\n }\n\n return Logger.prototype.createEntry_.call(this, message, level, data);\n };\n\n return new ConsoleLogger();\n});\n","Magento_Ui/js/lib/logger/entry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n './levels-pool'\n], function (logLevels) {\n 'use strict';\n\n /**\n * @param {String} message\n * @param {Number} level\n * @param {Object} [data]\n */\n function LogEntry(message, level, data) {\n /**\n * @readonly\n * @type {Number}\n */\n this.timestamp = Date.now();\n\n /**\n * @readonly\n * @type {Number}\n */\n this.level = level;\n\n /**\n * @readonly\n * @type {String}\n */\n this.levelName = logLevels.getNameByCode(level);\n\n /**\n * @readonly\n * @type {Object}\n */\n this.data = data;\n\n /**\n * @readonly\n * @type {String}\n */\n this.message = message;\n }\n\n return LogEntry;\n});\n","Magento_Ui/js/lib/logger/formatter.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'moment',\n 'mage/utils/template'\n], function (moment, mageTemplate) {\n 'use strict';\n\n /**\n * @param {String} dateFormat\n * @param {String} template\n */\n function LogFormatter(dateFormat, template) {\n /**\n * @protected\n * @type {String}\n */\n this.dateFormat_ = 'YYYY-MM-DD hh:mm:ss';\n\n /**\n * @protected\n * @type {String}\n */\n this.template_ = '[${ $.date }] [${ $.entry.levelName }] ${ $.message }';\n\n if (dateFormat) {\n this.dateFormat_ = dateFormat;\n }\n\n if (template) {\n this.template_ = template;\n }\n }\n\n /**\n * @param {LogEntry} entry\n * @returns {String}\n */\n LogFormatter.prototype.process = function (entry) {\n var message = mageTemplate.template(entry.message, entry.data),\n date = moment(entry.timestamp).format(this.dateFormat_);\n\n return mageTemplate.template(this.template_, {\n date: date,\n entry: entry,\n message: message\n });\n };\n\n return LogFormatter;\n});\n","Magento_Ui/js/lib/logger/entry-factory.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n './entry'\n], function (LogEntry) {\n 'use strict';\n\n return {\n /**\n * @param {String} message\n * @param {Number} level\n * @param {Object} [messageData]\n * @returns {LogEntry}\n */\n createEntry: function (message, level, messageData) {\n return new LogEntry(message, level, messageData);\n }\n };\n});\n","Magento_Ui/js/lib/logger/logger-utils.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 /**\n * Utils methods for logger\n * @param {Logger} logger\n */\n function LogUtils(logger) {\n this.logger = logger;\n\n }\n\n /**\n * Method for logging asynchronous operations\n * @param {Promise} promise\n * @param {Object} config\n */\n LogUtils.prototype.asyncLog = function (promise,
2config) {\n var levels,\n messages,\n wait;\n\n config = config || {};\n levels = config.levels || this.createLevels();\n messages = config.messages || this.createMessages();\n wait = config.wait || 5000;\n\n this.logger[levels.requested](messages.requested, config.data);\n setTimeout(function () {\n promise.state() === 'pending' ?\n this.logger[levels.failed](messages.failed, config.data) :\n this.logger[levels.loaded](messages.loaded, config.data);\n }.bind(this), wait);\n };\n\n /**\n * Method that creates object of messages\n * @param {String} requested - log message that showing that request for class is started\n * @param {String} loaded - log message that show when requested class is loaded\n * @param {String} failded - log message that show when requested class is failed\n * @returns {Object}\n */\n LogUtils.prototype.createMessages = function (requested, loaded, failded) {\n return {\n requested: requested || '',\n loaded: loaded || '',\n failed: failded || ''\n };\n };\n\n /**\n * Method that creates object of log levels\n * @param {String} requested - log message that showing that request for class is started\n * @param {String} loaded - log message that show when requested class is loaded\n * @param {String} failded - log message that show when requested class is failed\n * @returns {Object}\n */\n LogUtils.prototype.createLevels = function (requested, loaded, failded) {\n return {\n requested: requested || 'info',\n loaded: loaded || 'info',\n failed: failded || 'warn'\n };\n };\n\n return LogUtils;\n});\n","Magento_Ui/js/lib/knockout/bootstrap.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/** Loads all available knockout bindings, sets custom template engine, initializes knockout on page */\n\ndefine([\n 'ko',\n './template/engine',\n 'knockoutjs/knockout-es5',\n './bindings/bootstrap',\n './extender/observable_array',\n './extender/bound-nodes',\n 'domReady!'\n], function (ko, templateEngine) {\n 'use strict';\n\n ko.uid = 0;\n\n ko.setTemplateEngine(templateEngine);\n ko.applyBindings();\n});\n","Magento_Ui/js/lib/knockout/bindings/optgroup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'mageUtils'\n ], function (ko, utils) {\n 'use strict';\n\n var captionPlaceholder = {},\n optgroupTmpl = '<optgroup label=\"${ $.label }\"></optgroup>',\n nbspRe = / /g,\n optionsText,\n optionsValue,\n optionTitle;\n\n ko.bindingHandlers.optgroup = {\n /**\n * @param {*} element\n * @returns {Object}\n */\n init: function (element) {\n if (ko.utils.tagNameLower(element) !== 'select') {\n throw new Error('options binding applies only to SELECT elements');\n }\n\n // Remove all existing <option>s.\n while (element.length > 0) {\n element.remove(0);\n }\n\n // Ensures that the binding processor doesn't try to bind the options\n return {\n 'controlsDescendantBindings': true\n };\n },\n\n /**\n * @param {*} element\n * @param {*} valueAccessor\n * @param {*} allBindings\n */\n update: function (element, valueAccessor, allBindings) {\n var selectWasPreviouslyEmpty = element.length === 0,\n previousScrollTop = !selectWasPreviouslyEmpty && element.multiple ? element.scrollTop : null,\n includeDestroyed = allBindings.get('optionsIncludeDestroyed'),\n arrayToDomNodeChildrenOptions = {},\n captionValue,\n unwrappedArray = ko.utils.unwrapObservable(valueAccessor()),\n filteredArray,\n previousSelectedValues,\n itemUpdate = false,\n callback = setSelectionCallback,//eslint-disable-line no-use-before-define\n nestedOptionsLevel = -1;\n\n optionsText = ko.utils.unwrapObservable(allBindings.get('optionsText')) || 'text';\n optionsValue = ko.utils.unwrapObservable(allBindings.get('optionsValue')) || 'value';\n optionTitle = optionsText + 'title';\n\n if (element.multiple) {\n previousSelectedValues = ko.utils.arrayMap(\n selectedOptions(),//eslint-disable-line no-use-before-define\n ko.selectExtensions.readValue\n );\n } else {\n previousSelectedValues = element.selectedIndex >= 0 ?\n [ko.selectExtensions.readValue(element.options[element.selectedIndex])] :\n [];\n }\n\n if (unwrappedArray) {\n if (typeof unwrappedArray.length === 'undefined') { // Coerce single value into array\n unwrappedArray = [unwrappedArray];\n }\n\n // Filter out any entries marked as destroyed\n filteredArray = ko.utils.arrayFilter(unwrappedArray, function (item) {\n if (item && !item.label) {\n return false;\n }\n\n return includeDestroyed ||\n item === undefined ||\n item === null ||\n !ko.utils.unwrapObservable(item._destroy);\n });\n filteredArray.map(recursivePathBuilder, null);//eslint-disable-line no-use-before-define\n }\n\n /**\n * @param {*} option\n */\n arrayToDomNodeChildrenOptions.beforeRemove = function (option) {\n element.removeChild(option);\n };\n\n if (allBindings.has('optionsAfterRender')) {\n\n /**\n * @param {*} arrayEntry\n * @param {*} newOptions\n */\n callback = function (arrayEntry, newOptions) {\n setSelectionCallback(arrayEntry, newOptions);//eslint-disable-line no-use-before-define\n ko.dependencyDetection.ignore(\n allBindings.get('optionsAfterRender'),\n null,\n [newOptions[0],\n arrayEntry !== captionPlaceholder ? arrayEntry : undefined]\n );\n };\n }\n\n filteredArray = formatOptions(filteredArray);//eslint-disable-line no-use-before-define\n ko.utils.setDomNodeChildrenFromArrayMapping(\n element,\n filteredArray,\n optionNodeFromArray,//eslint-disable-line no-use-before-define\n arrayToDomNodeChildrenOptions,\n callback\n );\n\n ko.dependencyDetection.ignore(function () {\n var selectionChanged;\n\n if (allBindings.get('valueAllowUnset') && allBindings.has('value')) {\n // The model value is authoritative, so make sure its value is the one selected\n ko.selectExtensions.writeValue(\n element,\n ko.utils.unwrapObservable(allBindings.get('value')),\n true /* allowUnset */\n );\n } else {\n // Determine if the selection has changed as a result of updating the options list\n if (element.multiple) {\n // For a multiple-select box, compare the new selection count to the previous one\n // But if nothing was selected before, the selection can't have changed\n selectionChanged = previousSelectedValues.length &&\n selectedOptions().length < //eslint-disable-line no-use-before-define\n previousSelectedValues.length;\n } else {\n // For a single-select box, compare the current value to the previous value\n // But if nothing was selected before or nothing is selected now,\n // just look for a change in selection\n selectionChanged = previousSelectedValues.length && element.selectedIndex >= 0 ?\n ko.selectExtensions.readValue(element.options[element.selectedIndex]) !==\n previousSelectedValues[0] : previousSelectedValues.length || element.selectedIndex >= 0;\n }\n\n // Ensure consistency between model value and selected option.\n // If the dropdown was changed so that selection is no longer the same,\n // notify the value or selectedOptions binding.\n if (selectionChanged) {\n ko.utils.triggerEvent(element, 'change');\n }\n }\n });
2\n\n /*eslint-enable max-len, no-use-before-define*/\n\n if (previousScrollTop && Math.abs(previousScrollTop - element.scrollTop) > 20) {\n element.scrollTop = previousScrollTop;\n }\n\n /**\n * @returns {*}\n */\n function selectedOptions() {\n return ko.utils.arrayFilter(element.options, function (node) {\n return node.selected;\n });\n }\n\n /**\n * @param {*} object\n * @param {*} predicate\n * @param {*} defaultValue\n * @returns {*}\n */\n function applyToObject(object, predicate, defaultValue) {\n var predicateType = typeof predicate;\n\n if (predicateType === 'function') { // run it against the data value\n return predicate(object);\n } else if (predicateType === 'string') { // treat it as a property name on the data value\n return object[predicate];\n }\n\n return defaultValue;\n }\n\n /**\n * @param {*} obj\n */\n function recursivePathBuilder(obj) {\n\n obj[optionTitle] = (this && this[optionTitle] ? this[optionTitle] + '/' : '') + obj[optionsText].trim();\n\n if (Array.isArray(obj[optionsValue])) {\n obj[optionsValue].map(recursivePathBuilder, obj);\n }\n }\n\n /**\n * @param {Array} arrayEntry\n * @param {*} oldOptions\n * @returns {*[]}\n */\n function optionNodeFromArray(arrayEntry, oldOptions) {\n var option;\n\n if (oldOptions.length) {\n previousSelectedValues = oldOptions[0].selected ?\n [ko.selectExtensions.readValue(oldOptions[0])] : [];\n itemUpdate = true;\n }\n\n if (arrayEntry === captionPlaceholder) { // empty value, label === caption\n option = element.ownerDocument.createElement('option');\n ko.utils.setTextContent(option, allBindings.get('optionsCaption'));\n ko.selectExtensions.writeValue(option, undefined);\n } else if (typeof arrayEntry[optionsValue] === 'undefined') { // empty value === optgroup\n option = utils.template(optgroupTmpl, {\n label: arrayEntry[optionsText],\n title: arrayEntry[optionsText + 'title']\n });\n option = ko.utils.parseHtmlFragment(option)[0];\n\n } else {\n option = element.ownerDocument.createElement('option');\n option.setAttribute('data-title', arrayEntry[optionsText + 'title']);\n ko.selectExtensions.writeValue(option, arrayEntry[optionsValue]);\n ko.utils.setTextContent(option, arrayEntry[optionsText]);\n }\n\n return [option];\n }\n\n /**\n * @param {*} newOptions\n */\n function setSelectionCallback(newOptions) {\n var isSelected;\n\n // IE6 doesn't like us to assign selection to OPTION nodes before they're added to the document.\n // That's why we first added them without selection. Now it's time to set the selection.\n if (previousSelectedValues.length) {\n isSelected = ko.utils.arrayIndexOf(\n previousSelectedValues,\n ko.selectExtensions.readValue(newOptions.value)\n ) >= 0;\n\n ko.utils.setOptionNodeSelectionState(newOptions.value, isSelected);\n\n // If this option was changed from being selected during a single-item update, notify the change\n if (itemUpdate && !isSelected) {\n ko.dependencyDetection.ignore(ko.utils.triggerEvent, null, [element, 'change']);\n }\n }\n }\n\n /**\n * @param {*} string\n * @param {Number} times\n * @returns {Array}\n */\n function strPad(string, times) {\n return (new Array(times + 1)).join(string);\n }\n\n /**\n * @param {*} options\n * @returns {Array}\n */\n function formatOptions(options) {\n var res = [];\n\n nestedOptionsLevel++;\n\n if (!nestedOptionsLevel) { // zero level\n // If caption is included, add it to the array\n if (allBindings.has('optionsCaption')) {\n captionValue = ko.utils.unwrapObservable(allBindings.get('optionsCaption'));\n // If caption value is null or undefined, don't show a caption\n if (//eslint-disable-line max-depth\n captionValue !== null &&\n captionValue !== undefined &&\n captionValue !== false\n ) {\n res.push(captionPlaceholder);\n }\n }\n }\n\n ko.utils.arrayForEach(options, function (option) {\n var value = applyToObject(option, optionsValue, option),\n label = applyToObject(option, optionsText, value) || '',\n disabled = applyToObject(option, 'disabled', false) || false,\n obj = {},\n space = '\\u2007\\u2007\\u2007';\n\n obj[optionTitle] = applyToObject(option, optionsText + 'title', value);\n\n if (disabled) {\n obj.disabled = disabled;\n }\n\n label = label.replace(nbspRe, '').trim();\n\n if (Array.isArray(value)) {\n obj[optionsText] = strPad(' ', nestedOptionsLevel * 4) + label;\n res.push(obj);\n res = res.concat(formatOptions(value));\n } else {\n obj[optionsText] = strPad(space, nestedOptionsLevel * 2) + label;\n obj[optionsValue] = value;\n res.push(obj);\n }\n });\n nestedOptionsLevel--;\n\n return res;\n }\n }\n };\n ko.bindingHandlers.selectedOptions.after.push('optgroup');\n});\n","Magento_Ui/js/lib/knockout/bindings/collapsible.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 '../template/renderer'\n], function (ko, $, _, renderer) {\n 'use strict';\n\n var collapsible,\n defaults;\n\n defaults = {\n closeOnOuter: true,\n onTarget: false,\n openClass: '_active',\n as: '$collapsible'\n };\n\n collapsible = {\n\n /**\n * Sets 'opened' property to true.\n */\n open: function () {\n this.opened(true);\n },\n\n /**\n * Sets 'opened' property to false.\n */\n close: function () {\n this.opened(false);\n },\n\n /**\n * Toggles value of the 'opened' property.\n */\n toggle: function () {\n this.opened(!this.opened());\n }\n };\n\n /**\n * Document click handler which in case if event target is not\n * a descendant of provided container element, closes collapsible model.\n *\n * @param {HTMLElement} container\n * @param {Object} model\n * @param {EventObject} e\n */\n function onOuterClick(container, model, e) {\n var target = e.target;\n\n if (target !== container && !container.contains(target)) {\n model.close();\n }\n }\n\n /**\n * Creates 'css' binding which toggles\n * class specified in 'name' parameter.\n *\n * @param {Object} model\n * @param {String} name\n * @returns {Object}\n */\n function getClassBinding(model, name) {\n var binding = {};\n\n binding[name] = model.opened;\n\n return {\n css: binding\n };\n }\n\n /**\n * Prepares configuration for the binding based\n * on a default properties and provided options.\n *\n * @param {Object} [options={}]\n * @returns {Object} Complete instance configuration.\n */\n function buildConfig(options) {\n if (typeof options !== 'object') {\n options = {};\n }\n\n return _.extend({}, defaults, options);\n }\n\n ko.bindingHandlers.collapsible = {\n\n /**\n * Initializes 'collapsible' binding.\n */\n init: function (element, valueAccessor, allBindings, viewModel, bindingCtx) {\n var $collapsible = Object.create(collapsible),\n config = buildConfig(valueAccessor()),\n outerClick,\n bindings;\n\n _.bindAll($collapsible, 'open', 'close', 'toggle');
2\n\n $collapsible.opened = ko.observable(!!config.opened);\n\n bindingCtx[config.as] = $collapsible;\n\n if (config.closeOnOuter) {\n outerClick = onOuterClick.bind(null, element, $collapsible);\n\n $(document).on('click', outerClick);\n\n ko.utils.domNodeDisposal.addDisposeCallback(element, function () {\n $(document).off('click', outerClick);\n });\n }\n\n if (config.openClass) {\n bindings = getClassBinding($collapsible, config.openClass);\n\n ko.applyBindingsToNode(element, bindings, bindingCtx);\n }\n\n if (config.onTarget) {\n $(element).on('click', $collapsible.toggle);\n }\n\n if (viewModel && _.isFunction(viewModel.on)) {\n viewModel.on({\n close: $collapsible.close,\n open: $collapsible.open,\n toggleOpened: $collapsible.toggle\n });\n }\n }\n };\n\n ko.bindingHandlers.closeCollapsible = {\n\n /**\n * Creates listener for the click event on provided DOM element,\n * which closes associated with it collapsible model.\n */\n init: function (element, valueAccessor, allBindings, viewModel, bindingCtx) {\n var name = valueAccessor() || defaults.as,\n $collapsible = bindingCtx[name];\n\n if ($collapsible) {\n $(element).on('click', $collapsible.close);\n }\n }\n };\n\n ko.bindingHandlers.openCollapsible = {\n\n /**\n * Creates listener for the click event on provided DOM element,\n * which opens associated with it collapsible model.\n */\n init: function (element, valueAccessor, allBindings, viewModel, bindingCtx) {\n var name = valueAccessor() || defaults.as,\n $collapsible = bindingCtx[name];\n\n if ($collapsible) {\n $(element).on('click', $collapsible.open);\n }\n }\n };\n\n ko.bindingHandlers.toggleCollapsible = {\n\n /**\n * Creates listener for the click event on provided DOM element,\n * which toggles associated with it collapsible model.\n */\n init: function (element, valueAccessor, allBindings, viewModel, bindingCtx) {\n var name = valueAccessor() || defaults.as,\n $collapsible = bindingCtx[name];\n\n if ($collapsible) {\n $(element).on('click', $collapsible.toggle);\n }\n }\n };\n\n renderer\n .addAttribute('collapsible')\n .addAttribute('openCollapsible')\n .addAttribute('closeCollapsible')\n .addAttribute('toggleCollapsible');\n});\n","Magento_Ui/js/lib/knockout/bindings/autoselect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n 'jquery',\n '../template/renderer'\n], function (ko, $, renderer) {\n 'use strict';\n\n /**\n * 'Focus' event handler.\n *\n * @param {EventObject} e\n */\n function onFocus(e) {\n e.target.select();\n }\n\n ko.bindingHandlers.autoselect = {\n\n /**\n * Adds event handler which automatically\n * selects inputs' element text when field gets focused.\n */\n init: function (element, valueAccessor) {\n var enabled = ko.unwrap(valueAccessor());\n\n if (enabled !== false) {\n $(element).on('focus', onFocus);\n }\n }\n };\n\n renderer.addAttribute('autoselect');\n});\n","Magento_Ui/js/lib/knockout/bindings/tooltip.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'ko',\n 'underscore',\n 'mage/template',\n 'text!ui/template/tooltip/tooltip.html',\n '../template/renderer'\n], function ($, ko, _, template, tooltipTmpl, renderer) {\n 'use strict';\n\n var tooltip,\n defaults,\n positions,\n transformProp,\n checkedPositions = {},\n iterator = 0,\n previousTooltip,\n tooltipData,\n positionData = {},\n tooltipsCollection = {},\n isTouchDevice = (function () {\n return 'ontouchstart' in document.documentElement;\n })(),\n CLICK_EVENT = (function () {\n return isTouchDevice ? 'touchstart' : 'click';\n })();
2\n\n defaults = {\n tooltipWrapper: '[data-tooltip=tooltip-wrapper]',\n tooltipContentBlock: 'data-tooltip-content',\n closeButtonClass: 'action-close',\n tailClass: 'data-tooltip-tail',\n action: 'hover',\n delay: 300,\n track: false,\n step: 20,\n position: 'top',\n closeButton: false,\n showed: false,\n strict: true,\n center: false,\n closeOnScroll: true\n };\n\n tooltipData = {\n tooltipClasses: '',\n trigger: false,\n timeout: 0,\n element: false,\n event: false,\n targetElement: {},\n showed: false,\n currentID: 0\n };\n\n /**\n * Polyfill for css transform\n */\n transformProp = (function () {\n var style = document.createElement('div').style,\n base = 'Transform',\n vendors = ['webkit', 'moz', 'ms', 'o'],\n vi = vendors.length,\n property;\n\n if (typeof style.transform !== 'undefined') {\n return 'transform';\n }\n\n while (vi--) {\n property = vendors[vi] + base;\n\n if (typeof style[property] !== 'undefined') {\n return property;\n }\n }\n })();\n\n positions = {\n\n /*eslint max-depth: [0, 0]*/\n\n map: {\n horizontal: {\n s: 'w',\n p: 'left'\n },\n vertical: {\n s: 'h',\n p: 'top'\n }\n },\n\n /**\n * Wrapper function to get tooltip data (position, className, etc)\n *\n * @param {Object} s - object with sizes and positions elements\n * @returns {Object} tooltip data (position, className, etc)\n */\n top: function (s) {\n return positions._topLeftChecker(s, positions.map, 'vertical', '_bottom', 'top', 'right');\n },\n\n /**\n * Wrapper function to get tooltip data (position, className, etc)\n *\n * @param {Object} s - object with sizes and positions elements\n * @returns {Object} tooltip data (position, className, etc)\n */\n left: function (s) {\n return positions._topLeftChecker(s, positions.map, 'horizontal', '_right', 'left', 'top');\n },\n\n /**\n * Wrapper function to get tooltip data (position, className, etc)\n *\n * @param {Object} s - object with sizes and positions elements\n * @returns {Object} tooltip data (position, className, etc)\n */\n bottom: function (s) {\n return positions._bottomRightChecker(s, positions.map, 'vertical', '_top', 'bottom', 'left');\n },\n\n /**\n * Wrapper function to get tooltip data (position, className, etc)\n *\n * @param {Object} s - object with sizes and positions elements\n * @returns {Object} tooltip data (position, className, etc)\n */\n right: function (s) {\n return positions._bottomRightChecker(s, positions.map, 'horizontal', '_left', 'right', 'bottom');\n },\n\n /**\n * Check can tooltip setted on current position or not. If can't setted - delegate call.\n *\n * @param {Object} s - object with sizes and positions elements\n * @param {Object} map - mapping for get direction positions\n * @param {String} direction - vertical or horizontal\n * @param {String} className - class whats should be setted to tooltip\n * @param {String} side - parent method name\n * @param {String} delegate - method name if tooltip can't be setted in current position\n * @returns {Object} tooltip data (position, className, etc)\n */\n _topLeftChecker: function (s, map, direction, className, side, delegate) {\n var result = {\n position: {}\n },\n config = tooltip.getTooltip(tooltipData.currentID),\n startPosition = !config.strict ? s.eventPosition : s.elementPosition,\n changedDirection;\n\n checkedPositions[side] = true;\n\n if (\n startPosition[map[direction].p] - s.tooltipSize[map[direction].s] - config.step >\n s.scrollPosition[map[direction].p]\n ) {\n result.position[map[direction].p] = startPosition[map[direction].p] - s.tooltipSize[map[direction].s] -\n config.step;\n result.className = className;
2\n result.side = side;\n changedDirection = direction === 'vertical' ? 'horizontal' : 'vertical';\n result = positions._normalize(s, result, config, delegate, map, changedDirection);\n } else if (!checkedPositions[delegate]) {\n result = positions[delegate].apply(null, arguments);\n } else {\n result = positions.positionCenter(s, result);\n }\n\n return result;\n },\n\n /**\n * Check can tooltip setted on current position or not. If can't setted - delegate call.\n *\n * @param {Object} s - object with sizes and positions elements\n * @param {Object} map - mapping for get direction positions\n * @param {String} direction - vertical or horizontal\n * @param {String} className - class whats should be setted to tooltip\n * @param {String} side - parent method name\n * @param {String} delegate - method name if tooltip can't be setted in current position\n * @returns {Object} tooltip data (position, className, etc)\n */\n _bottomRightChecker: function (s, map, direction, className, side, delegate) {\n var result = {\n position: {}\n },\n config = tooltip.getTooltip(tooltipData.currentID),\n startPosition = !config.strict ? s.eventPosition : {\n top: s.elementPosition.top + s.elementSize.h,\n left: s.elementPosition.left + s.elementSize.w\n },\n changedDirection;\n\n checkedPositions[side] = true;\n\n if (\n startPosition[map[direction].p] + s.tooltipSize[map[direction].s] + config.step <\n s.scrollPosition[map[direction].p] + s.windowSize[map[direction].s]\n ) {\n result.position[map[direction].p] = startPosition[map[direction].p] + config.step;\n result.className = className;\n result.side = side;\n changedDirection = direction === 'vertical' ? 'horizontal' : 'vertical';\n result = positions._normalize(s, result, config, delegate, map, changedDirection);\n } else if (!checkedPositions[delegate]) {\n result = positions[delegate].apply(null, arguments);\n } else {\n result = positions.positionCenter(s, result);\n }\n\n return result;\n },\n\n /**\n * Centered tooltip if tooltip does not fit in window\n *\n * @param {Object} s - object with sizes and positions elements\n * @param {Object} data - current data (position, className, etc)\n * @returns {Object} tooltip data (position, className, etc)\n */\n positionCenter: function (s, data) {\n data = positions._positionCenter(s, data, 'horizontal', positions.map);\n data = positions._positionCenter(s, data, 'vertical', positions.map);\n\n return data;\n },\n\n /**\n * Centered tooltip side\n *\n * @param {Object} s - object with sizes and positions elements\n * @param {Object} data - current data (position, className, etc)\n * @param {String} direction - vertical or horizontal\n * @param {Object} map - mapping for get direction positions\n * @returns {Object} tooltip data (position, className, etc)\n */\n _positionCenter: function (s, data, direction, map) {\n if (s.tooltipSize[map[direction].s] < s.windowSize[map[direction].s]) {\n data.position[map[direction].p] = (s.windowSize[map[direction].s] -\n s.tooltipSize[map[direction].s]) / 2 + s.scrollPosition[map[direction].p];\n } else {\n data.position[map[direction].p] = s.scrollPosition[map[direction].p];\n data.tooltipSize = {};\n data.tooltipSize[map[direction].s] = s.windowSize[map[direction].s];\n }\n\n return data;\n },\n\n /**\n * Normalize horizontal or vertical position.\n *\n * @param {Object} s - object with sizes and positions elements\n * @param {Object} data - current data (position, className, etc)\n * @param {Object} config - tooltip config\n * @param {String}
2 delegate - method name if tooltip can't be setted in current position\n * @param {Object} map - mapping for get direction positions\n * @param {String} direction - vertical or horizontal\n * @returns {Object} tooltip data (position, className, etc)\n */\n _normalize: function (s, data, config, delegate, map, direction) {\n var startPosition = !config.center ? s.eventPosition : {\n left: s.elementPosition.left + s.elementSize.w / 2,\n top: s.elementPosition.top + s.elementSize.h / 2\n },\n depResult;\n\n if (startPosition[map[direction].p] - s.tooltipSize[map[direction].s] / 2 >\n s.scrollPosition[map[direction].p] && startPosition[map[direction].p] +\n s.tooltipSize[map[direction].s] / 2 <\n s.scrollPosition[map[direction].p] + s.windowSize[map[direction].s]\n ) {\n data.position[map[direction].p] = startPosition[map[direction].p] - s.tooltipSize[map[direction].s] / 2;\n } else {\n\n /*eslint-disable no-lonely-if*/\n if (!checkedPositions[delegate]) {\n depResult = positions[delegate].apply(null, arguments);\n\n if (depResult.hasOwnProperty('className')) {\n data = depResult;\n } else {\n data = positions._normalizeTail(s, data, config, delegate, map, direction, startPosition);\n }\n } else {\n data = positions._normalizeTail(s, data, config, delegate, map, direction, startPosition);\n }\n }\n\n return data;\n },\n\n /**\n * Calc tail position.\n *\n * @param {Object} s - object with sizes and positions elements\n * @param {Object} data - current data (position, className, etc)\n * @param {Object} config - tooltip config\n * @param {String} delegate - method name if tooltip can't be setted in current position\n * @param {Object} map - mapping for get direction positions\n * @param {String} direction - vertical or horizontal\n * @param {Object} startPosition - start position\n * @returns {Object} tooltip data (position, className, etc)\n */\n _normalizeTail: function (s, data, config, delegate, map, direction, startPosition) {\n data.tail = {};\n\n if (s.tooltipSize[map[direction].s] < s.windowSize[map[direction].s]) {\n\n if (\n startPosition[map[direction].p] >\n s.windowSize[map[direction].s] / 2 + s.scrollPosition[map[direction].p]\n ) {\n data.position[map[direction].p] = s.windowSize[map[direction].s] +\n s.scrollPosition[map[direction].p] - s.tooltipSize[map[direction].s];\n data.tail[map[direction].p] = startPosition[map[direction].p] -\n s.tooltipSize[map[direction].s] / 2 - data.position[map[direction].p];\n } else {\n data.position[map[direction].p] = s.scrollPosition[map[direction].p];\n data.tail[map[direction].p] = startPosition[map[direction].p] -\n s.tooltipSize[map[direction].s] / 2 - data.position[map[direction].p];\n }\n } else {\n data.position[map[direction].p] = s.scrollPosition[map[direction].p];\n data.tail[map[direction].p] = s.eventPosition[map[direction].p] - s.windowSize[map[direction].s] / 2;\n data.tooltipSize = {};\n data.tooltipSize[map[direction].s] = s.windowSize[map[direction].s];\n }\n\n return data;\n }\n };\n\n tooltip = {\n\n /**\n * Set new tooltip to tooltipCollection, save config, and add unic id\n *\n * @param {Object} config - tooltip config\n * @returns {String} tooltip id\n */\n setTooltip: function (config) {\n var property = 'id-' + iterator;\n\n tooltipsCollection[property] = config;\n iterator++;\n\n return property;\n },\n\n /**\n * Get tooltip config by id\n *\n * @param {String} id - tooltip id\n * @returns {Object} tooltip config\n */\n getTooltip: function (id) {\n return tooltipsCollection[id];\n },\n\n /**\n * Set content to current tooltip\n *\n * @param {Object} tooltipElement - tooltip element\n * @param {Object} viewModel - tooltip view model\n * @param {String} id - tooltip id\n * @param {Object} bindingCtx - tooltip context\n * @param {Object} event - action event\n */\n setContent: function (tooltipElement, viewModel, id, bindingCtx, event) {\n var html = $(tooltipElement).html(),\n config = tooltip.getTooltip(id),\n body = $('body');\n\n tooltipData.currentID = id;\n tooltipData.trigger = $(event.currentTarget);\n tooltip.setTargetData(event);\n body.on('mousemove.setTargetData', tooltip.setTargetData);\n tooltip.clearTimeout(id);\n\n tooltipData.timeout = _.delay(function () {\n body.off('mousemove.setTargetData', tooltip.setTargetData);\n\n if (tooltipData.trigger[0] === tooltipData.targetElement) {\n tooltip.destroy(id);\n event.stopPropagation();\n tooltipElement = tooltip.createTooltip(id);\n tooltipElement.find('.' + defaults.tooltipContentBlock).append(html);\n tooltipElement.applyBindings(bindingCtx);\n tooltip.setHandlers(id);\n tooltip.setPosition(tooltipElement, id);\n previousTooltip = id;\n }\n\n }, config.delay);\n },\n\n /**\n * Set position to current tooltip\n *\n * @param {Object} tooltipElement - tooltip element\n * @param {String} id - tooltip id\n */\n setPosition: function (tooltipElement, id) {\n var config = tooltip.getTooltip(id);\n\n tooltip.sizeData = {\n windowSize: {\n h: $(window).outerHeight(),\
2n w: $(window).outerWidth()\n },\n scrollPosition: {\n top: $(window).scrollTop(),\n left: $(window).scrollLeft()\n },\n tooltipSize: {\n h: tooltipElement.outerHeight(),\n w: tooltipElement.outerWidth()\n },\n elementSize: {\n h: tooltipData.trigger.outerHeight(),\n w: tooltipData.trigger.outerWidth()\n },\n elementPosition: tooltipData.trigger.offset(),\n eventPosition: this.getEventPosition(tooltipData.event)\n };\n\n _.extend(positionData, positions[config.position](tooltip.sizeData));\n tooltipElement.css(positionData.position);\n tooltipElement.addClass(positionData.className);\n tooltip._setTooltipSize(positionData, tooltipElement);\n tooltip._setTailPosition(positionData, tooltipElement);\n checkedPositions = {};\n },\n\n /**\n * Check position data and change tooltip size if needs\n *\n * @param {Object} data - position data\n * @param {Object} tooltipElement - tooltip element\n */\n _setTooltipSize: function (data, tooltipElement) {\n if (data.tooltipSize) {\n data.tooltipSize.w ?\n tooltipElement.css('width', data.tooltipSize.w) :\n tooltipElement.css('height', data.tooltipSize.h);\n }\n },\n\n /**\n * Check position data and set position to tail\n *\n * @param {Object} data - position data\n * @param {Object} tooltipElement - tooltip element\n */\n _setTailPosition: function (data, tooltipElement) {\n var tail,\n tailMargin;\n\n if (data.tail) {\n tail = tooltipElement.find('.' + defaults.tailClass);\n\n if (data.tail.left) {\n tailMargin = parseInt(tail.css('margin-left'), 10);\n tail.css('margin-left', tailMargin + data.tail.left);\n } else {\n tailMargin = parseInt(tail.css('margin-top'), 10);\n tail.css('margin-top', tailMargin + data.tail.top);\n }\n }\n },\n\n /**\n * Resolves position for tooltip\n *\n * @param {Object} event\n * @returns {Object}\n */\n getEventPosition: function (event) {\n var position = {\n left: event.originalEvent && event.originalEvent.pageX || 0,\n top: event.originalEvent && event.originalEvent.pageY || 0\n };\n\n if (position.left === 0 && position.top === 0) {\n _.extend(position, event.target.getBoundingClientRect());\n }\n\n return position;\n },\n\n /**\n * Close tooltip if action happened outside handler and tooltip element\n *\n * @param {String} id - tooltip id\n * @param {Object} event - action event\n */\n outerClick: function (id, event) {\n var tooltipElement = $(event.target).parents(defaults.tooltipWrapper)[0],\n isTrigger = event.target === tooltipData.trigger[0] || $.contains(tooltipData.trigger[0], event.target);\n\n if (tooltipData.showed && tooltipElement !== tooltipData.element[0] && !isTrigger) {\n tooltip.destroy(id);\n }\n },\n\n /**\n * Parse keydown event and if event trigger is escape key - close tooltip\n *\n * @param {Object} event - action event\n */\n keydownHandler: function (event) {\n if (tooltipData.showed && event.keyCode === 27) {\n tooltip.destroy(tooltipData.currentID);\n }\n },\n\n /**\n * Change tooltip position when track is enabled\n *\n * @param {Object} event - current event\n */\n track: function (event) {\n var inequality = {},\n map = positions.map,\n translate = {\n left: 'translateX',\n top: 'translateY'\n },\n eventPosition = {\n left: event.pageX,\n top: event.pageY\n },\n tooltipSize = {\n w: tooltipData.element.outerWidth(),\n h: tooltipData.element.outerHeight()\n },\n direction = positionData.side === 'bottom' || positionData.side === 'top' ? 'horizontal' : 'vertical';\n\n inequality[map[direction].p] = eventPosition[map[direction].p] - (positionData.position[map[direction].p] +\n tooltipSize[map[direction].s] / 2);\n\n if (positionData.position[map[direction].p] + inequality[map[direction].p] +\n tooltip.sizeData.tooltipSize[map[direction].s] >\n tooltip.sizeData.windowSize[map[direction].s] + tooltip.sizeData.scrollPosition[map[direction].p] ||\n inequality[map[direction].p] + positionData.position[map[direction].p] <\n tooltip.sizeData.scrollPosition[map[direction].p]) {\n\n return false;\n }\n\n tooltipData.element[0].style[transformProp] = translate[map[direction].p] +\n '(' + inequality[map[direction].p] + 'px)';\n },\n\n /**\n * Set handlers to tooltip\n *\n * @param {String} id - tooltip id\n */\n setHandlers: function (id) {\n var config = tooltip.getTooltip(id);\n\n if (config.track) {\n tooltipData.trigger.on('mousemove.track', tooltip.track);\n }\n\n if (config.action === 'click') {\n $(window).on(CLICK_EVENT + '.outerClick', tooltip.outerClick.bind(null, id));\n }\n\n if (config.closeButton) {\n $('.' + config.closeButtonClass).on('click.closeButton', tooltip.destroy.bind(null, id));\n }\n\n if (config.closeOnScroll) {\n document.addEventListener('scroll', tooltip.destroy, true);\n $(window).on('scroll.tooltip', tooltip.outerClick.bind(null, id));\n }\n\n $(window).on('keydown.tooltip', tooltip.keydownHandler);\n $(window).on('resize.outerClick', tooltip.outerClick.bind(null, id));\n },\n\n /**\n * Toggle tooltip\n *\n * @param {Object} tooltipElement - tooltip element\n * @param {Object} viewModel - tooltip view model\n * @param {String} id - tooltip id\n */\n toggleTooltip: function (tooltipElement, viewModel, id) {\n if (previousTooltip === id && tooltipData.showed) {\n tooltip.destroy(id);\n\n return false;\n }\n\n tooltip.setContent.apply(null, arguments);\n\n return false;\n },\n\n /**\n * Create tooltip and append to DOM\n *\n * @param {String} id - tooltip id\n * @returns {Object} tooltip element\n */\n createTooltip: function (id) {\n var body = $('body'),\n config = tooltip.getTooltip(id);\n\n $(template(tooltipTmpl, {\n data: config\n })).appendTo(body);\n\n tooltipData.showed = true;
2\n tooltipData.element = $(config.tooltipWrapper);\n\n return tooltipData.element;\n },\n\n /**\n * Check action and clean timeout\n *\n * @param {String} id - tooltip id\n */\n clearTimeout: function (id) {\n var config = tooltip.getTooltip(id);\n\n if (config.action === 'hover') {\n clearTimeout(tooltipData.timeout);\n }\n },\n\n /**\n * Check previous tooltip\n */\n checkPreviousTooltip: function () {\n if (!tooltipData.timeout) {\n tooltip.destroy();\n }\n },\n\n /**\n * Destroy tooltip instance\n */\n destroy: function () {\n if (tooltipData.element) {\n tooltipData.element.remove();\n tooltipData.showed = false;\n }\n\n positionData = {};\n tooltipData.timeout = false;\n tooltip.removeHandlers();\n },\n\n /**\n * Remove tooltip handlers\n */\n removeHandlers: function () {\n $('.' + defaults.closeButtonClass).off('click.closeButton');\n tooltipData.trigger.off('mousemove.track');\n document.removeEventListener('scroll', tooltip.destroy, true);\n $(window).off('scroll.tooltip');\n $(window).off(CLICK_EVENT + '.outerClick');\n $(window).off('keydown.tooltip');\n $(window).off('resize.outerClick');\n },\n\n /**\n * Set target element\n *\n * @param {Object} event - current event\n */\n setTargetData: function (event) {\n tooltipData.event = event;\n\n //TODO: bug chrome v.49; Link to issue https://bugs.chromium.org/p/chromium/issues/detail?id=161464\n if (event.timeStamp - (tooltipData.timestamp || 0) < 1) {\n return;\n }\n\n if (event.type === 'mousemove') {\n tooltipData.targetElement = event.target;\n } else {\n tooltipData.targetElement = event.currentTarget;\n tooltipData.timestamp = event.timeStamp;\n }\n },\n\n /**\n * Merged user config with defaults configuration\n *\n * @param {Object} config - user config\n * @returns {Object} merged config\n */\n processingConfig: function (config) {\n return _.extend({}, defaults, config);\n }\n };\n\n ko.bindingHandlers.tooltip = {\n\n /**\n * Initialize tooltip\n *\n * @param {Object} elem - tooltip DOM element\n * @param {Function} valueAccessor - ko observable property, tooltip data\n * @param {Object} allBindings - all bindings on current element\n * @param {Object} viewModel - current element viewModel\n * @param {Object} bindingCtx - current element binding context\n */\n init: function (elem, valueAccessor, allBindings, viewModel, bindingCtx) {\n var config = tooltip.processingConfig(valueAccessor()),\n $parentScope = config.parentScope ? $(config.parentScope) : $(elem).parent(),\n tooltipId;\n\n $(elem).addClass('hidden');\n\n if (isTouchDevice) {\n config.action = 'click';\n }\n tooltipId = tooltip.setTooltip(config);\n\n if (config.action === 'hover') {\n $parentScope.on(\n 'mouseenter',\n config.trigger,\n tooltip.setContent.bind(null, elem, viewModel, tooltipId, bindingCtx)\n );\n $parentScope.on(\n 'mouseleave',\n config.trigger,\n tooltip.checkPreviousTooltip.bind(null, tooltipId)\n );\n } else if (config.action === 'click') {\n $parentScope.on(\n 'click',\n config.trigger,\n tooltip.toggleTooltip.bind(null, elem, viewModel, tooltipId, bindingCtx)\n );\n }\n\n return {\n controlsDescendantBindings: true\n };\n }\n };\n\n renderer.addAttribute('tooltip');\n});\n","Magento_Ui/js/lib/knockout/bindings/scope.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/** Creates scope binding and registers in to ko.bindingHandlers object */\ndefine([\n 'ko',\n 'uiRegistry',\n 'mage/translate',\n '../template/renderer',\n 'jquery',\n '../../logger/console-logger'\n], function (ko, registry, $t, renderer, $, consoleLogger) {\n 'use strict';\n\n /**\n * Creates child context with passed component param as $data. Extends context with $t helper.\n * Applies bindings to descendant nodes.\n * @param {HTMLElement} el - element to apply bindings to.\n * @param {ko.bindingContext} bindingContext - instance of ko.bindingContext, passed to binding initially.\n * @param {Promise} promise - instance of jQuery promise\n * @param {Object} component - component instance to attach to new context\n */\n function applyComponents(el, bindingContext, promise,
2component) {\n promise.resolve();\n component = bindingContext.createChildContext(component);\n\n ko.utils.extend(component, {\n $t: $t\n });\n\n ko.utils.arrayForEach(el.childNodes, ko.cleanNode);\n\n ko.applyBindingsToDescendants(component, el);\n }\n\n ko.bindingHandlers.scope = {\n\n /**\n * Scope binding's init method.\n * @returns {Object} - Knockout declaration for it to let binding control descendants.\n */\n init: function () {\n return {\n controlsDescendantBindings: true\n };\n },\n\n /**\n * Reads params passed to binding, parses component declarations.\n * Fetches for those found and attaches them to the new context.\n * @param {HTMLElement} el - Element to apply bindings to.\n * @param {Function} valueAccessor - Function that returns value, passed to binding.\n * @param {Object} allBindings - Object, which represents all bindings applied to element.\n * @param {Object} viewModel - Object, which represents view model binded to el.\n * @param {ko.bindingContext} bindingContext - Instance of ko.bindingContext, passed to binding initially.\n */\n update: function (el, valueAccessor, allBindings, viewModel, bindingContext) {\n var component = valueAccessor(),\n promise = $.Deferred(),\n apply = applyComponents.bind(this, el, bindingContext, promise),\n loggerUtils = consoleLogger.utils;\n\n if (typeof component === 'string') {\n loggerUtils.asyncLog(\n promise,\n {\n data: {\n component: component\n },\n messages: loggerUtils.createMessages(\n 'requestingComponent',\n 'requestingComponentIsLoaded',\n 'requestingComponentIsFailed'\n )\n }\n );\n\n registry.get(component, apply);\n } else if (typeof component === 'function') {\n component(apply);\n }\n }\n };\n\n ko.virtualElements.allowedBindings.scope = true;\n\n renderer\n .addNode('scope')\n .addAttribute('scope', {\n name: 'ko-scope'\n });\n});\n","Magento_Ui/js/lib/knockout/bindings/mage-init.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'underscore',\n 'mage/apply/main'\n], function (ko, _, mage) {\n 'use strict';\n\n ko.bindingHandlers.mageInit = {\n /**\n * Initializes components assigned to HTML elements.\n *\n * @param {HTMLElement} el\n * @param {Function} valueAccessor\n */\n init: function (el, valueAccessor) {\n var data = valueAccessor();\n\n _.each(data, function (config, component) {\n mage.applyFor(el, config, component);\n });\n }\n };\n});\n","Magento_Ui/js/lib/knockout/bindings/bind-html.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'underscore',\n 'mage/apply/main',\n '../template/renderer'\n], function (ko, _, mage, renderer) {\n 'use strict';\n\n /**\n * Set html to node element.\n *\n * @param {HTMLElement} el - Element to apply bindings to.\n * @param {Function} html - Observable html content.\n */\n function setHtml(el, html) {\n ko.utils.emptyDomNode(el);\n html = ko.utils.unwrapObservable(html);\n\n if (!_.isNull(html) && !_.isUndefined(html)) {\n if (!_.isString(html)) {\n html = html.toString();\n }\n\n el.innerHTML = html;\n }\n }\n\n /**\n * Apply bindings and call magento attributes parser.\n *\n * @param {HTMLElement} el - Element to apply bindings to.\n * @param {ko.bindingContext} ctx - Instance of ko.bindingContext, passed to binding initially.\n */\n function applyComponents(el, ctx) {\n ko.utils.arrayForEach(el.childNodes, ko.cleanNode);\n ko.applyBindingsToDescendants(ctx, el);\n mage.apply();\n }\n\n ko.bindingHandlers.bindHtml = {\n /**\n * Scope binding's init method.\n *\n * @returns {Object} - Knockout declaration for it to let binding control descendants.\n */\n init: function () {\n return {\n controlsDescendantBindings: true\n };\n },\n\n /**\n * Reads params passed to binding.\n * Set html to node element, apply bindings and call magento attributes parser.\n *\n * @param {HTMLElement} el - Element to apply bindings to.\n * @param {Function} valueAccessor - Function that returns value, passed to binding.\n * @param {Object} allBindings - Object, which represents all bindings applied to element.\n * @param {Object} viewModel - Object, which represents view model binded to el.\n * @param {ko.bindingContext} bindingContext - Instance of ko.bindingContext, passed to binding initially.\n */\n update: function (el, valueAccessor, allBindings, viewModel, bindingContext) {\n setHtml(el, valueAccessor());\n applyComponents(el, bindingContext);\n }\n };\n\n renderer.addAttribute('bindHtml');\n});\n","Magento_Ui/js/lib/knockout/bindings/bootstrap.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 renderer = require('../template/renderer');\n\n renderer.addAttribute('repeat', renderer.handlers.wrapAttribute);\n\n renderer.addAttribute('outerfasteach', {\n binding: 'fastForEach',\n handler: renderer.handlers.wrapAttribute\n });\n\n renderer\n .addNode('repeat')\n .addNode('fastForEach');\n\n return {\n resizable: require('./resizable'),\n i18n: require('./i18n'),\n scope: require('./scope'),\n range: require('./range'),\n mageInit: require('./mage-init'),\n keyboard: require('./keyboard'),\n optgroup: require('./optgroup'),\n aferRender: require('./after-render'),\n autoselect: require('./autoselect'),\n datepicker: require('./datepicker'),\n outerClick: require('./outer_click'),\n fadeVisible: require('./fadeVisible'),\n collapsible: require('./collapsible'),\n staticChecked: require('./staticChecked'),\n simpleChecked: require('./simple-checked'),\n bindHtml: require('./bind-html'),\n tooltip: require('./tooltip'),\n repeat: require('knockoutjs/knockout-repeat'),\n fastForEach: require('knockoutjs/knockout-fast-foreach')\n };\n});
2\n","Magento_Ui/js/lib/knockout/bindings/i18n.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'ko',\n 'module',\n '../template/renderer',\n 'mage/translate'\n], function ($, ko, module, renderer) {\n 'use strict';\n\n var locations = {\n 'legend': 'Caption for the fieldset element',\n 'label': 'Label for an input element.',\n 'button': 'Push button',\n 'a': 'Link label',\n 'b': 'Bold text',\n 'strong': 'Strong emphasized text',\n 'i': 'Italic text',\n 'em': 'Emphasized text',\n 'u': 'Underlined text',\n 'sup': 'Superscript text',\n 'sub': 'Subscript text',\n 'span': 'Span element',\n 'small': 'Smaller text',\n 'big': 'Bigger text',\n 'address': 'Contact information',\n 'blockquote': 'Long quotation',\n 'q': 'Short quotation',\n 'cite': 'Citation',\n 'caption': 'Table caption',\n 'abbr': 'Abbreviated phrase',\n 'acronym': 'An acronym',\n 'var': 'Variable part of a text',\n 'dfn': 'Term',\n 'strike': 'Strikethrough text',\n 'del': 'Deleted text',\n 'ins': 'Inserted text',\n 'h1': 'Heading level 1',\n 'h2': 'Heading level 2',\n 'h3': 'Heading level 3',\n 'h4': 'Heading level 4',\n 'h5': 'Heading level 5',\n 'h6': 'Heading level 6',\n 'center': 'Centered text',\n 'select': 'List options',\n 'img': 'Image',\n 'input': 'Form element'\n },\n\n /**\n * Generates [data-translate] attribute's value\n * @param {Object} translationData\n * @param {String} location\n */\n composeTranslateAttr = function (translationData, location) {\n var obj = [{\n 'shown': translationData.shown,\n 'translated': translationData.translated,\n 'original': translationData.original,\n 'location': locations[location] || 'Text'\n }];\n\n return JSON.stringify(obj);\n },\n\n /**\n * Sets text for the element\n * @param {Object} el\n * @param {String} text\n */\n setText = function (el, text) {\n $(el).text(text);\n },\n\n /**\n * Sets [data-translate] attribute for the element\n * @param {Object} el - The element which is binded\n * @param {String} original - The original value of the element\n */\n setTranslateProp = function (el, original) {\n var location = $(el).prop('tagName').toLowerCase(),\n translated = $.mage.__(original),\n translationData = {\n shown: translated,\n translated: translated,\n original: original\n },\n translateAttr = composeTranslateAttr(translationData, location);\n\n $(el).attr('data-translate', translateAttr);\n\n setText(el, translationData.shown);\n },\n\n /**\n * Checks if node represents ko virtual node (nodeType === 8, nodeName === '#comment').\n *\n * @param {HTMLElement} node\n * @returns {Boolean}\n */\n isVirtualElement = function (node) {\n return node.nodeType === 8;\n },\n\n /**\n * Checks if it's real DOM element\n * in case of virtual element, returns span wrapper\n * @param {Object} el\n * @param {bool} isUpdate\n * @return {Object} el\n */\n getRealElement = function (el, isUpdate) {\n if (isVirtualElement(el)) {\n if (isUpdate) {\n return $(el).next('span');\n }\n\n return $('<span/>').insertAfter(el);\n }\n\n return el;\n },\n\n /**\n * execute i18n binding\n * @param {Object} element\n * @param {Function} valueAccessor\n * @param {bool} isUpdate\n */\n execute = function (element, valueAccessor, isUpdate) {\n var original = ko.unwrap(valueAccessor() || ''),\n el = getRealElement(element, isUpdate),\n inlineTranslation = (module.config() || {}).inlineTranslation;\n\n if (inlineTranslation) {\n setTranslateProp(el, original);\n } else {\n setText(el, $.mage.__(original));\n }\n };\n\n /**\n * i18n binding\n * @property {Function} init\n * @property {Function} update\n */\n ko.bindingHandlers.i18n = {\n\n /**\n * init i18n binding\n * @param {Object} element\n * @param {Function} valueAccessor\n */\n init: function (element, valueAccessor) {\n execute(element, valueAccessor);\n },\n\n /**\n * update i18n binding\n * @param {Object} element\n * @param {Function} valueAccessor\n */\n update: function (element, valueAccessor) {\n execute(element, valueAccessor, true);\n }\n };\n\n ko.virtualElements.allowedBindings.i18n = true;\n\n renderer\n .addNode('translate', {\n binding: 'i18n'\n })\n .addAttribute('translate', {\n binding: 'i18n'\n });\n});\n","Magento_Ui/js/lib/knockout/bindings/datepicker.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/** Creates datepicker binding and registers in to ko.bindingHandlers object */\ndefine([\n 'ko',\n 'underscore',\n 'jquery',\n 'mage/translate',\n 'mage/calendar',\n 'moment',\n 'mageUtils'\n], function (ko, _, $, $t, calendar, moment, utils) {\n 'use strict';\n\n var defaults = {\n dateFormat: 'mm\\/dd\\/yyyy',\n showsTime: false,\n timeFormat: null,\n buttonImage: null,\n buttonImageOnly: null,\n buttonText: $t('Select Date')\n };\n\n ko.bindingHandlers.datepicker = {\n /**\n * Initializes calendar widget on element and stores it's value to observable property.\n * Datepicker binding takes either observable property or object\n * { storage: {ko.observable}, options: {Object} }.\n * For more info about options take a look at \"mage/calendar\" and jquery.ui.datepicker widget.\n * @param {HTMLElement} el - Element, that binding is applied to\n * @param {Function} valueAccessor - Function that returns value, passed to binding\n */\n init: function (el, valueAccessor) {\n var config = valueAccessor(),\n observable,\n options = {};\n\n _.extend(options, defaults);\n\n if (typeof config === 'object') {\n observable = config.storage;\n\n _.extend(options, config.options);\n } else {\n observable = config;\n }\n\n $(el).calendar(options);\n\n observable() && $(el).datepicker(\n 'setDate',\n moment(\n observable(),\n utils.convertToMomentFormat(\n options.dateFormat + (options.showsTime ? ' ' + options.timeFormat : '')\n )\n ).toDate()\n );\n\n $(el).blur();\n\n ko.utils.registerEventHandler(el, 'change', function () {\n observable(this.value);\n });\n }\n };\n});\n","Magento_Ui/js/lib/knockout/bindings/staticChecked.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n '../template/renderer'\n], function (ko, renderer) {\n 'use strict';\n\n ko.bindingHandlers.staticChecked = {\n 'after': ['value', 'attr'],\n\n /**\n * Implements same functionality as a standard 'checked' binding,\n * but with a difference that it wont' change values array if\n * value of DOM element changes.\n */\n init: function (element, valueAccessor, allBindings) {\n var isCheckbox = element.type === 'checkbox',\n isRadio = element.type === 'radio',\n isValueArray,\n oldElemValue,\n useCheckedValue,\n checkedValue,\n updateModel,\n updateView;\n\n if (!isCheckbox && !isRadio) {\n return;\n }\n\n checkedValue = ko.pureComputed(function () {\n if (allBindings.has('checkedValue')) {\n return ko.utils.unwrapObservable(allBindings.get('checkedValue'));\n } else if (allBindings.has('value')) {\n return ko.utils.unwrapObservable(allBindings.get('value'));\n }\n\n return element.value;\n });\n\n isValueArray = isCheckbox && ko.utils.unwrapObservable(valueAccessor()) instanceof Array;\n oldElemValue = isValueArray ? checkedValue() : undefined;\n useCheckedValue = isRadio || isValueArray;\n\n /**\n * Updates values array if it's necessary.\n */\n updateModel = function () {\n var isChecked = element.checked,\n elemValue = useCheckedValue ? checkedValue() : isChecked,\n modelValue;\n\n if (ko.computedContext.isInitial()) {\n return;\n }\n\n if (isRadio && !isChecked) {\n return;\n }\n\n modelValue = ko.dependencyDetection.ignore(valueAccessor);\n\n if (isValueArray) {\n if (oldElemValue !== elemValue) {\n oldElemValue = elemValue;\n } else {\n ko.utils.addOrRemoveItem(modelValue, elemValue, isChecked);\n }\n } else {\n ko.expressionRewriting.writeValueToProperty(modelValue, allBindings, 'checked', elemValue, true);\n }\n };\n\n /**\n * Updates checkbox state.\n */\n updateView = function () {\n var modelValue = ko.utils.unwrapObservable(valueAccessor());\n\n if (isValueArray) {\n element.checked = ko.utils.arrayIndexOf(modelValue, checkedValue()) >= 0;\n } else if (isCheckbox) {\n element.checked = modelValue;\n } else {\n element.checked = checkedValue() === modelValue;\n }\n };\n\n ko.computed(updateModel, null, {\n disposeWhenNodeIsRemoved: element\n });\n\n ko.utils.registerEventHandler(element, 'click', updateModel);\n\n ko.computed(updateView, null, {\n disposeWhenNodeIsRemoved: element\n });\n }\n };\n\n ko.expressionRewriting.twoWayBindings.staticChecked = true;\n\n renderer.addAttribute('staticChecked');\n});\n","Magento_Ui/js/lib/knockout/bindings/range.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'jquery',\n 'underscore',\n '../template/renderer',\n 'jquery/ui'\n], function (ko, $, _, renderer) {\n 'use strict';\n\n var isTouchDevice = !_.isUndefined(document.ontouchstart),\n sliderFn = 'slider';\n\n ko.bindingHandlers.range = {\n\n /**\n * Initializes binding and a slider update.\n *\n * @param {HTMLElement} element\n * @param {Function} valueAccessor\n */\n init: function (element, valueAccessor) {\n var config = valueAccessor(),\n value = config.value;\n\n _.extend(config, {\n value: value(),\
2n\n /**\n * Callback which is being called when sliders' value changes.\n *\n * @param {Event} event\n * @param {Object} ui\n */\n slide: function (event, ui) {\n value(ui.value);\n }\n });\n\n $(element)[sliderFn](config);\n },\n\n /**\n * Updates sliders' plugin configuration.\n *\n * @param {HTMLElement} element\n * @param {Function} valueAccessor\n */\n update: function (element, valueAccessor) {\n var config = valueAccessor();\n\n config.value = ko.unwrap(config.value);\n\n $(element)[sliderFn]('option', config);\n }\n };\n\n renderer.addAttribute('range');\n\n if (!isTouchDevice) {\n return;\n }\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,\
2n clientY: touch.clientY,\n screenX: touch.screenX,\n screenY: touch.screenY\n });\n }\n });\n\n sliderFn = 'touchSlider';\n});\n","Magento_Ui/js/lib/knockout/bindings/after-render.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n '../template/renderer'\n], function (ko, renderer) {\n 'use strict';\n\n ko.bindingHandlers.afterRender = {\n\n /**\n * Binding init callback.\n */\n init: function (element, valueAccessor, allBindings, viewModel) {\n var callback = valueAccessor();\n\n if (typeof callback === 'function') {\n callback.call(viewModel, element, viewModel);\n }\n }\n };\n\n renderer.addAttribute('afterRender');\n});\n","Magento_Ui/js/lib/knockout/bindings/resizable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n 'jquery',\n 'Magento_Ui/js/lib/view/utils/async',\n 'uiRegistry',\n 'underscore',\n '../template/renderer',\n 'jquery/ui'\n], function (ko, $, async, registry, _, renderer) {\n 'use strict';\n\n var sizeOptions = [\n 'minHeight',\n 'maxHeight',\n 'minWidth',\n 'maxWidth'\n ],\n\n handles = {\n height: '.ui-resizable-s, .ui-resizable-n',\n width: '.ui-resizable-w, .ui-resizable-e'\n };\n\n /**\n * Recalcs visibility of handles, width and height of resizable based on content\n * @param {HTMLElement} element\n */\n function adjustSize(element) {\n var maxHeight,\n maxWidth;\n\n element = $(element);\n maxHeight = element.resizable('option').maxHeight;\n maxWidth = element.resizable('option').maxWidth;\n\n if (maxHeight && element.height() > maxHeight) {\n element.height(maxHeight + 1);\n $(handles.height).hide();\n } else {\n $(handles.height).show();\n }\n\n if (maxWidth && element.width() > maxWidth) {\n element.width(maxWidth + 1);\n $(handles.width).hide();\n } else {\n $(handles.width).show();\n }\n }\n\n /**\n * Recalcs allowed min, max width and height based on configured selectors\n * @param {Object} sizeConstraints\n * @param {String} componentName\n * @param {HTMLElement} element\n * @param {Boolean} hasWidthUpdate\n */\n function recalcAllowedSize(sizeConstraints, componentName, element, hasWidthUpdate) {\n var size;\n\n element = $(element);\n\n if (!element.data('resizable')) {\n return;\n }\n\n if (!hasWidthUpdate) {\n element.css('width', 'auto');\n }\n\n _.each(sizeConstraints, function (selector, key) {\n async.async({\n component: componentName,\n selector: selector\n }, function (elem) {\n size = key.indexOf('Height') !== -1 ? $(elem).outerHeight(true) : $(elem).outerWidth(true);\n\n if (element.data('resizable')) {\n element.resizable('option', key, size + 1);\n }\n });\n }, this);\n\n adjustSize(element);\n }\n\n /**\n * Preprocess config to separate options,\n * which must be processed further before applying\n *\n * @param {Object} config\n * @param {Object} viewModel\n * @param {*} element\n * @return {Object} config\n */\n function processConfig(config, viewModel, element) {\n var sizeConstraint,\n sizeConstraints = {},\n recalc,\n hasWidthUpdate;\n\n if (_.isEmpty(config)) {\n return {};\n }\n _.each(sizeOptions, function (key) {\n sizeConstraint = config[key];\n\n if (sizeConstraint && !_.isNumber(sizeConstraint)) {\n sizeConstraints[key] = sizeConstraint;\n delete config[key];\n }\n });\n hasWidthUpdate = _.some(sizeConstraints, function (value, key) {\n return key.indexOf('Width') !== -1;\n });\n\n recalc = recalcAllowedSize.bind(null, sizeConstraints, viewModel.name, element, hasWidthUpdate);\n config.start = recalc;\n $(window).on('resize.resizable', recalc);\n registry.get(viewModel.provider).on('reloaded', recalc);\n\n return config;\n }\n\n ko.bindingHandlers.resizable = {\n\n /**\n * Binding init callback.\n *\n * @param {*} element\n * @param {Function} valueAccessor\n * @param {Function} allBindings\n * @param {Object} viewModel\n */\n init: function (element, valueAccessor, allBindings, viewModel) {\n var config = processConfig(valueAccessor(), viewModel, element);\n\n $(element).resizable(config);\n }\n };\n\n renderer.addAttribute('resizable');\n});\n","Magento_Ui/js/lib/knockout/bindings/simple-checked.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n '../template/renderer'\n], function (ko, renderer) {\n 'use strict';\n\n ko.bindingHandlers.simpleChecked = {\n 'after': ['attr'],\n\n /**\n * Implements same functionality as a standard 'simpleChecked' binding,\n * but with a difference that it wont' change values array if\n * value of DOM element changes.\n */\n init: function (element, valueAccessor) {\n var isCheckbox = element.type === 'checkbox',\n isRadio = element.type === 'radio',\n updateView,\n updateModel;\n\n if (!isCheckbox && !isRadio) {\n return;\n }\n\n /**\n * Updates checked observable\n */\n updateModel = function () {\n var modelValue = ko.dependencyDetection.ignore(valueAccessor),\n isChecked = element.checked;\n\n if (ko.computedContext.isInitial()) {\n return;\n }\n\n if (modelValue.peek() === isChecked) {\n return;\n }\n\n if (isRadio && !isChecked) {\n return;\n }\n\n modelValue(isChecked);\n };\n\n /**\n * Updates checkbox state\n */\n updateView = function () {\n var modelValue = ko.utils.unwrapObservable(valueAccessor());\n\n element.checked = !!modelValue;\n };\n\n ko.utils.registerEventHandler(element, 'change', updateModel);\n\n ko.computed(updateModel, null, {\n disposeWhenNodeIsRemoved: element\n });\n ko.computed(updateView, null, {\n disposeWhenNodeIsRemoved: element\n });\n }\n };\n\n ko.expressionRewriting.twoWayBindings.simpleChecked = true;\n\n renderer.addAttribute('simpleChecked');\n renderer.addAttribute('simple-checked', {\n binding: 'simpleChecked'\n });\n});
2\n","Magento_Ui/js/lib/knockout/bindings/outer_click.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/** Creates outerClick binding and registers in to ko.bindingHandlers object */\ndefine([\n 'ko',\n 'jquery',\n 'underscore',\n '../template/renderer'\n], function (ko, $, _, renderer) {\n 'use strict';\n\n var defaults = {\n onlyIfVisible: true\n };\n\n /**\n * Checks if element sis visible.\n *\n * @param {Element} el\n * @returns {Boolean}\n */\n function isVisible(el) {\n var style = window.getComputedStyle(el),\n visibility = {\n display: 'none',\n visibility: 'hidden',\n opacity: '0'\n },\n visible = true;\n\n _.each(visibility, function (val, key) {\n if (style[key] === val) {\n visible = false;\n }\n });\n\n return visible;\n }\n\n /**\n * Document click handler which in case if event target is not\n * a descendant of provided container element,\n * invokes specfied in configuration callback.\n *\n * @param {HTMLElement} container\n * @param {Object} config\n * @param {EventObject} e\n */\n function onOuterClick(container, config, e) {\n var target = e.target,\n callback = config.callback;\n\n if (container === target || container.contains(target)) {\n return;\n }\n\n if (config.onlyIfVisible) {\n if (!_.isNull(container.offsetParent) && isVisible(container)) {\n callback();\n }\n } else {\n callback();\n }\n }\n\n /**\n * Prepares configuration for the binding based\n * on a default properties and provided options.\n *\n * @param {(Object|Function)} [options={}]\n * @returns {Object}\n */\n function buildConfig(options) {\n var config = {};\n\n if (_.isFunction(options)) {\n options = {\n callback: options\n };\n } else if (!_.isObject(options)) {\n options = {};\n }\n\n return _.extend(config, defaults, options);\n }\n\n ko.bindingHandlers.outerClick = {\n\n /**\n * Initializes outer click binding.\n */\n init: function (element, valueAccessor) {\n var config = buildConfig(valueAccessor()),\n outerClick = onOuterClick.bind(null, element, config),\n isTouchDevice = typeof document.ontouchstart !== 'undefined';\n\n if (isTouchDevice) {\n $(document).on('touchstart', outerClick);\n\n ko.utils.domNodeDisposal.addDisposeCallback(element, function () {\n $(document).off('touchstart', outerClick);\n });\n } else {\n $(document).on('click', outerClick);\n\n ko.utils.domNodeDisposal.addDisposeCallback(element, function () {\n $(document).off('click', outerClick);\n });\n }\n }\n };\n\n renderer.addAttribute('outerClick');\n});\n","Magento_Ui/js/lib/knockout/bindings/keyboard.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n '../template/renderer'\n], function (ko, renderer) {\n 'use strict';\n\n ko.bindingHandlers.keyboard = {\n\n /**\n * Attaches keypress handlers to element\n * @param {HTMLElement} el - Element, that binding is applied to\n * @param {Function} valueAccessor - Function that returns value, passed to binding\n * @param {Object} allBindings - all bindings object\n * @param {Object} viewModel - reference to viewmodel\n */\n init: function (el, valueAccessor, allBindings, viewModel) {\n var map = valueAccessor();\n\n ko.utils.registerEventHandler(el, 'keyup', function (e) {\n var callback = map[e.keyCode];\n\n if (callback) {\n return callback.call(viewModel, e);\n }\n });\n }\n };\n\n renderer.addAttribute('keyboard');\n});\n","Magento_Ui/js/lib/knockout/bindings/fadeVisible.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'ko'\n], function ($, ko) {\n 'use strict';\n\n ko.bindingHandlers.fadeVisible = {\n /**\n * Initially set the element to be instantly visible/hidden depen
2ding on the value.\n *\n * @param {HTMLElement} element\n * @param {Function} valueAccessor\n */\n init: function (element, valueAccessor) {\n var value = valueAccessor();\n\n // Use \"unwrapObservable\" so we can handle values that may or may not be observable\n $(element).toggle(ko.unwrap(value));\n },\n\n /**\n * Whenever the value subsequently changes, slowly fade the element in or out.\n *\n * @param {HTMLElement} element\n * @param {Function} valueAccessor\n */\n update: function (element, valueAccessor) {\n var value = valueAccessor();\n\n ko.unwrap(value) ? $(element).fadeIn() : $(element).fadeOut();\n }\n };\n});\n","Magento_Ui/js/lib/knockout/template/observable_source.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/**\n * Is being used by knockout template engine to store template to.\n */\ndefine([\n 'ko',\n 'uiClass'\n], function (ko, Class) {\n 'use strict';\n\n return Class.extend({\n\n /**\n * Initializes templateName, _data, nodes properties.\n *\n * @param {template} template - identifier of template\n */\n initialize: function (template) {\n this.templateName = template;\n this._data = {};\n this.nodes = ko.observable([]);\n },\n\n /**\n * Data setter. If only one arguments passed, returns corresponding value.\n * Else, writes into it.\n * @param {String} key - key to write to or to read from\n * @param {*} value\n * @return {*} - if 1 arg provided, returnes _data[key] property\n */\n data: function (key, value) {\n if (arguments.length === 1) {\n return this._data[key];\n }\n\n this._data[key] = value;\n }\n });\n});\n","Magento_Ui/js/lib/knockout/template/loader.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 var licenseRegExp = /<!--[\\s\\S]*?-->/,\n defaultPlugin = 'text',\n defaultExt = 'html';\n\n /**\n * Checks of provided string contains a file extension.\n *\n * @param {String} str - String to be checked.\n * @returns {Boolean}\n */\n function hasFileExtension(str) {\n return !!~str.indexOf('.') && !!str.split('.').pop();\n }\n\n /**\n * Checks if provided string contains a requirejs's plugin reference.\n *\n * @param {String} str - String to be checked.\n * @returns {Boolean}\n */\n function hasPlugin(str) {\n return !!~str.indexOf('!');\n }\n\n /**\n * Checks if provided string is a full path to the file.\n *\n * @param {String} str - String to be checked.\n * @returns {Boolean}\n */\n function isFullPath(str) {\n return !!~str.indexOf('://');\n }\n\n /**\n * Removes license comment from the provided string.\n *\n * @param {String} content - String to be processed.\n * @returns {String}\n */\n function removeLicense(content) {\n return content.replace(licenseRegExp, function (match) {\n return ~match.indexOf('/**') ? '' : match;\n });\n }\n\n return {\n\n /**\n * Attempts to extract template by provided path from\n * a DOM element and falls back to a file loading if\n * none of the DOM nodes was found.\n *\n * @param {String} path - Path to the template or a DOM selector.\n * @returns {jQueryPromise}\n */\n loadTemplate: function (path) {\n var content = this.loadFromNode(path),\n defer;\n\n if (content) {\n defer = $.Deferred();\n\n defer.resolve(content);\n\n return defer.promise();\n }\n\n return this.loadFromFile(path);\n },\n\n /**\n * Loads template from external file by provided\n * path, which will be preliminary formatted.\n *\n * @param {String} path - Path to the template.\n * @returns {jQueryPromise}\n */\n loadFromFile: function (path) {\n var loading = $.Deferred();\n\n path = this.formatPath(path);\n\n require([path], function (template) {\n template = removeLicense(template);\n loading.resolve(template);\n }, function (err) {\n loading.reject(err);\n });\n\n return loading.promise();\n },\n\n /**\n * Attempts to extract content of a node found by provided selector.\n *\n * @param {String} selector - Node's selector (not necessary valid).\n * @returns {String|Boolean} If specified node doesn't exists\n * 'false' will be returned, otherwise returns node's content.\n */\n loadFromNode: function (selector) {\n var node;\n\n try {\n node =\n document.getElementById(selector) ||\n document.querySelector(selector);\n\n return node ? node.innerHTML : false;\n } catch (e) {\n return false;\n }\n },\n\n /**\n * Adds requirejs's plugin and file extension to\n * to the provided string if it's necessary.\n *\n * @param {String} path - Path to be processed.\n * @returns {String} Formatted path.\n */\n formatPath: function (path) {\n var result = path;\n\n if (!hasPlugin(path)) {\n result = defaultPlugin + '!' + result;\n }\n\n if (isFullPath(path)) {\n return result;\n }\n\n if (!hasFileExtension(path)) {\n result += '.' + defaultExt;\n }\n\n return result.replace(/^([^\\/]+)/g, '$1/template');\n }\n };\n});\n","Magento_Ui/js/lib/knockout/template/renderer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'underscore',\n './loader'\n], function ($, _, loader) {\n 'use strict';\n\n var colonReg = /\\\\:/g,\n attributes = {},\n elements = {},\n globals = [],\n renderer,\n preset;\n\n renderer = {\n\n /**\n * Loads template by provided path and\n * than converts it's content to html.\n *\n * @param {String} tmplPath - Path to the template.\n * @returns {jQueryPromise}\n */\n render: function (tmplPath) {\n var loadPromise = loader.loadTemplate(tmplPath);\n\n return loadPromise.then(renderer.parseTemplate);\n },\n\n /**\n * Parses provided string as html content\n * and returns an array of DOM elements.\n *\n * @param {String} html - String to be processed.\n * @returns {Array}\n */\n parseTemplate: function (html) {\n var fragment = document.createDocumentFragment();\n\n $(fragment).append(html);\n\n return renderer.normalize(fragment);\n },\n\n /**\n * Processes custom attributes and nodes of provided DOM element.\n *\n * @param {HTMLElement} content - Element to be processed.\n * @returns {Array} An array of content's child nodes.\n */\n normalize: function (content) {\n globals.forEac
2h(function (handler) {\n handler(content);\n });\n\n return _.toArray(content.childNodes);\n },\n\n /**\n * Adds new global content handler.\n *\n * @param {Function} handler - Function which will be invoked for\n * an every content passed to 'normalize' method.\n * @returns {Renderer} Chainable.\n */\n addGlobal: function (handler) {\n if (!_.contains(globals, handler)) {\n globals.push(handler);\n }\n\n return this;\n },\n\n /**\n * Removes specified global content handler.\n *\n * @param {Function} handler - Handler to be removed.\n * @returns {Renderer} Chainable.\n */\n removeGlobal: function (handler) {\n var index = globals.indexOf(handler);\n\n if (~index) {\n globals.splice(index, 1);\n }\n\n return this;\n },\n\n /**\n * Adds new custom attribute handler.\n *\n * @param {String} id - Attribute identifier.\n * @param {(Object|Function)} [config={}]\n * @returns {Renderer} Chainable.\n */\n addAttribute: function (id, config) {\n var data = {\n name: id,\n binding: id,\n handler: renderer.handlers.attribute\n };\n\n if (_.isFunction(config)) {\n data.handler = config;\n } else if (_.isObject(config)) {\n _.extend(data, config);\n }\n\n data.id = id;\n attributes[id] = data;\n\n return this;\n },\n\n /**\n * Removes specified attribute handler.\n *\n * @param {String} id - Attribute identifier.\n * @returns {Renderer} Chainable.\n */\n removeAttribute: function (id) {\n delete attributes[id];\n\n return this;\n },\n\n /**\n * Adds new custom node handler.\n *\n * @param {String}
2 id - Node identifier.\n * @param {(Object|Function)} [config={}]\n * @returns {Renderer} Chainable.\n */\n addNode: function (id, config) {\n var data = {\n name: id,\n binding: id,\n handler: renderer.handlers.node\n };\n\n if (_.isFunction(config)) {\n data.handler = config;\n } else if (_.isObject(config)) {\n _.extend(data, config);\n }\n\n data.id = id;\n elements[id] = data;\n\n return this;\n },\n\n /**\n * Removes specified custom node handler.\n *\n * @param {String} id - Node identifier.\n * @returns {Renderer} Chainable.\n */\n removeNode: function (id) {\n delete elements[id];\n\n return this;\n },\n\n /**\n * Checks if provided DOM element is a custom node.\n *\n * @param {HTMLElement} node - Node to be checked.\n * @returns {Boolean}\n */\n isCustomNode: function (node) {\n return _.some(elements, function (elem) {\n return elem.name.toUpperCase() === node.tagName;\n });\n },\n\n /**\n * Processes custom attributes of a content's child nodes.\n *\n * @param {HTMLElement} content - DOM element to be processed.\n */\n processAttributes: function (content) {\n var repeat;\n\n repeat = _.some(attributes, function (attr) {\n var attrName = attr.name,\n nodes = content.querySelectorAll('[' + attrName + ']'),\n handler = attr.handler;\n\n return _.toArray(nodes).some(function (node) {\n var data = node.getAttribute(attrName);\n\n return handler(node, data, attr) === true;\n });\n });\n\n if (repeat) {\n renderer.processAttributes(content);\n }\n },\n\n /**\n * Processes custom nodes of a provided content.\n *\n * @param {HTMLElement} content - DOM element to be processed.\n */\n processNodes: function (content) {\n var repeat;\n\n repeat = _.some(elements, function (element) {\n var nodes = content.querySelectorAll(element.name),\n handler = element.handler;\n\n return _.toArray(nodes).some(function (node) {\n var data = node.getAttribute('args');\n\n return handler(node, data, element) === true;\n });\n });\n\n if (repeat) {\n renderer.processNodes(content);\n }\n },\n\n /**\n * Wraps provided string in curly braces if it's necessary.\n *\n * @param {String} args - String to be wrapped.\n * @returns {String} Wrapped string.\n */\n wrapArgs: function (args) {\n if (~args.indexOf('\\\\:')) {\
2n args = args.replace(colonReg, ':');\n } else if (~args.indexOf(':') && !~args.indexOf('}')) {\n args = '{' + args + '}';\n }\n\n return args;\n },\n\n /**\n * Wraps child nodes of provided DOM element\n * with knockout's comment tag.\n *\n * @param {HTMLElement} node - Node whose children should be wrapped.\n * @param {String} binding - Name of the binding for the opener comment tag.\n * @param {String} data - Data associated with a binding.\n *\n * @example\n * <div id=\"example\"><span/></div>\n * wrapChildren(document.getElementById('example'), 'foreach', 'data');\n * =>\n * <div id=\"example\">\n * <!-- ko foreach: data -->\n * <span></span>\n * <!-- /ko -->\n * </div>\n */\n wrapChildren: function (node, binding, data) {\n var tag = this.createComment(binding, data),\n $node = $(node);\n\n $node.prepend(tag.open);\n $node.append(tag.close);\n },\n\n /**\n * Wraps specified node with knockout's comment tag.\n *\n * @param {HTMLElement} node - Node to be wrapped.\n * @param {String} binding - Name of the binding for the opener comment tag.\n * @param {String} data - Data associated with a binding.\n *\n * @example\n * <div id=\"example\"></div>\n * wrapNode(document.getElementById('example'), 'foreach', 'data');\n * =>\n * <!-- ko foreach: data -->\n * <div id=\"example\"></div>\n * <!-- /ko -->\n */\n wrapNode: function (node, binding, data) {\n var tag = this.createComment(binding, data),\n $node = $(node);\n\n $node.before(tag.open);\n $node.after(tag.close);\n },\n\n /**\n * Creates knockouts' comment tag for the provided binding.\n *\n * @param {String} binding - Name of the binding.\n * @param {String} data - Data associated with a binding.\n * @returns {Object} Object with an open and close comment elements.\n */\n createComment: function (binding, data) {\n return {\n open: document.createComment(' ko ' + binding + ': ' + data + ' '),\n close: document.createComment(' /ko ')\n };\n }\n };\n\n renderer.handlers = {\n\n /**\n * Basic node handler. Replaces custom nodes\n * with a corresponding knockout's comment tag.\n *\n * @param {HTMLElement} node - Node to be processed.\n * @param {String} data\n * @param {Object} element\n * @returns {Boolean} True\n *\n * @example Sample syntaxes conversions.\n * <with args=\"model\">\n * <span/>\n * </with>\n * =>\n * <!-- ko with: model-->\n * <span/>\n * <!-- /ko -->\n */\n node: function (node, data, element) {\n data = renderer.wrapArgs(data);\n\n renderer.wrapNode(node, element.binding, data);\n $(node).replaceWith(node.childNodes);\n\n return true;\n },\n\n /**\n * Base attribute handler. Replaces custom attributes with\n * a corresponding knockouts' data binding.\n *\n * @param {HTMLElement} node - Node to be processed.\n * @param {String} data - Data associated with a binding.\n * @param {Object} attr - Attribute definition.\n *\n * @example Sample syntaxes conversions.\n * <div text=\"label\"></div>\n * =>\n * <div data-bind=\"text: label\"></div>\n */\n attribute: function (node, data, attr) {\n data = renderer.wrapArgs(data);\n\n renderer.bindings.add(node, attr.binding, data);\n node.removeAttribute(attr.name);\n },\n\n /**\n * Wraps provided node with a knockouts' comment tag.\n *\n * @param {HTMLElement} node - Node that will be wrapped.\n * @param {String} data - Data associated with a binding.\n * @param {Object} attr - Attribute definition.\n *\n * @example\n * <div outereach=\"data\" class=\"test\"></div>\n * =>\n * <!-- ko foreach: data -->\n * <div class=\"test\"></div>\n * <!-- /ko -->\n */\n wrapAttribute: function (node, data, attr) {\n data = renderer.wrapArgs(data);\n\n renderer.wrapNode(node, attr.binding, data);\n node.removeAttribute(attr.name);\n }\n };\n\n renderer.bindings = {\n\n /**\n * Appends binding string to the current\n * 'data-bind' attribute of provided node.\n *\n * @param {HTMLElement} node - DOM element whose 'data-bind' attribute will be extended.\n * @param {String} name - Name of a binding.\n * @param {String} data - Data associated with the binding.\n */\n add: function (node, name, data) {\n var bindings = this.get(node);\n\n if (bindings) {\n bindings += ', ';\n }\n\n bindings += name;
2\n\n if (data) {\n bindings += ': ' + data;\n }\n\n this.set(node, bindings);\n },\n\n /**\n * Extracts value of a 'data-bind' attribute from provided node.\n *\n * @param {HTMLElement} node - Node whose attribute to be extracted.\n * @returns {String}\n */\n get: function (node) {\n return node.getAttribute('data-bind') || '';\n },\n\n /**\n * Sets 'data-bind' attribute of the specified node\n * to the provided value.\n *\n * @param {HTMLElement} node - Node whose attribute will be altered.\n * @param {String} bindings - New value of 'data-bind' attribute.\n */\n set: function (node, bindings) {\n node.setAttribute('data-bind', bindings);\n }\n };\n\n renderer\n .addGlobal(renderer.processAttributes)\n .addGlobal(renderer.processNodes);\n\n /**\n * Collection of default binding conversions.\n */\n preset = {\n nodes: _.object([\n 'if',\n 'text',\n 'with',\n 'scope',\n 'ifnot',\n 'foreach',\n 'component'\n ], Array.prototype),\n attributes: _.object([\n 'css',\n 'attr',\n 'html',\n 'with',\n 'text',\n 'click',\n 'event',\n 'submit',\n 'enable',\n 'disable',\n 'options',\n 'visible',\n 'template',\n 'hasFocus',\n 'textInput',\n 'component',\n 'uniqueName',\n 'optionsText',\n 'optionsValue',\n 'checkedValue',\n 'selectedOptions'\n ], Array.prototype)\n };\n\n _.extend(preset.attributes, {\n if: renderer.handlers.wrapAttribute,\n ifnot: renderer.handlers.wrapAttribute,\n innerif: {\n binding: 'if'\n },\n innerifnot: {\n binding: 'ifnot'\n },\n outereach: {\n binding: 'foreach',\n handler: renderer.handlers.wrapAttribute\n },\n foreach: {\n name: 'each'\n },\n value: {\n name: 'ko-value'\n },\n style: {\n name: 'ko-style'\n },\n checked: {\n name: 'ko-checked'\n },\n disabled: {\n name: 'ko-disabled',\n binding: 'disable'\n },\n focused: {\n name: 'ko-focused',\n binding: 'hasFocus'\n },\n\n /**\n * Custom 'render' attrobute handler function. Wraps child elements\n * of a node with knockout's 'ko template:' comment tag.\n *\n * @param {HTMLElement} node - Element to be processed.\n * @param {String} data - Data specified in 'render' attribute of a node.\n */\n render: function (node, data) {\n data = data || 'getTemplate()';\n data = renderer.wrapArgs(data);\n\n renderer.wrapChildren(node, 'template', data);\n node.removeAttribute('render');\n }\n });\n\n _.extend(preset.nodes, {\n foreach: {\n name: 'each'\n },\n\n /**\n * Custom 'render' node handler function.\n * Replaces node with knockout's 'ko template:' comment tag.\n *\n * @param {HTMLElement} node - Element to be processed.\n * @param {String} data - Data specified in 'args' attribute of a node.\n */\n render: function (node, data) {\n data = data || 'getTemplate()';\n data = renderer.wrapArgs(data);\n\n renderer.wrapNode(node, 'template', data);\n $(node).replaceWith(node.childNodes);\n }\n });\n\n _.each(preset.attributes, function (data, id) {\n renderer.addAttribute(id, data);\n });\n\n _.each(preset.nodes, function (data, id) {\n renderer.addNode(id, data);\n });\n\n return renderer;\n});\n","Magento_Ui/js/lib/knockout/template/engine.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'ko',\n 'underscore',\n './observable_source',\n './renderer',\n '../../logger/console-logger'\n], function (ko, _, Source, renderer, consoleLogger) {\n 'use strict';\n\n var RemoteTemplateEngine,\n NativeTemplateEngine = ko.nativeTemplateEngine,\n sources = {};\n\n /**\n * Remote template engine class. Is used to be able to load remote templates via knockout template binding.\n */\n RemoteTemplateEngine = function () {};\n\n /**\n * Creates unique template identifier based on template name and it's extenders (optional)\n * @param {String} templateName\n * @return {String} - unique template identifier\n */\n function createTemplateIdentifier(templateName) {\n return templateName;\n }\n\n RemoteTemplateEngine.prototype = new NativeTemplateEngine;\n RemoteTemplateEngine.prototype.constructor = RemoteTemplateEngine;\n\n /**\n * Overrided method of native knockout template engine.\n * Caches template after it's unique name and renders in once.\n * If template name is not typeof string, delegates work to knockout.templateSources.anonymousTemplate.\n * @param {*} template\n * @param {HTMLElement} templateDocument - document\n * @param {Object} options - options, passed to template binding\n * @param {ko.bindingContext} bindingContext\n * @returns {TemplateSource} Object with methods 'nodes' and 'data'.\n */\n RemoteTemplateEngine.prototype.makeTemplateSource = function (template, templateDocument, options, bindingContext) {\n var source,\n templateId;\n\n if (typeof template === 'string') {\n templateId = createTemplateIdentifier(template);\n source = sources[templateId];\n\n if (!source) {\n source = new Source(template);\n source.requestedBy = bindingContext.$data.name;\n sources[templateId] = source;\n\n consoleLogger.info('templateStartLoading', {\n template: templateId,\n component: bindingContext.$data.name\n });\n\n renderer.render(template).done(function (rendered) {\n consoleLogger.info('templateLoadedFromServer', {\n template: templateId,\n component: bindingContext.$data.name\n });\n source.nodes(rendered);\n }).fail(function () {\n consoleLogger.error('templateLoadingFail', {\n template: templateId,\n component: bindingContext.$data.name\n });\n });\n }\n\n if (source.requestedBy !== bindingContext.$data.name) {\n consoleLogger.info('templateLoadedFromCac
2he', {\n template: templateId,\n component: bindingContext.$data.name\n });\n }\n\n return source;\n } else if (template.nodeType === 1 || template.nodeType === 8) {\n source = new ko.templateSources.anonymousTemplate(template);\n\n return source;\n }\n\n throw new Error('Unknown template type: ' + template);\n };\n\n /**\n * Overrided method of native knockout template engine.\n * Should return array of html elements.\n * @param {TemplateSource} templateSource - object with methods 'nodes' and 'data'.\n * @return {Array} - array of html elements\n */\n RemoteTemplateEngine.prototype.renderTemplateSource = function (templateSource) {\n var nodes = templateSource.nodes();\n\n return ko.utils.cloneNodes(nodes);\n };\n\n /**\n * Overrided method of native knockout template engine.\n * Created in order to invoke makeTemplateSource method with custom set of params.\n * @param {*} template - template identifier\n * @param {ko.bindingContext} bindingContext\n * @param {Object} options - options, passed to template binding\n * @param {HTMLElement} templateDocument - document\n * @return {Array} - array of html elements\n */\n RemoteTemplateEngine.prototype.renderTemplate = function (template, bindingContext, options, templateDocument) {\n var templateSource = this.makeTemplateSource(template, templateDocument, options, bindingContext);\n\n return this.renderTemplateSource(templateSource, bindingContext, options);\n };\n\n return new RemoteTemplateEngine;\n});\n","Magento_Ui/js/lib/knockout/extender/bound-nodes.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global WeakMap */\ndefine([\n 'ko',\n 'underscore',\n 'mage/utils/wrapper',\n 'uiEvents',\n 'es6-collections'\n], function (ko, _, wrapper, Events) {\n 'use strict';\n\n var nodesMap = new WeakMap();\n\n /**\n * Returns a array of nodes associated with a specified model.\n *\n * @param {Object} model\n * @returns {Undefined|Array}\n */\n function getBounded(model) {\n return nodesMap.get(model);\n }\n\n /**\n * Removes specified node to models' associations list, if it's\n * a root node (node is not a descendant of any previously added nodes).\n * Triggers 'addNode' event.\n *\n * @param {Object} model\n * @param {HTMLElement} node\n */\n function addBounded(model, node) {\n var nodes = getBounded(model),\n isRoot;\n\n if (!nodes) {\n nodesMap.set(model, [node]);\n\n Events.trigger.call(model, 'addNode', node);\n\n return;\n }
2\n\n isRoot = nodes.every(function (bounded) {\n return !bounded.contains(node);\n });\n\n if (isRoot) {\n nodes.push(node);\n\n Events.trigger.call(model, 'addNode', node);\n }\n }\n\n /**\n * Removes specified node from models' associations list.\n * Triggers 'removeNode' event.\n *\n * @param {Object} model\n * @param {HTMLElement} node\n */\n function removeBounded(model, node) {\n var nodes = getBounded(model),\n index;\n\n if (!nodes) {\n return;\n }\n\n index = nodes.indexOf(node);\n\n if (~index) {\n nodes.splice(index, 0);\n\n Events.trigger.call(model, 'removeNode', node);\n }\n\n if (!nodes.length) {\n nodesMap.delete(model);\n }\n }\n\n /**\n * Returns node's first sibling of 'element' type within the common component scope\n *\n * @param {HTMLElement} node\n * @param {*} data\n * @returns {HTMLElement}\n */\n function getElement(node, data) {\n var elem;\n\n while (node.nextElementSibling) {\n node = node.nextElementSibling;\n\n if (node.nodeType === 1 && ko.dataFor(node) === data) {\n elem = node;\n break;\n }\n }\n\n return elem;\n }\n\n wrapper.extend(ko, {\n\n /**\n * Extends kncokouts' 'applyBindings'\n * to track nodes associated with model.\n *\n * @param {Function} orig - Original 'applyBindings' method.\n * @param {Object} ctx\n * @param {HTMLElement} node - Original 'applyBindings' method.\n */\n applyBindings: function (orig, ctx, node) {\n var result = orig(),\n data = ctx && (ctx.$data || ctx);\n\n if (node && node.nodeType === 8) {\n node = getElement(node, data);\n }\n\n if (!node || node.nodeType !== 1) {\n return result;\n }\n\n if (data && data.registerNodes) {\n addBounded(data, node);\n }\n\n return result;\n },\n\n /**\n * Extends kncokouts' cleanNode\n * to track nodes associated with model.\n *\n * @param {Function} orig - Original 'cleanNode' method.\n * @param {HTMLElement} node - Original 'cleanNode' method.\n */\n cleanNode: function (orig, node) {\n var result = orig(),\n data;\n\n if (node.nodeType !== 1) {\n return result;\n }\n\n data = ko.dataFor(node);\n\n if (data && data.registerNodes) {\n removeBounded(data, node);\n }\n\n return result;\n }\n });\n\n return {\n\n /**\n * Returns root nodes associated with a model. If callback is provided,\n * will iterate through all of the present nodes triggering callback\n * for each of it. Also it will subscribe to the 'addNode' event.\n *\n * @param {Object} model\n * @param {Function} [callback]\n * @returns {Array|Undefined}\n */\n get: function (model, callback) {\n var nodes = getBounded(model) || [];\n\n if (!_.isFunction(callback)) {\n return nodes;\n }\n\n nodes.forEach(function (node) {\n callback(node);\n });\n\n this.add.apply(this, arguments);\n },\n\n /**\n * Subscribes to adding of nodes associated with a model.\n *\n * @param {Object} model\n */\n add: function (model) {\n var args = _.toArray(arguments).slice(1);\n\n args.unshift('addNode');\n\n Events.on.apply(model, args);\n },\n\n /**\n * Subscribes to removal of nodes associated with a model.\n *\n * @param {Object} model\n */\n remove: function (model) {\n var args = _.toArray(arguments).slice(1);\n\n args.unshift('removeNode');\n\n Events.on.apply(model, args);\n },\n\n /**\n * Removes subscriptions from the model.\n *\n * @param {Object} model\n */\n off: function (model) {\n var args = _.toArray(arguments).slice(1);\n\n Events.off.apply(model, args);\n }\n };\n});\n","Magento_Ui/js/lib/knockout/extender/observable_array.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'underscore'\n], function (ko, _) {\n 'use strict';\n\n /**\n * Iterator function.\n *\n * @param {String} callback\n * @param {Array} args\n * @param {Object} elem\n * @returns {*}\n */\n function iterator(callback, args, elem) {\n callback = elem[callback];\n\n if (_.isFunction(callback)) {\n return callback.apply(elem, args
2);\n }\n\n return callback;\n }\n\n /**\n * Wrapper function.\n *\n * @param {String} method\n * @returns {Function}\n */\n function wrapper(method) {\n return function (iteratee) {\n var callback = iteratee,\n elems = this(),\n args = _.toArray(arguments);\n\n if (_.isString(iteratee)) {\n callback = iterator.bind(null, iteratee, args.slice(1));\n\n args.unshift(callback);\n }\n\n args.unshift(elems);\n\n return _[method].apply(_, args);\n };\n }\n\n _.extend(ko.observableArray.fn, {\n each: wrapper('each'),\n\n map: wrapper('map'),\n\n filter: wrapper('filter'),\n\n some: wrapper('some'),\n\n every: wrapper('every'),\n\n groupBy: wrapper('groupBy'),\n\n sortBy: wrapper('sortBy'),\n\n /**\n * Wrapper for underscore findWhere function.\n *\n * @param {Object} properties\n * @return {Object}\n */\n findWhere: function (properties) {\n return _.findWhere(this(), properties);\n },\n\n /**\n * Wrapper for underscore contains function.\n *\n * @param {*} value\n * @return {Boolean}\n */\n contains: function (value) {\n return _.contains(this(), value);\n },\n\n /**\n * Inverse contains call.\n *\n * @return {Boolean}\n */\n hasNo: function () {\n return !this.contains.apply(this, arguments);\n },\n\n /**\n * Getter for length property.\n *\n * @return {Number}\n */\n getLength: function () {\n return this().length;\n },\n\n /**\n * Create object with keys that gets from each object property.\n *\n * @return {Object}\n */\n indexBy: function (key) {\n return _.indexBy(this(), key);\n },\n\n /**\n * Returns a copy of the array with all instances of the values removed.\n *\n * @return {Array}\n */\n without: function () {\n var args = Array.prototype.slice.call(arguments);\n\n args.unshift(this());\n\n return _.without.apply(_, args);\n },\n\n /**\n * Returns the first element of an array.\n *\n * @return {*}\n */\n first: function () {\n return _.first(this());\n },\n\n /**\n * Returns the last element of an array\n *\n * @return {*}\n */\n last: function () {\n return _.last(this());\n },\n\n /**\n * Iterate and pick provided properties.\n *\n * @return {Array}\n */\n pluck: function () {\n var args = Array.prototype.slice.call(arguments);\n\n args.unshift(this());\n\n return _.pluck.apply(_, args);\n }\n });\n});\n","Magento_Ui/js/lib/core/class.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'underscore',\n 'mageUtils',\n 'mage/utils/wrapper'\n], function (_, utils, wrapper) {\n 'use strict';\n\n var Class;\n\n /**\n * Returns property of an object if\n * it's his own property.\n *\n * @param {Object} obj - Object whose property should be retrieved.\n * @param {String} prop - Name of the property.\n * @returns {*} Value of the property or false.\n */\n function getOwn(obj, prop) {\n return _.isObject(obj) && obj.hasOwnProperty(prop) && obj[prop];\n }\n\n /**\n * Creates constructor function which allows\n * initialization without usage of a 'new' operator.\n *\n * @param {Object} protoProps - Prototypal properties of a new constructor.\n * @param {Function} constructor\n * @returns {Function} Created constructor.\n */\n function createConstructor(protoProps, constructor) {\n var UiClass = constructor;\n\n if (!UiClass) {\n\n /**\n * Default constructor function.\n */\n UiClass = function () {\n var obj = this;\n\n if (!_.isObject(obj) || Object.getPrototypeOf(obj) !== UiClass.prototype) {\n obj = Object.create(UiClass.prototype);\n }\n\n obj.initialize.apply(obj, arguments);\n\n return obj;\n };\n }\n\n UiClass.prototype = protoProps;\n UiClass.prototype.constructor = UiClass;\n\n return UiClass;\n }\n\n Class = createConstructor({\n\n /**\n * Entry point to the initialization of constructors' instance.\n *\n * @param {Object} [options={}]\n * @returns {Class} Chainable.\n */\n initialize: function (options) {\n this.initConfig(options);\n\n return this;\n },\n\n /**\n * Recursively extends data specified in constructors' 'defaults'\n * property with provided options object. Evaluates resulting\n * object using string templates (see: mage/utils/template.js).\n *\n * @param {Object} [options={}]\n * @returns {Class} Chainable.\n */\n initConfig: function (options) {\n var defaults = this.constructor.defaults,\n config = utils.extend({}, defaults, options || {}),\n ignored = config.ignoreTmpls || {},\n cached = utils.omit(config, ignored);\n\n config = utils.template(config, this, false, true);\n\n _.each(cached, function (value, key) {\n utils.nested(config, key, value);\n });\n\n return _.extend(this, config);\n }\n });\n\n _.extend(Class, {\n defaults: {\n ignoreTmpls: {\n templates: true\n }\n },\n\n /**\n * Creates new constructor based on a current prototype properties,\n * extending them with properties specified in 'exender' object.\n *\n * @param {Object} [extender={}]\n * @returns {Function} New constructor.\n */\n extend: function (extender) {\n var parent = this,\n parentProto = parent.prototype,\n childProto = Object.create(parentProto),\n child = createConstructor(childProto, getOwn(extender, 'constructor')),\n defaults;\n\n extender = extender || {};\n defaults = extender.defaults;\n\n delete extender.defaults;\n\n _.each(extender, function (method, name) {\n childProto[name] = wrapper.wrapSuper(parentProto[name], method);\n });\n\n child.defaults = utils.extend({}, parent.defaults || {});\n\n if (defaults) {\n utils.extend(child.defaults, defaults);\n extender.defaults = defaults;\n }\n\n return _.extend(child, {\n __super__: parentProto,\n extend: parent.extend\n });\n }\n });\n\n return Class;\n});\n","Magento_Ui/js/lib/core/collection.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'mageUtils',\n 'uiRegistry',\n 'uiElement'\n], function (_, utils, registry, Element) {\n 'use strict';\n\n /**\n * Removes non plain object items from the specfied array.\n *\n * @param {Array} container - Array whose value should be filtered.\n * @returns {Array}\n */\n function compact(container) {\n return container.filter(utils.isObject);\n }\n\n return Element.extend({\n defaults: {\n template: 'ui/collection',\n _elems: [],\n ignoreTmpls: {\n childDefaults: true\n }\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Model}
2 Chainable.\n */\n initObservable: function () {\n this._super()\n .observe({\n elems: []\n });\n\n return this;\n },\n\n /**\n * Called when another element was added to current component.\n *\n * @param {Object} elem - Instance of an element that was added.\n * @returns {Collection} Chainable.\n */\n initElement: function (elem) {\n elem.initContainer(this);\n\n return this;\n },\n\n /**\n * Returns instance of a child found by provided index.\n *\n * @param {String} index - Index of a child.\n * @returns {Object}\n */\n getChild: function (index) {\n return _.findWhere(this.elems(), {\n index: index\n });\n },\n\n /**\n * Requests specified components to insert\n * them into 'elems' array starting from provided position.\n *\n * @param {(String|Array)} elems - Name of the component to insert.\n * @param {Number} [position=-1] - Position at which to insert elements.\n * @returns {Collection} Chainable.\n */\n insertChild: function (elems, position) {\n var container = this._elems,\n insert = this._insert.bind(this),\n update;\n\n if (!Array.isArray(elems)) {\n elems = [elems];\n }\n\n elems.map(function (item) {\n return item.elem ?\n utils.insert(item.elem, container, item.position) :\n utils.insert(item, container, position);\n }
2).forEach(function (item) {\n if (item === true) {\n update = true;\n } else if (_.isString(item)) {\n registry.get(item, insert);\n } else if (utils.isObject(item)) {\n insert(item);\n }\n });\n\n if (update) {\n this._updateCollection();\n }\n\n return this;\n },\n\n /**\n * Removes specified child from collection.\n *\n * @param {(Object|String)} elem - Child or index of a child to be removed.\n * @param {Boolean} skipUpdate - skip collection update when element to be destroyed.\n *\n * @returns {Collection} Chainable.\n */\n removeChild: function (elem, skipUpdate) {\n if (_.isString(elem)) {\n elem = this.getChild(elem);\n }\n\n if (elem) {\n utils.remove(this._elems, elem);\n\n if (!skipUpdate) {\n this._updateCollection();\n }\n }\n\n return this;\n },\n\n /**\n * Destroys collection children with its' elements.\n */\n destroyChildren: function () {\n this.elems.each(function (elem) {\n elem.destroy(true);\n });\n\n this._updateCollection();\n },\n\n /**\n * Clear data. Call method \"clear\"\n * in child components\n *\n * @returns {Object} Chainable.\n */\n clear: function () {\n var elems = this.elems();\n\n _.each(elems, function (elem) {\n if (_.isFunction(elem.clear)) {\n elem.clear();\n }\n }, this);\n\n return this;\n },\n\n /**\n * Checks if specified child exists in collection.\n *\n * @param {String} index - Index of a child.\n * @returns {Boolean}\n */\n hasChild: function (index) {\n return !!this.getChild(index);\n },\n\n /**\n * Creates 'async' wrapper for the specified child\n * using uiRegistry 'async' method and caches it\n * in a '_requested' components object.\n *\n * @param {String} index - Index of a child.\n * @returns {Function} Async module wrapper.\n */\n requestChild: function (index) {\n var name = this.formChildName(index);\n\n return this.requestModule(name);\n },\n\n /**\n * Creates complete child name based on a provided index.\n *\n * @param {String} index - Index of a child.\n * @returns {String}\n */\n formChildName: function (index) {\n return this.name + '.' + index;\n },\n\n /**\n * Retrieves requested region.\n * Creates region if it was not created yet\n *\n * @returns {ObservableArray}\n */\n getRegion: function (name) {\n var regions = this.regions = this.regions || {};\n\n if (!regions[name]) {\n regions[name] = [];\n\n this.observe.call(regions, name);\n }\n\n return regions[name];\n },\n\n /**\n * Replaces specified regions' data with a provided one.\n * Creates region if it was not created yet.\n *\n * @param {Array} items - New regions' data.\n * @param {String} name - Name of the region.\n * @returns {Collection} Chainable.\n */\n updateRegion: function (items, name) {\n this.getRegion(name)(items);\n\n return this;\n },\n\n /**\n * Destroys collection along with its' elements.\n */\n destroy: function () {\n this._super();\n\n this.elems.each('destroy');\n },\n\n /**\n * Inserts provided component into 'elems' array at a specified position.\n * @private\n *\n * @param {Object} elem - Element to insert.\n */\n _insert: function (elem) {\n var index = this._elems.indexOf(elem.name);\n\n if (~index) {\n this._elems[index] = elem;\n }\n\n this._updateCollection()\n .initElement(elem);\n },\n\n /**\n * Synchronizes multiple elements arrays with a core '_elems' container.\n * Performs elemets grouping by theirs 'displayArea' property.\n * @private\n *\n * @returns {Collection} Chainable.\n */\n _updateCollection: function () {\n var _elems = compact(this._elems),\n grouped;
2\n\n grouped = _elems.filter(function (elem) {\n return elem.displayArea && _.isString(elem.displayArea);\n });\n grouped = _.groupBy(grouped, 'displayArea');\n\n _.each(grouped, this.updateRegion, this);\n\n _.each(this.regions, function (items) {\n var hasObsoleteComponents = items().length && !_.intersection(_elems, items()).length;\n\n if (hasObsoleteComponents) {\n items.removeAll();\n }\n });\n\n this.elems(_elems);\n\n return this;\n },\n\n /**\n * Tries to call specified method of a current component,\n * otherwise delegates attempt to its' children.\n *\n * @param {String} target - Name of the method.\n * @param {...*} parameters - Arguments that will be passed to method.\n * @returns {*} Result of the method calls.\n */\n delegate: function (target) {\n var args = _.toArray(arguments);\n\n target = this[target];\n\n if (_.isFunction(target)) {\n return target.apply(this, args.slice(1));\n }\n\n return this._delegate(args);\n },\n\n /**\n * Calls 'delegate' method of all of it's children components.\n * @private\n *\n * @param {Array} args - An array of arguments to pass to the next delegation call.\n * @returns {Array} An array of delegation resutls.\n */\n _delegate: function (args) {\n var result;\n\n result = this.elems.map(function (elem) {\n var target;\n\n if (!_.isFunction(elem.delegate)) {\n target = elem[args[0]];\n\n if (_.isFunction(target)) {\n return target.apply(elem, args.slice(1));\n }\n } else {\n return elem.delegate.apply(elem, args);\n }\n });\n\n return _.flatten(result);\n }\n });\n});\n","Magento_Ui/js/lib/core/events.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global WeakMap, Map*/\ndefine([\n 'ko',\n 'underscore',\n 'es6-collections'\n], function (ko, _) {\n 'use strict';\n\n var eventsMap = new WeakMap();\n\n /**\n * Returns events map or a specific event\n * data associated with a provided object.\n *\n * @param {Object} obj - Key in the events weakmap.\n * @param {String} [name] - Name of the event.\n * @returns {Map|Array|Boolean}\n */\n function getEvents(obj, name) {\n var events = eventsMap.get(obj);\n\n if (!events) {\n return false;\n }\n\n return name ? events.get(name) : events;\n }\n\n /**\n * Adds new event handler.\n *\n * @param {Object} obj - Key in the events weakmap.\n * @param {String} ns - Callback namespace.\n * @param {Function} callback - Event callback.\n * @param {String} name - Name of the event.\n */\n function addHandler(obj, ns, callback, name) {\n var events = getEvents(obj),\n observable,\n data;\n\n observable = !ko.isObservable(obj[name]) ?\n ko.getObservable(obj, name) :\n obj[name];\n\n if (observable) {\n observable.subscribe(callback);\n\n return;\n }\n\n if (!events) {\n events = new Map();\n\n eventsMap.set(obj, events);\n }\n\n data = {\n callback: callback,\n ns: ns\n };\n\n events.has(name) ?\n events.get(name).push(data) :\n events.set(name, [data]);\n }\n\n /**\n * Invokes provided callbacks with a specified arguments.\n *\n * @param {Array} handlers\n * @param {Array} args\n * @returns {Boolean}\n */\n function trigger(handlers, args) {\n var bubble = true,\n callback;
2\n\n handlers.forEach(function (handler) {\n callback = handler.callback;\n\n if (callback.apply(null, args) === false) {\n bubble = false;\n }\n });\n\n return bubble;\n }\n\n return {\n\n /**\n * Calls callback when name event is triggered.\n * @param {String} events\n * @param {Function} callback\n * @param {Function} ns\n * @return {Object} reference to this\n */\n on: function (events, callback, ns) {\n var iterator;\n\n if (arguments.length < 2) {\n ns = callback;\n }\n\n iterator = addHandler.bind(null, this, ns);\n\n _.isObject(events) ?\n _.each(events, iterator) :\n iterator(callback, events);\n\n return this;\n },\n\n /**\n * Removed callback from listening to target event\n * @param {String} ns\n * @return {Object} reference to this\n */\n off: function (ns) {\n var storage = getEvents(this);\n\n if (!storage) {\n return this;\n }\n\n storage.forEach(function (handlers, name) {\n handlers = handlers.filter(function (handler) {\n return !ns ? false : handler.ns !== ns;\n });\n\n handlers.length ?\n storage.set(name, handlers) :\n storage.delete(name);\n });\n\n return this;\n },\n\n /**\n * Triggers event and executes all attached callbacks.\n *\n * @param {String} name - Name of the event to be triggered.\n * @returns {Boolean}\n */\n trigger: function (name) {\n var handlers,\n args;\n\n handlers = getEvents(this, name),\n args = _.toArray(arguments).slice(1);\n\n if (!handlers || !name) {\n return true;\n }\n\n return trigger(handlers, args);\n }\n };\n});\n","Magento_Ui/js/lib/core/element/element.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'ko',\n 'underscore',\n 'mageUtils',\n 'uiRegistry',\n 'uiEvents',\n 'uiClass',\n './links',\n '../storage/local'\n], function (ko, _, utils, registry, Events, Class, links) {\n 'use strict';\n\n var Element;\n\n /**\n * Creates observable property using knockouts'\n * 'observableArray' or 'observable' methods,\n * depending on a type of 'value' parameter.\n *\n * @param {Object} obj - Object to whom property belongs.\n * @param {String} key - Key of the property.\n * @param {*}
2 value - Initial value.\n */\n function observable(obj, key, value) {\n var method = Array.isArray(value) ? 'observableArray' : 'observable';\n\n if (_.isFunction(obj[key]) && !ko.isObservable(obj[key])) {\n return;\n }\n\n if (ko.isObservable(value)) {\n value = value();\n }\n\n ko.isObservable(obj[key]) ?\n obj[key](value) :\n obj[key] = ko[method](value);\n }\n\n /**\n * Creates observable property using 'track' method.\n *\n * @param {Object} obj - Object to whom property belongs.\n * @param {String} key - Key of the property.\n * @param {*} value - Initial value.\n */\n function accessor(obj, key, value) {\n if (_.isFunction(obj[key]) || ko.isObservable(obj[key])) {\n return;\n }\n\n obj[key] = value;\n\n if (!ko.es5.isTracked(obj, key)) {\n ko.track(obj, [key]);\n }\n }\n\n Element = _.extend({\n defaults: {\n _requested: {},\n containers: [],\n exports: {},\n imports: {},\n links: {},\n listens: {},\n name: '',\n ns: '${ $.name.split(\".\")[0] }',\n provider: '',\n registerNodes: true,\n source: null,\n statefull: {},\n template: '',\n tracks: {},\n storageConfig: {\n provider: 'localStorage',\n namespace: '${ $.name }',\n path: '${ $.storageConfig.provider }:${ $.storageConfig.namespace }'\n },\n maps: {\n imports: {},\n exports: {}\n },\n modules: {\n storage: '${ $.storageConfig.provider }'\n }\n },\n\n /**\n * Initializes model instance.\n *\n * @returns {Element} Chainable.\n */\n initialize: function () {\n this._super()\n .initObservable()\n .initModules()\n .initStatefull()\n .initLinks()\n .initUnique();\n\n return this;\n },\n\n /**\n * Initializes observable properties.\n *\n * @returns {Element} Chainable.\n */\n initObservable: function () {\n _.each(this.tracks, function (enabled, key) {\n if (enabled) {\n this.track(key);\n }\n }, this);\n\n return this;\n },\n\n /**\n * Parses 'modules' object and creates\n * async wrappers for specified components.\n *\n * @returns {Element} Chainable.\n */\n initModules: function () {\n _.each(this.modules, function (name, property) {\n if (name) {\n this[property] = this.requestModule(name);\n }\n }, this);\n\n if (!_.isFunction(this.source)) {\n this.source = registry.get(this.provider);\n }\n\n return this;\n },\n\n /**\n * Called when current element was injected to another component.\n *\n * @param {Object} parent - Instance of a 'parent' component.\n * @returns {Collection} Chainable.\n */\n initContainer: function (parent) {\n this.containers.push(parent);\n\n return this;\n },\n\n /**\n * Initializes statefull properties\n * based on the keys of 'statefull' object.\n *\n * @returns {Element} Chainable.\n */\n initStatefull: function () {\n _.each(this.statefull, function (path, key) {\n if (path) {\n this.setStatefull(key, path);\n }\n }, this);\n\n return this;\n },\n\n /**\n * Initializes links between properties.\n *\n * @returns {Element} Chainbale.\n */\n initLinks: function () {\n return this.setListeners(this.listens)\n .setLinks(this.links, 'imports')\n .setLinks(this.links, 'exports')\n .setLinks(this.exports, 'exports')\n .setLinks(this.imports, 'imports');\n },\n\n /**\n * Initializes listeners of the unique property.\n *\n * @returns {Element} Chainable.\n */\n initUnique: function () {\n var update = this.onUniqueUpdate.bind(this),\n uniqueNs = this.uniqueNs;\n\n this.hasUnique = this.uniqueProp && uniqueNs;\n\n if (this.hasUnique) {\n this.source.on(uniqueNs, update, this.name);\n }\n\n return this;\n },\n\n /**\n * Makes specified property to be stored automatically.\n *\n * @param {String} key - Name of the property\n * that will be stored.\n * @param {String} [path=key] - Path to the property in storage.\n * @returns {Element} Chainable.\n */\n setStatefull: function (key, path) {\n var link = {};\n\n path = !_.isString(path) || !path ? key : path;\n link[key] = this.storageConfig.path + '.' + path;\n\n this.setLinks(link, 'imports')\n .setLinks(link, 'exports');\n\n return this;\n },\n\n /**\n * Updates property specified in uniqueNs\n * if elements' unique property is set to 'true'.\n *\n * @returns {Element} Chainable.\n */\n setUnique: function () {\n var property = this.uniqueProp;\n\n if (this[property]()) {\n this.source.set(this.uniqueNs, this.name);\n }\n\n return this;\n },\n\n /**\n * Creates 'async' wrapper for the specified component\n * using uiRegistry 'async' method and caches it\n * in a '_requested' components object.\n *\n * @param {String} name - Name of requested component.\n * @returns {Function} Async module wrapper.\n */\n requestModule: function (name) {\n var requested = this._requested;\n\n if (!requested[name]) {\n requested[name] = registry.async(name);\n }\n\n return requested[name];\n },\n\n /**\n * Returns path to elements' template.\n *\n * @returns {String}\n */\n getTemplate: function () {\n return this.template;\n },\n\n /**\n * Checks if template was specified for an element.\n *\n * @returns {Boolean}\n */\n hasTemplate: function () {\n return !!this.template;\n },\n\n /**\n * Returns value of the nested property.\n *\n * @param {String} path - Path to the property.\n * @returns {*} Value of the property.\n */\n get: function (path) {\n return utils.nested(this, path);\n },\n\n /**\n * Sets provided value as a value of the specified nested property.\n * Triggers changes notifications, if value has mutated.\n *\n * @param {String} path - Path to property.\n * @param {*} value - New value of the property.\n * @returns {Element} Chainable.\n */\n set: function (path, value) {\n var data = this.get(path),\n diffs;\n\n diffs = !_.isFunction(data) && !this.isTracked(path) ?\n utils.compare(data, value, path) :\n false;\n\n utils.nested(this, path, value);\n\n if (diffs) {\n this._notifyChanges(diffs);\n }\n\n return this;\n },\n\n /**\n * Removes nested property from the object.\n *\n * @param {String} path - Path to the property.\n * @returns {Element} Chainable.\n */\n remove: function (path) {\n var data = utils.nested(this, path),\n diffs;\n\n if (_.isUndefined(data) || _.isFunction(data)) {\n return this;\n }\n\n diffs = utils.compare(data, undefined, path);\n\n utils.nestedRemove(this, path);\n\n this._notifyChanges(diffs);\n\n return this;\n },\n\n /**\n * Creates observable properties for the current object.\n *\n * If 'useTrack' flag is set to 'true' then each property will be\n * created with a ES5 get/set accessor descriptors, instead of\n * making them an observable functions.\n * See 'knockout-es5' library for more information.\n *\n * @param {Boolean} [useAccessors=false] - Whether to create an\n * observable function or to use property accesessors.\n * @param {(Object|String|Array)} properties - List of observable properties.\n * @returns {Element} Chainable.\n *\n * @example Sample declaration and equivalent knockout methods.\n * this.key = 'value';\n * this.array = ['value'];\n *\n * this.observe(['key', 'array']);\n * =>\n * this.key = ko.observable('value');\n * this.array = ko.observableArray(['value']);\n *\n * @example Another syntaxes of the previous example.\n * this.observe({\n * key: 'value',\n * array: ['value']\n * });\n */\n observe: function (useAccessors, properties) {\n var model = this,\n trackMethod;\n\n if (typeof useAccessors !== 'boolean') {\n properties = useAccessors;\n useAccessors = false;\n }\n\n trackMethod = useAccessors ? accessor : observable;\n\n if (_.isString(properties)) {\n properties = properties.split(' ');\n }\n\n if (Array.isArray(properties)) {\n properties.forEac
2h(function (key) {\n trackMethod(model, key, model[key]);\n });\n } else if (typeof properties === 'object') {\n _.each(properties, function (value, key) {\n trackMethod(model, key, value);\n });\n }\n\n return this;\n },\n\n /**\n * Delegates call to 'observe' method but\n * with a predefined 'useAccessors' flag.\n *\n * @param {(String|Array|Object)} properties - List of observable properties.\n * @returns {Element} Chainable.\n */\n track: function (properties) {\n this.observe(true, properties);\n\n return this;\n },\n\n /**\n * Checks if specified property is tracked.\n *\n * @param {String} property - Property to be checked.\n * @returns {Boolean}\n */\n isTracked: function (property) {\n return ko.es5.isTracked(this, property);\n },\n\n /**\n * Invokes subscribers for the provided changes.\n *\n * @param {Object} diffs - Object with changes descriptions.\n * @returns {Element} Chainable.\n */\n _notifyChanges: function (diffs) {\n diffs.changes.forEac
2h(function (change) {\n this.trigger(change.path, change.value, change);\n }, this);\n\n _.each(diffs.containers, function (changes, name) {\n var value = utils.nested(this, name);\n\n this.trigger(name, value, changes);\n }, this);\n\n return this;\n },\n\n /**\n * Extracts all stored data and sets it to element.\n *\n * @returns {Element} Chainable.\n */\n restore: function () {\n var ns = this.storageConfig.namespace,\n storage = this.storage();\n\n if (storage) {\n utils.extend(this, storage.get(ns));\n }\n\n return this;\n },\n\n /**\n * Stores value of the specified property in components' storage module.\n *\n * @param {String} property\n * @param {*} [data=this[property]]\n * @returns {Element} Chainable.\n */\n store: function (property, data) {\n var ns = this.storageConfig.namespace,\n path = utils.fullPath(ns, property);\n\n if (arguments.length < 2) {\n data = this.get(property);\n }\n\n this.storage('set', path, data);\n\n return this;\n },\n\n /**\n * Extracts specified property from storage.\n *\n * @param {String} [property] - Name of the property\n * to be extracted. If not specified then all of the\n * stored will be returned.\n * @returns {*}\n */\n getStored: function (property) {\n var ns = this.storageConfig.namespace,\n path = utils.fullPath(ns, property),\n storage = this.storage(),\n data;\n\n if (storage) {\n data = storage.get(path);\n }\n\n return data;\n },\n\n /**\n * Removes stored property.\n *\n * @param {String} property - Property to be removed from storage.\n * @returns {Element} Chainable.\n */\n removeStored: function (property) {\n var ns = this.storageConfig.namespace,\n path = utils.fullPath(ns, property);\n\n this.storage('remove', path);\n\n return this;\n },\n\n /**\n * Destroys current instance along with all of its' children.\n * @param {Boolean} skipUpdate - skip collection update when element to be destroyed.\n */\n destroy: function (skipUpdate) {\n this._dropHandlers()\n ._clearRefs(skipUpdate);\n },\n\n /**\n * Removes events listeners.\n * @private\n *\n * @returns {Element} Chainable.\n */\n _dropHandlers: function () {\n this.off();\n\n if (_.isFunction(this.source)) {\n this.source().off(this.name);\n } else if (this.source) {\n this.source.off(this.name);\n }\n\n return this;\n },\n\n /**\n * Removes all references to current instance and\n * calls 'destroy' method on all of its' children.\n * @private\n * @param {Boolean} skipUpdate - skip collection update when element to be destroyed.\n *\n * @returns {Element} Chainable.\n */\n _clearRefs: function (skipUpdate) {\n registry.remove(this.name);\n\n this.containers.forEach(function (parent) {\n parent.removeChild(this, skipUpdate);\n }, this);\n\n return this;\n },\n\n /**\n * Overrides 'EventsBus.trigger' method to implement events bubbling.\n *\n * @param {...*} arguments - Any number of arguments that should be passed to the events' handler.\n * @returns {Boolean} False if event bubbling was canceled.\n */\n bubble: function () {\n var args = _.toArray(arguments),\n bubble = this.trigger.apply(this, args),\
2n result;\n\n if (!bubble) {\n return false;\n }\n\n this.containers.forEach(function (parent) {\n result = parent.bubble.apply(parent, args);\n\n if (result === false) {\n bubble = false;\n }\n });\n\n return !!bubble;\n },\n\n /**\n * Callback which fires when property under uniqueNs has changed.\n */\n onUniqueUpdate: function (name) {\n var active = name === this.name,\n property = this.uniqueProp;\n\n this[property](active);\n },\n\n /**\n * Clean data form data source.\n *\n * @returns {Element}\n */\n cleanData: function () {\n if (this.source && this.source.componentType === 'dataSource') {\n if (this.elems) {\n _.each(this.elems(), function (val) {\n val.cleanData();\n });\n } else {\n this.source.remove(this.dataScope);\n }\n }\n\n return this;\n },\n\n /**\n * Fallback data.\n */\n cacheData: function () {\n this.cachedComponent = utils.copy(this);\n },\n\n /**\n * Update configuration in component.\n *\n * @param {*} oldValue\n * @param {*} newValue\n * @param {String} path - path to value.\n * @returns {Element}\n */\n updateConfig: function (oldValue, newValue, path) {\n var names = path.split('.'),\n index = _.lastIndexOf(names, 'config') + 1;\n\n names = names.splice(index, names.length - index).join('.');\n this.set(names, newValue);\n\n return this;\n }\n }, Events, links);\n\n return Class.extend(Element);\n});\n","Magento_Ui/js/lib/core/element/links.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'ko',\n 'underscore',\n 'mageUtils',\n 'uiRegistry'\n], function (ko, _, utils, registry) {\n 'use strict';\n\n /**\n * Parse provided data.\n *\n * @param {String} placeholder\n * @param {String} data\n * @param {String} direction\n * @returns {Boolean|Object}\n */\n function parseData(placeholder, data, direction) {\n if (typeof data !== 'string') {\n return false;\n }\n\n data = data.split(':');\n\n if (!data[0]) {\n return false;\n }\n\n if (!data[1]) {\n data[1] = data[0];\n data[0] = placeholder;\n }\n\n return {\n target: data[0],\n property: data[1],\n direction: direction\n };\n }\n\n /**\n * Check if value not empty.\n *\n * @param {*} value\n * @returns {Boolean}\n */\n function notEmpty(value) {\n return typeof value !== 'undefined' && value != null;\n }\n\n /**\n * Update value for linked component.\n *\n * @param {Object} data\n * @param {Object} owner\n * @param {Object} target\n * @param {*} value\n */\n function updateValue(data, owner, target, value) {\n var component = target.component,\n property = target.property,\n linked = data.linked;\n\n if (data.mute) {\n return;\n }\n\n if (linked) {\n linked.mute = true;\n }\n\n if (owner.component !== target.component) {\n value = data.inversionValue ? !utils.copy(value) : utils.copy(value);\n }\n\n component.set(property, value, owner);\n\n if (linked) {\n linked.mute = false;\n }\n }\n\n /**\n * Get value form owner component property.\n *\n * @param {Object} owner\n * @returns {*}\n */\n function getValue(owner) {\n var component = owner.component,\n property = owner.property;\n\n return component.get(property);\n }\n\n /**\n * Format provided params to object.\n *\n * @param {String} ownerComponent\n * @param {String} targetComponent\n * @param {String} ownerProp\n * @param {String} targetProp\n * @param {String} direction\n * @returns {Object}\n */\n function form(ownerComponent, targetComponent, ownerProp, targetProp, direction) {\n var result,\n tmp;
2\n\n result = {\n owner: {\n component: ownerComponent,\n property: ownerProp\n },\n target: {\n component: targetComponent,\n property: targetProp\n }\n };\n\n if (direction === 'exports') {\n tmp = result.owner;\n result.owner = result.target;\n result.target = tmp;\n }\n\n return result;\n }\n\n /**\n * Set data to linked property.\n *\n * @param {Object} map\n * @param {Object} data\n */\n function setLinked(map, data) {\n var match;\n\n if (!map) {\n return;\n }\n\n match = _.findWhere(map, {\n linked: false,\n target: data.target,\n property: data.property\n });\n\n if (match) {\n match.linked = data;\n data.linked = match;\n }\n }\n\n /**\n * Set data by direction.\n *\n * @param {Object} maps\n * @param {String} property\n * @param {Object} data\n */\n function setData(maps, property, data) {\n var direction = data.direction,\n map = maps[direction];\n\n data.linked = false;\n\n (map[property] = map[property] || []).push(data);\n\n direction = direction === 'imports' ? 'exports' : 'imports';\n\n setLinked(maps[direction][property], data);\n }\n\n /**\n * Set links for components.\n *\n * @param {String} target\n * @param {String} owner\n * @param {Object} data\n * @param {String} property\n * @param {Boolean} immediate\n */\n function setLink(target, owner, data, property, immediate) {\n var direction = data.direction,\n formated = form(target, owner, data.property, property, direction),\n callback,\n value;\n\n owner = formated.owner;\n target = formated.target;\n\n callback = updateValue.bind(null, data, owner, target);\n\n owner.component.on(owner.property, callback, target.component.name);\n\n if (immediate) {\n value = getValue(owner);\n\n if (notEmpty(value)) {\n updateValue(data, owner, target, value);\n }\n }\n }\n\n /**\n * Transfer data between components.\n *\n * @param {Object} owner\n * @param {Object} data\n */\n function transfer(owner, data) {\n var args = _.toArray(arguments);\n\n if (data.target.substr(0, 1) === '!') {\n data.target = data.target.substr(1);\n data.inversionValue = true;\n }\n\n if (owner.name === data.target) {\n args.unshift(owner);\n\n setLink.apply(null, args);\n } else {\n registry.get(data.target, function (target) {\n args.unshift(target);\n\n setLink.apply(null, args);\n });\n }\n }\n\n return {\n /**\n * Assign listeners.\n *\n * @param {Object} listeners\n * @returns {Object} Chainable\n */\n setListeners: function (listeners) {\n var owner = this,\n data;\n\n _.each(listeners, function (callbacks, sources) {\n sources = sources.split(' ');\n callbacks = callbacks.split(' ');\n\n sources.forEach(function (target) {\n callbacks.forEach(function (callback) {//eslint-disable-line max-nested-callbacks\n data = parseData(owner.name, target, 'imports');\n\n if (data) {\n setData(owner.maps, callback, data);\n transfer(owner, data, callback);\n }\n });\n });\n });\n\n return this;\n },\n\n /**\n * Set links in provided direction.\n *\n * @param {Object} links\n * @param {String} direction\n * @returns {Object} Chainable\n */\n setLinks: function (links, direction) {\n var owner = this,\n property,\n data;\n\n for (property in links) {\n if (links.hasOwnProperty(property)) {\n data = parseData(owner.name, links[property], direction);\n\n if (data) {//eslint-disable-line max-depth\n setData(owner.maps, property, data);\n transfer(owner, data, property, true);\n }\n }\n }\n\n return this;\n }\n };\n});\n","Magento_Ui/js/lib/core/storage/local.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'underscore',\n 'uiRegistry',\n 'mageUtils',\n 'uiEvents'\n], function (_, registry, utils, EventsBus) {\n 'use strict';\n\n var root = 'appData',\n localStorage = window.localStorage,\n hasSupport,\n storage;\n\n /**\n * Flag which indicates whether localStorage is supported.\n */\n hasSupport = (function () {\n var key = '_storageSupported';\n\n try {\n localStorage.setItem(key, 'true');\n\n if (localStorage.getItem(key) === 'true') {\n localStorage.removeItem(key);\n\n return true;\n }\n\n return false;\n } catch (e) {\n return false;\n }\n })();\n\n if (!hasSupport) {\n localStorage = {\n _data: {},\n\n /**\n * Sets value of the specified item.\n *\n * @param {String} key - Key of the property.\n * @param {*} value - Properties' value.\n */\n setItem: function (key, value) {\n this._data[key] = value + '';\n },\n\n /**\n * Retrieves specfied item.\n *\n * @param {String} key - Key of the property to be retrieved.\n */\n getItem: function (key) {\n return this._data[key];\n },\n\n /**\n * Removes specfied item.\n *\n * @param {String} key - Key of the property to be removed.\n */\n removeItem: function (key) {\n delete this._data[key];\n },\n\n /**\n * Removes all items.\n */\n clear: function () {\n this._data = {};\n }\n };\n }\n\n /**\n * Extracts and parses data stored in localStorage by the\n * key specified in 'root' varaible.\n *\n * @returns {Object}\n */\n function getRoot() {\n var data = localStorage.getItem(root),\n result = {};\n\n if (!_.isNull(data) && typeof data != 'undefined') {\n result = JSON.parse(data);\n }\n\n return result;\n }\n\n /**\n * Writes provided data to the localStorage.\n *\n * @param {*} data - Data to be stored.\n */\n function setRoot(data) {\
2n localStorage.setItem(root, JSON.stringify(data));\n }\n\n /**\n * Provides methods to work with a localStorage\n * as a single nested structure.\n */\n storage = _.extend({\n\n /**\n * Retrieves value of the specified property.\n *\n * @param {String} path - Path to the property.\n *\n * @example Retrieveing data.\n * localStoarge =>\n * 'appData' => '\n * \"one\": {\"two\": \"three\"}\n * '\n * storage.get('one.two')\n * => \"three\"\n *\n * storage.get('one')\n * => {\"two\": \"three\"}\n */\n get: function (path) {\n var data = getRoot();\n\n return utils.nested(data, path);\n },\n\n /**\n * Sets specified data to the localStorage.\n *\n * @param {String} path - Path of the property.\n * @param {*} value - Value of the property.\n *\n * @example Setting data.\n * storage.set('one.two', 'four');\n * => localStoarge =>\n * 'appData' => '\n * \"one\": {\"two\": \"four\"}\n * '\n */\n set: function (path, value) {\n var data = getRoot();\n\n utils.nested(data, path, value);\n\n setRoot(data);\n },\n\n /**\n * Removes specified data from the localStorage.\n *\n * @param {String} path - Path to the property that should be removed.\n *\n * @example Removing data.\n * storage.remove('one.two', 'four');\n * => localStoarge =>\n * 'appData' => '\n * \"one\": {}\n * '\n */\n remove: function (path) {\n var data = getRoot();\n\n utils.nestedRemove(data, path);\n\n setRoot(data);\n }\n }, EventsBus);\n\n registry.set('localStorage', storage);\n\n return storage;\n});\n","Magento_Ui/js/form/switcher.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'uiRegistry',\n 'uiClass'\n], function (_, registry, Class) {\n 'use strict';\n\n return Class.extend({\n defaults: {\n rules: []\n },\n\n /**\n * Initializes instance of a DataSwitcher.\n *\n * @returns {DataSwitcher} Chainable.\n */\n initialize: function () {\n this._super()\n .initRules();\n\n return this;\n },\n\n /**\n *\n * @returns {DataSwitcher} Chainable.\n */\n initRules: function () {\n this.rules.forEac
2h(this.initRule, this);\n\n return this;\n },\n\n /**\n *\n * @param {Object} rule - Rule definition.\n * @returns {DataSwitcher} Chainable.\n */\n initRule: function (rule) {\n var handler = this.onValueChange.bind(this, rule);\n\n if (!rule.target) {\n rule.target = this.target;\n }\n\n if (!rule.property) {\n rule.property = this.property;\n }\n\n registry.get(rule.target, function (target) {\n this.applyRule(rule, target.get(rule.property));\n target.on(rule.property, handler);\n }.bind(this));\n\n return this;\n },\n\n /**\n *\n * @param {Object} rule - Rule definition.\n * @returns {DataSwitcher} Chainable.\n */\n addRule: function (rule) {\n this.rules.push(rule);\n this.initRule(rule);\n\n return this;\n },\n\n /**\n *\n * @param {Object} rule - Rule object.\n * @param {*} value - Current value associated with a rule.\n */\n applyRule: function (rule, value) {\n var actions = rule.actions;\n\n //TODO Refactor this logic in scope of MAGETWO-48585\n /* eslint-disable eqeqeq */\n if (rule.value != value) {\n return;\n } else if (rule.strict) {\n return;\n }\n\n /* eslint-enable eqeqeq */\n actions.forEach(this.applyAction, this);\n },\n\n /**\n *\n * @param {Object} action - Action object.\n */\n applyAction: function (action) {\n registry.get(action.target, function (target) {\n var callback = target[action.callback];\n\n callback.apply(target, action.params || []);\n });\n },\n\n /**\n *\n * @param {Object} rule - Rules object.\n * @param {*} value - Current value associated with a rule.\n */\n onValueChange: function (rule, value) {\n this.applyRule(rule, value);\n }\n });\n});\n","Magento_Ui/js/form/client.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'underscore',\n 'mageUtils',\n 'uiClass'\n], function ($, _, utils, Class) {\n 'use strict';\n\n /**\n * Before save validate request.\n *\n * @param {Object} data\n * @param {String} url\n * @param {String} selectorPrefix\n * @param {String} messagesClass\n * @returns {*}\n */\n function beforeSave(data, url, selectorPrefix, messagesClass) {\n var save = $.Deferred();\n\n data = utils.serialize(utils.filterFormData(data));\n data['form_key'] = window.FORM_KEY;\n\n if (!url || url === 'undefined') {\n return save.resolve();\n }\n\n $('body').trigger('processStart');\n\n $.ajax({\n url: url,\n data: data,\n\n /**\n * Success callback.\n * @param {Object} resp\n * @returns {Boolean}\n */\n success: function (resp) {\n if (!resp.error) {\n save.resolve();\n\n return true;\n }\n\n $('body').notification('clear');\n $.each(resp.messages || [resp.message] || [], function (key, message) {\n $('body').notification('add', {\n error: resp.error,\n message: message,\n\n /**\n * Insert method.\n *\n * @param {String} msg\n */\n insertMethod: function (msg) {\n var $wrapper = $('<div/>').addClass(messagesClass).html(msg);\n\n $('.page-main-actions', selectorPrefix).after($wrapper);\n }\n });\n });\n },\n\n /**\n * Complete callback.\n */\n complete: function () {\n $('body').trigger('processStop');\n }\n });\n\n return save.promise();\n }\n\n return Class.extend({\n\n /**\n * Assembles data and submits it using 'utils.submit' method\n */\n save: function (data, options) {\n var url = this.urls.beforeSave,\n save = this._save.bind(this, data, options);
2\n\n beforeSave(data, url, this.selectorPrefix, this.messagesClass).then(save);\n\n return this;\n },\n\n /**\n * Save data.\n *\n * @param {Object} data\n * @param {Object} options\n * @returns {Object}\n * @private\n */\n _save: function (data, options) {\n var url = this.urls.save;\n\n $('body').trigger('processStart');\n options = options || {};\n\n if (!options.redirect) {\n url += 'back/edit';\n }\n\n if (options.ajaxSave) {\n utils.ajaxSubmit({\n url: url,\n data: data\n }, options);\n\n $('body').trigger('processStop');\n\n return this;\n }\n\n utils.submit({\n url: url,\n data: data\n }, options.attributes);\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/adapter.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 'Magento_Ui/js/form/adapter/buttons'\n], function ($, _, buttons) {\n 'use strict';\n\n var selectorPrefix = '',\n eventPrefix;\n\n /**\n * Initialize listener.\n *\n * @param {Function} callback\n * @param {String} action\n */\n function initListener(callback, action) {\n var selector = selectorPrefix ? selectorPrefix + ' ' + buttons[action] : buttons[action],\n elem = $(selector)[0];\n\n if (!elem) {\n return;\n }\n\n if (elem.onclick) {\n elem.onclick = null;\n }\n\n $(elem).on('click' + eventPrefix, callback);\n }\n\n /**\n * Destroy listener.\n *\n * @param {String} action\n */\n function destroyListener(action) {\n var selector = selectorPrefix ? selectorPrefix + ' ' + buttons[action] : buttons[action],\n elem = $(selector)[0];\n\n if (!elem) {\n return;\n }\n\n if (elem.onclick) {\n elem.onclick = null;\n }\n\n $(elem).off('click' + eventPrefix);\n }\n\n return {\n\n /**\n * Attaches events handlers.\n *\n * @param {Object} handlers\n * @param {String} selectorPref\n * @param {String} eventPref\n */\n on: function (handlers, selectorPref, eventPref) {\n selectorPrefix = selectorPrefix || selectorPref;\n eventPrefix = eventPref;\n _.each(handlers, initListener);\n selectorPrefix = '';\n },\n\n /**\n * Removes events handlers.\n *\n * @param {Object} handlers\n * @param {String} eventPref\n */\n off: function (handlers, eventPref) {\n eventPrefix = eventPref;\n _.each(handlers, destroyListener);\n }\n };\n});\n","Magento_Ui/js/form/button-adapter.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'uiClass',\n 'jquery',\n 'underscore',\n 'uiRegistry'\n], function (Class, $, _, registry) {\n 'use strict';\n\n return Class.extend({\n\n /**\n * Initialize actions and adapter.\n *\n * @param {Object} config\n * @param {Element} elem\n * @returns {Object}\n */\n initialize: function (config, elem) {\n return this._super()\n .initActions()\n .initAdapter(elem);\n },\n\n /**\n * Creates callback from declared actions.\n *\n * @returns {Object}\n */\n initActions: function () {\n var callbacks = [];\n\n _.each(this.actions, function (action) {\n callbacks.push({\n action: registry.async(action.targetName),\n args: _.union([action.actionName], action.params)\n });\n });\n\n /**\n * Callback function.\n */\n this.callback = function () {\n _.each(callbacks, function (callback) {\n callback.action.apply(callback.action, callback.args);\n });\n };\n\n return this;\n },\n\n /**\n * Attach callback handler on button.\n *\n * @param {Element} elem\n */\n initAdapter: function (elem) {\n $(elem).on('click', this.callback);\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/form.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'Magento_Ui/js/lib/spinner',\n 'rjsResolver',\n './adapter',\n 'uiCollection',\n 'mageUtils',\n 'jquery',\n 'Magento_Ui/js/core/app',\n 'mage/validation'\n], function (_, loader, resolver, adapter, Collection, utils, $, app) {\n 'use strict';\n\n /**\n * Format params\n *\n * @param {Object} params\n * @returns {Array}\n */\n function prepareParams(params) {\n var result = '?';\n\n _.each(params, function (value, key) {\n result += key + '=' + value + '&';\n });\n\n return result.slice(0, -1);\n }\n\n /**\n * Collect form data.\n *\n * @param {Array} items\n * @returns {Object}\n */\n function collectData(items) {\n var result = {},\n name;\n\n items = Array.prototype.slice.call(items);
2\n\n items.forEach(function (item) {\n switch (item.type) {\n case 'checkbox':\n result[item.name] = +!!item.checked;\n break;\n\n case 'radio':\n if (item.checked) {\n result[item.name] = item.value;\n }\n break;\n\n case 'select-multiple':\n name = item.name.substring(0, item.name.length - 2); //remove [] from the name ending\n result[name] = _.pluck(item.selectedOptions, 'value');\n break;\n\n default:\n result[item.name] = item.value;\n }\n });\n\n return result;\n }\n\n /**\n * Makes ajax request\n *\n * @param {Object} params\n * @param {Object} data\n * @param {String} url\n * @returns {*}\n */\n function makeRequest(params, data, url) {\n var save = $.Deferred();\n\n data = utils.serialize(data);\n data['form_key'] = window.FORM_KEY;\n\n if (!url) {\n save.resolve();\n }\n\n $('body').trigger('processStart');\n\n $.ajax({\n url: url + prepareParams(params),\n data: data,\n dataType: 'json',\n\n /**\n * Success callback.\n * @param {Object} resp\n * @returns {Boolean}\n */\n success: function (resp) {\n if (resp.ajaxExpired) {\n window.location.href = resp.ajaxRedirect;\n }\n\n if (!resp.error) {\n save.resolve(resp);\n\n return true;\n }\n\n $('body').notification('clear');\n $.each(resp.messages, function (key, message) {\n $('body').notification('add', {\n error: resp.error,\n message: message,\n\n /**\n * Inserts message on page\n * @param {String} msg\n */\n insertMethod: function (msg) {\n $('.page-main-actions').after(msg);\n }\n });\n });\n },\n\n /**\n * Complete callback.\n */\n complete: function () {\n $('body').trigger('processStop');\n }\n });\n\n return save.promise();\n }\n\n /**\n * Check if fields is valid.\n *\n * @param {Array}items\n * @returns {Boolean}\n */\n function isValidFields(items) {\n var result = true;\n\n _.each(items, function (item) {\n if (!$.validator.validateSingleElement(item)) {\n result = false;\n }\n });\n\n return result;\n }\n\n return Collection.extend({\n defaults: {\n additionalFields: [],\n additionalInvalid: false,\n selectorPrefix: '.page-content',\n messagesClass: 'messages',\n errorClass: '.admin__field._error',\n eventPrefix: '.${ $.index }',\n ajaxSave: false,\n ajaxSaveType: 'default',\n imports: {\n reloadUrl: '${ $.provider}:reloadUrl'\n },\n listens: {\n selectorPrefix: 'destroyAdapter initAdapter',\n '${ $.name }.${ $.reloadItem }': 'params.set reload'\n },\n exports: {\n selectorPrefix: '${ $.provider }:client.selectorPrefix',\n messagesClass: '${ $.provider }:client.messagesClass'\n }\n },\n\n /** @inheritdoc */\n initialize: function () {\n this._super()\n .initAdapter();\n\n resolver(this.hideLoader, this);\n\n return this;\n }
2,\n\n /** @inheritdoc */\n initObservable: function () {\n return this._super()\n .observe([\n 'responseData',\n 'responseStatus'\n ]);\n },\n\n /** @inheritdoc */\n initConfig: function () {\n this._super();\n\n this.selector = '[data-form-part=' + this.namespace + ']';\n\n return this;\n },\n\n /**\n * Initialize adapter handlers.\n *\n * @returns {Object}\n */\n initAdapter: function () {\n adapter.on({\n 'reset': this.reset.bind(this),\n 'save': this.save.bind(this, true, {}),\n 'saveAndContinue': this.save.bind(this, false, {})\n }, this.selectorPrefix, this.eventPrefix);\n\n return this;\n },\n\n /**\n * Destroy adapter handlers.\n *\n * @returns {Object}\n */\n destroyAdapter: function () {\n adapter.off([\n 'reset',\n 'save',\n 'saveAndContinue'\n ], this.eventPrefix);\n\n return this;\n },\n\n /**\n * Hide loader.\n *\n * @returns {Object}\n */\n hideLoader: function () {\n loader.get(this.name).hide();\n\n return this;\n },\n\n /**\n * Validate and save form.\n *\n * @param {String} redirect\n * @param {Object} data\n */\n save: function (redirect, data) {\n this.validate();\n\n if (!this.additionalInvalid && !this.source.get('params.invalid')) {\n this.setAdditionalData(data)\n .submit(redirect);\n } else {\n this.focusInvalid();\n }\n },\n\n /**\n * Tries to set focus on first invalid form field.\n *\n * @returns {Object}\n */\n focusInvalid: function () {\n var invalidField = _.find(this.delegate('checkInvalid'));\n\n if (!_.isUndefined(invalidField) && _.isFunction(invalidField.focused)) {\n invalidField.focused(true);\n }\n\n return this;\n },\n\n /**\n * Set additional data to source before form submit and after validation.\n *\n * @param {Object} data\n * @returns {Object}
2\n */\n setAdditionalData: function (data) {\n _.each(data, function (value, name) {\n this.source.set('data.' + name, value);\n }, this);\n\n return this;\n },\n\n /**\n * Submits form\n *\n * @param {String} redirect\n */\n submit: function (redirect) {\n var additional = collectData(this.additionalFields),\n source = this.source;\n\n _.each(additional, function (value, name) {\n source.set('data.' + name, value);\n });\n\n source.save({\n redirect: redirect,\n ajaxSave: this.ajaxSave,\n ajaxSaveType: this.ajaxSaveType,\n response: {\n data: this.responseData,\n status: this.responseStatus\n },\n attributes: {\n id: this.namespace\n }\n });\n },\
2n\n /**\n * Validates each element and returns true, if all elements are valid.\n */\n validate: function () {\n this.additionalFields = document.querySelectorAll(this.selector);\n this.source.set('params.invalid', false);\n this.source.trigger('data.validate');\n this.set('additionalInvalid', !isValidFields(this.additionalFields));\n },\n\n /**\n * Trigger reset form data.\n */\n reset: function () {\n this.source.trigger('data.reset');\n },\n\n /**\n * Trigger overload form data.\n */\n overload: function () {\n this.source.trigger('data.overload');\n },\n\n /**\n * Updates data from server.\n */\n reload: function () {\n makeRequest(this.params, this.data, this.reloadUrl).then(function (data) {\n app(data, true);\n });\n }\n });\n});\n","Magento_Ui/js/form/provider.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'uiElement',\n './client',\n 'mageUtils'\n], function (_, Element, Client, utils) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n clientConfig: {\n urls: {\n save: '${ $.submit_url }',\n beforeSave: '${ $.validate_url }'\n }\n },\n ignoreTmpls: {\n data: true\n }\n },\n\n /**\n * Initializes provider component.\n *\n * @returns {Provider} Chainable.\n */\n initialize: function () {\n this._super()\n .initClient();\n\n return this;\n },\n\n /**\n * Initializes client component.\n *\n * @returns {Provider} Chainable.\n */\n initClient: function () {\n this.client = new Client(this.clientConfig);\n\n return this;\n },\n\n /**\n * Saves currently available data.\n *\n * @param {Object} [options] - Addtitional request options.\n * @returns {Provider} Chainable.\n */\n save: function (options) {\n var data = this.get('data');\n\n this.client.save(data, options);\n\n return this;\n },\n\n /**\n * Update data that stored in provider.\n *\n * @param {Boolean} isProvider\n * @param {Object} newData\n * @param {Object} oldData\n *\n * @returns {Provider}\n */\n updateConfig: function (isProvider, newData, oldData) {\n if (isProvider === true) {\n this.setData(oldData, newData, this);\n }\n\n return this;\n },\n\n /**\n * Set data to provder based on current data.\n *\n * @param {Object} oldData\n * @param {Object} newData\n * @param {Provider} current\n * @param {String} parentPath\n */\n setData: function (oldData, newData, current, parentPath) {\n _.each(newData, function (val, key) {\n if (_.isObject(val) || _.isArray(val)) {\n this.setData(oldData[key], val, current[key], utils.fullPath(parentPath, key));\n } else if (val != oldData[key] && oldData[key] == current[key]) {//eslint-disable-line eqeqeq\n this.set(utils.fullPath(parentPath, key), val);\n }\n }, this);\n }\n });\n});\n","Magento_Ui/js/form/element/single-checkbox.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'Magento_Ui/js/form/element/abstract',\n 'underscore',\n 'mage/translate'\n], function (AbstractField, _, $t) {\n 'use strict';\n\n return AbstractField.extend({\n defaults: {\n template: 'ui/form/components/single/field',\n checked: fal
2se,\n initialChecked: false,\n multiple: false,\n prefer: 'checkbox', // 'radio' | 'checkbox' | 'toggle'\n valueMap: {},\n\n templates: {\n radio: 'ui/form/components/single/radio',\n checkbox: 'ui/form/components/single/checkbox',\n toggle: 'ui/form/components/single/switcher'\n },\n\n listens: {\n 'checked': 'onCheckedChanged',\n 'value': 'onExtendedValueChanged'\n }\n },\n\n /**\n * @inheritdoc\n */\n initConfig: function (config) {\n this._super();\n\n if (!config.elementTmpl) {\n if (!this.prefer && !this.multiple) {\n this.elementTmpl = this.templates.radio;\n } else if (this.prefer === 'radio') {\n this.elementTmpl = this.templates.radio;\n } else if (this.prefer === 'checkbox') {\n this.elementTmpl = this.templates.checkbox;\n } else if (this.prefer === 'toggle') {\n this.elementTmpl = this.templates.toggle;\n } else {\n this.elementTmpl = this.templates.checkbox;\n }\n }\n\n if (this.prefer === 'toggle' && _.isEmpty(this.toggleLabels)) {\n this.toggleLabels = {\n 'on': $t('Yes'),\n 'off': $t('No')\n };\n }\n\n if (typeof this.default === 'undefined' || this.default === null) {\n this.default = '';\n }\n\n if (typeof this.value === 'undefined' || this.value === null) {\n this.value = _.isEmpty(this.valueMap) || this.default !== '' ? this.default : this.valueMap.false;\n this.initialValue = this.value;\n } else {\n this.initialValue = this.value;\n }\n\n if (this.multiple && !_.isArray(this.value)) {\n this.value = [];
2 // needed for correct observable assignment\n }\n\n this.initialChecked = this.checked;\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n initObservable: function () {\n return this\n ._super()\n .observe('checked');\n },\n\n /**\n * Get true/false key from valueMap by value.\n *\n * @param {*} value\n * @returns {Boolean|undefined}\n */\n getReverseValueMap: function getReverseValueMap(value) {\n var bool = false;\n\n _.some(this.valueMap, function (iValue, iBool) {\n if (iValue === value) {\n bool = iBool === 'true';\n\n return true;\n }\n });\n\n return bool;\n },\n\n /**\n * @inheritdoc\n */\n setInitialValue: function () {\n if (_.isEmpty(this.valueMap)) {\n this.on('value', this.onUpdate.bind(this));\n } else {\n this._super();\n this.checked(this.getReverseValueMap(this.value()));\n }\n\n return this;\n },\n\n /**\n * Handle dataScope changes for checkbox / radio button.\n *\n * @param {*} newExportedValue\n */\n onExtendedValueChanged: function (newExportedValue) {\n var isMappedUsed = !_.isEmpty(this.valueMap),\n oldChecked = this.checked.peek(),\n oldValue = this.initialValue,\n newChecked;\n\n if (this.multiple) {\n newChecked = newExportedValue.indexOf(oldValue) !== -1;\n } else if (isMappedUsed) {\n newChecked = this.getReverseValueMap(newExportedValue);\n } else if (typeof newExportedValue === 'boolean') {\n newChecked = newExportedValue;\n } else {\n newChecked = newExportedValue === oldValue;\n }\n\n if (newChecked !== oldChecked) {\n this.checked(newChecked);\n }\n },\n\n /**\n * Handle checked state changes for checkbox / radio button.\n *\n * @param {Boolean} newChecked\n */\n onCheckedChanged: function (newChecked) {\n var isMappedUsed = !_.isEmpty(this.valueMap),\n oldValue = this.initialValue,\n newValue;\n\n if (isMappedUsed) {\n newValue = this.valueMap[newChecked];\n } else {\n newValue = oldValue;\n }\n\n if (!this.multiple && newChecked) {\n this.value(newValue);\n } else if (!this.multiple && !newChecked) {\n if (typeof newValue === 'boolean') {\n this.value(newChecked);\n } else if (newValue === this.value.peek()) {\n this.value('');\n }\n\n if (isMappedUsed) {\n this.value(newValue);\n }\n } else if (this.multiple && newChecked && this.value.indexOf(newValue) === -1) {\n this.value.push(newValue);\n } else if (this.multiple && !newChecked && this.value.indexOf(newValue) !== -1) {\n this.value.splice(this.value.indexOf(newValue), 1);\n }\n },\n\n /**\n * @inheritdoc\n */\n onUpdate: function () {\n if (this.hasUnique) {\n this.setUnique();\n }\n\n return this._super();\n },\n\n /**\n * @inheritdoc\n */\n reset: function () {\n if (this.multiple && this.initialChecked) {\n this.value.push(this.initialValue);\n } else if (this.multiple && !this.initialChecked) {\n this.value.splice(this.value.indexOf(this.initialValue), 1);\n } else {\n this.value(this.initialValue);\n }\n\n this.error(false);\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n clear: function () {\n if (this.multiple) {\n this.value([]);\n } else {\n this.value('');\n }\n\n this.error(false);\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/element/textarea.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n './abstract'\n], function (Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n cols: 15,\n rows: 2,\n elementTmpl: 'ui/form/element/textarea'\n }\n });\n});\n","Magento_Ui/js/form/element/select.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'mageUtils',\n 'uiRegistry',\n './abstract',\n 'uiLayout'\n], function (_, utils, registry, Abstract, layout) {\n 'use strict';\n\n var inputNode = {\n parent: '${ $.$data.parentName }',\n component: 'Magento_Ui/js/form/element/abstract',\n template: '${ $.$data.template }',\n provider: '${ $.$data.provider }',\n name: '${ $.$data.index }
2_input',\n dataScope: '${ $.$data.customEntry }',\n customScope: '${ $.$data.customScope }',\n sortOrder: {\n after: '${ $.$data.name }'\n },\n displayArea: 'body',\n label: '${ $.$data.label }'\n };\n\n /**\n * Parses incoming options, considers options with undefined value property\n * as caption\n *\n * @param {Array} nodes\n * @return {Object}\n */\n function parseOptions(nodes, captionValue) {\n var caption,\n value;\n\n nodes = _.map(nodes, function (node) {\n value = node.value;\n\n if (value === null || value === captionValue) {\n if (_.isUndefined(caption)) {\n caption = node.label;\n }\n } else {\n return node;\n }\n });\n\n return {\n options: _.compact(nodes),\n caption: _.isString(caption) ? caption : false\n };\n }\n\n /**\n * Recursively loops over data to find non-undefined, non-array value\n *\n * @param {Array} data\n * @return {*} - first non-undefined value in array\n */\n function findFirst(data) {\n var value;\n\n data.some(function (node) {\n value = node.value;\n\n if (Array.isArray(value)) {\n value = findFirst(value);\n }\n\n return !_.isUndefined(value);\n });\n\n return value;\n }\n\n /**\n * Recursively set to object item like value and item.value like key.\n *\n * @param {Array} data\n * @param {Object} result\n * @returns {Object}\n */\n function indexOptions(data, result) {\n var value;\n\n result = result || {};\n\n data.forEach(function (item) {\n value = item.value;\n\n if (Array.isArray(value)) {\n indexOptions(value, result);\n } else {\n result[value] = item;\n }\n });\n\n return result;\n }\n\n return Abstract.extend({\n defaults: {\n customName: '${ $.parentName }.${ $.index }_input',\n elementTmpl: 'ui/form/element/select',\n caption: '',\n options: []\n },\n\n /**\n * Extends instance with defaults, extends config with formatted values\n * and options, and invokes initialize method of AbstractElement class.\n * If instance's 'customEntry' property is set to true, calls 'initInput'\n */\n initialize: function () {\n this._super();\n\n if (this.customEntry) {\n registry.get(this.name, this.initInput.bind(this));\n }\n\n if (this.filterBy) {\n this.initFilter();\n }\n\n return this;\n },\n\n /**\n * Calls 'initObservable' of parent, initializes 'options' and 'initialOptions'\n * properties, calls 'setOptions' passing options to it\n *\n * @returns {Object} Chainable.\n */\n initObservable: function () {\n this._super();\n\n this.initialOptions = this.options;\n\n this.observe('options caption')\n .setOptions(this.options());\n\n return this;\n },\n\n /**\n * Set link for filter.\n *\n * @returns {Object} Chainable\n */\n initFilter: function () {\n var filter = this.filterBy;\n\n this.filter(this.default, filter.field);\n this.setLinks({\n filter: filter.target\n }, 'imports');\n\n return this;\n },\n\n /**\n * Creates input from template, renders it via renderer.\n *\n * @returns {Object} Chainable.\n */\n initInput: function () {\n layout([utils.template(inputNode, this)]);\n\n return this;\n },\n\n /**\n * Matches specified value with existing options\n * or, if value is not specified, returns value of the first option.\n *\n * @returns {*}\n */\n normalizeData: function () {\n var value = this._super(),\n option;\n\n if (value !== '') {\n option = this.getOption(value);\n\n return option && option.value;\n }\n\n if (!this.caption()) {\n return findFirst(this.options);\n }\n },\n\n /**\n * Filters 'initialOptions' property by 'field' and 'value' passed,\n * calls 'setOptions' passing the result to it\n *\n * @param {*} value\n * @param {String} field\n */\n filter: function (value, field) {\n var source = this.initialOptions,\n result;\n\n field = field || this.filterBy.field;\n\n result = _.filter(source, function (item) {\n return item[field] === value || item.value === '';\n });\n\n this.setOptions(result);\n },\n\n /**\n * Change visibility for input.\n *\n * @param {Boolean} isVisible\n */\n toggleInput: function (isVisible) {\n registry.get(this.customName, function (input) {\n input.setVisible(isVisible);\n });\n },\n\n /**\n * Sets 'data' to 'options' observable array, if instance has\n * 'customEntry' property set to true, calls 'setHidden' method\n * passing !options.length as a parameter\n *\n * @param {Array} data\n * @returns {Object}
2 Chainable\n */\n setOptions: function (data) {\n var captionValue = this.captionValue || '',\n result = parseOptions(data, captionValue),\n isVisible;\n\n this.indexedOptions = indexOptions(result.options);\n\n this.options(result.options);\n\n if (!this.caption()) {\n this.caption(result.caption);\n }\n\n if (this.customEntry) {\n isVisible = !!result.options.length;\n\n this.setVisible(isVisible);\n this.toggleInput(!isVisible);\n }\n\n return this;\n },\n\n /**\n * Processes preview for option by it's value, and sets the result\n * to 'preview' observable\n *\n * @returns {Object} Chainable.\n */\n getPreview: function () {\n var value = this.value(),\n option = this.indexedOptions[value],\n preview = option ? option.label : '';\n\n this.preview(preview);\n\n return preview;\n },\n\n /**\n * Get option from indexedOptions list.\n *\n * @param {Number} value\n * @returns {Object} Chainable\n */\n getOption: function (value) {\n return this.indexedOptions[value];\n },\n\n /**\n * Select first available option\n *\n * @returns {Object} Chainable.\n */\n clear: function () {\n var value = this.caption() ? '' : findFirst(this.options);\n\n this.value(value);\n\n return this;\n },\n\n /**\n * Initializes observable properties of instance\n *\n * @returns {Object} Chainable.\n */\n setInitialValue: function () {\n if (_.isUndefined(this.value()) && !this.default) {\n this.clear();\n }\n\n return this._super();\n }\n });\n});\n","Magento_Ui/js/form/element/multiselect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'mageUtils',\n './select'\n], function (_, utils, Select) {\n 'use strict';\n\n return Select.extend({\n defaults: {\n size: 5,\n elementTmpl: 'ui/form/element/multiselect',\n listens: {\n value: 'setDifferedFromDefault setPrepareToSendData'\n }\n },\n\n /**\n * @inheritdoc\n */\n setInitialValue: function () {\n this._super();\n\n this.initialValue = utils.copy(this.initialValue);\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n normalizeData: function (value) {\n if (utils.isEmpty(value)) {\n value = [];\n }\n\n return _.isString(value) ? value.split(',') : value;\n },\n\n /**\n * Sets the prepared data to dataSource\n * by path, where key is component link to dataSource with\n * suffix \"-prepared-for-send\"\n *\n * @param {Array} data - current component value\n */\n setPrepareToSendData: function (data) {\
2n if (_.isUndefined(data) || !data.length) {\n data = '';\n }\n\n this.source.set(this.dataScope + '-prepared-for-send', data);\n },\n\n /**\n * @inheritdoc\n */\n getInitialValue: function () {\n var values = [\n this.normalizeData(this.source.get(this.dataScope)),\n this.normalizeData(this.default)\n ],\n value;\n\n values.some(function (v) {\n return _.isArray(v) && (value = utils.copy(v)) && !_.isEmpty(v);\n });\n\n return value;\n },\n\n /**\n * @inheritdoc\n */\n hasChanged: function () {\n var value = this.value(),\n initial = this.initialValue;\n\n return !utils.equalArrays(value, initial);\n },\n\n /**\n * @inheritdoc\n */\n reset: function () {\n this.value(utils.copy(this.initialValue));\n this.error(false);\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n clear: function () {\n this.value([]);\n this.error(false);\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/element/boolean.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n './abstract'\n], function (Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n checked: false,\n links: {\n checked: 'value'\n }\n },\n\n /**\n * @returns {*|void|Element}\n */\n initObservable: function () {\n return this._super()\n .observe('checked');\n },\n\n /**\n * Converts provided value to boolean.\n *\n * @returns {Boolean}\n */\n normalizeData: function () {\n return !!+this._super();\n },\n\n /**\n * Calls 'onUpdate' method of parent, if value is defined and instance's\n * 'unique' property set to true, calls 'setUnique' method\n *\n * @return {Object} - reference to instance\n */\n onUpdate: function () {\n if (this.hasUnique) {\n this.setUnique();\n }\n\n return this._super();\n }\n });\n});\n","Magento_Ui/js/form/element/single-checkbox-use-config.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'Magento_Ui/js/form/element/single-checkbox'\n], function (Component) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n isUseDefault: false,\n isUseConfig: false,\n listens: {\n 'isUseConfig': 'toggleElement',\n 'isUseDefault': 'toggleElement'\n }\n },\n\n /**\n * @inheritdoc\n */\n initObservable: function () {\n\n return this\n ._super()\n .observe('isUseConfig');\n },\n\n /**\n * Toggle element\n */\n toggleElement: function () {\n this.disabled(this.isUseDefault() || this.isUseConfig());\n\n if (this.source) {\n this.source.set('data.use_default.' + this.index, Number(this.isUseDefault()));\n }\n }\n });\n});\n","Magento_Ui/js/form/element/wysiwyg.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'Magento_Ui/js/lib/view/utils/async',\n 'underscore',\n 'ko',\n './abstract',\n 'Magento_Variable/variables'\n], function ($, _, ko, Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n elementSelector: 'textarea',\n value: '',\n $wysiwygEditorButton: '',\n links: {\n value: '${ $.provider }:${ $.dataScope }'\n },\n template: 'ui/form/field',\n elementTmpl: 'ui/form/element/wysiwyg',\n content: '',\n showSpinner: false,\n loading: false,\n listens: {\n disabled: 'setDisabled'\n }\n },\n\n /**\n *\n * @returns {} Chainable.\n */\n initialize: function () {\n this._super()\n .initNodeListener();\n\n $.async({\n component: this,\n selector: 'button'\n }, function (element) {\n this.$wysiwygEditorButton = this.$wysiwygEditorButton ?\n this.$wysiwygEditorButton.add($(element)) : $(element);\n }.bind(this));\n\n return this;\n },\n\n /**\n *\n * @returns {exports}
2\n */\n initObservable: function () {\n this._super()\n .observe('value');\n\n return this;\n },\n\n /**\n *\n * @returns {} Chainable.\n */\n initNodeListener: function () {\n $.async({\n component: this,\n selector: this.elementSelector\n }, this.setElementNode.bind(this));\n\n return this;\n },\n\n /**\n *\n * @param {HTMLElement} node\n */\n setElementNode: function (node) {\n $(node).bindings({\n value: this.value\n });\n },\n\n /**\n * Set disabled property to wysiwyg component\n *\n * @param {Boolean} status\n */\n setDisabled: function (status) {\n this.$wysiwygEditorButton.attr('disabled', status);\n\n /* eslint-disable no-undef */\n if (tinyMCE && tinyMCE.activeEditor) {\n _.each(tinyMCE.activeEditor.controlManager.controls, function (property, index, controls) {\n controls[property.id].setDisabled(status);\n });\n\n tinyMCE.activeEditor.getBody().setAttribute('contenteditable', !status);\n }\n\n /* eslint-enable no-undef*/\n }\n });\n});\n","Magento_Ui/js/form/element/single-checkbox-toggle-notice.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'Magento_Ui/js/form/element/single-checkbox'\n], function (SingleCheckbox) {\n 'use strict';\n\n return SingleCheckbox.extend({\n defaults: {\n notices: [],\n tracks: {\n notice: true\n }\n },\n\n /**\n * Choose notice on initialization\n *\n * @returns {*|void|Element}\n */\n initialize: function () {\n this._super()\n .chooseNotice();\n\n return this;\n },\n\n /**\n * Choose notice function\n *\n * @returns void\n */\n chooseNotice: function () {\n var checkedNoticeNumber = Number(this.checked());\n\n this.notice = this.notices[checkedNoticeNumber];\n },\n\n /**\n * Choose notice on update\n *\n * @returns void\n */\n onUpdate: function () {\n this._super();\n this.chooseNotice();\n }\n });\n});\n","Magento_Ui/js/form/element/website.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'uiRegistry',\n './select'\n], function (_, registry, Select) {\n 'use strict';\n\n return Select.extend({\n defaults: {\n customerId: null,\n isGlobalScope: 0\n },\n\n /**\n * Website component constructor.\n * @returns {exports}\n */\n initialize: function () {\n this._super();\n\n if (this.customerId || this.isGlobalScope) {\n this.disable(true);\n }\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/element/country.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'uiRegistry',\n './select'\n], function (_, registry, Select) {\n 'use strict';\n\n return Select.extend({\n defaults: {\n imports: {\n update: '${ $.parentName }.website_id:value'\n }\n },\n\n /**\n * Filters 'initialOptions' property by 'field' and 'value' passed,\n * calls 'setOptions' passing the result to it\n *\n * @param {*} value\n * @param {String} field\n */\n filter: function (value, field) {\n var result, defaultCountry, defaultValue;\n\n if (!field) { //validate field, if we are on update\n field = this.filterBy.field;\n }\n\n this._super(value, field);\n result = _.filter(this.initialOptions, function (item) {\n\n if (item[field]) {\n return ~item[field].indexOf(value);\n }\n\n return false;\n });\n\n this.setOptions(result);\n this.reset();\n\n if (!this.value()) {\n defaultCountry = _.filter(result, function (item) {\n return item['is_default'] && item['is_default'].includes(value);\n });\n\n if (defaultCountry.length) {\n defaultValue = defaultCountry.shift();\n this.value(defaultValue.value);\n }\n }\n }\n });\n});\n\n","Magento_Ui/js/form/element/date.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'moment',\n 'mageUtils',\n './abstract',\n 'moment-timezone-with-data'\n], function (moment, utils, Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n options: {},\n\n storeTimeZone: 'UTC',\n\n validationParams: {\n dateFormat: '${ $.outputDateFormat }'\n },\n\n /**\n * Format of date that comes from the\n * server (ICU Date Format).\n *\n * Used only in date picker mode\n * (this.options.showsTime == false).\n *\n * @type {String}\n */\n inputDateFormat: 'y-MM-dd',\n\n /**\n * Format of date that comes from the\n * server (ICU Date Format).\n *\n * Used only in date/time picker mode\n * (this.options.showsTime == false).\n *\n * @type {String}\n */\n inputDateTimeFormat: 'y-MM-dd h:mm',\n\n /**\n * Format of date that should be sent to the\n * server (ICU Date Format).\n *\n * Used only in date picker mode\n * (this.options.showsTime == false).\n *\n * @type {String}
2\n */\n outputDateFormat: 'MM/dd/y',\n\n /**\n * Format of date that should be sent to the\n * server (ICU Date Format).\n *\n * Used only in datetime picker mode with disabled ISO format.\n * (this.options.showsTime == true, this.options.outputDateTimeToISO == false)\n *\n * @type {String}\n */\n outputDateTimeFormat: '',\n\n /**\n * Converts output date/time to ISO string\n *\n * Used only in datetime picker mode\n * (this.options.showsTime == false)\n */\n outputDateTimeToISO: true,\n\n /**\n * Date/time format that is used to display date in\n * the input field.\n *\n * @type {String}\n */\n pickerDateTimeFormat: '',\n\n pickerDefaultDateFormat: 'MM/dd/y', // ICU Date Format\n pickerDefaultTimeFormat: 'h:mm a', // ICU Time Format\n\n elementTmpl: 'ui/form/element/date',\n\n /**\n * Format needed by moment timezone for conversion\n */\n timezoneFormat: 'YYYY-MM-DD HH:mm',\n\n listens: {\n 'value': 'onValueChange',\n 'shiftedValue': 'onShiftedValueChange'\n },\n\n /**\n * Date/time value shifted to corresponding timezone\n * according to this.storeTimeZone property. This value\n * will be sent to the server.\n *\n * @type {String}\n */\n shiftedValue: ''\n },\n\n /**\n * Initializes regular properties of instance.\n *\n * @returns {Object} Chainable.\n */\n initConfig: function () {\n this._super();\n\n if (!this.options.dateFormat) {\n this.options.dateFormat = this.pickerDefaultDateFormat;\n }\n\n if (!this.options.timeFormat) {\n this.options.timeFormat = this.pickerDefaultTimeFormat;\n }\n\n this.prepareDateTimeFormats();\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n initObservable: function () {\n return this._super().observe(['shiftedValue']);\n },\n\n /**\n * Prepares and sets date/time value that will be displayed\n * in the input field.\n *\n * @param {String} value\n */\n onValueChange: function (value) {\n var dateFormat,\n shiftedValue;\n\n if (value) {\n if (this.options.showsTime && !this.outputDateTimeToISO) {\n dateFormat = this.shiftedValue() ?\n this.outputDateTimeFormat :\n this.inputDateTimeFormat;\n\n value = moment(value, dateFormat).format(this.timezoneFormat);\n }\n\n if (this.options.showsTime) {\n shiftedValue = moment.tz(value, 'UTC').tz(this.storeTimeZone);\n } else {\n dateFormat = this.shiftedValue() ?\n this.outputDateFormat :\n this.inputDateFormat;\n\n shiftedValue = moment(value, dateFormat);\n }\n\n shiftedValue = shiftedValue.format(this.pickerDateTimeFormat);\n } else {\n shiftedValue = '';\n }\n\n if (shiftedValue !== this.shiftedValue()) {\n this.shiftedValue(shiftedValue);\n }\n },\n\n /**\n * Prepares and sets date/time value that will be sent\n * to the server.\n *\n * @param {String} shiftedValue\n */\n onShiftedValueChange: function (shiftedValue) {\n var value,\n formattedValue,\n formattedValueUTC,\n momentValue;\n\n if (shiftedValue) {\n momentValue = moment(shiftedValue, this.pickerDateTimeFormat);\n\n if (this.options.showsTime) {\n formattedValue = moment(momentValue).format(this.timezoneFormat);\n formattedValueUTC = moment.tz(formattedValue, this.storeTimeZone).tz('UTC');\n\n value = this.outputDateTimeToISO ?\n formattedValueUTC.toISOString() :\n formattedValueUTC.format(this.outputDateTimeFormat);\n } else {\n value = momentValue.format(this.outputDateFormat);\n }\n } else {\n value = '';\n }\n\n if (value !== this.value()) {\n this.value(value);\n }\n },\n\n /**\n * Prepares and converts all date/time formats to be compatible\n * with moment.js library.\
2n */\n prepareDateTimeFormats: function () {\n this.pickerDateTimeFormat = this.options.dateFormat;\n\n if (this.options.showsTime) {\n this.pickerDateTimeFormat += ' ' + this.options.timeFormat;\n }\n\n this.pickerDateTimeFormat = utils.convertToMomentFormat(this.pickerDateTimeFormat);\n\n if (this.options.dateFormat) {\n this.outputDateFormat = this.options.dateFormat;\n }\n\n this.inputDateFormat = utils.convertToMomentFormat(this.inputDateFormat);\n this.outputDateFormat = utils.convertToMomentFormat(this.outputDateFormat);\n this.validationParams.dateFormat = this.outputDateFormat;\n this.outputDateTimeFormat = this.options.outputDateTimeFormat || this.pickerDateTimeFormat;\n }\n });\n});\n","Magento_Ui/js/form/element/region.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'uiRegistry',\n './select',\n 'Magento_Checkout/js/model/default-post-code-resolver'\n], function (_, registry, Select, defaultPostCodeResolver) {\n 'use strict';\n\n return Select.extend({\n defaults: {\n skipValidation: false,\n imports: {\n update: '${ $.parentName }.country_id:value'\n }\n },\n\n /**\n * @param {String} value\n */\n update: function (value) {\n var country = registry.get(this.parentName + '.' + 'country_id'),\n options = country.indexedOptions,\n isRegionRequired,\n option;\n\n if (!value) {\n return;\n }\n option = options[value];\n\n if (typeof option === 'undefined') {\n return;\n }\n\n defaultPostCodeResolver.setUseDefaultPostCode(!option['is_zipcode_optional']);\n\n if (this.skipValidation) {\n this.validation['required-entry'] = false;\n this.required(false);\n } else {\n if (option && !option['is_region_required']) {\n this.error(false);\n this.validation = _.omit(this.validation, 'required-entry');\n } else {\n this.validation['required-entry'] = true;\n }\n\n if (option && !this.options().length) {\n registry.get(this.customName, function (input) {\n isRegionRequired = !!option['is_region_required'];\n input.validation['required-entry'] = isRegionRequired;\n input.validation['validate-not-number-first'] = true;\n input.required(isRegionRequired);\n });\n }\n\n this.required(!!option['is_region_required']);\n }\n },\n\n /**\n * Filters 'initialOptions' property by 'field' and 'value' passed,\n * calls 'setOptions' passing the result to it\n *\n * @param {*} value\n * @param {String} field\n */\n filter: function (value, field) {\n var country = registry.get(this.parentName + '.' + 'country_id'),\n option;\n\n if (country) {\n option = country.indexedOptions[value];\n\n this._super(value, field);\n\n if (option && option['is_region_visible'] === false) {\n // hide select and corresponding text input field if region must not be shown for selected country\n this.setVisible(false);\n\n if (this.customEntry) {// eslint-disable-line max-depth\n this.toggleInput(false);\n }\n }\n }\n }\n });\n});\n\n","Magento_Ui/js/form/element/abstract.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'mageUtils',\n 'uiLayout',\n 'uiElement',\n 'Magento_Ui/js/lib/vali
2dation/validator'\n], function (_, utils, layout, Element, validator) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n visible: true,\n preview: '',\n focused: false,\n required: false,\n disabled: false,\n valueChangedByUser: false,\n elementTmpl: 'ui/form/element/input',\n tooltipTpl: 'ui/form/element/helper/tooltip',\n fallbackResetTpl: 'ui/form/element/helper/fallback-reset',\n 'input_type': 'input',\n placeholder: false,\n description: '',\n labelVisible: true,\n label: '',\n error: '',\n warn: '',\n notice: '',\n customScope: '',\n default: '',\n isDifferedFromDefault: false,\n showFallbackReset: false,\n additionalClasses: {},\n isUseDefault: '',\n serviceDisabled: false,\n valueUpdate: false, // ko binding valueUpdate\n\n switcherConfig: {\n component: 'Magento_Ui/js/form/switcher',\n name: '${ $.name }_switcher',\n target: '${ $.name }',\n property: 'value'\n },\n listens: {\n visible: 'setPreview',\n value: 'setDifferedFromDefault',\n '${ $.provider }:data.reset': 'reset',\n '${ $.provider }:data.overload': 'overload',\n '${ $.provider }:${ $.customScope ? $.customScope + \".\" : \"\"}data.validate': 'validate',\n 'isUseDefault': 'toggleUseDefault'\n },\n ignoreTmpls: {\n value: true\n },\n\n links: {\n value: '${ $.provider }:${ $.dataScope }'\n }\n },\n\n /**\n * Invokes initialize method of parent class,\n * contains initialization logic\n */\n initialize: function () {\n _.bindAll(this, 'reset');\n\n this._super()\n .setInitialValue()\n ._setClasses()\n .initSwitcher();\n\n return this;\n },\n\n /**\n * Checks if component has error.\n *\n * @returns {Object}\n */\n checkInvalid: function () {\n return this.error() && this.error().length ? this : null;\n },\n\n /**\n * Initializes observable properties of instance\n *\n * @returns {Abstract} Chainable.\n */\n initObservable: function () {\n var rules = this.validation = this.validation || {};\n\n this._super();\n\n this.observe('error disabled focused preview visible value warn notice isDifferedFromDefault')\n .observe('isUseDefault serviceDisabled')\n .observe({\n 'required': !!rules['required-entry']\n });\n\n return this;\n },\n\n /**\n * Initializes regular properties of instance.\n *\n * @returns {Abstract} Chainable.\n */\n initConfig: function () {\n var uid = utils.uniqueid(),\n name,\n valueUpdate,\n scope;\n\n this._super();\n\n scope = this.dataScope.split('.');\n name = scope.length > 1 ? scope.slice(1) : scope;\n\n valueUpdate = this.showFallbackReset ? 'afterkeydown' : this.valueUpdate;\n\n _.extend(this, {\n uid: uid,\n noticeId: 'notice-' + uid,\n errorId: 'error-' + uid,\n inputName: utils.serializeName(name.join('.')),\n valueUpdate: valueUpdate\n });\n\n return this;\n },\n\n /**\n * Initializes switcher element instance.\n *\n * @returns {Abstract} Chainable.\n */\n initSwitcher: function () {\n if (this.switcherConfig.enabled) {\n layout([this.switcherConfig]);\n }\n\n return this;\n },\n\n /**\n * Sets initial value of the element and subscribes to it's changes.\n *\n * @returns {Abstract} Chainable.\n */\n setInitialValue: function () {\n this.initialValue = this.getInitialValue();\n\n if (this.value.peek() !== this.initialValue) {\n this.value(this.initialValue);\n }\n\n this.on('value', this.onUpdate.bind(this));\n this.isUseDefault(this.disabled());\n\n return this;\n },\n\n /**\n * Extends 'additionalClasses' object.\n *\n * @returns {Abstract} Chainable.\n */\n _setClasses: function () {\n var additional = this.additionalClasses;\n\n if (_.isString(additional)) {\n this.additionalClasses = {};\n\n if (additional.trim().length) {\n additional = additional.trim().split(' ');\n\n additional.forEach(function (name) {\n if (name.length) {\n this.additionalClasses[name] = true;\n }\n }, this);\n }\n }\n\n _.extend(this.additionalClasses, {\n _required: this.required,\n _error: this.error,\n _warn: this.warn,\n _disabled: this.disabled\n });\n\n return this;\n },\n\n /**\n * Gets initial value of element\n *\n * @returns {*} Elements' value.\n */\n getInitialValue: function () {\n var values = [this.value(), this.default],\n value;\n\n values.some(function (v) {\n if (v !== null && v !== undefined) {\n value = v;\n\n return true;\n }\n\n return false;\n });\n\n return this.normalizeData(value);\n },\n\n /**\n * Sets 'value' as 'hidden' property's value, triggers 'toggle' event,\n * sets instance's hidden identifier in params storage based on\n * 'value'.\n *\n * @returns {Abstract} Chainable.\n */\n setVisible: function (isVisible) {\n this.visible(isVisible);\n\n return this;\n },\n\n /**\n * Show element.\n *\n * @returns {Abstract} Chainable.\n */\n show: function () {\n this.visible(true);\n\n return this;\n },\n\n /**\n * Hide element.\n *\n * @returns {Abstract} Chainable.\n */\n hide: function () {\n this.visible(false);\n\n return this;\n },\n\n /**\n * Disable element.\n *\n * @returns {Abstract} Chainable.\n */\n disable: function () {\n this.disabled(true);\n\n return this;\n },\n\n /**\n * Enable element.\n *\n * @returns {Abstract} Chainable.\n */\n enable: function () {\n this.disabled(false);\n\n return this;\n },\n\n /**\n *\n * @param {(String|Object)} rule\n * @param {(Object|Boolean)} [options]\n * @returns {Abstract} Chainable.\n */\n setValidation: function (rule, options) {\n var rules = utils.copy(this.validation),\n changed;\n\n if (_.isObject(rule)) {\n _.extend(this.validation, rule);\n } else {\n this.validation[rule] = options;\n }\n\n changed = utils.compare(rules, this.validation).equal;\n\n if (changed) {\n this.required(!!rules['required-entry']);\n this.validate();\n }\n\n return this;\n },\n\n /**\n * Returns unwrapped preview observable.\n *\n * @returns {String} Value of the preview observable.\n */\n getPreview: function () {\n return this.value();\n },\n\n /**\n * Checks if element has addons\n *\n * @returns {Boolean}\n */\n hasAddons: function () {\n return this.addbefore || this.addafter;\n },\n\n /**\n * Checks if element has service setting\n *\n * @returns {Boolean}\n */\n hasService: function () {\n return this.service && this.service.template;\n },\n\n /**\n * Defines if value has changed.\n *\n * @returns {Boolean}\n */\n hasChanged: function () {\n var notEqual = this.value() !== this.initialValue;\n\n return !this.visible() ? false : notEqual;\n },\n\n /**\n * Checks if 'value' is not empty.\n *\n * @returns {Boolean}\n */\n hasData: function () {\n return !utils.isEmpty(this.value());\n },\n\n /**\n * Sets value observable to initialValue property.\n *\n * @returns {Abstract} Chainable.\n */\n reset: function () {\n this.value(this.initialValue);\n this.error(false);\n\n return this;\n },\n\n /**\n * Sets current state as initial.\n */\n overload: function () {\n this.setInitialValue();\n this.bubble('update', this.hasChanged());\n },\n\n /**\n * Clears 'value' property.\n *\n * @returns {Abstract} Chainable.\n */\n clear: function () {\n this.value('');\n\n return this;\n },\n\n /**\n * Converts values like 'null' or 'undefined' to an empty string.\n *\n * @param {*} value - Value to be processed.\n * @returns {*}\n */\n normalizeData: function (value) {\n return utils.isEmpty(value) ? '' : value;\n },\n\n /**\n * Validates itself by it's validation rules using validator object.\n * If validation of a rule did n
2ot pass, writes it's message to\n * 'error' observable property.\n *\n * @returns {Object} Validate information.\n */\n validate: function () {\n var value = this.value(),\n result = validator(this.validation, value, this.validationParams),\n message = !this.disabled() && this.visible() ? result.message : '',\n isValid = this.disabled() || !this.visible() || result.passed;\n\n this.error(message);\n this.bubble('error', message);\n\n //TODO: Implement proper result propagation for form\n if (!isValid) {\n this.source.set('params.invalid', true);\n }\n\n return {\n valid: isValid,\n target: this\n };\n },\n\n /**\n * Callback that fires when 'value' property is updated.\n */\n onUpdate: function () {\n this.bubble('update', this.hasChanged());\n\n this.validate();\n },\n\n /**\n * Restore value to default\n */\n restoreToDefault: function () {\n this.value(this.default);\n this.focused(true);\n },\n\n /**\n * Update whether value differs from default value\n */\n setDifferedFromDefault: function () {\n var value = typeof this.value() != 'undefined' && this.value() !== null ? this.value() : '',\n defaultValue = typeof this.default != 'undefined' && this.default !== null ? this.default : '';\n\n this.isDifferedFromDefault(value !== defaultValue);\n },\n\n /**\n * @param {Boolean} state\n */\n toggleUseDefault: function (state) {\n this.disabled(state);\n\n if (this.source && this.hasService()) {\n this.source.set('data.use_default.' + this.index, Number(state));\n }\n },\n\n /**\n * Callback when value is changed by user\n */\n userChanges: function () {\n this.valueChangedByUser = true;\n },\n\n /**\n * Returns correct id for 'aria-describedby' accessibility attribute\n *\n * @returns {Boolean|String}\n */\n getDescriptionId: function () {\n var id = false;\n\n if (this.error()) {\n id = this.errorId;\n } else if (this.notice()) {\n id = this.noticeId;\n }\n\n return id;\n }\n });\n});\n","Magento_Ui/js/form/element/checkbox-set.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'mageUtils',\n './abstract'\n], function (_, utils, Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n template: 'ui/form/element/checkbox-set',\n multiple: false,\n multipleScopeValue: null\n },\n\n /**\n * @inheritdoc\n */\n initConfig: function () {\n this._super();\n\n this.value = this.normalizeData(this.value);\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n initLinks: function () {\n var scope = this.source.get(this.dataScope);\n\n this.multipleScopeValue = this.multiple && _.isArray(scope) ? utils.copy(scope) : undefined;\n\n return this._super();\n },\n\n /**\n * @inheritdoc\n */\n reset: function () {\n this.value(utils.copy(this.initialValue));\n this.error(false);\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n clear: function () {\n var value = this.multiple ? [] : '';\n\n this.value(value);\n this.error(false);\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n normalizeData: function (value) {\n if (!this.multiple) {\n return this._super();\n }\n\n return _.isArray(value) ? utils.copy(value) : [];\n },\n\n /**\n * @inheritdoc\n */\n setInitialValue: function () {\n this._super();\n\n this.initialValue = utils.copy(this.initialValue);\n\n return this;\n },\n\n /**\n * @inheritdoc\n */\n getInitialValue: function () {\n var values = [this.multipleScopeValue, this.default, this.value.peek(), []],\n value;\n\n if (!this.multiple) {\n return this._super();\n }\n\n values.some(function (v) {\n return _.isArray(v) && (value = utils.copy(v));\n });\n\n return value;\n },\n\n /**\n * Returns labels which matches current value.\n *\n * @returns {String|Array}\n */\n getPreview: function () {\n var option;\n\n if (!this.multiple) {\n option = this.getOption(this.value());\n\n return option ? option.label : '';\n }\n\n return this.value.map(function (value) {\n return this.getOption(value).label;\n }, this);\n },\n\n /**\n * Returns option object assoctiated with provided value.\n *\n * @param {String}
2 value\n * @returns {Object}\n */\n getOption: function (value) {\n return _.findWhere(this.options, {\n value: value\n });\n },\n\n /**\n * @inheritdoc\n */\n hasChanged: function () {\n var value = this.value(),\n initial = this.initialValue;\n\n return this.multiple ?\n !utils.equalArrays(value, initial) :\n this._super();\n }\n });\n});\n","Magento_Ui/js/form/element/post-code.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'uiRegistry',\n './abstract'\n], function (_, registry, Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n imports: {\n update: '${ $.parentName }.country_id:value'\n }\n },\n\n /**\n * @param {String} value\n */\n update: function (value) {\n var country = registry.get(this.parentName + '.' + 'country_id'),\n options = country.indexedOptions,\n option;\n\n if (!value) {\n return;\n }\n\n option = options[value];\n\n if (option['is_zipcode_optional']) {\n this.error(false);\n this.validation = _.omit(this.validation, 'required-entry');\n } else {\n this.validation['required-entry'] = true;\n }\n\n this.required(!option['is_zipcode_optional']);\n }\n });\n});\n","Magento_Ui/js/form/element/text.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'uiElement',\n 'mageUtils'\n], function (Element, utils) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n visible: true,\n label: '',\n error: '',\n uid: utils.uniqueid(),\n disabled: false,\n links: {\n value: '${ $.provider }:${ $.dataScope }'\n }\n },\n\n /**\n * Has service\n *\n * @returns {Boolean} false.\n */\n hasService: function () {\n return false;\n },\n\n /**\n * Has addons\n *\n * @returns {Boolean} false.\n */\n hasAddons: function () {\n return false;\n },\n\n /**\n * Calls 'initObservable' of parent\n *\n * @returns {Object} Chainable.\n */\n initObservable: function () {\n this._super()\n .observe('disabled visible value');\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/element/media.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'mageUtils',\n './abstract'\n], function (utils, Abstract) {\n 'use strict';\n\n return Abstract.extend({\n defaults: {\n links: {\n value: ''\n }\n },\n\n /**\n * Initializes file component.\n *\n * @returns {Media} Chainable.\n */\n initialize: function () {\n this._super()\n .initFormId();\n\n return this;\n },\n\n /**\n * Defines form ID with which file input will be associated.\n *\n * @returns {Media} Chainable.\n */\n initFormId: function () {\n var namespace;\n\n if (this.formId) {\n return this;\n }\n\n namespace = this.name.split('.');\n this.formId = namespace[0];\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/adapter/buttons.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine(function () {\n 'use strict';
2\n\n return {\n 'reset': '#reset',\n 'save': '#save',\n 'saveAndContinue': '#save_and_continue'\n };\n});\n","Magento_Ui/js/form/components/area.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n './tab'\n], function (_, Tab) {\n 'use strict';\n\n return Tab.extend({\n defaults: {\n uniqueNs: 'params.activeArea',\n template: 'ui/area',\n changed: false,\n loading: false\n },\n\n /**\n * Extends instance with defaults. Invokes parent initialize method.\n * Calls initListeners and pushParams methods.\n */\n initialize: function () {\n _.bindAll(this, 'onChildrenUpdate', 'onContentLoading');\n\n return this._super();\n },\n\n /**\n * Calls initObservable of parent class.\n * Defines observable properties of instance.\n * @return {Object} - reference to instance\n */\n initObservable: function () {\n this._super()\n .observe('changed loading');\n\n return this;\n },\n\n /**\n * Calls parent's initElement method.\n * Assignes callbacks on various events of incoming element.\n * @param {Object} elem\n * @return {Object} - reference to instance\n */\n initElement: function (elem) {\n this._super();\n\n elem.on({\n 'update': this.onChildrenUpdate,\n 'loading': this.onContentLoading\n });\n\n return this;\n },\n\n /**\n * Is being invoked on children update.\n * Sets changed property to one incoming.\n * Invokes setActive method if settings\n * contain makeVisible property set to true.\n *\n * @param {Boolean} hasChanged\n */\n onChildrenUpdate: function (hasChanged) {\n if (!hasChanged) {\n hasChanged = _.some(this.delegate('hasChanged'));\n }\n\n this.changed(hasChanged);\n },\n\n /**\n * Callback that sets loading property to true.\n */\n onContentLoading: function (isLoading) {\n this.loading(isLoading);\n }\n });\n});\n","Magento_Ui/js/form/components/insert-form.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n './insert',\n 'mageUtils',\n 'jquery'\n], function (Insert, utils, $) {\n 'use strict';\n\n /**\n * Get page actions element.\n *\n * @param {String} elem\n * @param {String} actionsClass\n * @returns {String}\n */\n function getPageActions(elem, actionsClass) {\n var el = document.createElement('div');\n\n el.innerHTML = elem;\n\n return el.getElementsByClassName(actionsClass)[0];\n }\n\n /**\n * Return element without page actions toolbar\n *\n * @param {String} elem\n * @param {String} actionsClass\n * @returns {String}\n */\n function removePageActions(elem, actionsClass) {\n var el = document.createElement('div'),\n actions;\n\n el.innerHTML = elem;\n actions = el.getElementsByClassName(actionsClass)[0];\n\n if (actions) {\n el.removeChild(actions);\n }\n\n return el.innerHTML;\n }\n\n return Insert.extend({\n defaults: {\n externalFormName: '${ $.ns }.${ $.ns }',\n pageActionsClass: 'page-actions',\n actionsContainerClass: 'page-main-actions',\n exports: {\n prefix: '${ $.externalFormName }:selectorPrefix'\n },\n imports: {\n toolbarSection: '${ $.toolbarContainer }:toolbarSection',\n prefix: '${ $.toolbarContainer }:rootSelector',\n messagesClass: '${ $.externalFormName }:messagesClass'\n },\n settings: {\n ajax: {\n ajaxSave: true,\n exports: {\n ajaxSave: '${ $.externalFormName }:ajaxSave'\n },\n imports: {\n responseStatus: '${ $.externalFormName }:responseStatus',\n responseData: '${ $.externalFormName }:responseData'\n }\n }\n },\n modules: {\n externalForm: '${ $.externalFormName }'\n }\n }
2,\n\n /** @inheritdoc */\n initObservable: function () {\n return this._super()\n .observe('responseStatus');\n },\n\n /** @inheritdoc */\n initConfig: function (config) {\n var defaults = this.constructor.defaults;\n\n utils.extend(defaults, defaults.settings[config.formSubmitType] || {});\n\n return this._super();\n },\n\n /** @inheritdoc*/\n destroyInserted: function () {\n if (this.isRendered && this.externalForm()) {\n this.externalForm().delegate('destroy');\n this.removeActions();\n this.responseStatus(undefined);\n this.responseData = {};\n }\n\n return this._super();\n },\n\n /** @inheritdoc */\n onRender: function (data) {\n var actions = getPageActions(data, this.pageActionsClass);\n\n if (!data.length) {\n return this;\n }\n data = removePageActions(data, this.pageActionsClass);\n this.renderActions(actions);\n this._super(data);\n },\n\n /**\n * Insert actions in toolbar.\n *\n * @param {String} actions\n */\n renderActions: function (actions) {\n var $container = $('<
2div/>');\n\n $container\n .addClass(this.actionsContainerClass)\n .append(actions);\n\n this.formHeader = $container;\n\n $(this.toolbarSection).append(this.formHeader);\n },\n\n /**\n * Remove actions toolbar.\n */\n removeActions: function () {\n $(this.formHeader).siblings('.' + this.messagesClass).remove();\n $(this.formHeader).remove();\n this.formHeader = $();\n },\n\n /**\n * Reset external form data.\n */\n resetForm: function () {\n if (this.externalSource()) {\n this.externalSource().trigger('data.reset');\n this.responseStatus(undefined);\n }\n }\n });\n});\n","Magento_Ui/js/form/components/fieldset.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'Magento_Ui/js/lib/collapsible',\n 'underscore'\n], function (Collapsible, _) {\n 'use strict';\n\n return Collapsible.extend({\n defaults: {\n template: 'ui/form/fieldset',\n collapsible: false,\n changed: false,\n loading: false,\n error: false,\n opened: false,\n level: 0,\n visible: true,\n initializeFieldsetDataByDefault: false, /* Data in some fieldsets should be initialized before open */\n disabled: false,\n listens: {\n 'opened': 'onVisibilityChange'\n },\n additionalClasses: {}\n },\n\n /**\n * Extends instance with defaults. Invokes parent initialize method.\n * Calls initListeners and pushParams methods.\n */\n initialize: function () {\n _.bindAll(this, 'onChildrenUpdate', 'onChildrenError', 'onContentLoading');\n\n return this._super()\n ._setClasses();\n },\n\n /**\n * Initializes components' configuration.\n *\n * @returns {Fieldset} Chainable.\n */\n initConfig: function () {\n this._super();\n this._wasOpened = this.opened || !this.collapsible;\n\n return this;\n },\n\n /**\n * Calls initObservable of parent class.\n * Defines observable properties of instance.\n *\n * @returns {Object} Reference to instance\n */\n initObservable: function () {\n this._super()\n .observe('changed loading error visible');\n\n return this;\n },\n\n /**\n * Calls parent's initElement method.\n * Assignes callbacks on various events of incoming element.\n *\n * @param {Object} elem\n * @return {Object} - reference to instance\n */\n initElement: function (elem) {\n elem.initContainer(this);\n\n elem.on({\n 'update': this.onChildrenUpdate,\n 'loading': this.onContentLoading,\n 'error': this.onChildrenError\n });\n\n if (this.disabled) {\n try {\n elem.disabled(true);\n }\n catch (e) {\n\n }\n }\n\n return this;\n },\n\n /**\n * Is being invoked on children update.\n * Sets changed property to one incoming.\n *\n * @param {Boolean} hasChanged\n */\n onChildrenUpdate: function (hasChanged) {\n if (!hasChanged) {\n hasChanged = _.some(this.delegate('hasChanged'));\n }\n\n this.bubble('update', hasChanged);\n this.changed(hasChanged);\n },\n\n /**\n * Extends 'additionalClasses' object.\n *\n * @returns {Group} Chainable.\n */\n _setClasses: function () {\n var additional = this.additionalClasses,\
2n classes;\n\n if (_.isString(additional)) {\n additional = this.additionalClasses.split(' ');\n classes = this.additionalClasses = {};\n\n additional.forEach(function (name) {\n classes[name] = true;\n }, this);\n }\n\n _.extend(this.additionalClasses, {\n 'admin__collapsible-block-wrapper': this.collapsible,\n _show: this.opened,\n _hide: !this.opened,\n _disabled: this.disabled\n });\n\n return this;\n },\n\n /**\n * Handler of the \"opened\" property changes.\n *\n * @param {Boolean} isOpened\n */\n onVisibilityChange: function (isOpened) {\n if (!this._wasOpened) {\n this._wasOpened = isOpened;\n }\n },\n\n /**\n * Is being invoked on children validation error.\n * Sets error property to one incoming.\n *\n * @param {String} message - error message.\n */\n onChildrenError: function (message) {\n var hasErrors = false;\n\n if (!message) {\n hasErrors = this._isChildrenHasErrors(hasErrors, this);\n }\n\n this.error(hasErrors || message);\n },\n\n /**\n * Returns errors of children if exist\n *\n * @param {Boolean} hasErrors\n * @param {*} container\n * @return {Boolean}\n * @private\n */\n _isChildrenHasErrors: function (hasErrors, container) {\n var self = this;\n\n if (hasErrors === false && container.hasOwnProperty('elems')) {\n hasErrors = container.elems.some('error');\n\n if (hasErrors === false && container.hasOwnProperty('_elems')) {\n container._elems.forEach(function (child) {\n\n if (hasErrors === false) {\n hasErrors = self._isChildrenHasErrors(hasErrors, child);\n }\n });\n }\n }\n\n return hasErrors;\n },\n\n /**\n * Callback that sets loading property to true.\n */\n onContentLoading: function (isLoading) {\n this.loading(isLoading);\n }\n });\n});\n","Magento_Ui/js/form/components/group.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'uiCollection'\n], function (_, Collection) {\n 'use strict';\n\n return Collection.extend({\n defaults: {\n visible: true,\n label: '',\n showLabel: true,\n required: false,\n template: 'ui/group/group',\n fieldTemplate: 'ui/form/field',\n breakLine: true,\n validateWholeGroup: false,\n additionalClasses: {}\n },\n\n /**\n * Extends this with defaults and config.\n * Then calls initObservable, iniListenes and extractData methods.\n */\n initialize: function () {\n this._super()\n ._setClasses();\n\n return this;\n },\n\n /**\n * Calls initObservable of parent class.\n * Defines observable properties of instance.\n *\n * @return {Object} - reference to instance\n */\n initObservable: function () {\n this._super()\n .observe('visible')\n .observe({\n required: !!+this.required\n });\n\n return this;\n },\n\n /**\n * Extends 'additionalClasses' object.\n *\n * @returns {Group} Chainable.\n */\n _setClasses: function () {\n var additional = this.additionalClasses,\n classes;\n\n if (_.isString(additional)) {\n additional = this.additionalClasses.split(' ');\n classes = this.additionalClasses = {};\n\n additional.forEach(function (name) {\n classes[name] = true;\n }, this);\n }\n\n _.extend(this.additionalClasses, {\n 'admin__control-grouped': !this.breakLine,\n 'admin__control-fields': this.breakLine,\n required: this.required,\n _error: this.error,\n _disabled: this.disabled\n });\n\n return this;\n },\n\n /**\n * Defines if group has only one element.\n * @return {Boolean}\n */\n isSingle: function () {\n return this.elems.getLength() === 1;\n },\n\n /**\n * Defines if group has multiple elements.\n * @return {Boolean}\n */\n isMultiple: function () {\n return this.elems.getLength() > 1;\n },\n\n /**\n * Returns an array of child components previews.\n *\n * @returns {Array}\n */\n getPreview: function () {\n return this.elems.map('getPreview');\n }\n });\n});\n","Magento_Ui/js/form/components/collection.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'mageUtils',\n 'uiRegistry',\n 'uiComponent',\n 'uiLayout',\n 'Magento_Ui/js/modal/confirm'\n], function (_, utils, registry, Component, layout, confirm) {\n 'use strict';\n\n var childTemplate = {\n parent: '${ $.$data.name }',\n name: '${ $.$data.childIndex }',\n dataScope: '${ $.name }',\n nodeTemplate: '${ $.$data.name }.${ $.$data.itemTemplate }'\n };\n\n return Component.extend({\n defaults: {\n lastIndex: 0,\n template: 'ui/form/components/collection'\n },\n\n /**\n * Extends instance with default config, calls initialize of parent\n * class, calls initChildren method.\n */\n initialize: function () {\n this._super()\n .initChildren();\n\n return this;\n },\n\n /**\n * Activates the incoming child and triggers the update event.\n *\n * @param {Object} elem - Incoming child.\n */\n initElement: function (elem) {\n this._super();\n\n elem.activate();\n\n this.bubble('update');\n\n return this;\n },\n\n /**\n * Loops over corresponding data in data storage,\n * creates child for each and pushes it's identifier to initialItems array.\n *\n * @returns {Collection} Chainable.\n */\n initChildren: function () {\n var children = this.source.get(this.dataScope),\n initial = this.initialItems = [];\n\n _.each(children, function (item, index) {\n initial.push(index);\n this.addChild(index);\n }, this);\n\n return this;\n },\n\n /**\n * Creates new item of collection, based on incoming 'index'.\n * If not passed creates one with 'new_' prefix.\n *\n * @param {String|Object} [index] - Index of a child.\n * @returns {Collection} Chainable.\n */\n addChild: function (index) {\n this.childIndex = !_.isString(index) ?\n 'new_' + this.lastIndex++ :\n index;\n\n layout([utils.template(childTemplate, this)]);\n\n return this;\n },\n\n /**\n * Returnes true if current set of items differ from initial one,\n * or if some child has been changed.\n *\n * @returns {Boolean}\n */\n hasChanged: function () {\n var initial = this.initialItems,\n current = this.elems.pluck('index'),\n changed = !utils.equalArrays(initial, current);\n\n return changed || this.elems.some(function (elem) {\n return _.some(elem.delegate('hasChanged'));\n });\n },\n\n /**\n * Initiates validation of its' children components.\n *\n * @returns {Array} An array of validation results.\n */\n validate: function () {\n var elems;\n\n this.allValid = true;\n\n elems = this.elems.sortBy(function (elem) {\n return !elem.active();\n });
2\n\n elems = elems.map(this._validate, this);\n\n return _.flatten(elems);\n },\n\n /**\n * Iterator function for components validation.\n * Activates first invalid child component.\n *\n * @param {Object} elem - Element to run validation on.\n * @returns {Array} An array of validation results.\n */\n _validate: function (elem) {\n var result = elem.delegate('validate'),\n invalid;\n\n invalid = _.some(result, function (item) {\n return !item.valid;\n });\n\n if (this.allValid && invalid) {\n this.allValid = false;\n\n elem.activate();\n }\n\n return result;\n },\n\n /**\n * Creates function that removes element\n * from collection using '_removeChild' method.\n * @param {Object} elem - Element that should be removed.\n */\n removeAddress: function (elem) {\n var self = this;\n\n confirm({\n content: this.removeMessage,\n actions: {\n /** @inheritdoc */\n confirm: function () {\n self._removeAddress(elem);\n }\n }\n });\n },\n\n /**\n * Removes elememt from both collection and data storage,\n * activates first element if removed one was active,\n * triggers 'update' event.\n *\n * @param {Object} elem - Element to remove.\n */\n _removeAddress: function (elem) {\n var isActive = elem.active(),\n first;\n\n elem.destroy();\n\n first = this.elems.first();\n\n if (first && isActive) {\n first.activate();\n }\n\n this.bubble('update');\n }\n });\n});\n","Magento_Ui/js/form/components/tab_group.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'Magento_Ui/js/lib/collapsible'\n], function (_, Collapsible) {\n 'use strict';\n\n return Collapsible.extend({\n defaults: {\n listens: {\n '${ $.provider }:data.validate': 'onValidate'\n },\n collapsible: false,\n opened: true\n },\n\n /**\n * Invokes initElement method of parent class, calls 'initActivation' method\n * passing element to it.\n * @param {Object} elem\n * @returns {Object} - reference to instance\n */\n initElement: function (elem) {\n this._super()\n .initActivation(elem);\n\n return this;\n },\n\n /**\n * Activates element if one is first or if one has 'active' propert\n * set to true.\n *\n * @param {Object} elem\n * @returns {Object} - reference to instance\n */\n initActivation: function (elem) {\n var elems = this.elems(),\n isFirst = !elems.indexOf(elem);\n\n if (isFirst || elem.active()) {\n elem.activate();\n }\n\n return this;\n },\n\n /**\n * Delegates 'validate' method on element, then reads 'invali
2d' property\n * of params storage, and if defined, activates element, sets\n * 'allValid' property of instance to false and sets invalid's\n * 'focused' property to true.\n *\n * @param {Object} elem\n */\n validate: function (elem) {\n var result = elem.delegate('validate'),\n invalid;\n\n invalid = _.find(result, function (item) {\n return !item.valid;\n });\n\n if (invalid) {\n elem.activate();\n invalid.target.focused(true);\n }\n\n return invalid;\n },\n\n /**\n * Sets 'allValid' property of instance to true, then calls 'validate' method\n * of instance for each element.\n */\n onValidate: function () {\n this.elems.sortBy(function (elem) {\n return !elem.active();\n }).some(this.validate, this);\n }\n });\n});\n","Magento_Ui/js/form/components/button.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'uiElement',\n 'uiRegistry',\n 'uiLayout',\n 'mageUtils',\n 'underscore'\n], function (Element, registry, layout, utils, _) {\n 'use strict';\n\n return Element.extend({\n defaults: {\n buttonClasses: {},\n additionalClasses: {},\n displayArea: 'outsideGroup',\n displayAsLink: false,\n elementTmpl: 'ui/form/element/button',\n template: 'ui/form/components/button/simple',\n visible: true,\n disabled: false,\n title: ''\n },\n\n /**\n * Initializes component.\n *\n * @returns {Object} Chainable.\n */\n initialize: function () {\n return this._super()\n ._setClasses()\n ._setButtonClasses();\n },\n\n /** @inheritdoc */\n initObservable: function () {\n return this._super()\n .observe([\n 'visible',\n 'disabled',\n 'title'\n ]);\n },\n\n /**\n * Performs configured actions\n */\n action: function () {\n this.actions.forEach(this.applyAction, this);\n },\n\n /**\n * Apply action on target component,\n * but previously create this component from template if it is not existed\n *\n * @param {Object} action - action configuration\n */\n applyAction: function (action) {\n var targetName = action.targetName,\n params = utils.copy(action.params) || [],\n actionName = action.actionName,\n target;\n\n if (!registry.has(targetName)) {\n this.getFromTemplate(targetName);\n }\n target = registry.async(targetName);\n\n if (target && typeof target === 'function' && actionName) {\n params.unshift(actionName);\n target.apply(target, params);\n }\n },\n\n /**\n * Create target component from template\n *\n * @param {Object} targetName - name of component,\n * that supposed to be a template and need to be initialized\n */\n getFromTemplate: function (targetName) {\n var parentName = targetName.split('.'),\n index = parentName.pop(),\n child;\n\n parentName = parentName.join('.');\n child = utils.template({\n parent: parentName,\n name: index,\n nodeTemplate: targetName\n });\n layout([child]);\n },\n\n /**\n * Extends 'additionalClasses' object.\n *\n * @returns {Object} Chainable.\n */\n _setClasses: function () {\n if (typeof this.additionalClasses === 'string') {\n if (this.additionalClasses === '') {\n this.additionalClasses = {};\n\n return this;\n }\n\n this.additionalClasses = this.additionalClasses\n .trim()\n .split(' ')\n .reduce(function (classes, name) {\n classes[name] = true;\n\n return classes;\n }, {}\n );\n }\n\n return this;\n }
2,\n\n /**\n * Extends 'buttonClasses' object.\n *\n * @returns {Object} Chainable.\n */\n _setButtonClasses: function () {\n var additional = this.buttonClasses;\n\n if (_.isString(additional)) {\n this.buttonClasses = {};\n\n if (additional.trim().length) {\n additional = additional.trim().split(' ');\n\n additional.forEach(function (name) {\n if (name.length) {\n this.buttonClasses[name] = true;\n }\n }, this);\n }\n }\n\n _.extend(this.buttonClasses, {\n 'action-basic': !this.displayAsLink,\n 'action-additional': this.displayAsLink\n });\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/components/tab.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'uiCollection'\n], function (Collection) {\n 'use strict';\n\n return Collection.extend({\n defaults: {\n uniqueProp: 'active',\n active: false,\n wasActivated: false\n },\n\n /**\n * Extends instance with defaults. Invokes parent initialize method.\n * Calls initListeners and pushParams methods.\n */\n initialize: function () {\n this._super()\n .setUnique();\n },\n\n /**\n * Calls initObservable of parent class.\n * Defines observable properties of instance.\n * @return {Object} - reference to instance\n */\n initObservable: function () {\n this._super()\n .observe('active wasActivated');\n\n return this;\n },\n\n /**\n * Sets active property to true, then invokes pushParams method.\n */\n activate: function () {\n this.active(true);\n this.wasActivated(true);\n\n this.setUnique();\n\n return true;\n }\n });\n});\n","Magento_Ui/js/form/components/html.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 'uiComponent'\n], function ($, _, Component) {\n 'use strict';\n\n return Component.extend({\n defaults: {\n content: '',\n showSpinner: false,\n loading: false,\n visible: true,\n error: false,\n template: 'ui/content/content',\n additionalClasses: {},\n ignoreTmpls: {\n content: true\n }\n },\n\n /**\n * Extends instance with default config, calls 'initialize' method of\n * parent, calls 'initAjaxConfig'\n */\n initialize: function () {\n _.bindAll(this, 'onContainerToggle', 'onDataLoaded');\n\n this._super()\n ._setClasses()\n .initAjaxConfig();\n\n return this;\n },\n\n /**\n * Calls 'initObservable' method of parent, initializes observable\n * properties of instance\n *\n * @return {Object} - reference to instance\n */\n initObservable: function () {\n this._super()\n .observe('content loading visible');\n\n return this;\n },\n\n /**\n * Extends 'additionalClasses' object.\n *\n * @returns {Group} Chainable.\n */\n _setClasses: function () {\n var additional = this.additionalClasses,\n classes;\n\n if (_.isString(additional)) {\n additional = this.additionalClasses.split(' ');\n classes = this.additionalClasses = {};\n\n additional.forEach(function (name) {\n classes[name] = true;\n }, this);\n }\n\n _.extend(this.additionalClasses, {\n 'admin__scope-old': !!additional\n });\n\n return this;\n },\n\n /** @inheritdoc */\n initContainer: function (parent) {\n this._super();\n\n parent.on('active', this.onContainerToggle);\n\n return this;\n },\n\n /**\n * Initializes default ajax config on instance\n *\n * @return {Object} - reference to instance\n */\n initAjaxConfig: function () {\n this.ajaxConfig = {\n url: this.url,\n data: {\n FORM_KEY: window.FORM_KEY\n },\n success: this.onDataLoaded\n };\n\n return this;\n },\n\n /**\n * Calls 'loadData' if both 'active' variable and 'shouldLoad'\n * property are truthy\n *\n * @param {Boolean} active\n */\n onContainerToggle: function (active) {\n if (active && this.shouldLoad()) {\n this.loadData();\n }\n },\n\n /**\n * Defines if instance has 'content' property defined.\n *\n * @return {Boolean} [description]\n */\n hasData: function () {\n return !!this.content();\n },\n\n /**\n * Defines if instance should load external data\n *\n * @return {Boolean}\n */\n shouldLoad: function () {\n return this.url && !this.hasData() && !this.loading();\n },\n\n /**\n * Sets loading property to true, makes ajax call\n *\n * @return {Object}
2 - reference to instance\n */\n loadData: function () {\n this.loading(true);\n\n $.ajax(this.ajaxConfig);\n\n return this;\n },\n\n /**\n * Ajax's request success handler. Calls 'updateContent' passing 'data'\n * to it, then sets 'loading' property to false.\n *\n * @param {String} data\n */\n onDataLoaded: function (data) {\n this.updateContent(data)\n .loading(false);\n },\n\n /**\n * Sets incoming data 'content' property's value\n *\n * @param {String} content\n * @return {Object} - reference to instance\n */\n updateContent: function (content) {\n this.content(content);\n\n return this;\n }\n });\n});\n","Magento_Ui/js/form/components/collection/item.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'underscore',\n 'mageUtils',\n '../tab'\n], function (_, utils, Tab) {\n 'use strict';\n\n var previewConfig = {\n separator: ' ',\n prefix: ''\n };\n\n /**\n * Parses incoming data and returnes result merged with default preview config\n *\n * @param {Object|String} data\n * @return {Object}\n */\n function parsePreview(data) {\n if (typeof data == 'string') {\n data = {\n items: data\n };\n }\n\n data.items = utils.stringToArray(data.items);\n\n return _.defaults(data, previewConfig);\n }\n\n return Tab.extend({\n defaults: {\n label: '',\n uniqueNs: 'activeCollectionItem',\n previewTpl: 'ui/form/components/collection/preview'\n },\n\n /**\n * Extends instance with default config, calls initializes of parent class\n */\n initialize: function () {\n _.bindAll(this, 'buildPreview', 'hasPreview');\n\n return this._super();\n },\n\n /**\n * Calls initProperties of parent class, initializes properties\n * of instance.\n *\n * @return {Object} - reference to instance\n */\n initConfig: function () {\n this._super();\n\n this.displayed = [];\n\n return this;\n },\n\n /**\n * Calls initObservable of parent class, initializes observable\n * properties of instance.\n *\n * @return {Object} - reference to instance\n */\n initObservable: function () {\n this._super()\n .observe({\n noPreview: true,\n indexed: {}\n });\n\n return this;\n },\n\n /**\n * Is being called when child element has been initialized,\n * calls initElement of parent class, binds to element's update event,\n * calls insertToArea and insertToIndexed methods passing element to it\n *\n * @param {Object} elem\n */\n initElement: function (elem) {\n this._super()\n .insertToIndexed(elem);\n\n return this;\n },\n\n /**\n * Adds element to observable indexed object of instance\n *\n * @param {Object} elem\n * @return {Object} - reference to instance\n */\n insertToIndexed: function (elem) {\n var indexed = this.indexed();\n\n indexed[elem.index] = elem;\n\n this.indexed(indexed);\n\n return this;\n },\n\n /**\n * Destroys current instance along with all of its' children.\n * Overrides base method to clear data when this method is called.\n */\n destroy: function () {\n this._super();\n this._clearData();\n },\n\n /**\n * Clears all data associated with component.\n * @private\n *\n * @returns {Item} Chainable.\n */\n _clearData: function () {\n this.source.remove(this.dataScope);\n\n return this;\n },\n\n /**\n * Formats incoming previews array via parsePreview function.\n *\n * @param {Array} previews\n * @return {Array} - formatted previews\n */\n formatPreviews: function (previews) {\n return previews.map(parsePreview);\n },\n\n /**\n * Creates string view of previews\n *\n * @param {Object} data\n * @return {Strict} - formatted preview string\n */\n buildPreview: function (data) {\
2n var preview = this.getPreview(data.items),\n prefix = data.prefix;\n\n return prefix + preview.join(data.separator);\n },\n\n /**\n * Defines if instance has preview for incoming data\n *\n * @param {Object} data\n * @return {Boolean}\n */\n hasPreview: function (data) {\n return !!this.getPreview(data.items).length;\n },\n\n /**\n * Creates an array of previews for elements specified in incoming\n * items array, calls updatePreview afterwards.\n *\n * @param {Array} items - An array of element's indexes.\n * @returns {Array} An array of previews.\n */\n getPreview: function (items) {\n var elems = this.indexed(),\n displayed = this.displayed,\n preview;\n\n items = items.map(function (index) {\n var elem = elems[index];\n\n preview = elem && elem.visible() ? elem.getPreview() : '';\n\n preview = Array.isArray(preview) ?\n _.compact(preview).join(', ') :\n preview;\n\n utils.toggle(displayed, index, !!preview);\n\n return preview;\n });\n\n this.noPreview(!displayed.length);\n\n return _.compact(items);\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',\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: 2,\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 = false;\n this.element.removeAttr('aria-expanded');\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')) {\
2n 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 this.searchForm.toggleClass('active', isActive);\n this.searchLabel.toggleClass('active', isActive);\n\n if (this.isExpandable) {\n this.element.attr('aria-expanded', isActive);\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 this.searchForm.trigger('submit');\n e.preventDefault();\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 }\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 }\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(),\
2n 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 = isEmpty(value);\n\n if (value.length >= parseInt(this.options.minSearchLength, 10)) {\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.responseList.indexList = this.autoComplete.html(dropdown)\n .css(clonePosition)\n .show()\n .find(this.options.responseFieldElements + ':visible');\n\n this._resetResponseList(false);\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 }\n }, this));\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","Idus_Social/js/share.js":"define([\n\t'jquery',\n\t'Idus_Core/js/idus'\n], function ($, idus) {\n\t'use strict';\n\treturn function () {\n\t\t$('a.social-links').off('click').on('click', function () {\n\t\t\tvar btn = $(this);\n\t\t\tvar element = $(this).closest('.product-page');\n\t\t\tif(!element.length) element = $('.product-page:eq(0)');\n\t\t\tvar eventProps = false;\n\t\t\tif(window.idusDataLayer.products && window.idusDataLayer.products[element.data('id')]){\n\t\t\t\teventProps = {\n\t\t\t\t\tsku: window.idusDataLayer.products[element.data('id')].sku,\n\t\t\t\t\tid: element.data('id'),\n\t\t\t\t\tplatform: 'unknown'\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (!window.navigator.share) {\n\t\t\t\tvar parent = $(this).closest('div.social-links');\n\t\t\t\t$('.social-list', parent).slideToggle();\n\n\t\t\t\tif(btn.attr('aria-expanded') == 'true'){\n\t\t\t\t\tbtn.attr('aria-expanded', 'false');\n\t\t\t\t}else{\n\t\t\t\t\tbtn.attr('aria-expanded', 'true');\n\t\t\t\t}\n\t\t\t\t\n\t\t\t} else {\n\t\t\t\tvar shareData = $(this).closest('[data-share-title]');\n\t\t\t\tlet shareText = shareData.data('share-text').replace(/\\\\n/g, \"\\n\");\n\t\t\t\tvar url = shareData.data('share-url');\n\t\t\t\tif (window.customProductUrl) {\n\t\t\t\t\turl = window.customProductUrl;\n\t\t\t\t}\n\t\t\t\tnavigator.share({\n\t\t\t\t\ttitle: shareData.data('share-title'),\n\t\t\t\t\ttext: shareText,\n\t\t\t\t\turl: url\n\t\t\t\t}).then(function (res) {\n\t\t\t\t\t$(document).trigger('idus-productShare', [eventProps]);\n\t\t\t\t}).catch(function (err) {\n\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t$('.social-option').off('click').on('click', function (e) {\n\t\t\tvar self = $(this);\n\t\t\tvar parent = $(this).closest('div.social-links');\n\t\t\tvar url = $('a', self).attr('data-href');\n\t\t\tif (parent.hasClass('product')) {\n\t\t\t\turl = window.location.href;\n\t\t\t}\n\n\t\t\tif (window.customProductUrl) {\n\t\t\t\turl = window.customProductUrl;\n\t\t\t}\n\n\t\t\tif (self.hasClass('copyurl')) {\n\t\t\t\tidus.copy().copy(url);\n\t\t\t\te.preventDefault();\n\t\t\t} else {\n\t\t\t\t$('a', self).attr('href', $('a', self).attr('href').replace('%url_page%', url).replace('%name_page%', document.title));\n\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t$('a', self).attr('href', $('a', self).attr('href').replace(url, '%url_page%'));\n\t\t\t\t}, 500);\n\t\t\t}\n\t\t\t$('.social-list', parent).slideToggle();\n\t\t});\n\t}\n});","Idus_Social/js/social_post.js":"define([\n\t\t'jquery',\n\t\t'Idus_Core/js/idus',\n\t\t'Idus_Core/js/url',\n\t\t'Magento_Ui/js/modal/modal',\n\t\t'embeds',\n\t\t'idus_slider'\n\t],\n\tfunction ($, idus, url, modal, embeds, IdusSlider) {\n\t\t'use strict';\n\n\t\treturn function (data, el) {\n\t\t\tvar wrapper = $(el).closest('.social_posts');\n\t\t\tvar load_more = $('.social_post.load_more', wrapper);\n\n\t\t\t// init slider\n\t\t\tvar socialSlider = new IdusSlider(wrapper.get(0), {\n\t\t\t\tdots: data.dots,\n\t\t\t\tarrows: true,\n\t\t\t\tresponsive: [{\n\t\t\t\t\t\tbreakpoint: 1199,\n\t\t\t\t\t\tsettings: {\n\t\t\t\t\t\t\tslidesToScroll: parseInt($('.social_posts_content', wrapper).attr('show_tb')),\n\t\t\t\t\t\t\tslidesToShow: parseInt($('.social_posts_content', wrapper).attr('show_tb'))\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tbreakpoint: 767,\n\t\t\t\t\t\tsettings: {\n\t\t\t\t\t\t\tslidesToScroll: parseInt($('.social_posts_content', wrapper).attr('show_sp')),\n\t\t\t\t\t\t\tslidesToShow: parseInt($('.social_posts_content', wrapper).attr('show_sp'))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\tslidesToScroll: parseInt($('.social_posts_content', wrapper).attr('show_dt')),\n\t\t\t\tslidesToShow: parseInt($('.social_posts_content', wrapper).attr('show_dt'))\n\t\t\t}, {\n\t\t\t\tslides: '.idus-slider-slide'\n\t\t\t});\n\n\t\t\tsocialSlider.initControls();\n\t\t\tsocialSlider.initScroll();\n\n\t\t\tsocialSlider.checkIfOverflowing();\n\n\t\t\tsocialSlider.initSlides();\n\n\t\t\tif (localStorage.getItem('idus-slider-debug')) socialSlider.initDebugWindow();\n\n\t\t\tsocialSlider.attachMouseEvents();\n\t\t\tsocialSlider.initAutoplay();\n\n\t\t\tvar innerScroll = true;\n\t\t\tif ($(window).width() > 767) {\n\t\t\t\tinnerScroll = false;\n\t\t\t}\n\n\t\t\tvar object = $('#popup_modal_social_post_'+wrapper.attr('data-platform'));\n\n\t\t\tvar options = {\n\t\t\t\ttype: 'popup',\n\t\t\t\ttitle: false,\n\t\t\t\tresponsive: true,\n\t\t\t\tinnerScroll: innerScroll,\n\t\t\t\tmodalClass: 'popup_social_post',\n\t\t\t\tbuttons: [{\n\t\t\t\t\ttext: $.mage.__('\u05d4\u05e7\u05d5\u05d3\u05dd'),\n\t\t\t\t\tattr: {\n\t\t\t\t\t\t'data-action': 'prev'\n\t\t\t\t\t},\n\t\t\t\t\t'class': 'action primary no_loading',\n\t\t\t\t\tclick: function () {\n\t\t\t\t\t\tgoTo('prev');\n\t\t\t\t\t}\n\t\t\t\t}, {\n\t\t\t\t\ttext: $.mage.__('\u05d4\u05d1\u05d0'),\n\t\t\t\t\tattr: {\n\t\t\t\t\t\t'data-action': 'next'\n\t\t\t\t\t},\n\t\t\t\t\t'class': 'action primary no_loading',\n\t\t\t\t\tclick: function () {\n\t\t\t\t\t\tgoTo('next');\n\t\t\t\t\t}\n\t\t\t\t}],\n\t\t\t\tclosed: function () {\n\n\t\t\t\t\tif (!window.socialPost) return;\n\t\t\t\t\tvar products = $('.product_wrap', object).detach();\n\t\t\t\t\tproducts.hide();\n\t\t\t\t\tif (!$('.product_wrap', window.socialPost).length) $('<
2div class=\"product_wrap\"></div>').appendTo(window.socialPost);\n\t\t\t\t\t$('.product_wrap', window.socialPost).replaceWith(products);\n\t\t\t\t\twindow.socialPost = false;\n\t\t\t\t},\n\t\t\t};\n\t\t\t\n\t\t\tif (object.attr('init') == undefined) {\n\t\t\t\tmodal(options, object);\n\t\t\t\tobject.attr('init', 1);\n\t\t\t}\n\n\t\t\tfunction goTo(action) {\n\t\t\t\tvar id = object.attr('data-post');\n\t\t\t\tvar item = $('.social_post_' + id, wrapper);\n\t\t\t\tvar element = item.next();\n\t\t\t\tif (action == 'prev') element = item.prev();\n\t\t\t\tvar next = element;\n\t\t\t\tif (!next.length) {\n\t\t\t\t\tif ($('.social_post.load_more', wrapper).length) {\n\t\t\t\t\t\t$('button', load_more).attr('next', 'true').click();\n\t\t\t\t\t\t$('.loading', object).show();\n\t\t\t\t\t\t$('.content,.embeds,.default', object).hide();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnext = $('.social_post:eq(0)', wrapper);\n\t\t\t\t\t\tif (action == 'prev') next = $('.social_post:last-child', wrapper);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnext.click();\n\t\t\t}\n\n\t\t\tvar ajaxCall = false;\n\t\t\t$('button', load_more).on('click', function () {\n\n\t\t\t\tvar ajaxUrl = url.getUrl('social/post/more');\n\t\t\t\tif (ajaxCall) ajaxCall.abort();\n\t\t\t\tdata['page'] = (wrapper.attr('page') * 1) + 1;\n\t\t\t\tajaxCall = $.ajax({\n\t\t\t\t\turl: ajaxUrl,\n\t\t\t\t\ttype: \"POST\",\n\t\t\t\t\tdataType: \"json\",\n\t\t\t\t\tdata: data,\n\t\t\t\t\tbeforeSend: function () {\n\t\t\t\t\t\t$('.idus_social_post', load_more).addClass('active');\n\t\t\t\t\t\t$('button', load_more).hide();\n\t\t\t\t\t},\n\n\t\t\t\t\tcomplete: function (response) {\n\t\t\t\t\t\t$('.idus_social_post', load_more).removeClass('active');\n\t\t\t\t\t\t$('button', load_more).show();\n\t\t\t\t\t\tload_more.parent().append(load_more);\t\t\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t}).done(\n\t\t\t\t\tfunction (response) {\n\t\t\t\t\t\tif (response.success) {\n\t\t\t\t\t\t\tif (!response.load_more) {\n\t\t\t\t\t\t\t\tload_more.remove();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\twrapper.attr('page', response.page);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$.each(response.items, function () {\n\t\t\t\t\t\t\t\t$('.social_posts_list', wrapper).append(this);\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t$('.social_posts_list', wrapper).trigger('contentUpdated');\n\n\t\t\t\t\t\t\tif ($('button', load_more).attr('next') == 'true') {\n\t\t\t\t\t\t\t\t$('button', load_more).attr('next', 'false');\n\t\t\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\t\t\t$('.popup_social_post [data-action=\"next\"]').click();\n\t\t\t\t\t\t\t\t}, 100);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tsocialSlider.reInit();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.log(response);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t).fail(\n\t\t\t\t\tfunction (response) {\n\t\t\t\t\t\tconsole.log(response);\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t});\n\n\t\t\t$(document).on('click', '.popup_social_post .product_quickview', function () {\n\t\t\t\tobject.modal('closeModal');\n\t\t\t});\n\n\t\t\twrapper.on('click', '.social_post:not(.load_more)', function (e) {\n\t\t\t\tif($(e.target).hasClass('swatch-option')) return;\n\t\t\t\tvar self = $(this);\n\n\t\t\t\tif(self.hasClass('show')) return;\n\t\t\t\tself.addClass('show');\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tself.removeClass('show');\n\t\t\t\t},1000);\n\n\t\t\t\tvar object = $('#popup_modal_social_post_'+self.attr('platform'));\n\n\t\t\t\tif (!object.length) {\n\t\t\t\t\tobject = $('#popup_modal_social_post_'+wrapper.data('platform'));\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t$('.loading', object).show();\n\n\t\t\t\t// $('.embeds', object).show().html('<blockquote class=\"instagram-media w_100\" data-instgrm-captioned data-instgrm-version=\"7\"><a href=\"' + $('a', self).attr('data-href') + '\" target=\"_blank\"></a></blockquote>');\n\n\t\t\t\t$('.default', object).show();\n\t\t\t\t\n\t\t\t\t$('.default .additional', object).html($('.additional', self).html());\n\t\t\t\t$('.default .description', object).html($('img', self).data('title')).attr('dir', idus.getDir($('img', self).data('title')));\n\t\t\t\t$('.default .link a', object).attr('href', $('a', self).data('href'));\n\t\t\t\t$('.default img', object).show().attr('src', $('img', self).data('src'));\n\n\t\t\t\tif($('img', self).attr('embed')){\n\t\t\t\t\t$('.default .embed', object).show().html(JSON.parse($('img', self).attr('embed')));\n\t\t\t\t}else{\n\t\t\t\t\t$('.default .embed', object).hide().html('');\n\t\t\t\t}\n\n\t\t\t\tif (self.attr('type') == 'video') {\n\t\t\t\t\t$('.default video', object).show();\n\t\t\t\t\t$('.default video source').attr('src', $('img', self).attr('video'));\n\t\t\t\t\tvar video = $('.default video', object).clone();\n\t\t\t\t\t$('.default .video video', object).remove();\n\t\t\t\t\t$('.default .video').append(video);\n\t\t\t\t\t$('.default .img_wrap').hide();\n\t\t\t\t\t$('.default', object).addClass('has-video');\n\t\t\t\t\t$('.popup_social_post').on('modalclosed', function() { \n\t\t\t\t\t\tvideo.trigger('pause');\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t$('.default video', object).hide();\n\t\t\t\t\t$('.default video source').attr('src', '//:0');\n\t\t\t\t\t$('.default .img_wrap').show();\n\t\t\t\t\t$('.default', object).removeClass('has-video');\n\t\t\t\t}\n\n\t\t\t\t$(object).attr('data-post', self.attr('data-post'));\n\t\t\t\tvar product = $('.product_wrap', self).html();\n\t\t\t\tif (!product || product.trim() === '') {\n\t\t\t\t\tproduct = '';\n\t\t\t\t\t$('.social_post_wrap', object).attr('data-empty', true);\n\t\t\t\t} else {\n\t\t\t\t\t$('.social_post_wrap', object).attr('data-empty', false);\n\t\t\t\t}\n\t\t\t\tvar products = $('.product_wrap', self).detach();
2\n\t\t\t\tif (!$('.product_wrap', object).length) $('<div class=\"product_wrap\"></div>').appendTo($('.content', object));\n\t\t\t\telse $('.product_wrap', object).hide();\n\t\t\t\t$('.product_wrap', object).replaceWith(products);\n\t\t\t\t$('.product_wrap', object).show();\n\n\t\t\t\tobject.modal('openModal');\n\t\t\t\twindow.socialPost = self;\n\t\t\t\t// window.instgrm.Embeds.process();\n\n\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t$('.loading', object).hide();\n\t\t\t\t\t$(window).trigger('scroll');\n\t\t\t\t\t$('.instagram-media', object).attr('style', 'opacity: 1 !important; display: block !important;');\n\t\t\t\t}, 100);\n\t\t\t});\n\t\t}\n\t}\n);","Idus_Social/js/embeds.min.js":"(function(){\nvar global=this;\nvar __BUNDLE_START_TIME__=this.nativePerformanceNow?nativePerformanceNow():Date.now(),__DEV__=false,process=this.process||{};process.env=process.env||{};process.env.NODE_ENV=process.env.NODE_ENV||\"production\";!(function(t){\"use strict\";function e(){return s=Object.create(null)}function r(t){const e=t,r=s[e];return r&&r.isInitialized?r.publicModule.exports:i(e,r)}function n(t){const e=t;if(s[e]&&s[e].importedDefault!==f)return s[e].importedDefault;const n=r(e),o=n&&n.__esModule?n.default:n;return s[e].importedDefault=o}function o(t){const e=t;if(s[e]&&s[e].importedAll!==f)return s[e].importedAll;const n=r(e);let o;if(n&&n.__esModule)o=n;else{if(o={},n)for(const t in n)a.call(n,t)&&(o[t]=n[t]);o.default=n}return s[e].importedAll=o}function i(e,r){if(!p&&t.ErrorUtils){p=!0;let n;try{n=c(e,r)}catch(e){t.ErrorUtils.reportFatalError(e)}return p=!1,n}return c(e,r)}function l(t){return{segmentId:t>>>h,localId:t&m}}function c(e,i){if(!i&&I.length>0){const t=l(e),r=t.segmentId,n=t.localId,o=I[r];null!=o&&(o(n),i=s[e])}const c=t.nativeRequire;if(!i&&c){const t=l(e),r=t.segmentId;c(t.localId,r),i=s[e]}if(!i)throw u(e);if(i.hasError)throw d(e,i.error);i.isInitialized=!0;const f=i,a=f.factory,p=f.dependencyMap;try{const l=i.publicModule;if(l.id=e,g.length>0)for(let t=0;t<g.length;++t)g[t].cb(e,l);return a(t,r,n,o,l,l.exports,p),i.factory=void 0,i.dependencyMap=void 0,l.exports}catch(t){throw i.hasError=!0,i.error=t,i.isInitialized=!1,i.publicModule.exports=void 0,t}}function u(t){let e='Requiring unknown module \"'+t+'\".';return Error(e)}function d(t,e){const r=t;return Error('Requiring module \"'+r+'\", which threw an exception: '+e)}t.__r=r,t.__d=function(t,e,r){null==s[e]&&(s[e]={dependencyMap:r,factory:t,hasError:!1,importedAll:f,importedDefault:f,isInitialized:!1,publicModule:{exports:{}}})},t.__c=e,t.__registerSegment=function(t,e){I[t]=e};var s=e();const f={},a={}.hasOwnProperty;r.importDefault=n,r.importAll=o;let p=!1;const h=16,m=65535;r.unpackModuleId=l,r.packModuleId=function(t){return(t.segmentId<<h)+t.localId};const g=[];r.registerHook=function(t){const e={cb:t};return g.push(e),{release:()=>{for(let t=0;t<g.length;++t)if(g[t]===e){g.splice(t,1);break}}}};const I=[]})('undefined'!=typeof global?global:'undefined'!=typeof window?window:this);\n__s={\"js\":{},\"css\":{}}\nvar __d=this.__d;\n__d(function(g,r,i,a,m,e,d){\"use strict\";function t(t){return!isNaN(Number(t))}function n(t,n){t.className+=' '+n}function o(t,n){t.className=t.className.replace(n,'')}function s(t){const n=document.getElementsByTagName('iframe');let o;for(let s=n.length-1;s>=0;s--){const c=n[s];if(c.contentWindow===t.source){o=c;break}}return o}function c(t){const n=t.clientWidth,o=window.devicePixelRatio;return n&&o?parseInt(n*o,10):0}function l(t){const n=t.match(_);return n?n[1].replace(/^https?:\\/\\/(www.)?/,'https://www.')+'/':null}function u(t){if(t.hasAttribute(S))return t.getAttribute(S);const n=t.getElementsByTagName('a');for(let t=n.length-1;t>=0;t--){const o=l(n[t].href);if(o)return o}return null}function p(t){'performance'in window&&null!=window.performance&&'object'==typeof window.performance&&'function'==typeof window.performance.now&&t(window.performance.now())}function f(t){if('performance'in window&&null!=window.performance&&'object'==typeof window.performance&&'function'==typeof window.performance.getEntries){const n=window.performance.getEntries().filter(t=>t.name.match(G));n&&n.length&&'fetchStart'in n[0]&&'responseEnd'in n[0]&&t(n[0].fetchStart,n[0].responseEnd)}}function w(s,l){const u=W++,w=E+u,h={};s.id||(s.id=$+u);let y=l.replace(I,'$1/');if(y+='embed/',s.hasAttribute(A)&&(y+='captioned/'),y+='?cr=1',s.hasAttribute(M)){const n=parseInt(s.getAttribute(M),10);t(n)&&(y+='&v='+n)}const N=c(s);N&&(y+='&wp='+N.toString()),y+='&rd='+encodeURIComponent(window.location.origin);const C=window.location.pathname;if(C){const t=C+(window.location.search||'');y+='&rp='+encodeURIComponent(t.substring(0,200))}y=y.replace(j,k),h.ci=u,p(function(t){h.os=t}),f(function(t,n){h.ls=t,h.le=n});const U=encodeURIComponent(JSON.stringify(h)),B=document.createElement('iframe');
2B.className=s.className,B.id=w,B.src=y+'#'+U,B.setAttribute('allowTransparency','true'),B.setAttribute('allowfullscreen','true');const S=s.style.position;S&&B.setAttribute(v,S),B.setAttribute('frameBorder','0'),B.setAttribute('height','0'),B.setAttribute(L,s.id),B.setAttribute('scrolling','no'),B.setAttribute('style',s.style.cssText+';'+O),B.style.position='absolute',s.parentNode.insertBefore(B,s),n(s,T),o(s,R),P[w]=!0,p(function(t){K[w]={frameLoading:t}}),setTimeout(function(){b(w)},x)}function b(t){Object.prototype.hasOwnProperty.call(P,t)&&(delete P[t],y())}function h(t){if(!B.test(t.origin))return;const o=s(t);if(!o)return;const c=o.id;let l;try{l=JSON.parse(t.data)}catch(t){}if('object'!=typeof l||'string'!=typeof l.type||'object'!=typeof l.details)return;const{details:u,type:f}=l;let w=null;switch(f){case i(d[0]).MOUNTED:{const t=document.getElementById(o.getAttribute(L));if(t||i(d[1])(0),w=t.clientHeight,o.style.position=o.hasAttribute(v)?o.getAttribute(v):'','object'==typeof u.styles&&u.styles.length)try{for(let t=0;t<u.styles.length;t++){const n=u.styles[t][0],s=u.styles[t][1];o.style[n]=s}}catch(t){}n(o,U),t.parentNode&&t.parentNode.removeChild(t),b(c),p(function(t){K[c]&&(K[c].contentLoaded=t,window.__igEmbedLoaded&&window.__igEmbedLoaded({frameId:c,stats:K[c]}))});break}case i(d[0]).LOADING:p(function(t){K[c]&&(K[c].contentLoading=t)});break;case i(d[0]).MEASURE:{const t=u.height;D[c]!==t&&(w=t);break}case i(d[0]).UNMOUNTING:delete D[c]}null!==w&&(o.height=D[c]=w)}function y(){const t=document.getElementsByClassName(R);for(let n=0;n<t.length;n++){if(Object.keys(P).length>=C)break;const o=t[n];if('BLOCKQUOTE'===o.tagName){const t=u(o);t&&w(o,t)}}}function N(){if(!J){if(H)return;H=!0}i(d[2])(()=>{y(),J||(i(d[3]).add(window,'message',h.bind(this)),J=!0)})}const A='data-instgrm-captioned',E='instagram-embed-',x=1e4,O=\"\\n background-color: white;\\n border-radius: 3px;\\n border: 1px solid #dbdbdb;\\n box-shadow: none;\\n display: block;\\n margin: 0;\\n min-width: 326px;\\n padding: 0;\\n\",j=/^https?:\\/\\//,k='https://',I=/^(.*?)\\/?(\\?.*|#|$)/,C=3,R='instagram-media',T=\"instagram-media-registered\",U=\"instagram-media-rendered\",B=new RegExp(\"^https?://([\\\\w-]+\\\\.)*(\"+['instagram\\\\.com','instagr\\\\.am'].join('|')+\")$\"),L='data-instgrm-payload-id',$='instagram-media-payload-',S='data-instgrm-permalink',_=new RegExp('^('+B.source.replace(/^\\^/,'').replace(/\\$$/,'')+\"/p/[^/]+)\"),v='data-instgrm-preserve-position',G=new RegExp('^('+B.source.replace(/^\\^/,'').replace(/\\$$/,'')+'/embed\\\\.js)'),M='data-instgrm-version',D={};let J=!1;const P={};let W=0,H=!1;const K={};r(d[4]).getGlobalContext().process||(N(),r(d[4]).getGlobalContext().process=N)},0,[1,2,3,4,5]);\n__d(function(g,r,i,a,m,e,d){m.exports={MOUNTED:\"MOUNTED\",LOADING:\"LOADING\",UNMOUNTING:\"UNMOUNTING\",MEASURE:\"MEASURE\"}},1,[]);\n__d(function(g,r,i,a,m,e,d){'use strict';let n=r(d[0]);m.exports=function(o,t){if(!o){let o;if(void 0===t)o=new Error(\"Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.\");else{const l=[t];for(let n=2,o=arguments.length;n<o;n++)l.push(arguments[n]);(o=new Error(n.apply(null,l))).name='Invariant Violation',o.messageWithParams=l}throw o.framesToPop=1,o}}},2,[6]);\n__d(function(g,r,i,a,m,e,d){var n=function(...t){return(t=t.map(n=>String(n)))[0].split('%s').length!==t.length?n('ex args number mismatch: %s',JSON.stringify(t)):n._prefix+JSON.stringify(t)+n._suffix};n._prefix='<![EX[',n._suffix=']]>',m.exports=n},6,[]);\n__d(function(g,r,i,a,m,e,d){\"use strict\";function t(){if(!o)return;let t;for(;t=o.shift();)t();o=null}Object.defineProperty(e,'__esModule',{value:!0});let o=null;if(r(d[0]).canUseDOM){var n,u;const c=null===(n=document)||void 0===n?void 0:null===(u=n.documentElement)||void 0===u?void 0:u.doScroll;if(!('readyState'in document?'complete'===document.readyState||'loading'!==document.readyState&&!c:!!document.body)&&(o=[],i(d[1]).add(document,'DOMContentLoaded',t),i(d[1]).add(window,'load',t),c&&window===window.top)){const o=function(){try{c('left')}catch(t){return void setTimeout(o,0)}t()};o()}}e.default=function(t){o?o.push(t):t()}},3,[7,4]);\n__d(function(g,r,i,a,m,e,d){'use strict';const n=!('undefined'==typeof window||!window.document||!window.document.createElement||window._ssr),t={canUseDOM:n,canUseWorkers:'undefined'!=typeof Worker,canUseEventListeners:n&&!(!window.addEventListener&&!window.attachEvent),canUseVie
2wport:n&&!!window.screen,isInWorker:!n};m.exports=t},7,[]);\n__d(function(g,r,i,a,m,e,d){\"use strict\";Object.defineProperty(e,'__esModule',{value:!0});let t=!1;const n=i(d[0])(()=>{try{const n=Object.defineProperty({},'passive',{get:function(){t=!0}});r(d[1]).canUseDOM&&(window.addEventListener('test',null,n),window.removeEventListener('test',null,n))}catch(t){}return t}),s={capture:!1};class l{constructor(t){this.$EventListenerHelper1=null,this.$EventListenerHelper1=t}static add(t,o,c,u=s){let v=u;return n()||(v='boolean'!=typeof u&&!!u.capture),t.addEventListener(o,c,v),new l(()=>{t.removeEventListener(o,c,v)})}remove(){this.$EventListenerHelper1&&(this.$EventListenerHelper1(),this.$EventListenerHelper1=null)}}e.default=l},4,[8,7]);\n__d(function(g,r,i,a,m,e,d){function n(c,o){if('function'!=typeof c||null!=o&&'function'!=typeof o)throw new TypeError(t);var f=function(){var n=arguments,t=o?o.apply(this,n):n[0],u=f.cache;if(u.has(t))return u.get(t);var h=c.apply(this,n);return f.cache=u.set(t,h)||u,h};return f.cache=new(n.Cache||r(d[0])),f}var t='Expected a function';n.Cache=r(d[0]),m.exports=n},8,[9]);\n__d(function(g,r,i,a,m,e,d){function t(t){var o=-1,p=null==t?0:t.length;for(this.clear();++o<p;){var l=t[o];this.set(l[0],l[1])}}t.prototype.clear=r(d[0]),t.prototype.delete=r(d[1]),t.prototype.get=r(d[2]),t.prototype.has=r(d[3]),t.prototype.set=r(d[4]),m.exports=t},9,[10,11,12,13,14]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(){this.size=0,this.__data__={hash:new(r(d[0])),map:new(r(d[1])||r(d[2])),string:new(r(d[0]))}}},10,[15,16,17]);\n__d(function(g,r,i,a,m,e,d){function t(t){var o=-1,p=null==t?0:t.length;for(this.clear();++o<p;){var l=t[o];this.set(l[0],l[1])}}t.prototype.clear=r(d[0]),t.prototype.delete=r(d[1]),t.prototype.get=r(d[2]),t.prototype.has=r(d[3]),t.prototype.set=r(d[4]),m.exports=t},15,[18,19,20,21,22]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(){this.__data__=r(d[0])?r(d[0])(null):{},this.size=0}},18,[23]);\n__d(function(g,r,i,a,m,e,d){var t=r(d[0])(Object,'create');m.exports=t},23,[24]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(n,o){var t=r(d[0])(n,o);return r(d[1])(t)?t:void 0}},24,[25,26]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(n,o){return null==n?void 0:n[o]}},25,[]);\n__d(function(g,r,i,a,m,e,d){var t=/^\\[object .+?Constructor\\]$/,o=Function.prototype,n=Object.prototype,c=o.toString,p=n.hasOwnProperty,u=RegExp('^'+c.call(p).replace(/[\\\\^$.*+?()[\\]{}|]/g,'\\\\$&').replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g,'$1.*?')+'$');m.exports=function(o){return!(!r(d[0])(o)||r(d[1])(o))&&(r(d[2])(o)?u:t).test(r(d[3])(o))}},26,[27,28,29,30]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(n){var t=typeof n;return null!=n&&('object'==t||'function'==t)}},27,[]);\n__d(function(g,r,i,a,m,e,d){var n=(function(){var n=/[^.]+$/.exec(r(d[0])&&r(d[0]).keys&&r(d[0]).keys.IE_PROTO||'');return n?'Symbol(src)_1.'+n:''})();m.exports=function(t){return!!n&&n in t}},28,[31]);\n__d(function(g,r,i,a,m,e,d){m.exports=r(d[0])['__core-js_shared__']},31,[32]);\n__d(function(g,r,i,a,m,e,d){var t='object'==typeof self&&self&&self.Object===Object&&self,f=r(d[0])||t||Function('return this')();m.exports=f},32,[33]);\n__d(function(g,r,i,a,m,e,d){var t='object'==typeof g&&g&&g.Object===Object&&g;m.exports=t},33,[]);\n__d(function(g,r,i,a,m,e,d){var n='[object AsyncFunction]',t='[object Function]',o='[object GeneratorFunction]',c='[object Proxy]';m.exports=function(u){if(!r(d[0])(u))return!1;var b=r(d[1])(u);return b==t||b==o||b==n||b==c}},29,[27,34]);\n__d(function(g,r,i,a,m,e,d){var n='[object Null]',t='[object Undefined]',o=r(d[0])?r(d[0]).toStringTag:void 0;m.exports=function(c){return null==c?void 0===c?t:n:o&&o in Object(c)?r(d[1])(c):r(d[2])(c)}},34,[35,36,37]);\n__d(function(g,r,i,a,m,e,d){m.exports=r(d[0]).Symbol},35,[32]);\n__d(function(g,r,i,a,m,e,d){var t=Object.prototype,o=t.hasOwnProperty,n=t.toString,c=r(d[0])?r(d[0]).toStringTag:void 0;m.exports=function(t){var l=o.call(t,c),v=t[c];try{t[c]=void 0}catch(t){}var p=n.call(t);return l?t[c]=v:delete t[c],p}},36,[35]);\n__d(function(g,r,i,a,m,e,d){var t=Object.prototype.toString;m.exports=function(n){return t.call(n)}},37,[]);\n__d(function(g,r,i,a,m,e,d){var t=Function.prototype.toString;m.exports=function(n){if(null!=n){try{return t.call(n)}catch(t){}try{return n+''}catch(t){}}return''}},30,[]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(t){var s=this.has(t)&&delete this.__data__[t];return this.size-=s?1:0,s}},19,[]);\n__d(function(g,r,i,a,m,e,d){var _='__lodash_hash_undefined__',t=Object.prototype.hasOwnProperty;m.exports=function(n){var o=this.__data__;if(r(d[0])){var h=o[n];return h===_?void 0:h}return t.call(o,n)?o[n]:void 0}},20,[23]);\n__d(function(g,r,i,a,m,e,d){var t=Object.prototype.hasOwnProperty;m.exports=function(o){var n=this.__data__;return r(d[0])?void 0!==n[o]:t.call(n,o)}},21,[23]);\n__d(function(g,r,i,a,m,e,d){var _='__lodash_hash_undefined__';m.exports=function(s,t){var h=this.__data__;return this.size+=this.has(s)?0:1,h[s]=r(d[0])&&void 0===t?_:t,this}},22,[23]);\n__d(function(g,r,i,a,m,e,d){var n=r(d[0])(r(d[1]),'Map');m.exports=n},16,[24,32]);\n__d(function(g,r,i,a,m,e,d){function t(t){var o=-1,p=null==t?0:t.length;for(this.clear();++o<p;){var l=t[o];this.set(l[0],l[1])}}t.prototype.clear=r(d[0]),t.prototype.delete=r(d[1]),t.prototype.get=r(d[2]),t.prototype.has=r(d[3]),t.prototype.set=r(d[4]),m.exports=t},17,[38,39,40,41,42]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(){this.__data__=[],this.size=0}},38,[]);\n__d(function(g,r,i,a,m,e,d){var t=Array.prototype.splice;m.exports=function(n){var o=this.__data__,p=r(d[0])(o,n);return!(p<0||(p==o.length-1?o.pop():t.call(o,p,1),--this.size,0))}},39,[43]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(n,t){for(var f=n.length;f--;)if(r(d[0])(n[f][0],t))return f;return-1}},43,[44]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(n,t){return n===t||n!=n&&t!=t}},44,[]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(t){var _=this.__data__,n=r(d[0])(_,t);return n<0?void 0:_[n][1]}},40,[43]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(t){return r(d[0])(this.__data__,t)>-1}
2},41,[43]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(t,s){var _=this.__data__,n=r(d[0])(_,t);return n<0?(++this.size,_.push([t,s])):_[n][1]=s,this}},42,[43]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(t){var n=r(d[0])(this,t).delete(t);return this.size-=n?1:0,n}},11,[45]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(t,n){var _=t.__data__;return r(d[0])(n)?_['string'==typeof n?'string':'hash']:_.map}},45,[46]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(n){var o=typeof n;return'string'==o||'number'==o||'symbol'==o||'boolean'==o?'__proto__'!==n:null===n}},46,[]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(t){return r(d[0])(this,t).get(t)}},12,[45]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(n){return r(d[0])(this,n).has(n)}},13,[45]);\n__d(function(g,r,i,a,m,e,d){m.exports=function(s,t){var n=r(d[0])(this,s),h=n.size;return n.set(s,t),this.size+=n.size==h?0:1,this}},14,[45]);\n__d(function(g,r,i,a,m,e,d){\"use strict\";Object.defineProperty(e,'__esModule',{value:!0}),window.instgrm||(window.instgrm={Embeds:{}}),e.getGlobalContext=function(){return window.instgrm.Embeds}},5,[]);\nglobal.__r(0);\n}).call({});","Magento_Translation/js/i18n-config.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n(function () {\n 'use strict';\n\n require.config({\n config: {\n 'Magento_Ui/js/lib/knockout/bindings/i18n': {\n inlineTranslation: true\n }\n }\n });\n})();\n","Magento_Translation/js/add-class.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['jquery'], function ($) {\n 'use strict';\n\n return function (config, element) {\n $(element).addClass(config.class);\n };\n});\n","Magento_Customer/js/checkout-balance.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'jquery/ui'\n], function ($) {\n 'use strict';\n\n $.widget('mage.checkoutBalance', {\n /**\n * Initialize store credit events\n * @private\n */\n _create: function () {\n this.eventData = {\n price: this.options.balance,\n totalPrice: 0\n };\n this.element.on('change', $.proxy(function (e) {\n if ($(e.target).is(':checked')) {\n this.eventData.price = -1 * this.options.balance;\n } else {\n if (this.options.amountSubstracted) { //eslint-disable-line no-lonely-if\n this.eventData.price = parseFloat(this.options.usedAmount);\n this.options.amountSubstracted = false;\n } else {\n this.eventData.price = parseFloat(this.options.balance);\n }\n }\n this.element.trigger('updateCheckoutPrice', this.eventData);\n }, this));\n }\n });\n\n return $.mage.checkoutBalance;\n});\n","Magento_Customer/js/password-strength-indicator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'Magento_Customer/js/zxcvbn',\n 'mage/translate',\n 'mage/validation'\n], function ($, zxcvbn, $t) {\n 'use strict';\n\n $.widget('mage.passwordStrengthIndicator', {\n options: {\n cache: {},\n passwordSelector: '[type=password]',\n passwordStrengthMeterSelector: '[data-role=password-strength-meter]',\n passwordStrengthMeterLabelSelector: '[data-role=password-strength-meter-label]',\n formSelector: 'form',\n emailSelector: 'input[type=\"email\"]'\n },\n\n /**\n * Widget initialization\n * @private\n */\n _create: function () {\n this.options.cache.input = $(this.options.passwordSelector, this.element);\n this.options.cache.meter = $(this.options.passwordStrengthMeterSelector, this.element);\n this.options.cache.label = $(this.options.passwordStrengthMeterLabelSelector, this.element);\n\n // We need to look outside the module for backward compatibility, since someone can already use the module.\n // @todo Narrow this selector in 2.3 so it doesn't accidentally finds the email field from the\n // newsletter email field or any other \"email\" field.\n this.options.cache.email = $(this.options.formSelector).find(this.options.emailSelector);\n this._bind();\n },\n\n /**\n * Event binding, will monitor change, keyup and paste events.\n * @private\n */\n _bind: function () {\n this._on(this.options.cache.input, {\n 'change': this._calculateStrength,\n 'keyup': this._calculateStrength,\n 'paste': this._calculateStrength\n });\n\n if (this.options.cache.email.length) {\n this._on(this.options.cache.email, {\n 'change': this._calculateStrength,\n 'keyup': this._calculateStrength,\n 'paste': this._calculateStrength\n });\n }\n },\n\n /**\n * Calculate password strength\n * @private\n */\n _calculateStrength: function () {\n var password = this._getPassword(),\n isEmpty = password.length === 0,\n zxcvbnScore,\n displayScore,\n isValid;\n\n // Display score is based on combination of whether password is empty, valid, and zxcvbn strength\n if (isEmpty) {\n displayScore = 0;\n } else {\n this.options.cache.input.rules('add', {\n 'password-not-equal-to-user-name': this.options.cache.email.val()\n });\n\n // We should only perform this check in case there is an email field on screen\n if (this.options.cache.email.length &&\n password.toLowerCase() === this.options.cache.email.val().toLowerCase()) {\n displayScore = 1;\n } else {\n isValid = $.validator.validateSingleElement(this.options.cache.input);\n zxcvbnScore = zxcvbn(password).score;\n displayScore = isValid ? zxcvbnScore : 1;\n }\n }\n\n // Update label\n this._displayStrength(displayScore);\n }
2,\n\n /**\n * Display strength\n * @param {Number} displayScore\n * @private\n */\n _displayStrength: function (displayScore) {\n var strengthLabel = '',\n className;\n\n switch (displayScore) {\n case 0:\n strengthLabel = $t('No Password');\n className = 'password-none';\n break;\n\n case 1:\n strengthLabel = $t('Weak');\n className = 'password-weak';\n break;\n\n case 2:\n strengthLabel = $t('Medium');\n className = 'password-medium';\n break;\n\n case 3:\n strengthLabel = $t('Strong');\n className = 'password-strong';\n break;\n\n case 4:\n strengthLabel = $t('Very Strong');\n className = 'password-very-strong';\n break;\n }\n\n this.options.cache.meter\n .removeClass()\n .addClass(className);\n this.options.cache.label.text(strengthLabel);\n },\n\n /**\n * Get password value\n * @returns {*}\n * @private\n */\n _getPassword: function () {\n return this.options.cache.input.val();\n }\n });\n\n return $.mage.passwordStrengthIndicator;\n});\n","Magento_Customer/js/section-config.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['underscore'], function (_) {\n 'use strict';\n\n var baseUrls, sections, clientSideSections, canonize;\n\n /**\n * @param {String} url\n * @return {String}\n */\n canonize = function (url) {\n var route = url,\n key;\n\n for (key in baseUrls) { //eslint-disable-line guard-for-in\n route = url.replace(baseUrls[key], '');\n\n if (route != url) { //eslint-disable-line eqeqeq\n break;\n }\n }\n\n return route.replace(/^\\/?index.php\\/?/, '').toLowerCase();\n };\n\n return {\n /**\n * @param {String} url\n * @return {Array}\n */\n getAffectedSections: function (url) {\n var route = canonize(url),\n actions = _.find(sections, function (val, section) {\n var matched;\n\n if (section.indexOf('*') >= 0) {\n section = section.replace(/\\*/g, '[^/]+') + '$';\n matched = route.match(section);\n\n return matched && matched[0] == route; //eslint-disable-line eqeqeq\n }\n\n return route.indexOf(section) === 0;\n });\n\n return _.union(_.toArray(actions), _.toArray(sections['*']));\n },\n\n /**\n * @param {*} allSections\n * @return {*}\n */\n filterClientSideSections: function (allSections) {\n if (Array.isArray(allSections)) {\n return _.difference(allSections, clientSideSections);\n }\n\n return allSections;\n },\n\n /**\n * @param {String} sectionName\n * @return {Boolean}\n */\n isClientSideSection: function (sectionName) {\n return _.contains(clientSideSections, sectionName);\n },\n\n /**\n * @param {Object} options\n * @constructor\n */\n 'Magento_Customer/js/section-config': function (options) {\n baseUrls = options.baseUrls;\n sections = options.sections;\n clientSideSections = options.clientSideSections;\n }\n };\n});\n","Magento_Customer/js/address.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'Magento_Ui/js/modal/confirm',\n 'jquery/ui',\n 'mage/translate'\n], function ($, confirm) {\n 'use strict';\n\n $.widget('mage.address', {\n /**\n * Options common to all instances of this widget.\n * @type {Object}\n */\n options: {\n deleteConfirmMessage: $.mage.__('Are you sure you want to delete this address?')\n },\n\n /**\n * Bind event handlers for adding and deleting addresses.\n * @private\n */\n _create: function () {\n var options = this.options,\n addAddress = options.addAddress,\n deleteAddress = options.deleteAddress;\n\n if (addAddress) {\n $(document).on('click', addAddress, this._addAddress.bind(this));\n }\n\n if (deleteAddress) {\n $(document).on('click', deleteAddress, this._deleteAddress.bind(this));\n }\n },\n\n /**\n * Add a new address.\n * @private\n */\n _addAddress: function () {\n window.location = this.options.addAddressLocation;\n },\n\n /**\n * Delete the address whose id is specified in a data attribute after confirmation from the user.\n * @private\n * @param {jQuery.Event} e\n * @return {Boolean}\n */\n _deleteAddress: function (e) {\n var self = this;\n\n confirm({\n content: this.options.deleteConfirmMessage,\n actions: {\n\n /** @inheritdoc */\n confirm: function () {\n if (typeof $(e.target).parent().data('address') !== 'undefined') {\n window.location = self.options.deleteUrlPrefix + $(e.target).parent().data('address') +\n '/form_key/' + $.mage.cookies.get('form_key');\n } else {\n window.location = self.options.deleteUrlPrefix + $(e.target).data('address') +\n '/form_key/' + $.mage.cookies.get('form_key');\n }\n }\n }\n });\n\n return false;\n }\n });\n\n return $.mage.address;\n});\n","Magento_Customer/js/change-email-password.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'jquery',\n 'jquery/ui'\n], function ($) {\n 'use strict';\n\n $.widget('mage.changeEmailPassword', {\n options: {\n changeEmailSelector: '[data-role=change-email]',\n changePasswordSelector: '[data-role=change-password]',\n mainContainerSelector: '[data-container=change-email-password]',\n titleSelector: '[data-title=change-email-password]',\n emailContainerSelector: '[data-container=change-email]',\n newPasswordContainerSelector: '[data-container=new-password]',\n confirmPasswordContainerSelector: '[data-container=confirm-password]',\n currentPasswordSelector: '[data-input=current-password]',\n emailSelector: '[data-input=change-email]',\n newPasswordSelector: '[data-input=new-password]',\n confirmPasswordSelector: '[data-input=confirm-password]'\n },\n\n /**\n * Create widget\n * @private\n */\n _create: function () {\n this.element.on('change', $.proxy(function () {\n this._checkChoice();\n }, this));\n\n this._checkChoice();\n this._bind();\n },\n\n /**\n * Event binding, will monitor change, keyup and paste events.\n * @private\n */\n _bind: function () {\n this._on($(this.options.emailSelector), {\n 'change': this._updatePasswordFieldWithEmailValue,\n 'keyup': this._updatePasswordFieldWithEmailValue,\n 'paste': this._updatePasswordFieldWithEmailValue\n });\n },\n\n /**\n * Check choice\n * @private\n */\n _checkChoice: function () {\n if ($(this.options.changeEmailSelector).is(':checked') &&\n $(this.options.changePasswordSelector).is(':checked')) {\n this._showAll();\n } else if ($(this.options.changeEmailSelector).is(':checked')) {\n this._showEmail();\n } else if ($(this.options.changePasswordSelector).is(':checked')) {\n this._showPassword();\n } else {\n this._hideAll();\n }\n },\n\n /**\n * Show email and password input fields\n * @private\n */\n _showAll: function () {\n $(this.options.titleSelector).html(this.options.titleChangeEmailAndPassword);\n\n $(this.options.mainContainerSelector).show();\n $(this.options.emailContainerSelector).show();\n $(this.options.newPasswordContainerSelector).show();\n $(this.options.confirmPasswordContainerSelector).show();\n\n $(this.options.currentPasswordSelector).attr('data-validate', '{required:true}').prop('disabled', false);\n $(this.options.emailSelector).attr('data-validate', '{required:true}').prop('disabled', false);\n this._updatePasswordFieldWithEmailValue();\n $(this.options.confirmPasswordSelector).attr(\n 'data-validate',\n '{required:true, equalTo:\"' + this.options.newPasswordSelector + '\"}'\n ).prop('disabled', false);\n },\n\n /**\n * Hide email and password input fields\n * @private\n */\n _hideAll: function () {\n $(this.options.mainContainerSelector).hide();\n $(this.options.emailContainerSelector).hide();\n $(this.options.newPasswordContainerSelector).hide();\n $(this.options.confirmPasswordContainerSelector).hide();\n\n $(this.options.currentPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n $(this.options.emailSelector).removeAttr('data-validate').prop('disabled', true);\n $(this.options.newPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n $(this.options.confirmPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n },\n\n /**\n * Show email input fields\n * @private\n */\n _showEmail
2: function () {\n this._showAll();\n $(this.options.titleSelector).html(this.options.titleChangeEmail);\n\n $(this.options.newPasswordContainerSelector).hide();\n $(this.options.confirmPasswordContainerSelector).hide();\n\n $(this.options.newPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n $(this.options.confirmPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n },\n\n /**\n * Show password input fields\n * @private\n */\n _showPassword: function () {\n this._showAll();\n $(this.options.titleSelector).html(this.options.titleChangePassword);\n\n $(this.options.emailContainerSelector).hide();\n\n $(this.options.emailSelector).removeAttr('data-validate').prop('disabled', true);\n },\n\n /**\n * Update password validation rules with email input field value\n * @private\n */\n _updatePasswordFieldWithEmailValue: function () {\n $(this.options.newPasswordSelector).attr(\n 'data-validate',\n '{required:true, ' +\n '\\'validate-customer-password\\':true, ' +\n '\\'password-not-equal-to-user-name\\':\\'' + $(this.options.emailSelector).val() + '\\'}'\n ).prop('disabled', false);\n }\n });\n\n return $.mage.changeEmailPassword;\n});\n","Magento_Customer/js/logout-redirect.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], function ($) {\n 'use strict';
2\n\n return function (data) {\n $($.mage.redirect(data.url, 'assign', 1000));\n };\n});\n","Magento_Customer/js/addressValidation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'jquery/ui',\n 'validation'\n], function ($) {\n 'use strict';\n\n $.widget('mage.addressValidation', {\n options: {\n selectors: {\n button: '[data-action=save-address]'\n }\n },\n\n /**\n * Validation creation\n * @protected\n */\n _create: function () {\n var button = $(this.options.selectors.button, this.element);\n\n this.element.validation({\n\n /**\n * Submit Handler\n * @param {Element} form - address form\n */\n submitHandler: function (form) {\n\n button.attr('disabled', true);\n form.submit();\n }\n });\n }\n });\n\n return $.mage.addressValidation;\n});\n","Magento_Customer/js/invalidation-processor.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'underscore',\n 'uiElement',\n 'Magento_Customer/js/customer-data'\n], function (_, Element, customerData) {\n 'use strict';\n\n return Element.extend({\n /**\n * Initialize object\n */\n initialize: function () {\n this._super();\n this.process(customerData);\n },\n\n /**\n * Process all rules in loop, each rule can invalidate some sections in customer data\n *\n * @param {Object} customerDataObject\n */\n process: function (customerDataObject) {\n _.each(this.invalidationRules, function (rule, ruleName) {\n _.each(rule, function (ruleArgs, rulePath) {\n require([rulePath], function (Rule) {\n var currentRule = new Rule(ruleArgs);\n\n if (!_.isFunction(currentRule.process)) {\n throw new Error('Rule ' + ruleName + ' should implement invalidationProcessor interface');\n }\n currentRule.process(customerDataObject);\n });\n });\n });\n }\n });\n});\n","Magento_Customer/js/customer-data.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 'ko',\n 'Magento_Customer/js/section-config',\n 'mage/storage',\n 'jquery/jquery-storageapi'\n], function ($, _, ko, sectionConfig) {\n 'use strict';\n\n var options,\n storage,\n storageInvalidation,\n invalidateCacheBySessionTimeOut,\n invalidateCacheByCloseCookieSession,\n dataProvider,\n buffer,\n customerData;\n\n //TODO: remove global change, in this case made for initNamespaceStorage\n $.cookieStorage.setConf({\n path: '/',\n expires: 1\n });\n\n storage = $.initNamespaceStorage('mage-cache-storage').localStorage;\n storageInvalidation = $.initNamespaceStorage('mage-cache-storage-section-invalidation').localStorage;\n\n /**\n * @param {Object} invalidateOptions\n */\n invalidateCacheBySessionTimeOut = function (invalidateOptions) {\n var date;\n\n if (new Date($.localStorage.get('mage-cache-timeout')) < new Date()) {\n storage.removeAll();\n date = new Date(Date.now() + parseInt(invalidateOptions.cookieLifeTime, 10) * 1000);\n $.localStorage.set('mage-cache-timeout', date);\n }\n };\n\n /**\n * Invalidate Cache By Close Cookie Session\n */\n invalidateCacheByCloseCookieSession = function () {\n if (!$.cookieStorage.isSet('mage-cache-sessid')) {\n $.cookieStorage.set('mage-cache-sessid', true);\n storage.removeAll();\n }\n };
2\n\n dataProvider = {\n\n /**\n * @param {Object} sectionNames\n * @return {Object}\n */\n getFromStorage: function (sectionNames) {\n var result = {};\n\n _.each(sectionNames, function (sectionName) {\n result[sectionName] = storage.get(sectionName);\n });\n\n return result;\n },\n\n /**\n * @param {Object} sectionNames\n * @param {Number} updateSectionId\n * @return {*}\n */\n getFromServer: function (sectionNames, updateSectionId) {\n var parameters;\n\n sectionNames = sectionConfig.filterClientSideSections(sectionNames);\n parameters = _.isArray(sectionNames) ? {\n sections: sectionNames.join(',')\n } : [];\n parameters['update_section_id'] = updateSectionId;\n\n return $.getJSON(options.sectionLoadUrl, parameters).fail(function (jqXHR) {\n throw new Error(jqXHR);\n });\n }\n };\n\n /**\n * @param {Function} target\n * @param {String} sectionName\n * @return {*}\n */\n ko.extenders.disposableCustomerData = function (target, sectionName) {\n var sectionDataIds, newSectionDataIds = {};\n\n target.subscribe(function () {\n setTimeout(function () {\n storage.remove(sectionName);\n sectionDataIds = $.cookieStorage.get('section_data_ids') || {};\n _.each(sectionDataIds, function (data, name) {\n if (name != sectionName) { //eslint-disable-line eqeqeq\n newSectionDataIds[name] = data;\n }\n });\n $.cookieStorage.set('section_data_ids', newSectionDataIds);\n }, 3000);\n });\n\n return target;\n };\n\n buffer = {\n data: {},\n\n /**\n * @param {String} sectionName\n */\n bind: function (sectionName) {\n this.data[sectionName] = ko.observable({});\n },\n\n /**\n * @param {String} sectionName\n * @return {Object}\n */\n get: function (sectionName) {\n if (!this.data[sectionName]) {\n this.bind(sectionName);\n }\n\n return this.data[sectionName];\n },\n\n /**\n * @return {Array}\n */\n keys: function () {\n return _.keys(this.data);\n },\n\n /**\n * @param {String} sectionName\n * @param {Object} sectionData\n */\n notify: function (sectionName, sectionData) {\n if (!this.data[sectionName]) {\n this.bind(sectionName);\n }\n this.data[sectionName](sectionData);\n },\n\n /**\n * @param {Object} sections\n */\n update: function (sections) {\n var sectionId = 0,\n sectionDataIds = $.cookieStorage.get('section_data_ids') || {};\n\n _.each(sections, function (sectionData, sectionName) {\n sectionId = sectionData['data_id'];\n sectionDataIds[sectionName] = sectionId;\n storage.set(sectionName, sectionData);\n storageInvalidation.remove(sectionName);\n buffer.notify(sectionName, sectionData);\n });\n $.cookieStorage.set('section_data_ids', sectionDataIds);\n },\n\n /**\n * @param {Object} sections\n */\n remove: function (sections) {\n _.each(sections, function (sectionName) {\n storage.remove(sectionName);\n\n if (!sectionConfig.isClientSideSection(sectionName)) {\n storageInvalidation.set(sectionName, true);\n }\n });\n }\n };\n\n customerData = {\n\n /**\n * Customer data initialization\n */\n init: function () {\n var countryData,\n privateContentVersion = 'private_content_version',\n privateContent = $.cookieStorage.get(privateContentVersion),\n localPrivateContent = $.localStorage.get(privateContentVersion),\n needVersion = 'need_version',\n expiredSectionNames = this.getExpiredSectionNames();\n\n if (privateContent &&\n !$.cookieStorage.isSet(privateContentVersion) &&\n !$.localStorage.isSet(privateContentVersion)\n ) {\n $.cookieStorage.set(privateContentVersion, needVersion);\n $.localStorage.set(privateContentVersion, needVersion);\n this.reload([], false);\n } else if (localPrivateContent !== privateContent) {\n if (!$.cookieStorage.isSet(privateContentVersion)) {\n privateContent = needVersion;\n $.cookieStorage.set(privateContentVersion, privateContent);\n }\n $.localStorage.set(privateContentVersion, privateContent);\n this.reload([], false);\n } else if (expiredSectionNames.length > 0) {\n _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) {\n buffer.notify(sectionName, sectionData);\n });\n this.reload(expiredSectionNames, false);\n } else {\n _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) {\n buffer.notify(sectionName, sectionData);\n });\n\n if (!_.isEmpty(storageInvalidation.keys())) {\n this.reload(storageInvalidation.keys(), false);\n }\n }\n\n if (!_.isEmpty(privateContent)) {\n countryData = this.get('directory-data');\n\n if (_.isEmpty(countryData())) {\n customerData.reload(['directory-data'], false);\n }\n }\n },\n\n /**\n * Retrieve the list of sections that has expired since last page reload.\n *\n * Sections can expire due to lifetime constraints or due to inconsistent storage information\n * (validated by cookie data).\n *\n * @return {Array}\n */\n getExpiredSectionNames: function () {\n var expiredSectionNames = [],\n cookieSectionTimestamps = $.cookieStorage.get('section_data_ids') || {},\n sectionLifetime = options.expirableSectionLifetime * 60,\n currentTimestamp = Math.floor(Date.now() / 1000),\n sectionData;\n\n // process sections that can expire due to lifetime constraints\n _.each(options.expirableSectionNames, function (sectionName) {\n sectionData = storage.get(sectionName);\n\n if (typeof sectionData === 'object' && sectionData['data_id'] + sectionLifetime <= currentTimestamp) {\
2n expiredSectionNames.push(sectionName);\n }\n });\n\n // process sections that can expire due to storage information inconsistency\n _.each(cookieSectionTimestamps, function (cookieSectionTimestamp, sectionName) {\n sectionData = storage.get(sectionName);\n\n if (typeof sectionData === 'undefined' ||\n typeof sectionData === 'object' &&\n cookieSectionTimestamp != sectionData['data_id'] //eslint-disable-line\n ) {\n expiredSectionNames.push(sectionName);\n }\n });\n\n return _.uniq(expiredSectionNames);\n },\n\n /**\n * Check if some sections have to be reloaded.\n *\n * @deprecated Use getExpiredSectionNames instead.\n *\n * @return {Boolean}\n */\n needReload: function () {\n var expiredSectionNames = this.getExpiredSectionNames();\n\n return expiredSectionNames.length > 0;\n },\n\n /**\n * Retrieve the list of expired keys.\n *\n * @deprecated Use getExpiredSectionNames instead.\n *\n * @return {Array}\n */\n getExpiredKeys: function () {\n return this.getExpiredSectionNames();\n },\n\n /**\n * @param {String} sectionName\n * @return {*}\n */\n get: function (sectionName) {\n return buffer.get(sectionName);\n },\n\n /**\n * @param {String} sectionName\n * @param {Object} sectionData\n */\n set: function (sectionName, sectionData) {\n var data = {};\n\n data[sectionName] = sectionData;\n buffer.update(data);\n },\n\n /**\n * @param {Array} sectionNames\n * @param {Number} updateSectionId\n * @return {*}\n */\n reload: function (sectionNames, updateSectionId) {\n return dataProvider.getFromServer(sectionNames, updateSectionId).done(function (sections) {\n $(document).trigger('customer-data-reload', [sectionNames]);\n buffer.update(sections);\n });\n },\n\n /**\n * @param {Array} sectionNames\n */\n invalidate: function (sectionNames) {\n var sectionDataIds,\n sectionsNamesForInvalidation;\n\n sectionsNamesForInvalidation = _.contains(sectionNames, '*') ? buffer.keys() : sectionNames;\n $(document).trigger('customer-data-invalidate', [sectionsNamesForInvalidation]);\n buffer.remove(sectionsNamesForInvalidation);\n sectionDataIds = $.cookieStorage.get('section_data_ids') || {};\n\n // Invalidate section in cookie (increase version of section with 1000)\n _.each(sectionsNamesForInvalidation, function (sectionName) {\n if (!sectionConfig.isClientSideSection(sectionName)) {\n sectionDataIds[sectionName] += 1000;\n }\n });\n $.cookieStorage.set('section_data_ids', sectionDataIds);\n },\n\n /**\n * @param {Object} settings\n * @constructor\n */\n 'Magento_Customer/js/customer-data': function (settings) {\n options = settings;\n invalidateCacheBySessionTimeOut(settings);\n invalidateCacheByCloseCookieSession();\n customerData.init();\n }\n };\n\n /**\n * Events listener\n */\n $(document).on('ajaxComplete', function (event, xhr, settings) {\n var sections,\n redirects;\n\n if (settings.type.match(/post|put|delete/i)) {\n sections = sectionConfig.getAffectedSections(settings.url);\n\n if (sections) {\n customerData.invalidate(sections);\n redirects = ['redirect', 'backUrl'];\n\n if (_.isObject(xhr.responseJSON) && !_.isEmpty(_.pick(xhr.responseJSON, redirects))) { //eslint-disable-line\n return;\n }\n customerData.reload(sections, true);\n }\n }\n });\n\n /**\n * Events listener\n */\n $(document).on('submit', function (event) {\n var sections;\n\n if (event.target.method.match(/post|put|delete/i)) {\n sections = sectionConfig.getAffectedSections(event.target.action);\n\n if (sections) {\n customerData.invalidate(sections);\n }\n }\n });\n\n return customerData;\n});\n","Magento_Customer/js/action/check-email-availability.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'mage/storage',\n 'Magento_Checkout/js/model/url-builder'\n], function (storage, urlBuilder) {\n 'use strict';\n\n return function (deferred, email) {\n return storage.post(\n urlBuilder.createUrl('/customers/isEmailAvailable', {}),\n JSON.stringify({\n customerEmail: email\n }),\n false\n ).done(function (isEmailAvailable) {\n if (isEmailAvailable) {\n deferred.resolve();\n } else {\n deferred.reject();\n }\n }).fail(function () {\n deferred.reject();\n });\n };\n});\n","Magento_Customer/js/action/login.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'mage/storage',\n 'Magento_Ui/js/model/messageList',\n 'Magento_Customer/js/customer-data',\n 'mage/translate'\n], function ($, storage, globalMessageList, customerData, $t) {\n 'use strict';\n\n var callbacks = [],\n\n /**\n * @param {Object} loginData\n * @param {String} redirectUrl\n * @param {*} isGlobal\n * @param {Object} messageContainer\n */\n action = function (loginData, redirectUrl, isGlobal, messageContainer) {\n messageContainer = messageContainer || globalMessageList;\n\n return storage.post(\n 'customer/ajax/login',\n JSON.stringify(loginData),\n isGlobal\n ).done(function (response) {\n if (response.errors) {\n messageContainer.addErrorMessage(response);\n callbacks.forEach(function (callback) {\n callback(loginData);\n });\n } else {\n callbacks.forEach(function (callback) {\n callback(loginData);\n });\n customerData.invalidate(['customer']);\n\n if (redirectUrl) {\n window.location.href = redirectUrl;\n } else if (response.redirectUrl) {\n window.location.href = response.redirectUrl;\n } else {\n location.reload();\n }\n }\n }).fail(function () {\n messageContainer.addErrorMessage({\n 'message': $t('Could not authenticate. Please try again later')\n });\n callbacks.forEach(function (callback) {\n callback(loginData);\n });\n });\n };\n\n /**\n * @param {Function} callback\n */\n action.registerLoginCallback = function (callback) {\n callbacks.push(callback);\n };\n\n return action;\n});\n","Magento_Customer/js/view/authentication-popup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'ko',\n 'Magento_Ui/js/form/form',\n 'Magento_Customer/js/action/login',\n 'Magento_Customer/js/customer-data',\n 'Magento_Customer/js/model/authentication-popup',\n 'mage/translate',\n 'mage/url',\n 'Magento_Ui/js/modal/alert',\n 'mage/validation'\n], function ($, ko, Component, loginAction, customerData, authenticationPopup, $t, url, alert) {\n 'use strict';\n\n return Component.extend({\n registerUrl: window.authenticationPopup.customerRegisterUrl,\n forgotPasswordUrl: window.authenticationPopup.customerForgotPasswordUrl,\n autocomplete: window.authenticationPopup.autocomplete,\n modalWindow: null,\n isLoading: ko.observable(false),\n\n defaults: {\n template: 'Magento_Customer/authentication-popup'\n },\n\n /**\n * Init\n */\n initialize: function () {\n var self = this;\n\n this._super();\n url.setBaseUrl(window.authenticationPopup.baseUrl);\n loginAction.registerLoginCallback(function () {\n self.isLoading(false);\n });\n },\n\n /** Init popup login window */\n setModalElement: function (element) {\n if (authenticationPopup.modalWindow == null) {\n authenticationPopup.createPopUp(element);\n }\n },\n\n /** Is login form enabled for current customer */\n isActive: function () {\n var customer = customerData.get('customer');\n\n return customer() == false; //eslint-disable-line eqeqeq\n },\n\n /** Show login popup window */\n showModal: function () {\n if (this.modalWindow) {\
2n $(this.modalWindow).modal('openModal');\n } else {\n alert({\n content: $t('Guest checkout is disabled.')\n });\n }\n },\n\n /**\n * Provide login action\n *\n * @return {Boolean}\n */\n login: function (formUiElement, event) {\n var loginData = {},\n formElement = $(event.currentTarget),\n formDataArray = formElement.serializeArray();\n\n event.stopPropagation();\n formDataArray.forEach(function (entry) {\n loginData[entry.name] = entry.value;\n });\n\n if (formElement.validation() &&\n formElement.validation('isValid')\n ) {\n this.isLoading(true);\n loginAction(loginData);\n }\n\n return false;\n }\n });\n});\n","Magento_Customer/js/view/customer.js":"/**\n* Copyright \u00a9 Magento, Inc. All rights reserved.\n* See COPYING.txt for license details.\n*/\n\ndefine([\n 'uiComponent',\n 'Magento_Customer/js/customer-data'\n], function (Component, customerData) {\n 'use strict';\n\n return Component.extend({\n /** @inheritdoc */\n initialize: function () {\n this._super();\n\n this.customer = customerData.get('customer');\n }\n });\n});\n","Magento_Customer/js/model/authentication-popup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'Magento_Ui/js/modal/modal'\n], function ($, modal) {\n 'use strict';\n\n return {\n modalWindow: null,\n\n /**\n * Create popUp window for provided element\n *\n * @param {HTMLElement} element\n */\n createPopUp: function (element) {\n var options = {\n 'type': 'popup',\n 'modalClass': 'popup-authentication',\n 'focus': '[name=username]',\n 'responsive': true,\n 'innerScroll': true,\n 'trigger': '.proceed-to-checkout',\n 'buttons': []\n };\n\n this.modalWindow = element;\n modal(options, $(this.modalWindow));\n },\n\n /** Show login popup window */\n showModal: function () {\n $(this.modalWindow).modal('openModal').trigger('contentUpdated');\n }\n };\n});\n","Magento_Customer/js/model/customer.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 'ko',\n 'underscore',\n './address-list'\n], function ($, ko, _, addressList) {\n 'use strict';\n\n var isLoggedIn = ko.observable(window.isCustomerLoggedIn),\n customerData = {};\n\n if (isLoggedIn()) {\n customerData = window.customerData;\n } else {\n customerData = {};\n }\n\n return {\n customerData: customerData,\n customerDetails: {},\n isLoggedIn: isLoggedIn,\n\n /**\n * @param {Boolean} flag\n */\n setIsLoggedIn: function (flag) {\n isLoggedIn(flag);\n },\n\n /**\n * @return {Array}\n */\n getBillingAddressList: function () {\n return addressList();\n },\n\n /**\n * @return {Array}\n */\n getShippingAddressList: function () {\n return addressList();\n },\n\n /**\n * @param {String} fieldName\n * @param {*} value\n */\n setDetails: function (fieldName, value) {\n if (fieldName) {\n this.customerDetails[fieldName] = value;\n }\n },\n\n /**\n * @param {String} fieldName\n * @return {*}\n */\n getDetails: function (fieldName) {\n if (fieldName) {\n if (this.customerDetails.hasOwnProperty(fieldName)) {\
2n return this.customerDetails[fieldName];\n }\n\n return undefined;\n }\n\n return this.customerDetails;\n },\n\n /**\n * @param {Array} address\n * @return {Number}\n */\n addCustomerAddress: function (address) {\n var fields = [\n 'customer_id', 'country_id', 'street', 'company', 'telephone', 'fax', 'postcode', 'city',\n 'firstname', 'lastname', 'middlename', 'prefix', 'suffix', 'vat_id', 'default_billing',\n 'default_shipping'\n ],\n customerAddress = {},\n hasAddress = 0,\n existingAddress;\n\n if (!this.customerData.addresses) {\n this.customerData.addresses = [];\n }\n\n customerAddress = _.pick(address, fields);\n\n if (address.hasOwnProperty('region_id')) {\n customerAddress.region = {\n 'region_id': address['region_id'],\n region: address.region\n };\n }\n\n for (existingAddress in this.customerData.addresses) {\n if (this.customerData.addresses.hasOwnProperty(existingAddress)) {\n if (_.isEqual(this.customerData.addresses[existingAddress], customerAddress)) { //eslint-disable-line\n hasAddress = existingAddress;\n break;\n }\n }\n }\n\n if (hasAddress === 0) {\n return this.customerData.addresses.push(customerAddress) - 1;\n }\n\n return hasAddress;\n },\n\n /**\n * @param {*} addressId\n * @return {Boolean}\n */\n setAddressAsDefaultBilling: function (addressId) {\n if (this.customerData.addresses[addressId]) {\n this.customerData.addresses[addressId]['default_billing'] = 1;\n\n return true;\n }\n\n return false;\n },\n\n /**\n * @param {*} addressId\n * @return {Boolean}\n */\n setAddressAsDefaultShipping: function (addressId) {\n if (this.customerData.addresses[addressId]) {\n this.customerData.addresses[addressId]['default_shipping'] = 1;\n\n return true;\n }\n\n return false;\n }\n };\n});\n","Magento_Customer/js/model/address-list.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n 'ko',\n './customer-addresses'\n], function (ko, defaultProvider) {\n 'use strict';\n\n return ko.observableArray(defaultProvider.getAddressItems());\n});\n","Magento_Customer/js/model/customer-addresses.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 'ko',\n './customer/address'\n], function ($, ko, Address) {\n 'use strict';\n\n var isLoggedIn = ko.observable(window.isCustomerLoggedIn);\n\n return {\n /**\n * @return {Array}\n */\n getAddressItems: function () {\n var items = [],\n customerData = window.customerData;\n\n if (isLoggedIn()) {\n if (Object.keys(customerData).length) {\n $.each(customerData.addresses, function (key, item) {\n items.push(new Address(item));\n });\n }\n }\n\n return items;\n }\n };\n});\n","Magento_Customer/js/model/customer/address.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([], function () {\n 'use strict';\n\n /**\n * Returns new address object.\n *\n * @param {Object} addressData\n * @return {Object}
2\n */\n return function (addressData) {\n var regionId;\n\n if (addressData.region['region_id'] && addressData.region['region_id'] !== '0') {\n regionId = addressData.region['region_id'] + '';\n }\n\n return {\n customerAddressId: addressData.id,\n email: addressData.email,\n countryId: addressData['country_id'],\n regionId: regionId,\n regionCode: addressData.region['region_code'],\n region: addressData.region.region,\n customerId: addressData['customer_id'],\n street: addressData.street,\n company: addressData.company,\n telephone: addressData.telephone,\n fax: addressData.fax,\n postcode: addressData.postcode,\n city: addressData.city,\n firstname: addressData.firstname,\n lastname: addressData.lastname,\n middlename: addressData.middlename,\n prefix: addressData.prefix,\n suffix: addressData.suffix,\n vatId: addressData['vat_id'],\n sameAsBilling: addressData['same_as_billing'],\n saveInAddressBook: addressData['save_in_address_book'],\n customAttributes: addressData['custom_attributes'],\n\n /**\n * @return {*}\n */\n isDefaultShipping: function () {\n return addressData['default_shipping'];\n },\n\n /**\n * @return {*}\n */\n isDefaultBilling: function () {\n return addressData['default_billing'];\n },\n\n /**\n * @return {*}\n */\n getAddressInline: function () {\n return addressData.inline;\n },\n\n /**\n * @return {String}\n */\n getType: function () {\n return 'customer-address';\n },\n\n /**\n * @return {String}\n */\n getKey: function () {\n return this.getType() + this.customerAddressId;\n },\n\n /**\n * @return {String}\n */\n getCacheKey: function () {\n return this.getKey();\n },\n\n /**\n * @return {Boolean}\n */\n isEditable: function () {\n return false;\n },\n\n /**\n * @return {Boolean}\n */\n canUseForBilling: function () {\n return true;\n }\n };\n };\n});\n","Magento_Customer/js/invalidation-rules/website-rule.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n 'uiClass'\n], function (Element) {\n 'use strict';\n\n return Element.extend({\n\n defaults: {\n scopeConfig: {}\n },\n\n /**\n * Takes website id from current customer data and compare it with current website id\n * If customer belongs to another scope, we need to invalidate current section\n *\n * @param {Object} customerData\n */\n process: function (customerData) {\n var customer = customerData.get('customer');\n\n if (this.scopeConfig && customer() &&\n ~~customer().websiteId !== ~~this.scopeConfig.websiteId && ~~customer().websiteId !== 0) {\n customerData.reload(['customer']);\n }\n }\n });\n});\n","Idus_Order/js/missing/confirm.js":"\ndefine([\n 'jquery',\n 'Magento_Ui/js/modal/confirm',\n 'Idus_Core/js/url',\n 'Magento_Ui/js/modal/alert',\n 'mage/translate',\n 'domReady!'\n], function ($, confirm,url,alert) {\n 'use strict';\n\n return function (config, el) {\n var data = {};\n data['order_number'] = $('input[name=order_number]').val();\n\n $('.idus-missing-confirm button.find-order').on('click', function() {\
2n var email = $('.find-order input.email').val();\n\n var pattern = /^\\b[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b$/i;\n\n if(!pattern.test(email)){\n alert({ content: $.mage.__('Invalid Email') ,title: $.mage.__('Attention')});\n }\n\n data['email'] = email;\n findOrder(data);\n });\n\n $('.idus-missing-confirm-action button').on('click', function() {\n data['status'] = $(this).attr('status_to');\n getConfirm(data);\n });\n\n function getConfirm(data) {\n \n if(config.confirm){\n confirm({\n title: $.mage.__('Are You Sure'),\n actions: {\n confirm: function () {\n saveData(data);\n },\n\n cancel: function () {\n return false;\n }\n }\n }); \n }
2else{\n saveData(data);\n }\n }\n\n function saveData(data){\n $.ajax({\n url: url.getUrl('order/missing/changestatus'),\n type: \"POST\",\n dataType: \"json\",\n data : data,\n /** @inheritdoc */\n beforeSend: function () {\n loader(1);\n },\n\n /** @inheritdoc */\n complete: function () {\n loader(0);\n }\n }).done(\n function (response) {\n if(response.success){\n idus.scrollTo($('.idus-missing-confirm-success').show());\n $('.idus-missing-confirm-action, .idus-missing-confirm-items-wrap, .idus-missing-confirm .idus-missing-confirm-content, .idus-missing-confirm-description').hide();\n }else{\n alert({ content: response.message ,title: $.mage.__('Attention')});\n }\n }\n );\n }\n\n function findOrder(data){\n var items = $('.idus-missing-confirm-items .idus-missing-confirm-items-wrap');\n\n $.ajax({\n url: url.getUrl('order/missing/findorder'),\n type: \"POST\",\n dataType: \"json\",\n data : data,\n /** @inheritdoc */\n beforeSend: function () {\n loader(1);\n },\n\n /** @inheritdoc */\n complete: function () {\n loader(0);\n }\n }).done(\n function (response) {\n if(response.items){\n $.each(response.items,function(item_id, item){\n var itemStatus = $('.idus-missing-confirm-items-item.clone', items).clone().removeClass('clone');\n\n if(item.image){\n $('img', itemStatus).attr('src', item.image).show();\n }
2else{\n $('img', itemStatus).hide();\n $('.image div', itemStatus).show();\n }\n\n $.each(item,function(index,attr){\n $('.' + index +' span', itemStatus).text(attr);\n });\n\n $(itemStatus).addClass(item.picked);\n\n itemStatus.appendTo('.idus-missing-confirm-items-wrap', items);\n });\n\n $('.idus-missing-confirm-items-wrap, .idus-missing-confirm-action, .idus-missing-confirm-items-title').show();\n $('.idus-missing-confirm-description, .idus-missing-confirm .idus-missing-confirm-content').hide();\n }else{\n alert({ content: response.message ,title: $.mage.__('Attention')});\n }\n }\n );\n }\n\n function loader(active){\n if(active){\n $('.idus-missing-confirm-loader').addClass('active');\n }
2else{\n $('.idus-missing-confirm-loader').removeClass('active');\n }\n }\n }\n});\n","requirejs/domReady.js":"/**\n * @license RequireJS domReady 2.0.1 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.\n * Available via the MIT or new BSD license.\n * see: http://github.com/requirejs/domReady for details\n */\n/*jslint */\n/*global require: false, define: false, requirejs: false,\n window: false, clearInterval: false, document: false,\n self: false, setInterval: false */\n\n\ndefine(function () {\n 'use strict';\n\n var isTop, testDiv, scrollIntervalId,\n isBrowser = typeof window !== \"undefined\" && window.document,\n isPageLoaded = !isBrowser,\n doc = isBrowser ? document : null,\n readyCalls = [];\n\n function runCallbacks(callbacks) {\n var i;\n for (i = 0; i < callbacks.length; i += 1) {\n callbacks[i](doc);\n }\n }\n\n function callReady() {\n var callbacks = readyCalls;\n\n if (isPageLoaded) {\n //Call the DOM ready callbacks\n if (callbacks.length) {\n readyCalls = [];\n runCallbacks(callbacks);\n }\n }\n }\n\n /**\n * Sets the page as loaded.\n */\n function pageLoaded() {\n if (!isPageLoaded) {\n isPageLoaded = true;\n if (scrollIntervalId) {\n clearInterval(scrollIntervalId);\n }\n\n callReady();\n }\n }\n\n if (isBrowser) {\n if (document.addEventListener) {\n //Standards. Hooray! Assumption here that if standards based,\n //it knows about DOMContentLoaded.\n document.addEventListener(\"DOMContentLoaded\", pageLoaded, false);\n window.addEventListener(\"load\", pageLoaded, false);\n } else if (window.attachEvent) {\n window.attachEvent(\"onload\", pageLoaded);\n\n testDiv = document.createElement('div');\n try {\n isTop = window.frameElement === null;\n } catch (e) {}\n\n //DOMContentLoaded approximation that uses a doScroll, as found by\n //Diego Perini: http://javascript.nwbox.com/IEContentLoaded/,\n //but modified by other contributors, including jdalton\n if (testDiv.doScroll && isTop && window.external) {\n scrollIntervalId = setInterval(function () {\n try {\n testDiv.doScroll();\n pageLoaded();\n } catch (e) {}\n }, 30);\n }\n }\n\n //Check if document already complete, and if so, just trigger page load\n //listeners. Latest webkit browsers also use \"interactive\", and\n //will fire the onDOMContentLoaded before \"interactive\" but not after\n //entering \"interactive\" or \"complete\". More details:\n //http://dev.w3.org/html5/spec/the-end.html#the-end\n //http://stackoverflow.com/questions/3665561/document-readystate-of-interactive-vs-ondomcontentloaded\n //Hmm, this is more complicated on further use, see \"firing too early\"\n //bug: https://github.com/requirejs/domReady/issues/1\n //so removing the || document.readyState === \"interactive\" test.\n //There is still a window.onload binding that should get fired if\n //DOMContentLoaded is missed.\n if (document.readyState === \"complete\") {\n pageLoaded();\n }\n }\n\n /** START OF PUBLIC API **/\n\n /**\n * Registers a callback for DOM ready. If DOM is already ready, the\n * callback is called immediately.\n * @param {Function} callback\n */\n function domReady(callback) {\n if (isPageLoaded) {\n callback(doc);\n } else {\n readyCalls.push(callback);\n }\n return domReady;\n }\n\n domReady.version = '2.0.1';\n\n /**\n * Loader Plugin API method\n */\n domReady.load = function (name, req, onLoad, config) {\n if (config.isBuild) {\n onLoad(null);\n } else {\n domReady(onLoad);\n }\n };\n\n /** END OF PUBLIC API **/\n\n return domReady;\n});","Idus_Banner/js/idus.slider.js":"define(['idusVimeo', 'idusEasings', 'Idus_Core/js/idus'], function (VimeoVideo, idusEasings, idusHelper) {\n\t'use strict';\n\n\treturn function IdusSlider(sliderWrapper, settings, selectors) {\n\n\t\tif (settings.auto_width) settings.slidesToShow = 1;\n\n\t\t// get current device dt / sp\n\t\tvar device = 'dt';\n\t\tif (window.innerWidth <= 767) device = 'sp';\n\n\t\tthis.defaultSelectors = {\n\n\t\t\tslider: '.idus-slider',\n\t\t\tscrollWrapper: '.idus-slider-scroll-wrapper',\n\t\t\tslides: '.idus-slider-slide:not([data-device]):not(.hide), .idus-slider-slide[data-device=\"' + device + '\"]:not(.hide), .idus-slider-slide[data-device=\"all\"]:not(.hide)',\n\t\t\tslide: '.idus-slider-slide',\n\t\t\tlazyImages: '.idus-slider-slide-img[data-lazy], .idus-slider-slide-img[loading=\"lazy\"]',\n\t\t\trightBtn: '.idus_slider_arrow_right',\n\t\t\tleftBtn: '.idus_slider_arrow_left',\n\t\t\tbullets: '.idus_slider_bullets',\n\t\t\tbullet: '.idus_slider_bullet',\n\t\t\tcontrols: '.idus_slider_control',\n\t\t\tvideo: '.idus-slider-slide-video',\n\t\t\tcounter: '.idus-slider-slide_counter .current-slide'\n\t\t};\n\n\t\tif (selectors) {\n\n\t\t\tfor (var selector in this.defaultSelectors) {\n\n\t\t\t\tif (selectors[selector]) this.defaultSelectors[selector] = selectors[selector];\n\t\t\t}\n\t\t}\n\n\t\tthis.selectors = this.defaultSelectors;\n\n\t\tthis.defaultSettings = {\n\t\t\tauto_width: false,\n\t\t\tarrows: fal
2se,\n\t\t\tautoplay: false,\n\t\t\tautoplaySpeed: false,\n\t\t\tdots: false,\n\t\t\tresponsive: [{\n\t\t\t\tbreakpoint: 1199,\n\t\t\t\tsettings: {\n\t\t\t\t\tslidesToScroll: 1,\n\t\t\t\t\tslidesToShow: 1\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tbreakpoint: 767,\n\t\t\t\tsettings: {\n\t\t\t\t\tslidesToScroll: 1,\n\t\t\t\t\tslidesToShow: 1\n\t\t\t\t}\n\t\t\t}\n\t\t\t],\n\t\t\tslidesToScroll: 1,\n\t\t\tslidesToShow: 1,\n\t\t\tdrag: false,\n\t\t\tclone: false\n\t\t};\n\n\t\tif (settings) {\n\n\t\t\tfor (var setting in this.defaultSettings) {\n\n\t\t\t\tif (settings[setting]) this.defaultSettings[setting] = settings[setting];\n\t\t\t}\n\t\t}\n\n\t\tvar self = this;\n\t\tthis.sliderWrapper = sliderWrapper;\n\t\tthis.slider = sliderWrapper.querySelector(this.selectors.slider);\n\t\tthis.sliderScrollWrapper = sliderWrapper.querySelector(this.selectors.scrollWrapper);\n\t\tif (!this.slider) return false;\n\t\tthis.slides = this.slider.querySelectorAll(this.selectors.slides);\n\t\tthis.settings = this.defaultSettings;\n\t\tthis.easing = 'easeInOutExpo';\n\t\tthis.slidesAmount = 1;\n\t\tthis.activeSlide = 0;\n\t\tthis.activeSlides = [];\n\t\tthis.lazyImages = this.slider.querySelectorAll(this.selectors.lazyImages) ? this.slider.querySelectorAll(this.selectors.lazyImages).length : false;\n\t\tthis.scrollAnimationInterval = 750;\n\t\tthis.disableSnap = settings.auto_width ? true : false;\n\t\tthis.disableSnapOnScroll = true;\n\t\tthis.ltr = (getComputedStyle(this.slider).direction === 'ltr');\n\n\t\tthis.interacted = false;\n\n\t\tthis.busy = false;\n\t\tthis.autoplayInterval = false;\n\t\tthis.autoplayCooldown = false;\n\n\t\tthis.isStatic = false;\n\t\tvar isStaticClass = 'is__static';\n\t\tif (device === 'sp') isStaticClass = 'is__sp_static';\n\t\tif (this.slider.classList.toString().indexOf(isStaticClass) !== -1) this.isStatic = true;\n\n\t\tif (this.settings.responsive && this.settings.responsive.length) {\n\n\t\t\tfor (var i = 0; i < this.settings.responsive.length; i++) {\n\n\t\t\t\tvar resSetting = this.settings.responsive[i];\n\n\t\t\t\tif (window.innerWidth <= resSetting.breakpoint) {\n\n\t\t\t\t\tfor (var resKey in resSetting.settings) {\n\n\t\t\t\t\t\tthis.settings[resKey] = resSetting.settings[resKey];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.hasOverflow = false;\n\t\tthis.hasControls = false;\n\t\tthis.rightBtn = this.sliderScrollWrapper.querySelector(this.selectors.rightBtn);\n\t\tthis.leftBtn = this.sliderScrollWrapper.querySelector(this.selectors.leftBtn);\n\t\tthis.bullets = this.sliderScrollWrapper.querySelector(this.selectors.bullets);\n\t\tthis.counter = this.sliderScrollWrapper.querySelector(this.selectors.counter);\n\n\t\tthis.scrollLeft = this.slider.scrollLeft;\n\n\t\tthis.mouseDown = false;\n\t\tthis.dragging = false;\n\t\tthis.draggingX = false;\n\t\tthis.mouseIn = false;\n\n\t\tthis.vimeoVideos = {};\n\t\tthis.videoPlaying = false;\n\n\t\tthis.debugWindow = false;\n\n\t\tthis.accessibilitySkipToEndBtn = this.sliderWrapper.querySelector('.idus-slider-accessibility-skiptoend');\n\t\tthis.accessibilitySkipToStartBtn = this.sliderWrapper.querySelector('.idus-slider-accessibility-skiptostart');\n\t\tthis.accessibilitySkipToLeftBtn = this.sliderWrapper.querySelector('.idus-slider-accessibility-skiptoleft');\n\t\tthis.accessibilitySkipToRightBtn = this.sliderWrapper.querySelector('.idus-slider-accessibility-skiptoright');\n\n\t\tthis.initAccessibility = function () {\n\n\t\t\tif (!self.checkIfOverflowing()) return false;\n\n\t\t\tif (!self.accessibilitySkipToEndBtn ||\n\t\t\t\t!self.accessibilitySkipToStartBtn ||\n\t\t\t\t!self.accessibilitySkipToLeftBtn ||\n\t\t\t\t!self.accessibilitySkipToRightBtn) return false;\n\n\t\t\tself.sliderWrapper.classList.add('accessible');\n\n\t\t\t['focus', 'focusin'].forEach(function (eventName) {\n\t\t\t\tself.sliderWrapper.addEventListener(eventName, function () {\n\t\t\t\t\tif (document.body.classList.contains('tab-mode')) {\n\t\t\t\t\t\tself.pauseAutoplay();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tlet clickEvents = ['click', 'keydown'];
2\n\t\t\tclickEvents.forEach(function (eventName) {\n\n\t\t\t\tself.accessibilitySkipToEndBtn.addEventListener(eventName, function (e) {\n\t\t\t\t\tif (e instanceof KeyboardEvent && (e.key != 'Enter')) return;\n\t\t\t\t\tself.accessibilitySkipToStartBtn.focus();\n\t\t\t\t});\n\t\n\t\t\t\tself.accessibilitySkipToStartBtn.addEventListener(eventName, function (e) {\n\t\t\t\t\tif (e instanceof KeyboardEvent && (e.key != 'Enter')) return;\n\t\t\t\t\tself.accessibilitySkipToEndBtn.focus();\n\t\t\t\t});\n\t\n\t\t\t\tself.accessibilitySkipToLeftBtn.addEventListener(eventName, function (e) {\n\t\t\t\t\tif (e instanceof KeyboardEvent && (e.key != 'Enter')) return;\n\t\t\t\t\tif (self.leftBtn) self.leftBtn.focus();\n\t\t\t\t});\n\t\n\t\t\t\tself.accessibilitySkipToRightBtn.addEventListener(eventName, function (e) {\n\t\t\t\t\tif (e instanceof KeyboardEvent && (e.key != 'Enter')) return;\n\t\t\t\t\tif (self.rightBtn) self.rightBtn.focus();\n\t\t\t\t});\n\t\t\t});\n\t\t};\n\n\t\tthis.setDynamic = function (isDynamic) {\n\n\t\t\tif (isDynamic) {\n\n\t\t\t\tself.slider.classList.remove('is__static', 'is__sp_static');\n\t\t\t\t/* self.slider.classList.add('is__dynamic', 'is__sp_dynamic'); */\n\t\t\t\tself.showControls();\n\t\t\t} else {\n/* \n\t\t\t\tself.slider.classList.add('is__static', 'is__sp_static');\n\t\t\t\tself.slider.classList.remove('is__dynamic', 'is__sp_dynamic'); */\n\t\t\t\tself.hideControls();\n\t\t\t}\n\t\t};\n\n\t\tthis._isOverflowing = null;\n\t\tthis.checkIfOverflowing = function () {\n\n\t\t\tif (self._isOverflowing !== null) return self._isOverflowing;\n\n\t\t\tif (!self.isStatic && (self.slides.length > self.settings.slidesToShow)) {\n\t\t\t\tself.hasOverflow = true;\n\t\t\t\tself.setDynamic(true);\n\n\t\t\t\tself.slidesAmount = Math.ceil(self.slides.length / self.settings.slidesToScroll);\n\n\t\t\t\tself._isOverflowing = true;\n\t\t\t\treturn true;\n\t\t\t} else {\n\t\t\t\tself.hasOverflow = false;\n\t\t\t\tself.setDynamic(false);\n\n\t\t\t\tfor (var i = 0; i < self.slides.length; i++) {\t\n\n\t\t\t\t\tself.initVideoSlide(self.slides[i]);\n\t\t\t\t}\n\n\t\t\t\tself._isOverflowing = false;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t};\n\n\t\tthis.initControls = function () {\n\n\t\t\tif (!self.checkIfOverflowing()) {\n\n\t\t\t\tself.removeControls();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (self.settings.arrows * 1) self.initArrowControls();\n\t\t\tif (self.settings.dots * 1 && !self.settings.auto_width) self.initBulletControls();\n\t\t};\n\n\t\tthis.initScroll = function () {\n\n\t\t\tif (!self.checkIfOverflowing()) return false;\n\n\t\t\tif (self.settings.clone) self.initCloneToFitSlideToShow();\n\n\t\t\tif (self.initSnapFixForiOS() && !self.settings.auto_width) self.disableSnapOnScroll = false;\n\n\t\t\tvar scrollTimeout = false;\n\t\t\tself.slider.addEventListener('scroll', function () {\n\n\t\t\t\tself.busy = true;\n\n\t\t\t\tself.scrollLeft = Math.abs(this.scrollLeft);\n\n\t\t\t\tif (scrollTimeout) clearTimeout(scrollTimeout);\n\t\t\t\tscrollTimeout = setTimeout(function () {\n\t\t\t\t\tif (!self.settings.auto_width) {\n\t\t\t\t\t\tself.activeSlide = Math.round(self.scrollLeft / self.getScrollAmount());\n\t\t\t\t\t}\n\n\t\t\t\t\tself.triggerActiveSlides();\n\t\t\t\t\tself.adjustControls();\n\n\t\t\t\t\tif (self.counter) self.counter.innerText = self.activeSlide + 1;\n\n\t\t\t\t\tif (self.lazyImages) self.lazyLoadImages();\n\n\t\t\t\t\tself.busy = false;\n\t\t\t\t}, 30);\n\n\t\t\t\tif (self.debugWindow) self.updateDebugWindow();\n\t\t\t});\n\n\t\t\tif (!idusHelper.isMobile()) self.initDragScroll();\n\n\t\t\tself.slider.scrollLeft = 0;\n\t\t};\n\n\t\tthis.initArrowControls = function () {\n\n\t\t\tif (self.canScrollRight()) self.rightBtn.classList.remove('disabled');\n\t\t\tif (self.canScrollLeft()) self.leftBtn.classList.remove('disabled');\n\n\t\t\tself.hasControls = true;\n\n\t\t\tself.rightBtn.addEventListener('click', arrowRightHandler);\n\t\t\tself.rightBtn.addEventListener('keydown', arrowRightHandler);\n\t\t\tself.leftBtn.addEventListener('click', arrowLeftHandler);\n\t\t\tself.leftBtn.addEventListener('keydown', arrowLeftHandler);\n\n\t\t\t// arrow left click event\n\t\t\tfunction arrowLeftHandler(e) {\n\n\t\t\t\tif (e.type === 'keydown' && (e.which !== 13 && e.which !== 32)) return false;\n\n\t\t\t\tself.interacted = true;\n\t\t\t\tself.goScrollLeft();\n\t\t\t}\n\n\t\t\t// arrow right click event\n\t\t\tfunction arrowRightHandler(e) {\n\n\t\t\t\tif (e.type === 'keydown' && (e.which !== 13 && e.which !== 32)) return false;\n\n\t\t\t\tself.interacted = true;\n\t\t\t\tself.goScrollRight();\n\t\t\t}\n\t\t};\n\n\t\tthis.goScrollRight = function (force) {\n\n\t\t\tif (!force && self.ltr) return self.goScrollLeft(true);\n\n\t\t\tif (!self.ltr && self.rightBtn.classList.toString().indexOf('disabled') !== -1) return false;\n\t\t\tself.scrollLeft = self.scrollLeft - self.getScrollAmount(false);\n\t\t\tif (self.scrollLeft < 0) self.scrollLeft = 0;\n\n\t\t\tself.setClientScroll();\n\t\t};\n\n\t\tthis.goScrollLeft = function (force) {\n\n\t\t\tif (!force && self.ltr) return self.goScrollRight(true);\n\n\t\t\tif (self.lazyImages) self.lazyLoadImages(true);\n\n\t\t\tif ((!self.ltr && self.leftBtn.classList.toString().indexOf('disabled') !== -1) ||\n\t\t\t\tself.ltr && self.rightBtn.classList.toString().indexOf('disabled') !== -1) {\n\n\t\t\t\tself.scrollLeft = 0;\n\t\t\t\tself.setClientScroll(true);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tself.scrollLeft = self.scrollLeft + self.getScrollAmount();\n\n\t\t\tif (self.scrollLeft > (self.slider.scrollWidth - self.slider.clientWidth)) self.scrollLeft = (self.slider.scrollWidth - self.slider.clientWidth);\n\n\t\t\tself.setClientScroll();\n\t\t};\n\n\t\tthis.goToSlide = function (slide, ease, interval) {\n\n\t\t\tif (typeof ease === 'undefined' || ease === null) ease = true;\n\t\t\tif (!interval) interval = self.scrollAnimationInterval;\n\n\t\t\tself.scrollLeft = self.getScrollAmount() * slide;\n\n\t\t\tif (self.scrollLeft < 0) self.scrollLeft = 0;\n\t\t\tif (self.scrollLeft > (self.slider.scrollWidth - self.slider.clientWidth)) self.scrollLeft = (self.slider.scrollWidth - self.slider.clientWidth);\n\n\t\t\tself.setClientScroll(ease, false, interval);\n\t\t};\n\n\t\tthis.setClientScroll = function (ease, cb, interval) {\n\n\t\t\tif (typeof ease === 'undefined' || ease === null) ease = true;\n\t\t\tif (typeof cb !== 'function') {\n\t\t\t\tcb = function () {\n\t\t\t\t\treturn false;\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tself.disableControls();\n\n\t\t\tif (self.lazyImages) self.lazyLoadImages();\n\n\t\t\tvar scrollTo = -1 * self.scrollLeft;\n\t\t\tif (self.isIE() || self.ltr) scrollTo = Math.abs(scrollTo);\n\t\t\tvar scrollStart = self.slider.scrollLeft;\n\t\t\tif (!interval) interval = self.scrollAnimationInterval;\n\t\t\tvar scrollDiff = Math.max(self.slider.scrollLeft, scrollTo) - Math.min(self.slider.scrollLeft, scrollTo);\n\t\t\tvar fps = 60;\n\n\t\t\tif (!ease) {\n\n\t\t\t\tself.slider.scrollLeft = scrollTo;\n\t\t\t\tself.enableControls();\n\t\t\t} else {\n\n\t\t\t\tif (self.disableSnapOnScroll) self.slider.classList.add('disable-snap');\n\t\t\t\tvar easing = self.easing;\n\t\t\t\tif (ease && typeof ease === 'string' && idusEasings[ease]) easing = ease;\n\t\t\t\tvar frame = 0;\n\t\t\t\tvar scrollAnim = setInterval(function () {\n\t\t\t\t\tif (scrollStart < scrollTo) self.slider.scrollLeft = ((self.isIE() || self.isiOs() || self.ltr) ? 1 : -1) * idusEasings[easing](frame, Math.abs(scrollStart), ((self.isIE() || self.isiOs() || self.ltr) ? 1 : -1) * scrollDiff, fps);\n\t\t\t\t\telse {\n\n\t\t\t\t\t\tif (self.ltr) self.slider.scrollLeft = idusEasings[easing](frame, Math.abs(scrollStart), -1 * scrollDiff, fps);\n\t\t\t\t\t\telse self.slider.scrollLeft = (self.isIE() ? 1 : -1) * idusEasings[easing](frame, Math.abs(scrollStart), scrollDiff, fps);\n\t\t\t\t\t}\n\n\t\t\t\t\tframe++;\n\t\t\t\t\tif (frame >= fps) self.finishClientScroll(cb, scrollAnim);\n\t\t\t\t}, Math.ceil(interval / fps));\n\t\t\t}\n\t\t};\n\n\t\tthis.finishClientScroll = function (cb, interval) {\n\n\t\t\tif (!self.disableSnap) {\n\t\t\t\tif (self.scrollLeft % self.getScrollAmount !== 0) self.snapToClosestPoint(false);\n\t\t\t\tif (self.disableSnapOnScroll) self.slider.classList.remove('disable-snap');\n\t\t\t}\n\n\t\t\tself.enableControls();\n\t\t\tcb();\n\t\t\tclearInterval(interval);\n\t\t}
2\n\n\t\tthis.getScrollAmount = function (next = true) {\n\n\t\t\tif (!self.checkIfOverflowing()) return 0;\n\t\t\tif (self.settings.auto_width) return self.getAutoScrollAmount(next);\n\n\t\t\tvar deduction = 0;\n\n\t\t\tif (getComputedStyle(self.slider).padding) {\n\n\t\t\t\t// paddings[0] = top\n\t\t\t\t// paddings[1] = right\n\t\t\t\t// paddings[2] = bottom\n\t\t\t\t// paddings[3] = left\n\t\t\t\tvar paddings = getComputedStyle(self.slider).padding.split(' ');\n\t\t\t\tfor (var i = 0; i < paddings.length; i++) {\n\n\t\t\t\t\tpaddings[i] = parseInt(paddings[i].replace('px', ''));\n\t\t\t\t}\n\n\t\t\t\tif (paddings[3] > 0) deduction = paddings[3];\n\t\t\t}\n\n\t\t\tvar totalWidth = 0;\n\n\t\t\tfor (var i = 0; i < self.activeSlides.length; i++) {\n\n\t\t\t\ttotalWidth += self.activeSlides[i].clientWidth;\n\t\t\t}\n\n\t\t\treturn totalWidth - deduction;\n\t\t};\n\n\t\tthis.getAutoScrollAmount = function (next = true) {\n\t\t\tself.triggerAutoWidthActiveSlides();\n\n\t\t\tlet mappedSlides = Array.from(self.slides)\n\t\t\t\t.map(slide => slide.classList.contains('active'));\n\n\t\t\tlet activeSlideIndex = next ? mappedSlides.lastIndexOf(true) : mappedSlides.indexOf(true);\n\t\t\tconsole.log(activeSlideIndex);\n\t\t\tif (activeSlideIndex === -1 ||\n\t\t\t\t(next && activeSlideIndex === self.slides.length - 1) ||\n\t\t\t\t(!next && activeSlideIndex === 0)) return 0;\n\n\t\t\tlet nextSlide = self.slides[activeSlideIndex + (next ? 1 : -1)];\n\n\t\t\tlet containerRect = self.slider.getBoundingClientRect();\n\t\t\tlet nextSlideRect = nextSlide.getBoundingClientRect();\n\n\t\t\tlet outOfView = next ? containerRect.left - nextSlideRect.left : nextSlideRect.right - containerRect.right;\n\t\t\tconsole.log(outOfView);\n\n\t\t\treturn outOfView > 0 ? Math.ceil(outOfView) : 0;\n\n\t\t}\n\n\t\tthis.triggerAutoWidthActiveSlides = function () {\n\t\t\tconsole.log('triggerAutoWidthActiveSlides');\n\t\t\tif (!self.slides) self.slides = self.slider.querySelectorAll(self.selectors.slides);\n\t\t\tif (!self.slides || !self.slides.length) return false;\n\n\t\t\tself.activeSlides = self.getFullyVisibleElements();\n\t\t\tconsole.log(self.activeSlides);\n\t\t\tfor (var i = 0; i < self.slides.length; i++) {\n\n\t\t\t\tif (self.activeSlides.includes(self.slides[i])) {\n\t\t\t\t\tself.slides[i].classList.toggle('active', true);\n\t\t\t\t\tself.slides[i].dispatchEvent(new Event('idus-SliderSlideActive'));\n\t\t\t\t} else {\n\t\t\t\t\tself.slides[i].classList.toggle('active', false);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.getFullyVisibleElements = function () {\n\t\t\tconst containerRect = self.slider.getBoundingClientRect();\n\t\t\tconst children = Array.from(self.slider.children);\n\n\t\t\treturn children.filter((child) =>
2 {\n\t\t\t\tconst rect = child.getBoundingClientRect();\n\n\t\t\t\treturn (\n\t\t\t\t\trect.left >= containerRect.left &&\n\t\t\t\t\trect.right <= containerRect.right\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\tthis.adjustControls = function () {\n\n\t\t\tif (!self.hasControls) return true;\n\n\t\t\tif (self.rightBtn) {\n\t\t\t\tif (!self.canScrollRight()) self.rightBtn.classList.add('disabled');\n\t\t\t\telse self.rightBtn.classList.remove('disabled');\n\t\t\t}\n\n\t\t\tif (self.leftBtn) {\n\t\t\t\tif (!self.canScrollLeft()) self.leftBtn.classList.add('disabled');\n\t\t\t\telse self.leftBtn.classList.remove('disabled');\n\t\t\t}\n\n\t\t\tif (self.bullets && !self.sliderWrapper.querySelector(self.selectors.bullet + '[data-slide=\"' + self.activeSlide + '\"].active')) {\n\n\t\t\t\tself.sliderWrapper.querySelector(self.selectors.bullet + '.active').classList.remove('active');\n\t\t\t\tself.sliderWrapper.querySelector(self.selectors.bullet + '[data-slide=\"' + self.activeSlide + '\"]').classList.add('active');\n\t\t\t}\n\n\t\t\tif (self.bullets) self.bullets.dataset.activeSlide = self.activeSlide;\n\t\t};\n\n\t\tthis.disableControls = function () {\n\n\t\t\tvar controls = self.getSliderControls();\n\t\t\tfor (var i = 0; i < controls.length; i++) {\n\n\t\t\t\tcontrols[i].setAttribute('disabled', 'disabled');\n\t\t\t}\n\t\t};\n\n\t\tthis.enableControls = function () {\n\n\t\t\tvar controls = self.getSliderControls();\n\t\t\tfor (var i = 0; i < controls.length; i++) {\n\n\t\t\t\tcontrols[i].removeAttribute('disabled');\n\t\t\t}\n\t\t};\n\n\t\tthis.hideControls = function () {\n\n\t\t\tvar controls = self.getSliderControls();\n\t\t\tfor (var i = 0; i < controls.length; i++) {\n\n\t\t\t\tcontrols[i].classList.add('hide');\n\t\t\t\tcontrols[i].classList.remove('show');\n\t\t\t}\n\t\t};\n\n\t\tthis.removeControls = function () {\n\n\t\t\tvar controls = self.getSliderControls();\n\t\t\tfor (var i = 0; i < controls.length; i++) {\n\n\t\t\t\tcontrols[i].parentNode.removeChild(controls[i]);\n\t\t\t}\n\t\t};\n\n\t\tthis.showControls = function () {\n\n\t\t\tvar controls = self.getSliderControls();\n\t\t\tfor (var i = 0; i < controls.length; i++) {\n\n\t\t\t\tcontrols[i].classList.add('show');\n\t\t\t\tcontrols[i].classList.remove('hide');\n\t\t\t}\n\t\t};\n\n\t\tthis.getSliderControls = function () {\n\n\t\t\treturn self.sliderWrapper.querySelectorAll(self.selectors.controls);\n\t\t};\n\n\t\tthis.canScrollRight = function (force) {\n\n\t\t\tif (!force && self.ltr) return self.canScrollLeft(true);\n\t\t\treturn self.scrollLeft > 5;\n\t\t};\n\n\t\tthis.canScrollLeft = function (force) {\n\n\t\t\tif (!force && self.ltr) return self.canScrollRight(true);\n\t\t\tvar diff = (self.slider.scrollWidth - self.slider.clientWidth) - self.scrollLeft;\n\t\t\treturn diff > 5;\n\t\t};\n\n\t\tthis.initBulletControls = function () {\n\n\t\t\tvar bullets = self.bullets.querySelectorAll(self.selectors.bullet);\n\n\t\t\tif (bullets.length !== self.slidesAmount) bullets = self.matchBullets(bullets);\n\n\t\t\tfor (var i = 0; i < bullets.length; i++) {\n\n\t\t\t\tbullets[i].addEventListener('click', bulletClick);\n\t\t\t\tbullets[i].addEventListener('keyup', bulletClick);\n\t\t\t}\n\t\t\tself.hasControls = true;\n\n\t\t\t// bullet click handler\n\t\t\tfunction bulletClick(e) {\n\n\t\t\t\tif (e.type === 'keyup' && (e.which !== 13 && e.which !== 32)) return false;\n\n\t\t\t\tself.interacted = true;\n\n\t\t\t\tif (this.parentNode.getAttribute('disabled')) return false;\n\t\t\t\t// this.parentNode.querySelector(self.selectors.bullet + '.active').classList.remove('active');\n\t\t\t\t// this.classList.add('active');\n\t\t\t\tself.goToSlide(this.dataset.slide);\n\t\t\t}\n\n\t\t\tif (self.bullets) self.bullets.dataset.activeSlide = self.activeSlide;\n\t\t};\n\n\t\tthis.matchBullets = function (bullets) {\n\n\t\t\tfor (var i = self.slidesAmount; i < bullets.length; i++) {\n\n\t\t\t\tself.bullets.removeChild(bullets[i]);\n\t\t\t}\n\n\t\t\tself.bullets.dataset.slides = self.slidesAmount;\n\n\t\t\treturn self.bullets.querySelectorAll(self.selectors.bullet);\n\t\t};\n\n\t\tthis.initDragScroll = function () {\n\n\t\t\tif (!self.settings.drag) return false;\n\n\t\t\tself.slider.addEventListener('mousedown', function (e) {\n\n\t\t\t\te.preventDefault();\n\t\t\t\tself.mouseDown = true;\n\t\t\t\tself.dragging = false;\n\t\t\t});\n\n\t\t\tself.slider.addEventListener('mouseup', self.stopDragging, false);\n\t\t\tself.slider.addEventListener('mouseenter', self.stopDragging, false);\n\t\t\tself.slider.addEventListener('mouseleave', self.stopDragging, false);\n\n\t\t\tself.slider.addEventListener('mousemove', function (e) {\n\n\t\t\t\tif (self.mouseDown && !self.dragging) {\n\n\t\t\t\t\tself.dragging = true;\n\t\t\t\t\tself.slider.classList.add('dragging');\n\t\t\t\t\tself.draggingX = e.clientX;\n\t\t\t\t} else if (self.dragging) {\n\n\t\t\t\t\tif (e.clientX > self.draggingX) {\n\n\t\t\t\t\t\tvar diff = e.clientX - self.draggingX;\n\t\t\t\t\t\tself.scrollLeft += diff;\n\t\t\t\t\t\tif (self.scrollLeft > (self.slider.scrollWidth - self.getScrollAmount())) self.scrollLeft = (self.slider.scrollWidth - self.getScrollAmount());\n\n\t\t\t\t\t\tvar scrollTo = -1 * self.scrollLeft;\n\t\t\t\t\t\tself.slider.scrollLeft = scrollTo;\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvar diff = self.draggingX - e.clientX;\n\t\t\t\t\t\tself.scrollLeft -= diff;\n\t\t\t\t\t\tif (self.scrollLeft < 0) self.scrollLeft = 0;\n\n\t\t\t\t\t\tvar scrollTo = -1 * self.scrollLeft;\n\t\t\t\t\t\tself.slider.scrollLeft = scrollTo;\n\t\t\t\t\t}\n\n\t\t\t\t\tself.draggingX = e.clientX;\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\n\t\tthis.stopDragging = function () {\n\n\t\t\tif (self.busy) return false;\n\n\t\t\tself.mouseDown = false;\n\t\t\tself.dragging = false;\n\t\t\tself.draggingX = false;\n\n\t\t\tif (!self.isAtSnapPoint()) {\n\n\t\t\t\tself.snapToClosestPoint(true, function () {\n\t\t\t\t\tself.slider.classList.remove('dragging');\n\t\t\t\t});\n\t\t\t} else self.slider.classList.remove('dragging');\n\t\t};\n\n\t\tthis.isAtSnapPoint = function () {\n\n\t\t\tif (self.scrollLeft % (self.getScrollAmount() / self.settings.slidesToScroll) === 0) return true;\n\t\t\telse return false;\n\t\t};\n\n\t\tthis.snapToClosestPoint = function (ease, cb) {\n\n\t\t\tif (typeof ease === 'undefined' || ease === null) ease = true;\n\n\t\t\tvar distanceFromNearest = self.scrollLeft % (self.getScrollAmount() / self.settings.slidesToScroll);\n\t\t\tif (distanceFromNearest <= ((self.getScrollAmount() / self.settings.slidesToScroll) / 2)) self.scrollLeft -= distanceFromNearest;\n\t\t\telse self.scrollLeft += (self.getScrollAmount() / self.settings.slidesToScroll) - distanceFromNearest;\n\n\t\t\tself.setClientScroll(ease, cb);\n\t\t};\n\n\t\tthis.triggerActiveSlides = function () {\n\n\t\t\tif (self.settings.auto_width) return this.triggerAutoWidthActiveSlides();\n\n\t\t\tself.slides = self.slider.querySelectorAll(self.selectors.slides);\n\n\t\t\tif (!self.slides || !self.slides.length) return false;\n\n\t\t\tvar scrolledSlides = Math.round((Math.round((self.scrollLeft / (self.getScrollAmount()) + Number.EPSILON) * 100) / 100) * self.settings.slidesToScroll);\n\n\t\t\tif (!isFinite(scrolledSlides)) {\n\n\t\t\t\tfor (var i = 0; i < Math.min(self.settings.slidesToShow, self.slides.length);
2 i++) {\n\n\t\t\t\t\tself.slides[i].classList.add('active');\n\t\t\t\t\tself.slides[i].dispatchEvent(new Event('idus-SliderSlideActive'));\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\tfor (var i = 0; i < self.slides.length; i++) {\n\n\t\t\t\t\tif (i >= scrolledSlides && i < (scrolledSlides + self.settings.slidesToScroll)) {\n\n\t\t\t\t\t\tif (!self.slides[i].classList.contains('active')) {\n\n\t\t\t\t\t\t\tself.slides[i].classList.add('active');\n\t\t\t\t\t\t\tself.slides[i].dispatchEvent(new Event('idus-SliderSlideActive'));\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (self.slides[i].classList.contains('active')) {\n\n\t\t\t\t\t\tself.slides[i].classList.remove('active');\n\t\t\t\t\t\tself.slides[i].dispatchEvent(new Event('idus-SliderSlideInActive'));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tself.activeSlides = self.slider.querySelectorAll(self.selectors.slide + '.active');\n\t\t};\n\n\t\tthis.attachActiveEventToSlides = function () {\n\n\t\t\tif (!self.slides || !self.slides.length) return false;\n\t\t\tfor (var i = 0; i < self.slides.length; i++) {\n\n\t\t\t\tself.slides[i].addEventListener('idus-SliderSlideActive', self.slideIsActive);\n\n\t\t\t\tself.slides[i].addEventListener('idus-SliderSlideInActive', self.slideIsInActive);\n\t\t\t}\n\t\t};\n\n\t\tthis.slideIsActive = function (e) {\n\n\t\t\tif (e.target.querySelector(self.selectors.video)) self.initVideoSlide(e.target);\n\t\t};\n\n\t\tthis.slideIsInActive = function (e) {\n\n\t\t\tif (e.target.querySelector(self.selectors.video)) self.pauseVideoSlide(e.target);\n\t\t};\n\n\t\tthis.initVideoSlide = function (slide) {\n\n\t\t\tif (!slide) return false;\n\t\t\tif(slide.querySelector('video')) return self.actionHtmlVideo(slide, 'play');\n\t\t\tvar vimeoVideo = self.getSlideVideo(slide);\n\t\t\tif (!vimeoVideo) return false;\n\n\t\t\tvimeoVideo.play();\n\t\t\tvimeoVideo.show();\n\n\t\t\tself.videoPlaying = true;\n\t\t};\n\n\t\tthis.pauseVideoSlide = function (slide) {\n\t\t\t\n\t\t\tif(slide.querySelector('video')) return self.actionHtmlVideo(slide, 'pause');\n\t\t\tvar vimeoVideo = self.getSlideVideo(slide);\n\t\t\tif (!vimeoVideo) return false;\n\n\t\t\tvimeoVideo.pause();\n\t\t\tvimeoVideo.hide();\n\n\t\t\tself.videoPlaying = false;\n\t\t};\n\n\t\tthis.getSlideVideo = function (slide) {\n\n\t\t\tif(slide.querySelector('video')) return this.initHtmlVideo(slide);\n\n\t\t\tif (!slide.querySelector('iframe[data-type=\"vimeo\"]')) return false;\n\n\t\t\tvar vimeoVideo = false;\n\n\t\t\tif (slide.dataset.vimeoUid && self.vimeoVideos[slide.dataset.vimeoUid]) {\n\n\t\t\t\tvimeoVideo = self.vimeoVideos[slide.dataset.vimeoUid];\n\t\t\t} else {\n\t\t\t\tvar uId = Date.now();\n\t\t\t\tslide.dataset.vimeoUid = uId;\n\t\t\t\tvimeoVideo = new VimeoVideo(slide.querySelector('iframe[data-type=\"vimeo\"]'));\n\t\t\t\tself.vimeoVideos[uId] = vimeoVideo;\n\t\t\t}\n\n\t\t\treturn vimeoVideo;\n\t\t}\n\t\n\t\tthis.actionHtmlVideo = function (slide, action = \"play\") {\n\t\t\t\n\t\t\tif (slide.dataset.init !== \"true\") this.initHtmlVideo(slide); \n\t\t\t\n\t\t\tlet video = slide.querySelector('video');\n\t\t\tlet playButton = slide.querySelector('.video-control-play');\n\t\t\tlet muteButton = slide.querySelector('.video-control-mute');\n\t\t\t\n\t\t\tif (!slide.classList.contains('active')) {\n\t\t\t\tvideo.pause();\n\t\t\t\tvideo.muted = true;\n\t\t\t} else {\n\t\t\t\t\n\t\t\t\tif (action === \"play\" && playButton.dataset.command === \"pause\") {\n\t\t\t\t\tvideo.play();\n\t\t\t\t\tplayButton.classList.add('playing');\n\t\t\t\t} else if (action === \"pause\" && playButton.dataset.command === \"play\") {\t\t\t\t\t\n\t\t\t\t\tvideo.play();\n\t\t\t\t\tplayButton.classList.remove('playing');\n\t\t\t\t}\n\n\t\t\t\tif(muteButton.dataset.command === \"unmute\"){\n\t\t\t\t\tvideo.muted = true;\n\t\t\t\t\tmuteButton.classList.remove('muted');\n\t\t\t\t}else{\n\t\t\t\t\tvideo.muted = false;\n\t\t\t\t\tmuteButton.classList.add('muted');\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn slide.dataset.init = true;\n\t\t};\n\t\t\t\t\n\t\tthis.initHtmlVideo = function (slide) {\n\n\t\t\tlet slideObj = {\n\n\t\t\t\tmute: slide.querySelector('.video-control-mute'),\n\t\t\t\tplay: slide.querySelector('.video-control-play'),\n\t\t\t\tvideoController: slide.querySelector('.idus-slider-slide-video-controls'),\n\t\t\t\thtmlVideo: slide.querySelector('video'),\n\t\t\t};\n\t\t\t\n\t\t\tslideObj.videoController.style.display = \"block\";\n\n\t\t\tif(slideObj.htmlVideo.hasAttribute(\"autoplay\")){\n\t\t\t\tslideObj.play.dataset.command = \"pause\";\n\t\t\t}else{\n\t\t\t\tslideObj.play.dataset.command = \"play\";\n\t\t\t\tslideObj.play.classList.remove(\"playing\");\n\t\t\t}\n\n\t\t\tconst togglePlay = (event) => {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tif (slideObj.play.classList.toggle(\"playing\")) {\t\t\t\t\t\n\t\t\t\t\tslideObj.play.dataset.command = \"pause\";\n\t\t\t\t\tslideObj.htmlVideo.play();\n\t\t\t\t} else {\n\t\t\t\t\tslideObj.play.dataset.command = \"play\";\n\t\t\t\t\tslideObj.htmlVideo.pause();\n\t\t\t\t}\n\t\t\t};\n\t\t\n\t\t\tconst toggleMute = (event) => {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tif (slideObj.mute.classList.contains(\"muted\")) {\n\t\t\t\t\tslideObj.mute.dataset.command = \"unmute\";\n\t\t\t\t\tslideObj.htmlVideo.muted = true;\n\t\t\t\t\tslideObj.mute.classList.remove(\"muted\")\n\t\t\t\t} else {\n\t\t\t\t\tslideObj.mute.dataset.command = \"mute\";\n\t\t\t\t\tslideObj.htmlVideo.muted = false;\n\t\t\t\t\tslideObj.mute.classList.add(\"muted\");\n\t\t\t\t}\n\t\t\t};\n\t\t\n\t\t\tslideObj.play.addEventListener('click', togglePlay);\n\t\t\tslideObj.mute.addEventListener('click', toggleMute);\n\t\t\treturn slide.dataset.init = true;\n\t\t}\n\t\t\n\t\tthis.initSlides = function () {\n\n\t\t\tself.attachActiveEventToSlides();\n\t\t\tself.triggerActiveSlides();\n\t\t\tself.initFilters();\n\t\t};\n\n\t\tthis.initDebugWindow = function () {\n\n\t\t\tvar debugWindow = document.createElement('div');\n\t\t\tdebugWindow.classList.add('idus_slider_debug_window');\n\t\t\tself.debugWindow = debugWindow;\n\n\t\t\tself.sliderScrollWrapper.appendChild(debugWindow);\n\n\t\t\tself.appendInfoToDebugWindow('scrollLeft', 'self');\n\t\t\tself.appendInfoToDebugWindow('scrollLeft', 'sliderElement');\n\t\t\tself.appendInfoToDebugWindow('getScrollAmount', 'self', true);\n\n\t\t\tself.updateDebugWindow();\n\t\t};\n\n\t\tthis.appendInfoToDebugWindow = function (info, type, isFunc) {\n\n\t\t\tif (typeof isFunc === 'undefined' || isFunc === null) isFunc = false;\n\n\t\t\tvar debugWindowInfo = document.createElement('div');\n\t\t\tdebugWindowInfo.innerHTML = '<span class=\"title\">' + type + '.' + info + '</span>: <span class=\"value\"></span>';\n\t\t\tdebugWindowInfo.classList.add('idus_slider_debug_window_info', 'idus_slider_debug_window_' + info);\n\t\t\tdebugWindowInfo.dataset.info = info;\n\t\t\tdebugWindowInfo.dataset.type = type;\n\t\t\tdebugWindowInfo.dataset.isFunc = isFunc;\n\t\t\tself.debugWindow.appendChild(debugWindowInfo);\n\t\t};\n\n\t\tthis.getDebugInfo = function (info, type, isFunc) {\n\n\t\t\tif (isFunc && isFunc == 'true') return self[info]();\n\t\t\tif (type === 'sliderElement') return self.slider[info];\n\n\t\t\treturn self[info];\n\t\t};\n\n\t\tthis.updateDebugWindow = function () {\n\n\t\t\tvar debugItems = self.debugWindow.querySelectorAll('.idus_slider_debug_window_info');\n\n\t\t\tfor (var i = 0; i < debugItems.length;
2 i++) {\n\n\t\t\t\tvar debugItemVal = debugItems[i].querySelector('span.value');\n\t\t\t\tdebugItemVal.innerText = self.getDebugInfo(debugItems[i].dataset.info, debugItems[i].dataset.type, debugItems[i].dataset.isFunc);\n\t\t\t}\n\t\t};\n\n\t\tthis.initAutoplay = function () {\n\n\t\t\tif (!self.settings.autoplay || !self.settings.autoplaySpeed || self.settings.auto_width) return false;\n\n\t\t\tself.autoplayInterval = setInterval(function () {\n\n\t\t\t\tif (self.interacted) return self.pauseAutoplay();\n\n\t\t\t\tif (self.slider.querySelectorAll(':focus').length > 0) {\n\n\t\t\t\t\tself.interacted = true;\n\t\t\t\t\treturn self.pauseAutoplay();\n\t\t\t\t}\n\n\t\t\t\tif (!self.autoplayCooldown && !self.mouseIn && !self.busy && !self.videoPlaying && document.hasFocus() && document.body.classList.toString().indexOf('freeze_animations') === -1) {\n\n\t\t\t\t\tvar goTo = self.activeSlide + 1;\n\t\t\t\t\tif (self.activeSlide === (self.slidesAmount - 1)) goTo = 0;\n\n\t\t\t\t\tself.goToSlide(goTo);\n\t\t\t\t}\n\t\t\t}, self.settings.autoplaySpeed);\n\t\t};\n\n\t\tthis.pauseAutoplay = function () {\n\n\t\t\tclearInterval(self.autoplayInterval);\n\t\t\tself.autoplayInterval = false;\n\t\t};\n\n\t\tthis.attachMouseEvents = function () {\n\n\t\t\tself.slider.addEventListener('mouseenter', function () {\n\t\t\t\tself.mouseIn = true;\n\t\t\t}, false);\n\n\t\t\tself.slider.addEventListener('mouseleave', function () {\n\t\t\t\tself.mouseIn = false;\n\t\t\t}, false);\n\n\t\t\tself.slider.addEventListener('mousedown', function () {\n\t\t\t\tself.busy = true;\n\t\t\t}, false);\n\n\t\t\tself.slider.addEventListener('mouseup', function () {\n\t\t\t\tself.busy = false;\n\t\t\t}, false);\n\t\t};\n\n\t\tthis.lazyLoadImages = function (all) {\n\t\t\tvar slides = (all ? self.slides : self.activeSlides);\n\t\t\tfor (var i = 0; i < slides.length; i++) {\n\n\t\t\t\tif (slides[i].querySelector(self.selectors.lazyImages)) {\n\n\t\t\t\t\tvar lazyImg = slides[i].querySelector(self.selectors.lazyImages);\n\t\t\t\t\tlazyImg.onload = function () {\n\t\t\t\t\t\tthis.classList.add('lazy-loaded');\n\t\t\t\t\t};\n\n\t\t\t\t\tif (lazyImg.dataset.lazy) {\n\t\t\t\t\t\tlazyImg.src = lazyImg.dataset.lazy;\n\t\t\t\t\t\tdelete lazyImg.dataset.lazy;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tlazyImg.removeAttribute('loading');\n\t\t\t\t\tself.lazyImages--;\n\t\t\t\t\tif (self.lazyImages === 0) self.lazyImages = false;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tthis.lazyLoadImage = function (slide) {\n\n\t\t\tvar lazyImg = slide.querySelector('.idus-slider-slide-img[data-lazy');\n\t\t\tif (lazyImg) {\n\n\t\t\t\tlazyImg.src = lazyImg.dataset.lazy;\n\t\t\t\tdelete lazyImg.dataset.lazy;\n\t\t\t}\n\t\t};\n\n\t\tthis.reInit = function () {\n\n\t\t\tself.slides = self.slider.querySelectorAll(self.selectors.slides);\n\t\t\tself.lazyImages = self.slider.querySelectorAll(self.selectors.lazyImages) ? self.slider.querySelectorAll(self.selectors.lazyImages).length : false;\n\t\t\tself.checkIfOverflowing();\n\t\t};\n\n\t\tthis.isIE = function () {\n\n\t\t\treturn document.body.classList.toString().indexOf('is_ie') !== -1;\n\t\t};\n\n\t\tthis.isiOs = function () {\n\n\t\t\treturn false; // disabling this for now... seems like apple fixes ios...\n\t\t\treturn !!/iP(hone|od|ad)/.test(navigator.platform);\n\t\t};\n\n\t\tthis.initMobileSwipes = function () {\n\n\t\t\tvar xDown = null;\n\t\t\tvar yDown = null;\n\n\t\t\tvar swipe = false;\n\n\t\t\tself.slider.addEventListener('touchend', function (e) {\n\n\t\t\t\tif (swipe && !self.busy) self.goToSlide((swipe === 'hard right') ? self.activeSlide + 1 : self.activeSlide - 1, 'easeOutExpo', self.scrollAnimationInterval / 1.5);\n\n\t\t\t\txDown = null;\n\t\t\t\tyDown = null;\n\t\t\t\tswipe = false;\n\n\t\t\t\tsetTimeout(function () {\n\n\t\t\t\t\tself.autoplayCooldown = false;\n\t\t\t\t}, 3000);\n\t\t\t});\n\n\t\t\tself.slider.addEventListener('touchstart', function (e) {\n\n\t\t\t\txDown = e.touches[0].clientX;\n\t\t\t\tyDown = e.touches[0].clientY;\n\t\t\t\tswipe = false;\n\t\t\t\tself.autoplayCooldown = true;\n\t\t\t});\n\n\t\t\tself.slider.addEventListener('touchmove', function (e) {\n\n\t\t\t\tif (!xDown || !yDown) return;\n\n\t\t\t\tvar xUp = e.touches[0].clientX;\n\t\t\t\tvar yUp = e.touches[0].clientY;\n\n\t\t\t\tvar xDiff = xDown - xUp;\n\t\t\t\tvar yDiff = yDown - yUp;\n\n\t\t\t\tif (Math.abs(xDiff) > Math.abs(yDiff)) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tif (xDiff > 0) swipe = 'hard left';\n\t\t\t\t\telse swipe = 'hard right';\n\t\t\t\t}\n\t\t\t}, { passive: false });\n\t\t};\n\n\t\tthis.initSnapFixForiOS = function () {\n\n\t\t\tif (/iP(hone|od|ad)/.test(navigator.platform)) {\n\t\t\t\tvar version = (navigator.appVersion).match(/OS (\\d+)_(\\d+)_?(\\d+)?/);\n\n\t\t\t\tif (version[1]) if (parseInt(version[1], 10) < 15) return true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t};\n\n\t\tthis.initFilters = function () {\n\n\t\t\tvar filters = self.sliderWrapper.getElementsByClassName('idus-slider-filters-filter');\n\t\t\tif (!filters || !filters.length) return;\n\n\t\t\tfor (var i = 0; i < filters.length;
2 i++) {\n\n\t\t\t\tfilters[i].addEventListener('click', function (e) {\n\t\t\t\t\tvar el = this;\n\n\t\t\t\t\tself._isOverflowing = null;\n\n\t\t\t\t\tvar filterVal = el.dataset.value;\n\t\t\t\t\tvar slides = self.sliderWrapper.querySelectorAll('.idus-slider-slide');\n\t\t\t\t\tvar filteredSlides = self.sliderWrapper.querySelectorAll('[data-filter-value*=\"' + filterVal + '\"]');\n\n\t\t\t\t\tself.sliderWrapper.classList.remove('filtered-slides');\n\n\t\t\t\t\t[].forEach.call(slides, function (pro) {\n\t\t\t\t\t\tpro.classList.remove('hide', 'active', 'filtered');\n\t\t\t\t\t});\n\n\t\t\t\t\tif (el.classList.toString().indexOf('active') !== -1) {\n\n\t\t\t\t\t\tself.triggerActiveSlides();\n\t\t\t\t\t\tself.adjustControls();\n\t\t\t\t\t\treturn el.classList.remove('active');\n\t\t\t\t\t}\n\n\t\t\t\t\t[].forEach.call(filters, function (ft) {\n\t\t\t\t\t\tft.classList.remove('active');\n\t\t\t\t\t});\n\n\t\t\t\t\tel.classList.add('active');\n\n\t\t\t\t\t[].forEach.call(slides, function (pro) {\n\t\t\t\t\t\tpro.classList.add('hide');\n\t\t\t\t\t});\n\n\t\t\t\t\t[].forEach.call(filteredSlides, function (prof) {\n\t\t\t\t\t\tprof.classList.remove('hide');\n\t\t\t\t\t\tprof.classList.add('filtered');\n\t\t\t\t\t});\n\n\t\t\t\t\tself.sliderWrapper.classList.add('filtered-slides');\n\n\t\t\t\t\tself.triggerActiveSlides();\n\t\t\t\t\tself.adjustControls();\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\tthis.initAccessibility();\n\n\t\tthis.contentTimeChange = function () {\n\n\t\t\tvar customTimeChange = this.slider.querySelectorAll('.idus-slider-slide-content-desc');\n\n\t\t\tif (customTimeChange) {\n\t\t\t\tcustomTimeChange.forEach(function (element) {\n\n\t\t\t\t\tvar timeToChange = element.getAttribute('data-content-change-time');\n\t\t\t\t\tif (timeToChange == 0) return;\n\n\t\t\t\t\tsetInterval(function () {\n\t\t\t\t\t\telement.classList.toggle('content-changed');\n\n\t\t\t\t\t}, timeToChange);\n\n\t\t\t\t\telement.addEventListener('click', function () {\n\n\t\t\t\t\t\tthis.classList.toggle('content-changed');\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis.contentTimeChange();\n\n\t\tthis.initCloneToFitSlideToShow = function () {\n\n\t\t\tvar slidesToShow = this.settings.slidesToShow;\n\t\t\tvar slidesCount = this.slides.length;\n\n\t\t\tif (slidesCount % slidesToShow === 0) return;
2\n\n\t\t\tvar numberSlidesToClone = slidesToShow - (slidesCount % slidesToShow);\n\t\t\tvar slides = this.slides;\n\t\t\tvar nodeToClone = slides[slides.length - 1];\n\t\t\tfor (var i = 0; i < numberSlidesToClone; i++) {\n\n\t\t\t\tvar clonedNode = nodeToClone.cloneNode(false);\n\t\t\t\tclonedNode.classList.add('cloned');\n\t\t\t\tthis.slider.appendChild(clonedNode);\n\t\t\t}\n\t\t}\n\t};\n});\n","Idus_Banner/js/personalization.banner.js":"define(['jquery',], function ($) {\n\n var personalizationBanner = {\n setPersonalizedSlider: function (slider_wrapper) {\n \n window.idusPersonalization = window.idusPersonalization || [];\n var hasPersonalization = this.removeIrrelevantSlides(slider_wrapper);\n if (hasPersonalization) {\n this.setSlidesOrder(slider_wrapper);\n this.changePersonalizedContent(slider_wrapper);\n }\n },\n removeIrrelevantSlides: function (slider_wrapper) {\n var personalizedSlides = $('.idus-slider-slide:not([data-personalization=\"all\"]):not([data-personalization=\"none\"])', slider_wrapper);\n var slidesToRemove = [];\n var hasPersonalization = false;\n personalizedSlides.each(function () {\n var personalization = JSON.parse(this.dataset.personalization);\n\n if (!window.idusPersonalization.isDataExists(personalization)) {\n slidesToRemove.push(this);\n } else {\n hasPersonalization = true;\n slider_wrapper.addClass('has_personalization');\n }\n });\n\n if (hasPersonalization) {\n var noPersonalizedSlides = $('.idus-slider-slide[data-personalization=\"none\"]', slider_wrapper);\n noPersonalizedSlides.each(function () {\n slidesToRemove.push(this);\n });\n }\n slidesToRemove.forEach(function (slide) {\n slide.remove();\n });\n\n return hasPersonalization;\n },\n setSlidesOrder: function (slider_wrapper) {\n\n var slides = $('.idus-slider-slide', slider_wrapper);\n\n this.setOrderByKey(slides);\n },\n setOrderByKey: function (slides, maxIndex = 0) {\n\n var index = 1;\n var filteredSlides = slides;\n var slide = filteredSlides.get(0);\n var key, keySlides, filterBy;\n try {\n key = JSON.parse(slide.dataset.personalization).key;\n filterBy = `[data-personalization*='\"key\":\"${key}\"']`;\n } catch {\n key = slide.dataset.personalization\n filterBy = `[data-personalization='${key}']`;\n }\n\n keySlides = slides.filter(filterBy);\n if (keySlides && keySlides.length) {\n\n if (key != 'all') {\n\n var personalizationData = idusPersonalization.getData(key);\n if (personalizationData && personalizationData.values) {\n personalizationData.values.forEach(function (valueData) {\n\n var value = valueData.value;\n var valueSlides = keySlides.filter(`[data-personalization*='\"value\":\"${value}\"']`);\n\n if (valueSlides.length) {\n valueSlides.each(function (slide) {\n \n valueSlides[slide].setAttribute('data-order', index);\n valueSlides[slide].style.setProperty('--slideIndex', index);\n maxIndex = index > maxIndex ? index : maxIndex;\n index++;\n })\n }\n })\n }\n } else {\n index = maxIndex + 1;
2\n var valueSlides = keySlides.filter('[data-personalization=\"all\"]');\n if (valueSlides.length) {\n valueSlides.each(function (slide) {\n slide.setAttribute('data-order', index);\n slide.style.setProperty('--slideIndex', index);\n index++;\n })\n }\n }\n }\n\n filteredSlides = filteredSlides.not(filterBy);\n if (filteredSlides.length) {\n\n this.setOrderByKey(filteredSlides, maxIndex);\n }\n },\n changePersonalizedContent: function (slider_wrapper) {\n \n var contentTitle = $('.idus-slider-content-title', slider_wrapper);\n if (contentTitle.length && contentTitle.data().personalizationResults) {\n $('span.html', contentTitle).html(contentTitle.data().personalizationResults);\n }\n\n var contentDesc = $('.idus-slider-content-desc', slider_wrapper);\n if (contentDesc.length && contentDesc.data().personalizationResults) {\n $('span.html', contentDesc).html(contentDesc.data().personalizationResults);\n }\n\n var contentBtn = $('.idus-slider-content-button', slider_wrapper);\n if (!contentBtn.length) return;\n\n var btnAction = {\n 'hide': false,\n 'show': true\n }\n\n var action = btnAction[contentBtn.data().onPersonalizationResults];\n\n if (!action && !contentBtn.hasClass('hide')) {\n contentBtn.addClass('hide');\n } else if (action) {\n contentBtn.removeClass('hide');\n return;\n }\n\n var link = $('.button', contentBtn);\n if (link.data().personalizationResults) link.attr('href', link.data().personalizationResults);\n\n var text = $('span', link)\n if (text.data().personalizationResults) text.text(text.data().personalizationResults);\n }\n }\n return personalizationBanner;\n});","Idus_Banner/js/ajaxProducts.js":"define(['jquery', 'Idus_Core/js/url', 'uiClass'], function ($, urlHelper, Class) {\n\n return Class.extend({\n options: {\n class: {\n slider: '.idus-slider',\n slide: '.idus-slider-slide',\n placeholder_slide: '.idus-slider-slide-placeholder',\n product_item: '.product-item'\n }\n },\n initialize: function (config, element) {\n let self = this;\n self.element = element;\n self.config = config\n let getProductIdsEvent = new CustomEvent(\"getDynamicProductIds\", {'detail': self});\n document.dispatchEvent(getProductIdsEvent);\n },\n renderProductSlides: function (productIds) {\n let self = this;\n let config = self.config;\n let element = self.element;\n\n if (element.dataset.isRendered) return;\n element.classList.toggle('is-loading', true);\n\n if (!productIds || !productIds.length) {\n productIds = [];\n let placeholderSlides = element.querySelectorAll(self.options.class.placeholder_slide);\n\n placeholderSlides.forEach(function (slide) {\n productIds.push(slide.dataset.productId);\n });\n }\n\n if (productIds.length > config.product_slide_limit) {\n productIds = productIds.slice(0, config.product_slide_limit);\n }\n\n productIds = productIds.filter(function(value, index, array) {\n return array.indexOf(value) === index;\n });\n\n element.dataset.isRendered = true;\n\n let clonedSlide = element.querySelector(self.options.class.slide).cloneNode(true);\n let newSlidesArr = [];\n productIds.forEach(function (productId) {\n \n ajaxPath = `product/ajax/item?product_id=${productId}`\n if (config.layout_key) {\n ajaxPath += `&layout_key=${config.layout_key}`;\n }\n if (config.layout_title) {\n\n ajaxPath += `&title=${config.layout_title}`;\n }\n\n ajaxPath = urlHelper.getUrl() + ajaxPath;\n\n fetch(ajaxPath)\n .then(response => {\n\n if (!response.ok) {\n console.log('Error Fetching Products');\n element.classList.toggle('is-loading', false);\n return false;\n }\n return response.json();\n })\n .then(data =>
2 {\n if (data.success) {\n\n let productElement = clonedSlide.querySelector(self.options.class.product_item);\n if (!productElement) return;\n\n productElement.parentNode.innerHTML = data.html;\n\n let index = element.dataset.slidesFetched;\n if (!index) index = 0;\n else index = index * 1 + 1;\n clonedSlide.style.setProperty(\"--slideIndex\", index);\n clonedSlide.classList.remove('idus-slider-slide-placeholder');\n delete clonedSlide.dataset.productId;\n newSlidesArr.push(clonedSlide.cloneNode(true));\n\n element.dataset.slidesFetched = index;\n\n if (index == productIds.length - 1) {\n element.querySelector(self.options.class.slider).replaceChildren(...newSlidesArr);\n element.dataset.mageInit = localStorage.getItem(config.banner_key);\n $(element).trigger('contentUpdated');\n element.classList.toggle('is-loading', false);\n }\n } else {\n console.log(data.error_message);\n element.classList.toggle('is-loading', false);\n }\n });\n });\n }\n })\n});
2","Idus_Banner/js/script.js":"define([\n\t'jquery',\n\t'Idus_Core/js/idus',\n\t'Idus_Core/js/slick.min',\n\t'Idus_Core/js/jquery.matchHeight',\n\t'Magento_Ui/js/modal/modal',\n\t'mage/translate',\n\t'idusPinchZoom',\n\t'idus_personalization_banner',\n\t'mage/mage'\n], function ($,idus,slick,matchHeight,modal,$t,IdusPinchZoom,personalizationBanner) {\n\t'use strict';\n\n\t// --------\n\t// Global Slider Logics\n\t// --------\n\t$(document).on('click', '[data-emulate-filter] a[href]', function (e) {\n\t\t\n\t\te.preventDefault();\n\t\tvar linkEl = $(e.target).closest('a[href]');\n\t\tvar linkHref = linkEl.attr('href');\n\n\t\tif (linkHref && linkHref.indexOf('?') === 0) {\n\n\t\t\treturn $(document).trigger('idus-filterEmulation', linkEl);\n\t\t}\n\n\t\treturn false;\n\t});\n\n\treturn function(){\n\n\t\t// get args & slider obj\n\t\tvar slider_wrapper = $(arguments[1]);\n\t\tvar slider_setting = arguments[0];\n\t\tvar slider = $('.idus-slider:not(.idus-slider-thumbs)',slider_wrapper);\n\n\t\tif (slider_setting.personalization && slider_setting.personalization != \"0\") personalizationBanner.setPersonalizedSlider(slider_wrapper);\n\n\t\t// mylist\n\t\tif(slider_setting.mylist != undefined){\n\t\t\tif(!getMylistSlides(slider_setting.mylist)){\n\t\t\t\tslider_wrapper.remove();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t\n\t\t// has thumbs?\n\t\tslider_thumbs = false;\n\t\tif(slider_setting.thumbs){\n\t\t\tvar slider_thumbs = $('.idus-slider-thumbs',slider_wrapper);\n\t\t\tif(slider_thumbs == undefined) slider_thumbs = false;\n\t\t}\n\n\t\t// prevent reinit\n\t\tif(slider.hasClass('is__init')) return;\n\n\t\tvar popup_options = {\n\t\t\ttype: 'popup',\n\t responsive: true,\n innerScroll: true,\n title: false,\n buttons: fal
2se,\n modalClass : 'banner-popup-class'\n };\n\n \n var bannerId = slider_wrapper.data('banner-id');\n var bannerLoadImg = slider_wrapper.data('loader');\n if(bannerLoadImg != undefined)\n \tbannerLoadImg = '<img src=\"' + bannerLoadImg + '\" />';\n var classes = {\n \tslide: 'idus-slider-slide',\n \tpopup_opener: 'banner-popup-open',\n \tbanner_popup_loader: 'banner-popup-loader',\n \tbanner_popup_content: 'banner-popup-content',\n \tbanner_slide_video_wrapper: 'idus-slider-slide-video',\n \tbanner_slide_video_overlay: 'idus-slider-slide-video-overlay',\n \tbanner_slide_video_controls: 'idus-slider-slide-video-controls',\n \tbanner_slide_video_controls_mute: 'video-control-mute',\n \tbanner_slide_video_controls_play: 'video-control-play',\n \tbanner_slide_video_youtube_close: 'video-youtube-control-close',\n \tbanner_slide_video_youtube_init: 'video-youtube-control-init',\n };\n\n // check if banner has a popup opener somewhere\n var popUpOpeners = $('a[target=\"popup\"]', slider_wrapper);\n var popUpModal = $('.banner-popup');\n\n if (popUpModal.length === 0) {\n\t\t\t// create a popup div and append it to the body\n \t\tpopUpModal = document.createElement('div');\n \tpopUpModal.classList.add('banner-popup');\n \tpopUpModal.style.display = 'none';\n\n \t$('body').append(popUpModal);\n\n \tpopUpModal = $('.banner-popup');\n\n \t// reset and init a loader\n \tresetPopup(popUpModal, bannerLoadImg);\n\n \t// init created div as a modal\n \t// all ajax will be loaded into this bad boy\n \tmodal(popup_options, popUpModal);\n\n \t// delete all content inside popup when it closes\n \t// and push a loader into the popup\n \tpopUpModal.on('modalclosed', function () {\n \t\tresetPopup(popUpModal, bannerLoadImg);\n \t});\n\n \t// init the load when a modal is opened\n \tpopUpModal.on('modalopened', function () {\n \t\ttogglePopupLoader(popUpModal);\n \t});\n }\n\n if (popUpOpeners.length > 0) {\n \t// init popups\n \t$.each(popUpOpeners, function (i, v) {\n \t\tvar me = $(this); \t\t\t \t\n\t \tme.click(function (e) {\n\t \t\te.preventDefault();\n\t \t\tresetPopup(popUpModal, bannerLoadImg);\n\n\t \t\t// calculate slide index\n\t \t\tvar slide = me.closest('.' + classes.slide); \t\t\n\t \t\tvar slideIndex = getSlideIndex(slide, slider);\n\n\t \t\t// get button number to pass to ajax\n\t \t\tvar btn = me.parent().attr('class').indexOf('button_2') !== -1 ? 2 : 1;\n\n \t\t\t\tpopUpModal.modal('openModal');\n\n \t\t\t\t// load ajax\n \t\t\t\t$.ajax({\n \t\t\t\t\turl: '/banner/ajax/popup?id=' + bannerId +\n \t\t\t\t\t\t'&slide=' + slideIndex +\n \t\t\t\t\t\t'&btn=' + btn,\n \t\t\t\t\ttype: 'GET',\n \t\t\t\t\tsuccess: function (res) { \t\t\t\t\t\t\n \t\t\t\t\t\t$('.' + classes.banner_popup_content, popUpM
2odal).html(res);\n \t\t\t\t\t\t$('iframe', popUpModal).load(function () {\n \t\t\t\t\t\t\ttogglePopupLoader(popUpModal);\n \t\t\t\t\t\t});\n \t\t\t\t\t},\n \t\t\t\t\terror: function (err) {\n\t\t\t\t\t\t\tconsole.log(err);\n\t\t\t\t\t\t\tpopUpModal.modal('closeModal');\n \t\t\t\t\t}\n \t\t\t\t});\n\t \t});\n \t});\n }\n\n\t\t// responsive - remove irrelevant slides\n\t\tif($(window).width() > 767){\n\t\t\t$('.idus-slider-slide[data-device=\"sp\"]',slider).remove();\n\t\t\tslider.data('device','dt');\n\n\t\t\tif(slider_thumbs){\n\t\t\t\tif(slider_thumbs.hasClass('idus-slider-slidestoshow_dt_1')){\n\t\t\t\t\tslider_thumbs.remove();\n\t\t\t\t\tslider_thumbs = false;\n\t\t\t\t}else{\n\t\t\t\t\t$('.idus-slider-slide[data-device=\"sp\"]',slider_thumbs).remove();\n\t\t\t\t\tslider_thumbs.data('device','dt');\n\t\t\t\t}\n\t\t\t}\n\n\t\t}else{\n\t\t\t$('.idus-slider-slide[data-device=\"dt\"]',slider).remove();\n\t\t\tslider.data('device','sp');\n\n\t\t\tif(slider_thumbs){\n\t\t\t\tif(slider_thumbs.hasClass('idus-slider-slidestoshow_sp_1')){\n\t\t\t\t\tslider_thumbs.remove();\n\t\t\t\t\tslider_thumbs = false;\n\t\t\t\t}else{\n\t\t\t\t\t$('.idus-slider-slide[data-device=\"dt\"]',slider_thumbs).remove();\n\t\t\t\t\tslider_thumbs.data('device','sp');\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t}\n\t\tvar slides_count = $('.idus-slider-slide',slider).length;\n\n\t\tvar slidesToShowByDevice = slider_setting.slidesToShow;\n\t\tvar isDynamic = slider.hasClass('is__dynamic');\n\t\tif ($(window).width() <= 767) {\n\t\t\tslidesToShowByDevice = slider_setting.responsive[1].settings.slidesToShow;\n\t\t\tisDynamic = slider.hasClass('is__sp_dynamic');\n\t\t\tif (isDynamic) isDynamic = slider.hasClass('prevent-slick-mobile') ? false : true;\n\t\t}\n\t\telse if ($(window).width() > 767 && $(window).width() <= 1199) slidesToShowByDevice = slider_setting.responsive[0].settings.slidesToShow;\n\t\t\n\t\tif(slides_count < 2 || slides_count <= slidesToShowByDevice){\n\t\t\tslider.removeClass('is__dynamic').removeClass('is__sp_dynamic').addClass('is__static').addClass('is__sp_static');\n\t\t\tif(slider_thumbs){\n\t\t\t\tslider_thumbs.removeClass('is__dynamic').removeClass('is__sp_dynamic').addClass('is__static').addClass('is__sp_static');\n\n\t\t\t\t// fix lazy images\n\t\t\t\t$('img[data-lazy]',slider_thumbs).each(function(){ $(this).attr('src',$(this).data('lazy')); });\n\t\t\t\t\n\t\t\t}\n\n\t\t\tvar currSlide = $(slider.find('.idus-slider-slide').get(0));\n\t\t\tinitVideo(slider, currSlide, true);\n\t\t\tinitPinchZoom(slider);\n\t\t} else if(slides_count > 0 && isDynamic) {\n\n\t\t\tslider.removeClass('is__static').addClass('is__dynamic');\n\t\t\tslider.removeClass('is__tb_static').addClass('is__tb_static');\n\t\t\t\n\t\t\tslider.on('afterChange', function (e, el, slide) {\n\t\t\t\t// when we go to a new slide init a video there\n\t\t\t\tinitVideo(el, slide);\n\t\t\t});\n\n\t\t\tslider.on('beforeChange', function (e, el, slide, nextSlide) {\n\t\t\t\t// when we go to a new slide if there is a video there\n\t\t\t\t// play that video\n\t\t\t\tvar htmlVideo = $('video', $(el.$slides[nextSlide]));\n\t\t\t\tvar slideIframe = $('iframe', $(el.$slides[nextSlide]));\n\t\t\t\tif (slideIframe.length) {\n\t\t\t\t\tvar player = slideIframe[0];\n\n\t\t\t\t\tif (player.src && player.src !== '' && player.src !== location.href) {\n\t\t\t\t\t\tplayVideo(player);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (htmlVideo.length) {\n\t\t\t\t\tvar player = htmlVideo[0];\n\t\t\t\t\tplayVideo(player);\n\t\t\t\t\t\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tslider.on('init', function (e, el) {\n\t\t\t\t// init a video on the first slide\n\t\t\t\t// when slick first inits\n\t\t\t\tinitVideo(el, 0);\n\t\t\t\tinitPinchZoom(slider);\n\t\t\t\tinitFilters(slider_wrapper, el);\n\t\t\t});\n\n\t\t\tvar selectedSlide = $('.idus-slider-slide.selected', slider);\n\n\t\t\tslider_setting.rtl = slider_setting.direction === 'rtl';\n\n\t\t\tif (window.slickCSSEase) slider_setting.cssEase = window.slickCSSEase;\n\n\t\t\tif(slider_thumbs){\n\t\t\t\tvar slider_setting_thumbs = slider_setting.thumbs;\n\t\t\t\tdelete slider_setting.thumbs;\n\t\t\t\tslider.slick(slider_setting);\n\t\t\t\tslider_thumbs.slick(slider_setting_thumbs);\n\t\t\t}else{\n\t\t\t\tdelete slider_setting.asNavFor;\n\t\t\t\tslider.slick(slider_setting);\n\t\t\t}\n\n\t\t\tif (selectedSlide && selectedSlide.length > 0) {\n\n\t\t\t\tslider.slick('slickGoTo', selectedSlide.index() === 0 ? 0 : (selectedSlide.index() - 1));\n\t\t\t}\n\n\t\t\t// remove responsive hide classes\n\t\t\tslider_wrapper.attr('class', function(i, c){\n\t\t\t\treturn c.replace(/(^|\\s)\\S+_hide/g, '');\n\t\t\t});\n\n\t\t\t$('.slick-prev.slick-arrow').html($t('Prev')).attr('aria-label', $t('Prev'));\n\t\t\t$('.slick-next.slick-arrow').html($t('Next')).attr('aria-label', $t('Next'));\n\n\t\t\tvar checkSlickInitialized = setInterval(function () {\n\t\t\t\tif (slider.hasClass('slick-initialized')) {\n\t\t\t\t\tclearInterval(checkSlickInitialized);\n\n\t\t\t\t\tvar slickInstance = slider.slick('getSlick');\n\t\t\t\t\tvar originalKeyHandler = slickInstance.keyHandler;\n\n\t\t\t\t\t// Remove the default keydown.slick event listener for downkey\n\t\t\t\t\tslickInstance.$list.off('keydown.slick', originalKeyHandler);\n\t\t\t\t\tslickInstance.$list.on('keydown', function (e) {\n\t\t\t\t\t\tconst preventDefaultKeys = ['ArrowLeft', 'ArrowRight', 37, 39];\n\t\t\t\t\t\tlet tabMode = document.body.classList.contains('tab-mode');\n\n\t\t\t\t\t\tif (tabMode && (preventDefaultKeys.includes(e.ke
2y) || preventDefaultKeys.includes(e.which))) {\n\t\t\t\t\t\t\t//if tab mode and pressed key is right/left arrow - prevent default\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// else act normal\n\t\t\t\t\t\t\toriginalKeyHandler.call(slickInstance, e);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tif (slider_setting.centerMode) {\n\t\t\t\t\t\thandleCenterMode(slickInstance, slider);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (slider_setting.swipeToSlide) {\n\t\t\t\t\t\thandleSwipeToSlide(slickInstance);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, 100); // Check every that the slider is initialized\n\t\t\t\n\t\t} else {\n\n\t\t\t// static slider with more than 1 slide\n\t\t\tvar slides = $('.idus-slider-slide', slider);\n\t\t\tslides.each(function (i, slide) {\n\n\t\t\t\tif ($('.idus-slider-slide-video', slide).length) initVideo(slider, slide, true);\n\t\t\t});\n\t\t}\n\n\t\tif (!slider.hasClass('is__dynamic')) $('img[data-lazy]', slider).each(function(){ $(this).attr('src',$(this).data('lazy')); });\n\n\t\tvar arrow = $('.scrolling_down', slider_wrapper);\n\t\t\tif (arrow && arrow.length){\n\t\t\t\tarrow.off('off').on('click', function(){\t\t\t\t\n\t\t\t\t\t$('html').animate({ scrollTop: $(slider_wrapper)[0].scrollHeight }, 1000);\n\t\t\t\t});\n\t\t}\n\n\t\tif (slider_wrapper.data('emulate-filter')) {\n\n\t\t\tinitFilterEmulation(slider_wrapper);\n\t\t}\n\n\t\tif (slider_setting.lazy_loading) {\n\n\t\t\thandleLazyLoading(slider_wrapper.get(0));\n\t\t}\n\n\t\tslider.addClass('is__init');\n\n\t\tvar personalizedloader = $('.idus_personalized_banner_loader', slider_wrapper);\n\t\tif (personalizedloader.length) {\n\t\t\tpersonalizedloader.removeClass('active');\n\t\t}\n\n\t\t/**\n\t\t * Inits filters on a filterable slider\n\t\t * @param {Element} slider slider wrapper\n\t\t * @param {Object} slick slick object\t\t \n\t\t */\n\t\tfunction initFilters(slider, slick) {\n\t\t\tvar filters = $('.idus-slider-filters-filter', slider);\n\t\t\tvar products = $('.idus-slider-slide', slider).not('.slick-cloned');\n\n\t\t\tif (!filters || filters.length === 0 || products.length === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfilters.each(function (index, filter) {\n\t\t\t\tfilter.addEventListener(\"keyup\", function(event) {\n\t\t\t\t if (event.keyCode === 13) {\n\t\t\t\t event.preventDefault();\n\t\t\t\t event.target.click();\n\t\t\t\t }\n\t\t\t\t});\n\t\t\t\tif (!filter.dataset.value || filter.dataset.value === '') {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t$('.idus-slider-filters-filter').off().on('click', function(e) {\t\t\t\t\n\t\t\t\tvar el = $(this);\n\t\t\t\tvar currSlider = el.closest('.idus-slider-wrapper');\n if (el.hasClass('active')) {\n el.removeClass('active').siblings().removeClass('active');\n $('.idus-slider', currSlider).slick('slickUnfilter');\n return;\n }\n el.addClass('active').siblings().removeClass('active');\n var filterVal = this.dataset.value; \n $('.idus-slider', currSlider).slick('slickUnfilter').slick('slickFilter', '[data-filter-value*=\"' + filterVal + '\"]');\n });\n\t\t}\n\n\t\t/**\n\t\t * [resetPopup Clears the element supplied and inits a loader inside it]\n\t\t * @param {[type]} popup [DOM element]\n\t\t */\n\t\tfunction resetPopup(popup, loadImg) {\n\t\t\tif(loadImg != undefined){\n\t\t\t\tpopup.html('<div class=\"banner-popup-loader idus-loader absolute\">'\n\t\t\t\t\t+ loadImg\n\t\t\t\t\t+ '</div><div class=\"banner-popup-content\"></div>');\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\t/**\n\t\t * [togglePopupLoader Toggles the 'active' class on the loader]\n\t\t * @param {[type]} popup [description]\n\t\t * @return {[type]} [description]\n\t\t */\n\t\tfunction togglePopupLoader(popup) {\n\t\t\treturn $('.banner-popup-loader', popup).toggleClass('active');\n\t\t}\n\n\t\tfunction getSlideIndex(slide, slider) {\n\t\t\tif (slider.attr('class').indexOf('static') !== -1) {\n\t\t\t\t// slider is static, easy.\n\t\t\t\treturn slider.children().index(slide);\n\t\t\t} else {\n\t\t\t\t// dynamic slider, go by data-slick-index\n\t\t\t\treturn slide.data('slick-index');\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Inits a video on the supplied slide\n\t\t * @param {Object} slider the whole slider object\n\t\t * @param {Integer} slide the index of the current slide we are working with\n\t\t * @param {Boolean} isStatic is our slide static\n\t\t */\n\t\tfunction initVideo(slider, slide, isStatic) {\n\t\t\tisStatic = isStatic || false\n\t\t\tif (isStatic) {\n\t\t\t\tvar currSlide = slide;\n\t\t\t\tvar htmlVideo = $('video', currSlide);\n\t\t\t\tvar slideIframe = $('iframe', currSlide);\n\t\t\t\tvar otherSlides = $('.idus-slider-slide', slider).not(currSlide);\n\t\t\t\tvar controls = $('.' + classes.banner_slide_video_controls, currSlide);\n\t\t\t} else {\n\t\t\t\tvar currSlide = $(slider.$slides[slide]);\n\t\t\t\tvar htmlVideo = $('video', currSlide);\n\t\t\t\tvar slideIframe = $('iframe', currSlide);\n\t\t\t\tvar otherSlides = $(slider.$slides).not(currSlide);\n\t\t\t\tvar controls = $('.' + classes.banner_slide_video_controls, currSlide);\n\t\t\t}\n\n\t\t\t// destroy all videos in slides that are out of sight\n\t\t\tif ((otherSlides.length > 0) && ($('iframe', otherSlides).length) > 0) {\n\t\t\t\t$.each(otherSlides, function (i, v) {\n\t\t\t\t\tdestroyVideo(slider, v);\n\t\t\t\t});\n\t\t\t}\n\t\t\t\n\t\t\tif (slideIframe.length > 0) {\t\t\t\t\t\n\t\t\t\tvar player = slideIframe[0];\n\n\t\t\t\tif (player.src && player.src !== '' && player.src !== location.href && player.dataset.type !== 'youtube') {\n\t\t\t\t\tif(parseInt(player.dataset.autoplay)) {\n\t\t\t\t\t\tplayVideo(player);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpauseVideo(player);\n\t\t\t\t\t}\n\t\t\t\t\tcontrols.fadeIn();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tplayer.onload = function () {\t\t\t\t\t\t\n\t\t\t\t\tif (player.dataset.type !== 'youtube') {\n\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\tif(parseInt(player.dataset.autoplay)) {\n\t\t\t\t\t\t\t\tplayVideo(player);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tpauseVideo(player);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tplayer.style.opacity = 1;\n\t\t\t\t\t\t\tcontrols.fadeIn();\n\t\t\t\t\t\t}, 250);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tplayer.src = player.dataset.src;\n\t\t\t} else if (htmlVideo.length > 0) {\n\t\t\t\tvar player = htmlVideo[0];\n\t\t\t\tplayVideo(player);\n\t\t\t\tcontrols.fadeIn();\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t$('.idus-slider-slide-inner > a', slider).on('click', function (e) {\n\n\t\t\t\tif (e.target.dataset.command) {\n\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});
2\n\n\t\t\tinitControls(slider, currSlide);\n\t\t}\n\n\t\t/**\n\t\t * Inits a youtube type video, displays a play button and close button when played.\n\t\t * @param {Object} slider Our slide object\n\t\t * @param {Integer} slide The index of the slide we are working with\n\t\t */\n\t\tfunction initYoutube(slider, slide) {\n\t\t\tvar currSlide = slide;\n\t\t\tvar closeBtn = $('.' + classes.banner_slide_video_youtube_close, currSlide);\n\t\t\tvar initBtn = $('.' + classes.banner_slide_video_youtube_init, currSlide);\n\t\t\tvar controls = $('.' + classes.banner_slide_video_controls, currSlide);\t\t\t\n\t\t\tvar player = $('iframe', currSlide)[0];\n\n\t\t\t// hide vid, show controls, show image\n\t\t\tplayer.style.opacity = 0;\n\t\t\tcloseBtn.hide();\t\t\t\n\t\t\tcontrols.hide();\n\t\t\tinitBtn.show();\n\t\t\tpauseVideo(player);\n\n\t\t\tcloseBtn.click(function () {\n\t\t\t\tplayer.style.opacity = 0;\n\t\t\t\tpauseVideo(player);\n\t\t\t\tcloseBtn.fadeOut();\n\t\t\t\tcontrols.fadeOut();\n\t\t\t\tinitBtn.fadeIn();\n\t\t\t});\n\n\t\t\tinitBtn.click(function () {\n\t\t\t\tplayer.style.opacity = 1;\n\t\t\t\tplayVideo(player);\n\t\t\t\tcloseBtn.fadeIn();\n\t\t\t\tcontrols.fadeIn();\n\t\t\t\tinitBtn.fadeOut();\n\t\t\t});\n\t\t}\n\n\t\t/**\n\t\t * Inits play and mute controls for videos\n\t\t * @param {Object} slider Our slide object\n\t\t * @param {Integer} slide The index of the slide we are working with\n\t\t */\n\t\tfunction initControls(slider, slide) {\t\t\t\t\n\t\t\tvar currSlide = slide;\n\t\t\tvar htmlVideo = $('video', currSlide);\n\t\t\tvar slideIframe = $('iframe', currSlide);\n\t\t\tif (slideIframe.data('type') === 'youtube') {\n\t\t\t\tinitYoutube(slider, currSlide);\n\t\t\t}\n\t\t\tvar player = slideIframe.length ? slideIframe[0] : htmlVideo[0];\n\t\t\tvar muter = $('.' + classes.banner_slide_video_controls_mute, currSlide);\n\t\t\tvar playPauser = $('.' + classes.banner_slide_video_controls_play, currSlide);\n\n\t\t\tmuter.html('<span>Unmute</span>');\n\t\t\t\n\t\t\tif(parseInt(player.dataset.autoplay)){\n\t\t\t\tplayPauser.html('<span>Pause</span>');\n\t\t\t}else{\n\t\t\t\tplayPauser.html('<span>Play</span>');\n\t\t\t}\n\t\t\t\n\t\t\tmuter.click(function () {\n\t\t\t\tif (muter.hasClass('muted')) {\n\t\t\t\t\tunmuteVideo(player);\n\t\t\t\t\tmuter.html('<span>Mute</span>');\n\t\t\t\t} else {\n\t\t\t\t\tmuteVideo(player);\n\t\t\t\t\tmuter.html('<span>Unmute</span>');\n\t\t\t\t}\n\t\t\t\tmuter.toggleClass('muted');\n\t\t\t});\n\n\t\t\tplayPauser.click(function () {\n\t\t\t\tif (playPauser.hasClass('playing')) {\n\t\t\t\t\tpauseVideo(player);\n\t\t\t\t\tplayPauser.html('<span>Play</span>');\n\t\t\t\t} else {\n\t\t\t\t\tplayVideo(player);\n\t\t\t\t\tplayPauser.html('<span>Pause</span>');\n\t\t\t\t}\n\t\t\t\tplayPauser.toggleClass('playing');\n\t\t\t});\n\n\t\t\t$(document).on('click', '.idus-slider-slide-inner > a', function (e) {\n\n\t\t\t\tif ($(e.target).is('.video-control-mute, .video-control-play')) {\n\t\t\t\t\t\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\t/**\n\t\t * Pauses a video, if video type is youtube we hide it and reinit it.\n\t\t * @param {Object} slider Our whole slider\n\t\t * @param {Integer} slide The index of our slide\n\t\t */\n\t\tfunction destroyVideo(slider, slide) {\n\t\t\tvar currSlide = slide;\n\t\t\tvar slideIframe = $('iframe', currSlide);\n\t\t\tvar htmlVideo = $('video', currSlide);\n\t\t\tvar controls = $('.' + classes.banner_slide_video_controls, currSlide);\n\t\t\tvar player = (slideIframe.length > 0) ? slideIframe[0] : htmlVideo[0];\n\t\t\tif(player == undefined) return;\n\t\t\tif (player.dataset != undefined && player.dataset.type === 'youtube') {\n\t\t\t\tinitYoutube(slider, currSlide);\n\t\t\t} else {\n\t\t\t\tpauseVideo(player);\n\t\t\t\tcontrols.fadeOut();\n\t\t\t}\t\t\t\n\t\t}\n\n\t\t/**\n\t\t * Play a video\n\t\t * @param {Element} player iframe/native player element\n\t\t */\n\t\tfunction playVideo(player) {\n\t\t\t//muteVideo(player);\n\t\t\tvar playerType = player.dataset.type;
2\n\t\t\tswitch (playerType) {\n\t\t\t\tcase 'youtube':\n\t\t\t\t\tiframeSendCommand(player, {\n\t\t\t\t\t\tevent: 'command',\n\t\t\t\t\t\tfunc: 'playVideo'\n\t\t\t\t\t});\t\t\t\t\t\t\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'vimeo':\n\t\t\t\t\tiframeSendCommand(player, {\n\t\t\t\t\t\tmethod: 'play',\n\t\t\t\t\t\tvalue: 1\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'native':\n\t\t\t\t\tplayer.play();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Pause a video\n\t\t * @param {Element} player iframe/native player element\n\t\t */\n\t\tfunction pauseVideo(player) {\n\t\t\tvar playerType = player.dataset.type;\n\t\t\tswitch (playerType) {\n\t\t\t\tcase 'youtube':\n\t\t\t\t\tiframeSendCommand(player, {\n\t\t\t\t\t\tevent: 'command',\n\t\t\t\t\t\tfunc: 'pauseVideo'\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'vimeo':\n\t\t\t\t\tiframeSendCommand(player, {\n\t\t\t\t\t\tmethod: 'pause',\n\t\t\t\t\t\tvalue: 1\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'native':\n\t\t\t\t\tplayer.pause();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Mute a video\n\t\t * @param {Element} player iframe/native player element\n\t\t */\n\t\tfunction muteVideo(player) {\n\t\t\tvar playerType = player.dataset.type;\n\t\t\tswitch (playerType) {\n\t\t\t\tcase 'youtube':\n\t\t\t\t\tiframeSendCommand(player, {\n\t\t\t\t\t\tevent: 'command',\n\t\t\t\t\t\tfunc: 'mute'\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'vimeo':\n\t\t\t\t\tiframeSendCommand(player, {\n\t\t\t\t\t\tmethod: 'setVolume',\n\t\t\t\t\t\tvalue: 0\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'native':\n\t\t\t\t\tplayer.muted = true;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Unmute a video\n\t\t * @param {Element} player iframe/native player element\n\t\t */\n\t\tfunction unmuteVideo(player) {\n\t\t\tvar playerType = player.dataset.type;\n\t\t\tswitch (playerType) {\n\t\t\t\tcase 'youtube':\n\t\t\t\t\tiframeSendCommand(player, {\n\t\t\t\t\t\tevent: 'command',\n\t\t\t\t\t\tfunc: 'unMute'\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'vimeo':\n\t\t\t\t\tiframeSendCommand(player, {\n\t\t\t\t\t\tmethod: 'setVolume',\n\t\t\t\t\t\tvalue: 1\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'native':\n\t\t\t\t\tplayer.muted = false;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Send a command to an iframe to trigger it's player API\n\t\t * @param {Element} iframe our player element\n\t\t * @param {String} command the command\n\t\t */\n\t\tfunction iframeSendCommand(iframe, command) {\n\t\t\tif(iframe.contentWindow){\n\t\t\t\tiframe.contentWindow.postMessage(JSON.stringify(command), \"*\");\n\t\t\t}\n\t\t}\n\n\t\tfunction initFilterEmulation(wrapper) {\n\n\t\t\tvar linkEls = $('.idus-slider-slide a[href]', wrapper);\n\n\t\t\tlinkEls.each(function (i, linkEl) {\n\n\t\t\t\tvar link = $(linkEl).attr('href');\n\t\t\t\tvar reg = new RegExp('[?]([a-zA-Z0-9-_]*)=');\n\t\t\t\tvar matches = reg.exec(link);\n\n\t\t\t\tif (matches && matches[1]) {\n\n\t\t\t\t\t$('[data-filter=\"'+matches[1]+'\"]', '#layered-filter-block').addClass('filter-is-emulated');\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tfunction getMylistSlides(type) {\n\n\t\t\tvar date = new Date();\n\t\t\tvar time = date.getTime();\n\t\t\tvar lists = idus.getLocalStorage('idus_mylist_'+type,1);\n\t\t\tif(!lists || lists == undefined) lists = {};\n\t\t\tvar template_obj = $('#idus_slider_'+type+'_template');\n\t\t\tvar template = template_obj.html();\n\t\t\tvar list_name = 'general';\n\n\t\t\tvar html = '';\n\t\t\t$.each(lists,function(list,products){\n\t\t\t\t$.each(products,function(id,product){\n\t\t\t\t\tif(window.idusDataLayer.last_pageView_sku != undefined && window.idusDataLayer.last_pageView_sku == product.sku) return true;\n\t\t\t\t\tif(product.last_view < time){\n\t\t\t\t\t\tdelete lists[list][id];\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\thtml += template.split('%product_id%').join(id).split('%list%').join(list).split('%name%').join(product['name']).split('%image%').join(product['image']).split('%url%').join(product['url']);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tif(html == '') return false;\n\t\t\tslider.html(html);\n\t\t\tslider_wrapper.addClass('has__items');\n\n\t\t\t// handle item remove\n\t\t\t$(slider).on('click','.'+type+'_item_remove',function(){\n\t\t\t\tvar item = $(this).closest('.'+type+'_item');\n\t\t\t\tvar item_list = lists[item.attr('list')];\n\n\t\t\t\tdelete item_list[item.attr('product_id')];
2\n\t\t\t\tidus.setLocalStorage('idus_mylist_'+type,lists,1);\n\t\t\t\twindow.mylistView.updateDelta('remove', type, item.attr('list'), item.attr('product_id'));\n\n\t\t\t\twindow.mylistView.updateCounter(type, -1);\n\t\t\t\titem.fadeOut();\n\t\t\t\tif(window.idusDataLayer.last_pageView_sku != undefined){\n\t\t\t\t\tif(_.size(item_list) === 1) slider_wrapper.removeClass('has__items');\n\t\t\t\t}else{\n\t\t\t\t\tif(_.size(item_list) === 0) slider_wrapper.removeClass('has__items');\n\t\t\t\t}\n\n\t\t\t});\n\n\t\t\t// handle remove all items\n\t\t\tvar remove_all_btn = $('.idus-slider-content-button a',slider_wrapper);\n\t\t\tif(remove_all_btn != undefined){\n\t\t\t\tremove_all_btn.on('click',function(e){\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\n\t\t\t\t\tlists[list_name] = {};\n\t\t\t\t\twindow.mylistView.updateCounter(type, _.size(lists));\n\t\t\t\t\tidus.setLocalStorage('idus_mylist_'+type,lists,1);\n\t\t\t\t\t$('.idus-slider-slide',slider_wrapper).fadeOut();\n\t\t\t\t\t\n\t\t\t\t\tslider_wrapper.removeClass('has__items');\n\n\t\t\t\t});\n\t\t\t}\n\t\t\t\n\t\t\treturn true;\n\t\t}\n\n\t\tfunction initPinchZoom(slider) {\n\n\t\t\tif (slider_setting.pinch_zoom) {\n\n\t\t\t\tvar pinchZoom = new IdusPinchZoom();\n\t\t\t\tpinchZoom.init(slider, $('.idus-slider-slide-img', slider));\n\t\t\t}\n\t\t}\n\n\t\tfunction handleLazyLoading(sliderWrapper) {\t\t\t\n\n\t\t\tlet images = sliderWrapper.querySelectorAll('.idus-slider-slide-img');\n\t\t\tif (!images.length) return;\n\n\t\t\t//First Check If all images loaded\n\t\t\tlet allImagesComplete = checkIfImagesLoaded(images);\n\t\t\tif (allImagesComplete) sliderWrapper.dataset.imagesLoaded = true;\n\t\t\telse {\n\t\t\t\t//If not loaded handle load on scroll\n\t\t\t\tfor (let image of images) {\n\t\t\t\t\t// When image loades, check again if all images loaded\n\t\t\t\t\timage.addEventListener('load', () => {\n\t\t\t\t\t\tif (checkIfImagesLoaded(images)) sliderWrapper.dataset.imagesLoaded = true;\n\t\t\t\t\t});\n\t\t\t\t};\n\t\t\t\tsliderWrapper.elementIsViewed = function() {\n\t\t\t\t\tloadImagesOnScroll(sliderWrapper);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfunction checkIfImagesLoaded(images) {\n\t\t\tlet allImagesComplete = true;\n\t\t\tfor (let image of images) {\n\t\t\t\tif (image.complete) image.dataset.loaded = true;\n\t\t\t\telse allImagesComplete = false;\n\t\t\t};\n\t\t\treturn allImagesComplete;\n\t\t}\n\n\t\tfunction loadImagesOnScroll(sliderWrapper) {\n\n\t\t\tif (sliderWrapper.dataset.imagesloaded) return false;\n\n\t\t\tlet sliderImages = sliderWrapper.querySelectorAll('.idus-slider-slide-img');\n\t\t\tsliderImages.forEach(function (img) {\n\t\t\t\timg.removeAttribute('loading');\n\t\t\t\tif (img.datasrc && !img.src) img.src = img.datasrc;\n\n\t\t\t\timg.dispatchEvent(new Event('load'));\n\t\t\t});\n\t\t}\n\n\t\tfunction handleCenterMode(slickInstance, $slider) {\n\t\t\t\n\t\t\tlet sliderWidth = $slider.find('.slick-list').width();\n\t\t\t$slider.get(0).style.setProperty('--max-distace-from-center', sliderWidth / 2);\n\n\t\t\tconst originalSetCSSHandler = slickInstance.setCSS;\n\t\t\t// Intercept the original set css to catch all drag / swipe events\n\t\t\tslickInstance.setCSS = function (i) {\n\t\t\t\t//Call original handler\n\t\t\t\toriginalSetCSSHandler.call(this, i);\n\n\t\t\t\tsetCenterModeCssVariables($slider);\n\t\t\t}\n\n\t\t\tslickInstance.animateSlide = function (e, t) {\n\n\t\t\t\t//copied the original animate slide and altered it\n\t\t\t\tvar o = {},\n\t\t\t\t\ts = this;\n\t\t\t\tlet iterations = s.options.speed / 4;\n\t\t\t\tlet index = 0;\n\n\t\t\t\tfunction startCssInterval(s, t) {\n\t\t\t\t\tlet setCssInterval = setInterval(function () {\n\t\t\t\t\t\t//set the center mode variables while transitioning\n\t\t\t\t\t\tsetCenterModeCssVariables($slider);\n\t\t\t\t\t\tindex++;\n\n\t\t\t\t\t\tif (index == iterations) {\n\t\t\t\t\t\t\tclearInterval(setCssInterval);\n\t\t\t\t\t\t\ts.disableTransition(), t.call();\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 4);\n\t\t\t\t}\n\n\t\t\t\ts.animateHeight(),\n\t\t\t\t\t!0 === s.options.rtl && !1 === s.options.vertical && (e = -e),\n\t\t\t\t\t!1 === s.transformsEnabled\n\t\t\t\t\t\t? !1 === s.options.vertical\n\t\t\t\t\t\t\t? s.$slideTrack.animate({ left: e }, s.options.speed, s.options.easing, t)\n\t\t\t\t\t\t\t: s.$slideTrack.animate({ top: e }, s.options.speed, s.options.easing, t)\n\t\t\t\t\t\t: !1 === s.cssTransitions\n\t\t\t\t\t\t\t? (!0 === s.options.rtl && (s.currentLeft = -s.currentLeft),\n\t\t\t\t\t\t\t\ti({ animStart: s.currentLeft }).animate(\n\t\t\t\t\t\t\t\t\t{ animStart: e },\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tduration: s.options.speed,\n\t\t\t\t\t\t\t\t\t\teasing: s.options.easing,\n\t\t\t\t\t\t\t\t\t\tstep: function (i) {\n\t\t\t\t\t\t\t\t\t\t\t(i = Math.ceil(i)), !1 === s.options.vertical ? ((o[s.animType] = \"translate(\" + i + \"px, 0px)\"), s.$slideTrack.css(o)) : ((o[s.animType] = \"translate(0px,\" + i + \"px)\"), s.$slideTrack.css(o));\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tcomplete: function () {\n\t\t\t\t\t\t\t\t\t\t\tt && t.call();\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t))\n\t\t\t\t\t\t\t: (s.applyTransition(),\n\t\t\t\t\t\t\t\t(e = Math.
2ceil(e)),\n\t\t\t\t\t\t\t\t!1 === s.options.vertical ? (o[s.animType] = \"translate3d(\" + e + \"px, 0px, 0px)\") : (o[s.animType] = \"translate3d(0px,\" + e + \"px, 0px)\"),\n\t\t\t\t\t\t\t\ts.$slideTrack.css(o),\n\t\t\t\t\t\t\t\tt && startCssInterval(s, t));\n\t\t\t}\n\n\t\t\tsetCenterModeCssVariables($slider);\n\t\t}\n\n\t\tfunction setCenterModeCssVariables($slider) {\n\t\t\tlet sliderWidth = $slider.find('.slick-list').width();\n\t\t\tlet sliderOffset = $slider.find('.slick-list').offset();\n\t\t\tlet sliderCenterX = sliderOffset.left + sliderWidth / 2;\n\t\t\tlet items = $slider.find('.idus-slider-slide');\n\n\n\t\t\tlet closestItem = $slider.find('.slide-center-closest');\n\t\t\tlet closestItemDistance = sliderWidth;\n\t\t\tif (closestItem.length) closestItemDistance = closestItem.get(0).style.getPropertyValue('--distance-from-center') * 1;\n\n\t\t\titems.each(function () {\n\n\t\t\t\tlet item = $(this);\n\t\t\t\tlet itemBounding = this.getBoundingClientRect();\n\t\t\t\tlet itemCenterX = itemBounding.right - (itemBounding.right - itemBounding.left) / 2;\n\n\t\t\t\tlet distance = Math.abs(itemCenterX - sliderCenterX);\n\t\t\t\tif (closestItemDistance === false) closestItemDistance = distance;\n\n\t\t\t\tif (distance <= closestItemDistance) {\n\t\t\t\t\tif (closestItem.length) {\n\t\t\t\t\t\tclosestItem.removeClass('slide-center-closest');\n\t\t\t\t\t}\n\t\t\t\t\tclosestItem = item;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.style.setProperty(\"--distance-from-center\", `${distance}`);\n\t\t\t});\n\t\t\t\n\t\t\tclosestItem.addClass('slide-center-closest');\n\t\t}\n\n\t\tfunction handleSwipeToSlide(slickInstance) {\n\t\t\tslickInstance.getNavigableIndexes = function(){\n\t\t\t\tvar i, e = this, t = 0, o = 0, s = [];\n\t\t\t\tfor (t = -1*e.slideCount; t < i; )\n\t\t\t\t\ts.push(t),\n\t\t\t\t\tt = o + e.options.slidesToScroll,\n\t\t\t\t\to += e.options.slidesToScroll <= e.options.slidesToShow ? e.options.slidesToScroll : e.options.slidesToShow;\n\t\t\t\treturn s\n\t\t\t}\n\t\t}\n\t}\n});","Idus_Banner/js/idus.slider.buttonMapping.js":"define([\n\t'jquery',\n\t'Idus_Core/js/idus',\n\t'idus_slider'\n], function ($, idusHelper, IdusSlider) {\n\t'use strict';\n\n\treturn function () {\n\n\t\tvar settings = arguments[0];\n\t\tvar element = arguments[1];\n\n\t\tsettings = settings || {};\n\t\tsettings.selectors = {\n\t\t\tbuttonLink: '.idus-slider-slide-img-button-link',\n\t\t\tbutton: '.idus-slider-slide-img-button',\n\t\t\tbuttonContentItem: '.idus-slider-slide-img-buttons-content-item'\n\t\t};\n\n\t\tif (settings.clickBehavior || window.idusSliderButtonMappingClickBehavior) {\n\n\t\t\t$(settings.selectors.button, element).on('click', function (e) {\n\n\t\t\t\tif (!$(this).hasClass('active')) e.preventDefault();\n\t\t\t\telse{\n\t\t\t\t\t$(this).removeClass('active');\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t$(this).addClass('active').siblings().removeClass('active');\n\t\t\t\t$(settings.selectors.buttonContentItem + '[data-button-map-key=\"' + $(this).data('button-map-key') + '\"]', element)\n\t\t\t\t\t.addClass('active')\n\t\t\t\t\t.siblings()\n\t\t\t\t\t.removeClass('active');\n\n\t\t\t\treturn false;\n\t\t\t});\n\t\t}\n\t}\n});","Idus_Banner/js/css3banner.js":"define([\n\t'jquery',\n\t'Idus_Core/js/idus',\n\t'idus_slider',\n\t'idus_personalization_banner'\n], function ($, idusHelper, IdusSlider,personalizationBanner) {\n\t'use strict';\n\n\treturn function(){\n\n\t\tvar sliderSettings = arguments[0];\n\t\tvar sliderWrapper = arguments[1];\n\n\t\tvar slider = new IdusSlider(sliderWrapper, sliderSettings, null);\n\t\tif (!slider || !slider.slider) return;\n\t\tslider.initControls();\n\t\tslider.initScroll();\n\n\t\tslider.checkIfOverflowing();\n\n\t\tslider.initSlides();\n\n\t\tif (localStorage.getItem('idus-slider-debug')) slider.initDebugWindow();\n\n\t\tslider.attachMouseEvents();\n\t\tslider.initAutoplay();\n\n\t\tif (sliderSettings.personalization && sliderSettings.personalization != \"0\") personalizationBanner.setPersonalizedSlider($(sliderWrapper));\n\t\t// mylist\n\t\tif(sliderSettings.mylist != undefined){\n\t\t\tif(!getMylistSlides(sliderSettings.mylist)){\n\t\t\t\t$(sliderWrapper).remove();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t//Remove Personalization loader\n\t\tvar personalizedloader = $('.idus_personalized_banner_loader', $(sliderWrapper));\n\t\tif (personalizedloader.length) {\n\t\t\tpersonalizedloader.removeClass('active');\n\t\t}\n\n\t\tfunction getMylistSlides(type) {\n\n\t\t\tvar date = new Date();\n\t\t\tvar time = date.getTime();\n\t\t\tvar lists = idus.getLocalStorage('idus_mylist_'+type,1);\n\t\t\tif(!lists || lists == undefined) lists = {};\n\t\t\tvar template_obj = $('#idus_slider_'+type+'_template');\n\t\t\tvar template = template_obj.html();\n\t\t\tvar list_name = 'general';\n\n\t\t\tvar html = '';\n\t\t\t$.each(lists,function(list,products){\n\t\t\t\t$.each(products,function(id,product){\n\t\t\t\t\tif(window.idusDataLayer.last_pageView_sku != undefined && window.idusDataLayer.last_pageView_sku == product.sku) return true;\n\t\t\t\t\tif(product.last_view < time){\n\t\t\t\t\t\tdelete lists[list][id];\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\thtml += template.split('%product_id%').join(id).split('%list%').join(list).split('%name%').join(product['name']).split('%image%').join(product['image']).split('%url%').join(product['url']);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tif(html == '') return false;\n\t\t\t$('.idus-slider', $(sliderWrapper)).html(html);\n\t\t\t$(sliderWrapper).addClass('has__items');\n\n\t\t\t// handle item remove\n\t\t\t$('.idus-slider', $(sliderWrapper)).on('click','.'+type+'_item_remove',function(){\n\t\t\t\tvar item = $(this).closest('.'+type+'_item');\n\t\t\t\tvar item_list = lists[item.attr('list')];\n\n\t\t\t\tdelete item_list[item.attr('product_id')];
2\n\t\t\t\tidus.setLocalStorage('idus_mylist_'+type,lists,1);\n\t\t\t\twindow.mylistView.updateDelta('remove', type, item.attr('list'), item.attr('product_id'));\n\n\t\t\t\twindow.mylistView.updateCounter(type, -1);\n\t\t\t\titem.fadeOut();\n\t\t\t\tif(window.idusDataLayer.last_pageView_sku != undefined){\n\t\t\t\t\tif(_.size(item_list) === 1) $(sliderWrapper).removeClass('has__items');\n\t\t\t\t}else{\n\t\t\t\t\tif(_.size(item_list) === 0) $(sliderWrapper).removeClass('has__items');\n\t\t\t\t}\n\n\t\t\t});\n\n\t\t\t// handle remove all items\n\t\t\tvar remove_all_btn = $('.idus-slider-content-button a', $(sliderWrapper));\n\t\t\tif(remove_all_btn != undefined){\n\t\t\t\tremove_all_btn.on('click',function(e){\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\n\t\t\t\t\tlists[list_name] = {};\n\t\t\t\t\twindow.mylistView.updateCounter(type, _.size(lists));\n\t\t\t\t\tidus.setLocalStorage('idus_mylist_'+type,lists,1);\n\t\t\t\t\t$('.idus-slider-slide', $(sliderWrapper)).fadeOut();\n\t\t\t\t\t\n\t\t\t\t\t$(sliderWrapper).removeClass('has__items');\n\n\t\t\t\t});\n\t\t\t}\n\t\t\t\n\t\t\treturn true;\n\t\t}\n\t}\n});","Idus_Banner/js/closeable.js":"define(['jquery'], function ($) {\n\n return function(config, element) {\n\n $(element).off('click').on('click', function() {\n \n $(element).closest('.idus-slider-wrapper').slideUp();\n\n if(config.closeableBanner.closeableStorageType == \"sessionStorage\") {\n sessionStorage.setItem(`closeableBanner-${config.closeableBanner.bannerId}`, 'closed');\n } else if(config.closeableBanner.closeableStorageType == \"localStorage\") {\n localStorage.setItem(`closeableBanner-${config.closeableBanner.bannerId}`, 'closed');\n }\n }); \n };\n});","Idus_Membership/js/membership.datalayer.js":"require([\n 'jquery',\n 'idus_dataLayer',\n 'domReady!'\n], function ($) {\n 'use strict';\n\n window.idusDataLayer = window.idusDataLayer || [];\n\n var DL_SETTINGS = {\n ajaxURLs: {\n confirmation: 'membership/index/confirmation'\n },\n classes: {\n regeisterCheckboxes: '#membership_register_check, #membership_join_check',\n registerSubmit: '.action.membership_register_submit, .action.membership_join_submit',\n customerRegisterSubmit: '#account-register-send',\n unregister: '.action.membership_unregister_submit',\n loginLink: '.login-link',\n confirmation: '.action.customer_confirmation',\n accountDashbord: '.customer-dashboard',\n accountDashbordNavigation: '.customer-dashboard-navigation',\n accountDashbordContent: '.customer-dashboard-content'\n },\n confirmation: {\n flag: false,\n step: 1\n },\n location: false,\n };\n\n $(document).on('click', DL_SETTINGS.classes.regeisterCheckboxes, function () {\n\n if (!this.checked) return;\n let jsonData = getCustomData('club_membership', 'begin_registration');\n window.idusDataLayer.push(jsonData);\n });\n\n // Membership Popup Open\n $(document).on('click', DL_SETTINGS.classes.loginLink, function (e, data) {\n\n if (debounce != undefined) clearTimeout(debounce);\n\t\tvar debounce = setTimeout(function () {\n if (!data || !data.hasOwnProperty('membership') || !data.membership) return;\n\n if (data.hasOwnProperty('location')) DL_SETTINGS.location = data.location;\n else DL_SETTINGS.location = false;\n\n let jsonData = getCustomData('membershipPopupOpen', 'begin_registration');\n\n //if guest - loginPopupOpen, not membershipPopupOpen\n if (jsonData.customData.userType == 'guest') return;\n\n window.idusDataLayer.push(jsonData);\n }, 1000);\n });\n\n $(document).ajaxComplete(function (event, request, settings) {\n var ajaxURL = settings.url; // url requested\n var isSuccess = request.responseJSON ? request.responseJSON.success : false; // is request successful\n\n if (isSuccess && ajaxURL.indexOf(DL_SETTINGS.ajaxURLs.confirmation) !== -1) {\n\n if (request.responseJSON.done) {\n $('body').on('init
2CustomerComplete', function () {\n if (DL_SETTINGS.confirmation.flag) return;\n let jsonData = getCustomData('club_membership', 'membership_confirmation');\n window.idusDataLayer.push(jsonData);\n DL_SETTINGS.confirmation.flag = true;\n });\n } else if (DL_SETTINGS.confirmation.step == 1) {\n let jsonData = getCustomData('club_membership', 'begin_registration');\n window.idusDataLayer.push(jsonData);\n }\n }\n });\n\n $(DL_SETTINGS.classes.accountDashbord).on('click', DL_SETTINGS.classes.accountDashbordNavigation + ' .tab:not(.active)', function () {\n let navigation = this;\n $('body').one('contentUpdated', function () {\n let dashbordContent = navigation.closest(DL_SETTINGS.classes.accountDashbord).querySelector(DL_SETTINGS.classes.accountDashbordContent);\n if (dashbordContent.getAttribute('active') != 'tab_membership') return;\n\n let registerCheckbox = dashbordContent.querySelectorAll(DL_SETTINGS.classes.regeisterCheckboxes);\n \n if (!registerCheckbox.length) return;\n\n let eventPushed = false;
2\n registerCheckbox.forEach(checkbox => {\n let checked = checkbox.checked;\n if (!checked) checked = checkbox.value;\n if (!checked || eventPushed) return;\n\n let jsonData = getCustomData('club_membership', 'begin_registration');\n window.idusDataLayer.push(jsonData);\n eventPushed = true;\n })\n });\n });\n\n $(document).on('click', DL_SETTINGS.classes.registerSubmit, function () {\n let form = $(this).closest('.form');\n if (!form.valid()) return;\n\n let jsonData = getCustomData('club_membership', 'submit_registration');\n jsonData.customData.membershipRequest = true;\n window.idusDataLayer.push(jsonData);\n });\n\n $(document).on('click', DL_SETTINGS.classes.unregister, function() {\n\n let jsonData = getCustomData('club_membership', 'cancel_registration');\n window.idusDataLayer.push(jsonData);\n });\n\n $(document).on('click', DL_SETTINGS.classes.customerRegisterSubmit, function () {\n\n let submitBtn = this;\n let registrationForm = submitBtn.closest('form');\n if (!registrationForm || !$(registrationForm).valid()) return;\n let registerCheckbox = registrationForm.querySelectorAll(DL_SETTINGS.classes.regeisterCheckboxes);\n if (!registerCheckbox.length) return;\n let checked = true;
2\n try {\n registerCheckbox.forEach(checkbox => {\n if (!checkbox.checked) {\n checked = false; \n throw new Error();\n }\n });\n } catch (e) {}\n\n if(!checked || checked == 'false') return;\n\n $('body').on('initCustomerComplete', function () {\n\n if (DL_SETTINGS.confirmation.flag) return;\n let jsonData = getCustomData('club_membership', 'submit_registration');\n jsonData.customData.membershipRequest = true;\n window.idusDataLayer.push(jsonData);\n DL_SETTINGS.confirmation.flag = true;\n });\n });\n \n function getCustomData(eventName, type) {\n\n let location = DL_SETTINGS.location ? DL_SETTINGS.location : getLocation();\n let jsonData = {\n customEvent: eventName,\n customData: {\n type: type,\n location: location\n }\n }\n\n if (window.localStorage != undefined) var storage = JSON.parse(window.localStorage.getItem('mage-cache-storage'));\n if (storage != undefined && storage.customer != undefined && storage.customer.customer_id > 0) {\n jsonData.customData.user_id = storage.customer.customer_id;\n jsonData.customData.groupId = storage.customer.group_id;\n jsonData.customData.membershipExists = storage.customer.membership_exists ? true : false;\n\n if (storage.customer.club_id) {\n jsonData.customData.clubId = storage.customer.club_id;\n } \n\n } else {\n jsonData.customData.userType = 'guest'\n }\n return jsonData;\n }\n\n function getLocation() {\n\n let location = 'general';\n if (document.body.classList.contains('catalog-product-view') ||\n $('.idus_popup_wrap.product_quickview._show').length) {\n location = 'product';\n } else if (document.body.classList.contains('checkout-cart-index')) {\n location = 'cart';\n } else if (document.body.classList.contains('checkout-index-index')) {\n location = 'checkout';\n } else if (document.body.classList.contains('customer-account-index')) {\n location = 'account';\n } else if (document.body.classList.contains('catalog-category-view')) {\
2n location = 'category';\n } else if (document.body.classList.contains('cms-home')) {\n location = 'homepage';\n }\n\n return location;\n }\n});","Idus_Membership/js/customer/confirmation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'Idus_Core/js/idus',\n 'Idus_Core/js/url',\n 'Idus_Customer/js/customer',\n 'Magento_Ui/js/modal/alert',\n], function ($, idus, url, customer, alert) {\n 'use strict';\n\n $.widget('mage.customer_confirmation', {\n options: {\n loader : '.customer_confirmation_loader',\n ajaxCall : false,\n },\n _create: function () {\n var self = this;\n\n $('button.customer_confirmation').off('click').on('click',function(){\n self.submit($(this));\n });\n\n $('#verify-code-back-confirmation').off('click').on('click',function(){\n var telephone = $('#telephone-field-confirmation').show().addClass('active');\n if(telephone.hasClass('exists')){\n $('.telephone_exists').show();\n $('.telephone_dosent_exists').hide();\n $('#telephone-confirmation').prop('disabled', true);\n $('.customer_confirmation .not_me').show();\n }\n $('#verify-code-field-confirmation').hide().removeClass('active');\n $('#verify-code-confirmation').prop('disabled', true);\n });\n\n $('.customer_confirmation .not_me').off('click').on('click',function(){\n $('.telephone_exists').hide();\n $('.telephone_dosent_exists').show();\n $('#telephone-confirmation').prop('disabled', false);\n $('#telephone-field-confirmation').removeClass('exists');\n $(this).hide();\n });\n\n setTimeout(function(){\n var telephone = $('#telephone-confirmation');\n if(telephone.val() == ''){\n telephone.val(telephone.data('value')).trigger('change');\n }\n },250);\n },\n\n submit: function (element) {\n var self = this;\n var data = {};\n var fieldset = element.closest('fieldset');\n\n var valid = true;\n $('label.error', fieldset).remove();\n $('input:not([disabled]),select:not([disabled]),textarea:not([disabled])', fieldset).each(function(){\n this.formAjax = fieldset[0];\n if(!fieldset.validate().element(this)){\n valid = false;\n }\n data[this.name] = this.value;\n });\n if(!valid) return false;\n\n var ajaxUrl = url.getUrl('membership/index/confirmation');\n if(self.options.ajaxCall) self.options.ajaxCall.abort();\n\n self.options.ajaxCall = $.ajax({\n url: ajaxUrl,\n type: \"POST\",\n dataType: \"json\",\n data : data,\n\n beforeSend: function () {\n self.loader(fieldset, 1);\n },\n\n complete: function (response) {\n self.loader(fieldset, 0);\n }\n }).done(\n function (response) {\n $('.customer_confirmation .not_me').hide();\n \n if(response.elements){\n idus.responseElements(response.elements);\n }\n\n if(response.success){\n element.closest('.mini-login-content').removeClass('confirmation_error');\n idus.setMessages($.mage.__(response.message));\n if(response.done){\n $(window).trigger('initCustomer');\n if(element.closest('#widget-membership').length && !$('body').hasClass('checkout-cart-index') && !$('body').hasClass('checkout-index-index')){\n if(response.customer_group_id && response.customer_group_id == '1'){\n $('#widget-membership').trigger('init');\n return true;\n }\n }
2else{\n setTimeout(function(){\n location.reload();\n },1500);\n }\n $('.modal-popup._show .modal-content').children().first().modal('closeModal');\n }\n }else{\n element.closest('.mini-login-content').addClass('confirmation_error');\n idus.setMessages($.mage.__(response.message), 'error');\n \n var elementError = fieldset.find('> .active .field.error').html(response.message);\n console.log(elementError);\n setTimeout(function(){\n elementError.html('');\n }, 10000);\n }\n }\n ).fail(\n function (response) {\n $('.customer_confirmation_message', fieldset).text(response.error_message);\n }\n );\n },\n\n loader: function (element,active) {\n\n $('button', element).prop('disabled', active);\n if(active){\n $(this.options.loader).addClass('active');\n }
2else{\n $(this.options.loader).removeClass('active');\n }\n },\n });\n\n return $.mage.customer_confirmation;\n});\n","Idus_Membership/js/customer/register.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'Idus_Core/js/idus',\n 'Idus_Core/js/url',\n 'Idus_Customer/js/customer',\n 'Magento_Ui/js/modal/alert',\n], function ($, idus, url, customer, alert) {\n 'use strict';\n\n $.widget('mage.customer_register', {\n options: {\n loader : '.membership_register_loader',\n ajaxCall : false,\n },\n _create: function () {\n var self = this;\n\n $('[name=membership_join]').off('change').on('change',function(){\n $(this).val(this.checked);\n var membership_register = $(this).closest('.membership_register');\n var form = $('.membership_register_form', membership_register);\n if(this.checked){\n form.slideDown();\n $('input,select,textarea', form).prop('disabled', false);\n membership_register.closest('form').parent().addClass('membership_register_show');\n }
2else{\n form.slideUp();\n $('input,select,textarea', form).prop('disabled', true);\n membership_register.closest('form').parent().removeClass('membership_register_show');\n }\n });\n\n $('.button.membership-register').on('click',function(){\n $('#membership_register_check_popup').prop('checked',true).trigger('change');\n });\n\n $('.membership_register_submit').off('click').on('click',function(){\n self.submit($(this).closest('.membership_register'));\n });\n\n $('.membership_unregister_submit').off('click').on('click',function(){\n var data = {'membership_unjoin' : true};\n self.submit($(this).closest('.membership_unregister'),data);\n });\n },\n\n submit: function (element,data) {\n var self = this;\n var valid = true;\n $('.membership_message',element).text('');\n\n var form = element.closest('form'); \n if(data == undefined) data = {};\n $('input:not([disabled]):not([type=radio]),input[type=radio]:checked:not([disabled]),select:not([disabled]),textarea:not([disabled])',element).each(function() {\n if(form.length && !form.validate().element(this)){\n valid = false;\n }\n data[this.name] = $(this).val();\n });\n if(!valid) return false;\n\n var ajaxUrl = url.getUrl('membership/index/join');\n if(self.options.ajaxCall) self.options.ajaxCall.abort();\n\n self.options.ajaxCall = $.ajax({\n url: ajaxUrl,\n type: \"POST\",\n dataType: \"json\",\n data : data,\n\n beforeSend: function () {\n self.loader(element,1);\n },\n\n complete: function (response) {\n self.loader(element,0);\n }\n }).done(\n function (response) {\n $('.membership_message',element).text(response.error_message);\n if(response.success){\n $(window).trigger('initCustomer');\n idus.setMessages($.mage.__(response.error_message));\n setTimeout(function(){\n location.reload();\n },1500);\n }
2else{\n idus.setMessages(response.error_message, 'info');\n }\n }\n ).fail(\n function (response) {\n $('.membership_message',element).text(response.error_message);\n }\n );\n },\n\n loader: function (element,active) {\n\n element.prop('disabled',active);\n if(active){\n $(this.options.loader).addClass('active');\n }else{\n $(this.options.loader).removeClass('active');\n }\n },\n });\n\n return $.mage.customer_register;\n});\n","Idus_Membership/js/customer/relatives.js":"define([\n\t'jquery',\n\t'Idus_Core/js/idus',\n\t'Idus_Core/js/url',\n\t'Magento_Ui/js/modal/alert'\n], function($, idus, url, alert) {\n\t'use strict';\n\n\t$('#add-relative').on('click', function(e) {\n\t\te.preventDefault\n\t\tvar queryString = $('.form-add-relative').serialize();\n\t\t$.ajax({\n\t\t\turl: url.getUrl('membership/index/addrelative'),\n\t\t\ttype: \"POST\",\n\t\t\tdataType: \"json\",\n\t\t\tdata: queryString,\n\t\t\tbeforeSend: function() {\n\t\t\t\t$('.add_relative_loader').addClass('active');\n\t\t\t},\n\t\t}).done(\n\t\t\tfunction(response) {\n\t\t\t\t$('.add_relative_loader').removeClass('active');\n\t\t\t\tif (response.success) {\n\t\t\t\t\tidus.setMessages(response.message, 'success');\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tlocation.reload();\n\t\t\t\t\t}, 1000);\n\t\t\t\t} else { \n\t\t\t\t\tidus.setMessages(response.message, 'error');\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t});\n});","Idus_Membership/js/customer/login.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'Idus_Core/js/idus',\n 'Idus_Core/js/url',\n 'Idus_Customer/js/customer',\n 'Magento_Ui/js/modal/alert',\n], function ($, idus, url, customer, alert) {\n 'use strict';\n\n $.widget('mage.customer_login', {\n options: {\n loader : '.membership_login_loader',\n ajaxCall : false,\n },\n _create: function () {\n var self = this;\n\n $('.membership_login_submit').off('click').on('click',function(){\n self.submit($(this).closest('.membership_login_steps'),self.check);\n });\n\n $('[name=membership_login_check]').off('change').on('change',function(){\n $(this).val(this.checked);\n if(this.checked){\n $('.membership_login_form',$(this).closest('.membership_login')).slideDown();\n $('#customer-popup-login').addClass('membership_login_show');\n }
2else{\n $('.membership_login_form',$(this).closest('.membership_login')).slideUp();\n $('#customer-popup-login').removeClass('membership_login_show');\n }\n });\n\n $('.membership_login_back_step').off('click').on('click',function(){\n var element = $('.membership_login_steps:visible');\n\n var prev = element.prev();\n if(prev.length){\n $('input', element.hide()).prop('disabled', true);\n $('input', prev.slideDown()).prop('disabled', false);\n if(prev.hasClass('membership_login_step_1')){\n $('.membership_login_back_step').hide();\n }\n }\n self.initStep();\n });\n\n $(document).on('ajaxComplete', function (event, xhr, settings) {\n if(settings.data && settings.data.indexOf && settings.data.indexOf('type=register') > 0){\n if(xhr.responseJSON.errors.code != undefined && xhr.responseJSON.errors.code == 10){\n var setp = $('.membership_login_step_1').hide();\n\n $('.membership_login_step_2 .membership_message').text(xhr.responseJSON.message);\n $.each(xhr.responseJSON.errors.membership,function(k,v){\n $('input[name=membership_'+k+']',setp).addClass('system').val(v);\n });\n\n if($('input.system',setp).length){\n $('input:not(.system)',setp).closest('.field').remove();\n $('#customer-account-register-form .back button').click();\n $('.to-membership button').click();\n $('.membership_login_submit',setp).click();\n }\n self.initStep();\n }\n }\n });\n\n $('input[type=\"text\"][name*=\"membership_\"]', '.membership_login_steps').on('keyup', function (e) {\n if (e.which === 13) {\n $('.membership_login_submit', $(this).closest('.membership_login_steps')).click();\n }\n });\n },\n\n check: function (element,response){\n if(response.success === true){\n if(response.data != undefined){\n $.each(response.data,function(k,v){\n $('input[name=membership_'+k+']',element).val(v);\n });\n }\n\n if(response.validate != undefined){\n \n $.each(response.validate,function(k,v){\n var validate = $('.membership_validate_'+k);\n validate.show();\n $('input',validate).prop('disabled',false);\n $('.demo',validate).text(v);\n });\n\n }else if(response.login){\n $('.membership_login input:not([type=radio])').val('');\n $('.membership_login input[type=radio]').prop('checked',0);\n \n $('.membership_message',element).text(response.login);\n var mage_cache = idus.getLocalStorage('checkout_data',1);\n if(!mage_cache) mage_cache = {};\n\n mage_cache.customer = response.customer;\n idus.setLocalStorage('checkout_data', mage_cache, 1);\n\n idus.initCustomer();\n window.initMembership = false;\n $('body').on('initCustomerComplete',function(){\n if(!window.initMembership){\n window.initMembership = true;\n\n if($('.modal-popup._show .modal-content').length){\n $('.modal-popup._show .modal-content').children().first().modal('closeModal');\n }\n if($('[data-role=\"dropdownDialog\"]:visible').length){\n $('[data-role=\"dropdownDialog\"]:visible').dropdownDialog('close');\n }\n\n if($('body').hasClass('checkout-cart-index') || $('body').hasClass('checkout-index-index') || $('body').hasClass('customer-account-index')){\n window.location.reload();\n }
2else{\n setTimeout(function(){\n $('.membership_login_steps').slideUp();\n $('input[type=\"text\"][name*=\"membership_\"]', '.membership_login_steps').val('');\n $('.membership_message', '.membership_login_steps').html('');\n $('.membership_login_steps.membership_login_step_1').slideDown();\n },1000);\n }\n }\n });\n\n return true;\n }\n var next = element.next();\n if(response.to_step)next = $('.membership_login_step_'+response.to_step);\n if(next.length){\n $('input',next).prop('disabled',false);\n element.hide();\n next.slideDown();\n $('.membership_login_back_step').show();\n }\n }
2else{\n if(response.error_message){\n $('.membership_message',element).text(response.error_message);\n }\n }\n },\n\n submit: function (element,callback) {\n var self = this;\n var valid = true;\n var form = element.closest('form');\n $('.membership_message',element).text('');\n $('input:not([disabled]):not([type=radio]),input[type=radio]:not([disabled]),select:not([disabled]),textarea:not([disabled])',element).each(function() {\n if(!form.validate().element(this)){\n valid = false;\n }\n });\n if(!valid) return false;\n\n var data = {};\n $('input:not([disabled]):not([type=radio]),input[type=radio]:checked:not([disabled]),select:not([disabled]),textarea:not([disabled])',element.parent()).each(function() {\n data[this.name] = $(this).val();\n });\n\n var ajaxUrl = url.getUrl('membership/index/check');\n if(self.options.ajaxCall) self.options.ajaxCall.abort();\n\n self.options.ajaxCall = $.ajax({\n url: ajaxUrl,\n type: \"POST\",\n dataType: \"json\",\n data : data,\n\n beforeSend: function () {\n self.loader(element,1);\n },\n\n complete: function (response) {\n self.loader(element,0);\n self.initStep();\n }\n }).done(\n function (response) {\n callback.call(this, element, response);\n }\n ).fail(\n function (response) {\n callback.call(this, element, response);\n }\n );\n },\n\n loader: function (element,active) {\n\n element.prop('disabled',active);\n if(active){\n $(this.options.loader).addClass('active');\n }
2else{\n $(this.options.loader).removeClass('active');\n }\n },\n\n initStep: function (){\n $('.membership_login').attr('step', $('.membership_login_steps:visible').index());\n }\n });\n\n return $.mage.customer_login;\n});","Idus_Membership/js/customer/renewal.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'Idus_Core/js/idus',\n 'Idus_Core/js/url',\n 'Idus_Customer/js/customer',\n 'Magento_Ui/js/modal/alert',\n], function ($, idus, url, customer, alert) {\n 'use strict';\n\n $.widget('mage.customer_renewal', {\n options: {\n loader : '.membership_renewal_loader',\n ajaxCall : false,\n },\n _create: function () {\n var self = this;\n\n $('#renewal_action').off('click').on('click',function(){\n self.submit($(this));\n });\n\n $('[name=membership_renewal]').off('change').on('change',function(){\n $(this).val(this.checked);\n var membership_renewal = $(this).closest('.membership_renewal');\n var form = $('.membership_renewal_form', membership_renewal);\n if(this.checked){\n form.slideDown();\n $('input,select,textarea', form).prop('disabled', false);\n membership_renewal.closest('form').parent().addClass('membership_renewal_show');\n }
2else{\n form.slideUp();\n $('input,select,textarea', form).prop('disabled', true);\n membership_renewal.closest('form').parent().addClass('membership_renewal_show');\n }\n });\n },\n\n submit: function (element) {\n var self = this;\n var data = {action: element.attr('action')};\n var renewal = element.closest('.membership_renewal');\n var valid = true;\n $('label.error', renewal).remove();\n $('input:not([disabled]),select:not([disabled]),textarea:not([disabled])', renewal).each(function(){\n this.formAjax = renewal[0];\n if(!renewal.validate().element(this)){\n valid = false;\n }\n data[this.name] = this.value;\n });\n if(!valid) return false;\n\n var ajaxUrl = url.getUrl('membership/index/renewal');\n if(self.options.ajaxCall) self.options.ajaxCall.abort();\n\n self.options.ajaxCall = $.ajax({\n url: ajaxUrl,\n type: \"POST\",\n dataType: \"json\",\n data : data,\n\n beforeSend: function () {\n self.loader(element,1);\n },\n\n complete: function (response) {\n self.loader(element,0);\n }\n }).done(\n function (response) {\n\n idus.setMessages($.mage.__(response.message));\n\n if(response.success){\n element.attr('action', response.action);\n if(response.action == 'renewal'){\n $('.membership_renewal_form').slideDown();\n }
2else{\n $('.membership_renewal_form').slideUp();\n }\n var text = $('.text',element).data('text');\n var data_text = $('.text',element).text();\n $('.text',element).text(text).data('text', data_text);\n $(window).trigger('initCustomer');\n\n if(response.reload || $('body').hasClass('checkout-index-index') || $('body').hasClass('checkout-cart-index')){\n setTimeout(function(){\n location.reload();\n },1500);\n }\n }\n }\n ).fail(\n function (response) {\n $('.membership_message',element).text(response.error_message);\n }\n );\n },\n\n loader: function (element,active) {\n\n element.prop('disabled',active);\n if(active){\n $(this.options.loader).addClass('active');\n }
2else{\n $(this.options.loader).removeClass('active');\n }\n },\n });\n\n return $.mage.customer_renewal;\n});\n","Idus_Membership/js/checkout/points.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'Idus_Core/js/idus',\n 'Idus_Core/js/url',\n 'Magento_Ui/js/modal/alert',\n], function ($, idus, url, alert) {\n 'use strict';\n\n $.widget('mage.checkout_points', {\n options: {\n loader : '.checkout_summary_loader',\n ajaxCall : false,\n },\n _create: function () {\n var self = this;\n\n $('#membership_points').off('change').on('change',function(){\n if(!$(this).hasClass('select_points')) return false;\n self.save($(this));\n });\n\n $('#membership_points').off('click').on('click',function(){\n self.maxPoints($(this),1);\n });\n\n if($('#membership_points').hasClass('empty') && $('#membership_points').attr('data-value') > 0){\n self.save($('#membership_points'));\n }\n\n $(document).on('totalChange','.cart-totals',function(){\n $('#membership_points').trigger('change');\n });\n\n $(document).ajaxComplete(function (event, request, settings) {\n if(request.responseJSON && request.responseJSON.success){\n var disabled = request.responseJSON.disabled_points;\n if(disabled != undefined){\n $('#membership_points').prop('disabled', disabled);\n if(disabled){\n $('.membership_points_wrap').addClass('disabled');\n }
2else{\n $('.membership_points_wrap').removeClass('disabled');\n }\n }\n }\n });\n },\n\n maxPoints: function (element,save) {\n var self = this;\n if(!element.hasClass('max_points')) return false;\n\n var add_class = 'use_points';\n var remove_class = 'unuse_points';\n var text = $.mage.__('Use Points');\n var value = 0;\n\n if(element.hasClass('use_points')){\n add_class = 'unuse_points';\n remove_class = 'use_points';\n text = $.mage.__('Unuse Points');\n value = element.attr('max_point');\n }\n\n element.removeClass(remove_class).addClass(add_class).attr('title',text).attr('value',value);\n $('span',element).text(text);\n if(save) self.save(element);\n },\n\n save: function (element) {\n var self = this;\n\n var ajaxUrl = url.getUrl('membership/index/points');\n if(self.options.ajaxCall) self.options.ajaxCall.abort();\n\n var data = {points:element.val()}\n data['init_totals'] = 0;\n\n if(element.val() != element.attr('data-value')){\n data['init_totals'] = 1;\n }\n\n self.options.ajaxCall = $.ajax({\n url: ajaxUrl,\n type: \"POST\",\n dataType: \"json\",\n data : data,\n\n beforeSend: function () {\n $('#cart-totals').css({opacity: 0.5}).trigger('beforeChange');\n self.loader(element,1);\n },\n\n complete: function (response) {\n $('#cart-totals').css({opacity: 1});\n self.loader(element,0);\n }\n }).done(\n function (response) {\n\n if(response.points == 0 && element.val() > 0){\n idus.setMessages($.mage.__('\u05dc\u05d0 \u05e0\u05d9\u05ea\u05df \u05dc\u05de\u05de\u05e9'));\n self.maxPoints(element,0);\n }\n \n if(response.success){\n if(response.points > response.max_points){\n element.val(response.max_points);\n return self.save(element);\n }
2else{\n if(Math.floor(response.points) < Math.floor(element.val())){\n idus.setMessages($.mage.__('\u05e9\u05d9\u05de\u05d5 \u05dc\u05d1! \u05e1\u05db\u05d5\u05dd \u05de\u05d9\u05de\u05d5\u05e9 \u05d4\u05e0\u05e7\u05d5\u05d3\u05d5\u05ea \u05d4\u05e9\u05ea\u05e0\u05d4'));\n }\n element.attr('data-value', response.points).val(response.points);\n if(response.totals){\n $('.checkout-index-totals-wrapper,.checkout-cart-totals-wrapper').html(response.totals).trigger('totalsWrapperChange');\n }\n\n if(response.shipping_methods){\n $('.shipping_methods').data('methods',response.shipping_methods).trigger('methodsChange');\n }\n\n if(response.checkout_data){\n idus.setLocalStorage('checkout_data', response.checkout_data, 1);\n }\n\n if(response.custom_points){\n var customPoints = $(response.custom_points);\n var selectHtml = $('select', customPoints);\n\n if(selectHtml.length){\n $('.membership_points_custom select').html(selectHtml.html());\n }
2else{\n $('.membership_points_custom').html(response.custom_points);\n self._create();\n }\n }else if(element.hasClass('select_points')){\n self.updateSelectPoints(response.points,response.max_points);\n }\n }\n }else{\n element.val(element.attr('data-value'));\n if(response.error_message){\n alert({content: response.error_message});\n }\n }\n }\n ).fail(\n function (response) {\n element.val(element.attr('data-value'));\n }\n );\n },\n\n updateSelectPoints: function (points,max_points) {\n var options = '';\n var from = 1;\n var to = max_points+1;\n var select = $('#membership_points');\n var selectPoints = false;\n\n var sort_points = $('.membership_points_wrap').attr('sort_points');\n var zero_option = $('.membership_points_wrap').attr('zero_option');\n\n if(sort_points == 'disending'){\n from = max_points*-1;\n to = 0;\n }\n\n if(select.attr('type_max_points') == 'steps_min_points'){\n var minToUse = select.attr('min_to_use');\n var steps = Math.floor(max_points / minToUse) + 1;\n max_points = (steps - 1) * minToUse;\n for (var i = 1; i < steps; i++) {\n var selected = '';\n var value = Math.abs(i) * minToUse;\n if(points == value){\n selectPoints = true;\n selected = ' selected=\"selected\"';\n }\n options += '<option value=\"'+value+'\"'+selected+'>'+value+'</option>';\n }\n }
2else{\n for (var i = from; i < to; i++) {\n var selected = '';\n var value = Math.abs(i);\n if(points == value){\n selectPoints = true;\n selected = ' selected=\"selected\"';\n }\n options += '<option value=\"'+value+'\"'+selected+'>'+value+'</option>';\n }\n }\n\n $('option:not(.default)', select).remove();\n\n if(zero_option){\n if(sort_points == 'disending'){\n options += '<option value=\"0\">0</option>';\n }else{\n options = '<option value=\"0\">0</option>' + options;\n }\n }\n\n select.append(options);\n $('.points_amount span').text(max_points);\n \n if(points > 0 && !selectPoints){\n select.trigger('change');\n }\n },\n\n loader: function (element,active) {\n\n element.prop('disabled',active);\n if(active){\n $(this.options.loader).addClass('active');\n }
2else{\n $(this.options.loader).removeClass('active');\n }\n },\n });\n\n return $.mage.checkout_points;\n});\n","Idus_Membership/js/checkout/benefits.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'jquery',\n 'Idus_Core/js/idus',\n 'Idus_Core/js/url',\n 'Magento_Ui/js/modal/alert',\n], function ($, idus, url, alert) {\n 'use strict';\n\n $.widget('mage.checkout_benefits', {\n options: {\n loader : '.checkout_summary_loader,.checkout_benefits_loader',\n loading_text : {add : $.mage.__('\u05de\u05d5\u05e1\u05d9\u05e3'),remove : $.mage.__('\u05de\u05e1\u05d9\u05e8')},\n loading_success : {add : $.mage.__('\u05e0\u05d5\u05e1\u05e3'),remove : $.mage.__('\u05d4\u05d5\u05e1\u05e8')},\n ajaxCall : false,\n },\n _create: function () {\n var self = this;\n\n $('.membership_benefits_wrap .benefit-action button').off('click').on('click',function(){\n self.save($(this).prop('disabled',true));\n });\n\n $(document).ajaxComplete(function (event, request, settings) {\n if(request.responseJSON && request.responseJSON.success){\n var disabled = request.responseJSON.disabled_benefits;\n if(disabled != undefined){\n if(disabled)\n $('.membership_benefits_wrap').addClass('disabled');\n else\n $('.membership_benefits_wrap').removeClass('disabled');\n }\n }\n });\n },\n\n save: function (element) {\n var self = this;\n var item = element.closest('.benefit-item');\n\n var ajaxUrl = url.getUrl('membership/index/benefits');\n if(self.options.ajaxCall) self.options.ajaxCall.abort();\n var action = 'add';\n if(element.hasClass('action-remove')) action = 'remove';\n\n var benefit_id = element.attr('benefit_id');\n var count = 1;\n if($('[name=count]',item).length) count = $('[name=count]',item).val();\n\n var data = {'benefit_id':benefit_id, 'action':action, count:count};\n\n $('span',element).text(self.options.loading_text[action]);\n\n self.options.ajaxCall = $.ajax({\n url: ajaxUrl,\n type: \"POST\",\n dataType: \"json\",\n data : data,\n\n beforeSend: function () {\n $('#cart-totals').css({opacity: 0.5}).trigger('beforeChange');\n self.loader(element,1);\n },\n\n complete: function (response) {\n $('#cart-totals').css({opacity: 1});\n self.loader(element,0);\n }\n\n }).done(\n function (response) {\n\n if(response.benefits){\n var benefitsUsed = 0;\n $.each(response.benefits,function(benefit_id,benefit){\n var _element = $('.benefit-item[benefit_id='+benefit_id+']');\n var button = $('button', _element);\n if(button.hasClass('action-add') && benefit['used'] == true){\n self.switch(_element, button);\n }else if(button.hasClass('action-remove') && benefit['used'] != true){\n self.switch(_element, button);\n }\n\n if(benefit['used']){\n benefitsUsed++;\n }\n });\n\n $('.membership_benefits_wrap').attr('used_count', benefitsUsed);\n }\n\n if(response.success){\n\n $('span',element).text(self.options.loading_success[action]);\n element.prop('disabled', false);\n\n if(response.totals){\n $('.checkout-index-totals-wrapper,.checkout-cart-totals-wrapper').html(response.totals);\n $('.cart-totals').trigger('totalChange');\n }\n \n if(response.shipping_methods){\n $('.shipping_methods').data('methods',response.shipping_methods).trigger('methodsChange');\n }\n\n if(response.checkout_data){\n idus.set
2LocalStorage('checkout_data', response.checkout_data, 1);\n }\n\n if(action == 'add') $('.benefit-count',item).hide();\n else $('.benefit-count',item).show();\n\n if(response.alerts){\n $.each(response.alerts, function(){\n idus.setMessages($.mage.__(this));\n });\n }\n\n }else{\n if(response.error_message){\n $('span',element).text(element.attr('title'));\n alert({content: response.error_message});\n }\n }\n }\n ).fail(\n function (response) {\n $('span',element).text(element.attr('title'));\n }\n );\n },\n\n switch: function (element, button){\n setTimeout(function(){\n var title = button.attr('title');\n var data_title = button.attr('data-title');\n button.attr('title',data_title).attr('data-title',title).toggleClass('action-add').toggleClass('action-remove');\n $('span',button).text(data_title);\n\n if(button.hasClass('action-remove')){\n element.attr('action', 'remove');\n }
2else{\n element.attr('action', 'add');\n }\n },1000);\n },\n\n loader: function (element,active) {\n\n element.prop('disabled',active);\n if(active){\n $(this.options.loader).addClass('active');\n }else{\n $(this.options.loader).removeClass('active');\n }\n },\n });\n\n return $.mage.checkout_benefits;\n});\n","Idus_Newsletter/js/script.js":"define([\n\t'jquery',\n\t'Idus_Core/js/idus',\n\t'mage/translate',\n], function($,idus,$t){\n\t'use strict';\n\treturn function(config, element){\n\t\t$(arguments[1]).each(function(){\n\t\t\tvar $newsletter = $(this);\n\t\t\tvar $loader = $('.idus-loader',$newsletter);\n\t\t\tvar $form = $('.idus-newsletter-form',$newsletter);\n\t\t\tvar $success = $('.idus-newsletter-success',$newsletter);\n\t\t\tvar $submit = $('.idus-newsletter-subscribe',$form);\n\t\t\tvar $input = $('.newsletter',$form);\n\t\t\tvar $response = $('.idus-newsletter-response',$form);\n\t\t\tvar $popup = $newsletter.closest('.idus_popup');\n\t\t\t// if($input.hasClass('manually')){\n\t\t\t// \t$input.attr('readonly','readonly');\n\t\t\t// }\n\n\t\t\t$form.submit(function(e) {\n\t\t\t\te.preventDefault();\n\t\t\t\t\n\t\t\t\t$response.text('');\n\t\t\t\tif($input.val() == '') return;\n\t\t\t\tif(!$form.valid()) return;\n\n\t\t\t\t$submit.attr('disabled','disabled');\n\t\t\t\t$loader.addClass('active');\n\n\t\t\t\t$.ajax({\n\t\t\t\t\ttype: 'POST',\n\t\t\t\t\tdataType: 'json',\n\t\t\t\t\turl: $form.attr('action'),\n\t\t\t\t\tdata: $form.serialize(),\n\t\t\t\t\tcomplete: function(response){\n\n\t\t\t\t\t\tvar json = response.responseJSON;\n\n\t\t\t\t\t\tif(json == undefined){\n\n\t\t\t\t\t\t\t$loader.removeClass('active');\n\t\t\t\t\t\t\t$response.html('<span>'+$t( response.statusText + '(' + response.status + ')' )+'</span>');\n\t\t\t\t\t\t\t$newsletter.addClass('is__error').removeClass('is__success');\n\n\t\t\t\t\t\t}else{\n\n\t\t\t\t\t\t\t// error\n\t\t\t\t\t\t\tif(json.action != 'success'){\n\n\t\t\t\t\t\t\t\t$loader.removeClass('active');\n\t\t\t\t\t\t\t\t$newsletter.addClass('is__error').removeClass('is__success');\n\t\t\t\t\t\t\t\tif(json.msg != undefined){\n\t\t\t\t\t\t\t\t\t$response.html('<span>'+json.msg+'</span>');\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// success\n\t\t\t\t\t\t\t}else{\n\n\t\t\t\t\t\t\t\tlet imageElement = element.querySelector('.idus-newsletter-image img');\n\t\t\t\t\t\t\t\tlet imageMobileElement = element.querySelector('.idus-newsletter-image-mobile img');\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tlet successImage = config?.success_image;\n\t\t\t\t\t\t\t\tlet successImageMobile = config?.success_image_mobile || config?.success_image;\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tif (imageElement && successImage){\n\t\t\t\t\t\t\t\t\timageElement.src = successImage;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (imageMobileElement && successImageMobile){\n\t\t\t\t\t\t\t\t\timageMobileElement.src = successImageMobile;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t$newsletter.addClass('is__success').removeClass('is__error');\n\n\t\t\t\t\t\t\t\t// has success msg\n\t\t\t\t\t\t\t\tif($success.length > 0){\n\t\t\t\t\t\t\t\t\t$newsletter.css('min-height',$newsletter.outerHeight());\n\t\t\t\t\t\t\t\t\t$form.animate({opacity:0}
2,function(){\n\n\t\t\t\t\t\t\t\t\t\t$input.val('');\n\t\t\t\t\t\t\t\t\t\t$loader.removeClass('active');\n\t\t\t\t\t\t\t\t\t\t$form.hide();\n\t\t\t\t\t\t\t\t\t\t$success.css({opacity:0}).removeAttr('style').animate({opacity:1});\n\t\t\t\t\t\t\t\t\t\t$success.find('.text').focus();\n\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}else if(json.msg != undefined){\n\n\t\t\t\t\t\t\t\t\t$input.val('');\n\t\t\t\t\t\t\t\t\t$loader.removeClass('active');\n\t\t\t\t\t\t\t\t\t$response.text(json.msg);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ($popup.length) {\n\t\t\t\t\t\t\t\t\tvar closeBtn = $('.action-close', $popup.closest('.idus_popup_wrap'))\n\t\t\t\t\t\t\t\t\tcloseBtn.trigger('focus');\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t$(document).trigger('idus-newsletterSubscribe', json.hashed_email);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t$submit.removeAttr('disabled');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\n\t\t});\n\t}\n});","Idus_MageFixes/js/mage-translation-dictionary.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n 'text!js-translation.json'\n], function (dict) {\n 'use strict';\n\n return JSON.parse(dict);\n});","Idus_MageFixes/js/mage/mage.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * \n * Fixed contentUpdated event by Asher\n * this script can sometimes load before the body element is present\n * so triggering contentUpdated will not apply/init js on dynamically loaded elements\n * \n */\n(function (root, factory) {\n 'use strict';\n\n if (typeof define === 'function' && define.amd) {\n define([\n 'jquery',\n 'mage/apply/main'\n ], factory);\n } else {\n factory(root.jQuery);\n }\n}(this, 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","Idus_Pages/js/navigation.js":"/**\n * Copyright \u00a9 2013-2017 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n define([\n\t\"jquery\",\n\t'Idus_Core/js/idus',\n\t'Idus_Core/js/url',\n\t\"mage/translate\"\n], function ($, idus,url){\n\t'use strict';\n\tvar navigation = $('#page-header-navigation');\n\n\tif ($('#page-header-navigation-toggle', navigation).prop('checked')) $('body').addClass('page-header-navigation-open');\n\n\t$('#page-header-navigation-toggle', navigation).on('change',function(){\n\n\t\t// add class
2no scroll when nav open in mobile (Prevent Scroll on IOS)\n\t\t$('html').toggleClass('noscroll', this.checked);\n\n\t\tif(this.checked){\n\t\t\t$('body').addClass('page-header-navigation-open');\n\t\t\t$(this).siblings('label').attr('aria-label', '\u05e1\u05d2\u05d9\u05e8\u05ea \u05ea\u05e4\u05e8\u05d9\u05d8');\n\t\t\tif(!$('li.category-item.open', navigation).length){\n\t\t\t\t$('li.category-item.open_default', navigation).addClass('open').closest('.page-header-navigation-container').addClass('child-open');\n\t\t\t}\n\t\t}else{\n\t\t\t$('body').removeClass('page-header-navigation-open');\n\t\t\t$('.open, .child-open', '#page-header-navigation').removeClass('open child-open');\n\t\t\t$(this).siblings('label').attr('aria-label', '\u05e4\u05ea\u05d9\u05d7\u05ea \u05ea\u05e4\u05e8\u05d9\u05d8');\n\t\t}\n\t});\n\n\t$('#page-header-navigation').on('focusout', function (e) {\n\n\t\tif (!e.which && $(e.relatedTarget).is('a.action.showcart')) return;\n\t\tif (!e.which && $(e.relatedTarget).is('#customer-login-link')) return;\n\n\t\tif (window.innerWidth > 767 && e.relatedTarget && !$(e.relatedTarget).parents('#page-header-navigation').length) {\n\n\t\t\t$('#page-header-navigation-toggle').prop('checked', false);\n\t\t\t$('body').removeClass('page-header-navigation-open');\n\t\t}\n\t});\n\n\t$('.idus_loader_page').on('loading',function(){\n\t\tif (window.closeMenuOnLoading) {\n\n\t\t\t$('#page-header-navigation-toggle', navigation).prop('checked', false);\n\t\t\t$(document.body).removeClass('page-header-navigation-open');\n\t\t}\n\t});\n\n\t$('body').on('click','.page-header-navigation-container .parent > .action',function(e){\n\t\tif($('#page-header-navigation-toggle', navigation).is(':checked') && !window.disableNavParents){\n\t\t\te.preventDefault();\n\t\t\tvar element = $(this).closest('.parent');\n\t\t\telement.siblings().removeClass('open');\n\t\t\t$('.parent',element).removeClass('open');\n\t\t\telement.toggleClass('open');\n\t\t\telement.closest('.page-header-navigation-container').toggleClass('child-open', !!$('.category-item.parent.open').length);\n\t\t\tvar ref = this;\n\t\t\t// setTimeout(function(){\n\t\t\t// \t$('.page-header-navigation-container', navigation).scrollTop( $(this).scrollTop() + $(ref).position().top - $(this).height()/2 + $(ref).height()/2 );\n\t\t\t// },300);\n\n\t\t\tif(!$('li.category-item.open', navigation).length){\n\t\t\t\t$('li.category-item.open_default', navigation).addClass('open').closest('.page-header-navigation-container').addClass('child-open');\n\t\t\t}\n\t\t}\n\t});\n\n\t$('body').on('click','.page-header-navigation-dropdown-back',function(e){\n\t\tif($('#page-header-navigation-toggle', navigation).is(':checked')){\n\t\t\te.preventDefault();\n\t\t\tvar element = $(this).closest('.parent');\n\t\t\telement.removeClass('open');\n\t\t\telement.closest('.page-header-navigation-container').removeClass('child-open');\n\t\t}\n\t});\n\n\tvar currUrl = url.getWindowUrl('?');\n\tvar selected = $('.category-item a.nav_link[href=\"' + decodeURI(currUrl[0]) + '\"]', navigation);\n\t\n\tif (!selected.length) {\n\n\t\tselected = $('.category-item a.nav_link[href=\"' + decodeURI(currUrl[0]) + '\"]', navigation);\n\t}\n\n selected.parents('li.category-item').addClass('selected');\n\n if(!$('li.category-item.selected', navigation).length){\n \t$('li.category-item.open_default', navigation).addClass('selected');\n }\n\n\tif (window.idus.isMobile()) {\n\t\n\t\t$(document).on('click', '.category-item.level_0.parent > .nav_link', function () {\n\n\t\t\t$(this).closest('ul').get(0).scrollTop = 0;\n\t\t});\n\t}\n});","Idus_Pages/js/navigation.dataLayer.js":"require([\n 'jquery',\n 'idus_dataLayer',\n 'domReady!'\n], function ($) {\n 'use strict';\n\n\tvar navigation = $('#page-header-navigation');\n var footer = $('.footer_element_content_list');\n\n navigation.on('click', 'a', function () {\n\n var levels = [];\n var linkObj = $(this);\n\n if(linkObj.hasClass('nav_link')){\n\n if($('#page-header-navigation-toggle', navigation).is(':checked') \n && !window.disableNavParents\n && linkObj.closest('.category-item').hasClass('parent')) {\n\n return;\n }\n\n levels = getCategoriesList(linkObj, levels);\n\n } else {\n\n var banner = linkObj.closest('.idus-slider-wrapper');\n var bannerTitle\n if(banner.length){\n bannerTitle = banner.find('.idus-slider-content-title').text();\n bannerTitle = bannerTitle ? bannerTitle.trim() : '';\n \n if (!bannerTitle) {\n \n bannerTitle = undefined\n var label = banner.attr('data-banner-label');\n if (label) {\n bannerTitle = label\n } else {\n bannerTitle = `banner_id-${banner.attr('data-banner-id')}`;\n }\n }\n } \n\n var parentLinkObj = linkObj.closest('.category-item').children('.nav_link');\n levels = getCategoriesList(parentLinkObj, levels);\n\n var linkSpan = linkObj.children('span').first();\n var linkTitle = '';\n\n //If link has span with text\n if(linkSpan.length && linkSpan.text().trim().length > 0){\n\n linkTitle = linkSpan.text().trim();\n\n //If link has no span but has text\n } else if (!linkSpan.length && linkObj.text().trim().length > 0){\n\n linkTitle = linkObj.text().trim();\n\n //If link has no text and has aria-label attribue\n } else if(linkObj.attr('aria-label') !== undefined && linkObj.attr('aria-label') !== false) {\n\n linkTitle = linkObj.attr('aria-label').trim();\n\n //If link has no identification\n } else {\n\n linkTitle = linkObj.attr('href');\n }\n\n if (bannerTitle) levels.push(bannerTitle);\n\n levels.push(linkTitle);\n }\n\n sendClickEvent(levels,linkObj);\n });\n\n footer.on('click', 'a', function () {\n\n var linkObj = $(this);\n var footerAnchor = linkObj.text().trim();\n var footerTitle = linkObj.closest('.footer_element').find('.footer_element_title')\n var levels = [];\n \n var i = 1;\n if (footerTitle.length){\n\n levels[`level${i}`] = footerTitle.text().trim();\n i++;\n }\n\n levels[`level${i}`] = footerAnchor;\n \n var footerEvent = {\n event: 'autoEvent',\n clickType: 'FooterClick',\n ...levels\n };\n \n window.idusDataLayer.push({\n customEvent: 'autoEvent',\n customData: footerEvent\n });\n });\n\n function sendClickEvent(eventData,linkObj) {\n\n var jsonData = {};\n jsonData['event'] = 'autoEvent'\n jsonData['clickType'] = 'MainMenuClick';\n\n var navContent = linkObj.closest('.navigation-container-content');\n\n if (navContent.length) {\n eventData.shift();\n }\n \n eventData.forEach(function (dataItem, i) {\n\n jsonData[`level${i + 1}`] = dataItem;\n });\n\n //window.dataLayer.push(jsonData);\n window.idusDataLayer.push({\n customEvent: 'autoEvent',\n customData: jsonData\n }); \n }\n\n function getCategoriesList(categoryLinkElement, levels) {\n\n levels.unshift(categoryLinkElement.attr('title'));\n\n var title = categoryLinkElement.closest('.category-item').siblings('.nav-category-items-group-title');\n\n if (title.length) {\n\n levels.unshift(title.find('span').text());\n }\n\n if (categoryLinkElement.closest('.page-header-navigation-dropdown').length) {\n\n var parentCategoryLink = categoryLinkElement.closest('.page-header-navigation-dropdown').siblings('.nav_link');\n levels = getCategoriesList(parentCategoryLink, levels);\n }\n\n return levels;\n }\n});\n","Idus_Pages/js/footer.js":"/**\n * Copyright \u00a9 2013-2017 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n\t\"jquery\",\n\t'Idus_Core/js/idus',\n\t\"mage/translate\"\n], function ($, idus){\n\t'use strict';\n\t\n});\n","Idus_Pages/js/header.js":"/**\n * Copyright \u00a9 2013-2017 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine(['jquery', 'Idus_Core/js/idus'], function ($, idus) {\n\t'use strict';\n\n\treturn function (config) {\n\n\t\twindow.headerHeightDelay = getComputedStyle(document.documentElement).getPropertyValue('--header-height-calc-delay');
2\n\n\t\tfunction setHeaderHeightVar() {\n\n\t\t\tvar delay = window.headerHeightDelay;\n\t\t\tif (!delay) delay = 0;\n\t\t\telse delay = delay.match(/\\d+/);\n\n\t\t\tif (!delay.length) delay = 0;\n\t\t\telse delay = delay[0];\n\n\t\t\tsetTimeout(function () {\n\t\t\t\tif ($('.idus_notification_bar_wrap').length > 0) {\n\t\t\t\t\tvar headerNotification = ($('.idus_notification_bar_wrap').height() + $('.page-header .page-header-container').height());\n\t\t\t\t\tdocument.documentElement.style.setProperty('--header-height', headerNotification + 'px');\n\t\t\t\t} else {\n\t\t\t\t\tdocument.documentElement.style.setProperty('--header-height', $('.page-header .page-header-container').height() + 'px');\n\t\t\t\t}\n\t\t\t}, parseInt(delay));\n\t\t}\n\n\t\twindow.setHeaderHeightVar = setHeaderHeightVar;\n\t\t$(window).on('resize', window.setHeaderHeightVar);\n\t\t$(document.body).on('idus-headerStickyClassAdded idus-headerStickyClassRemoved contentUpdated', window.setHeaderHeightVar);\n\n\t\t// put value on search input\n\t\tvar searchQuery = idus.getParamUrl('q');\n\n\t\tif (searchQuery && searchQuery.length > 0) {\n\n\t\t\tdocument.getElementById('header-search-input').value = searchQuery;\n\t\t}\n\n\t\tvar header = document.getElementsByClassName('page-header')[0];\n\t\tvar isAddStickyClass = config.stickyClassEnabled;\n\n\t\tif (isAddStickyClass && header) {\n\n\t\t\tvar stickyOffset = config.stickyOffsetTop;\n\t\t\tvar stickyClass = 'sticky-header';\n\t\t\tvar stickyToppedClass = 'sticky-header__topped';\n\t\t\tvar stickyHiddenClass = 'sticky-header__hidden';\n\n\t\t\tstickHeader(header, stickyOffset, stickyClass, stickyToppedClass);\n\t\t\tstickHeaderIsHidden(header, stickyHiddenClass, stickyToppedClass);\n\t\t\twindow.setHeaderHeightVar();\n\n\t\t\tvar headerIObserver = new IntersectionObserver(function (entries) {\n\n\t\t\t\tentries.forEach((entry) => {\n\n\t\t\t\t\tif (!entry.isIntersecting && !header.classList.contains(stickyClass)) {\n\n\t\t\t\t\t\theader.classList.add(stickyClass);\n\t\t\t\t\t\theader.classList.remove(stickyToppedClass);\n\t\t\t\t\t\t$(document.body).trigger('idus-headerStickyClassAdded');\n\t\t\t\t\t} else if (entry.isIntersecting && !header.classList.contains(stickyToppedClass)) {\n\n\t\t\t\t\t\theader.classList.remove(stickyClass);\n\t\t\t\t\t\theader.classList.add(stickyToppedClass);\n\t\t\t\t\t\t$(document.body).trigger('idus-headerStickyClassRemoved');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tvar headerSpacer = document.createElement('div');\n\t\t\theaderSpacer.style.height = stickyOffset + 'px';\n\t\t\theaderSpacer.style.position = 'absolute';\n\t\t\theaderSpacer.style.top = 0;\n\t\t\theaderSpacer.style.right = 0;\n\t\t\theaderSpacer.style.left = 0;\n\t\t\theaderSpacer.style.visibility = 'hidden';\n\t\t\theaderSpacer.style.zIndex = -1000;\n\t\t\theaderSpacer.classList.add('header-spacer');\n\t\t\tdocument.body.prepend(headerSpacer);\n\n\t\t\theaderIObserver.observe(headerSpacer);\n\n\t\t\t// var ticking = false;\n\t\t\t// window.addEventListener('scroll', function () {\n\n\t\t\t// \tif (!ticking) {\n\t\t\t// \t\twindow.requestAnimationFrame(function () {\n\t\t\t// \t\t\tstickHeader(header, stickyOffset, stickyClass, stickyToppedClass);\n\t\t\t// \t\t\tticking = false;\n\t\t\t// \t\t});\n\t\t\t// \t}\n\t\t\t// \tticking = true;\n\t\t\t// });\n\t\t}\n\n\t\tfunction stickHeader(_header, _stickyOffset, _stickyClass, _stickyToppedClass) {\n\t\t\tif ((window.pageYOffset > _stickyOffset) && !_header.classList.contains(_stickyClass)) {\n\t\t\t\t_header.classList.add(_stickyClass);\n\t\t\t\t_header.classList.remove(_stickyToppedClass);\n\t\t\t\t$(document.body).trigger('idus-headerStickyClassAdded');\n\t\t\t} else if ((window.pageYOffset <= _stickyOffset) && !_header.classList.contains(_stickyToppedClass)) {\n\t\t\t\t_header.classList.remove(_stickyClass);\n\t\t\t\t_header.classList.add(_stickyToppedClass);\n\t\t\t\t$(document.body).trigger('idus-headerStickyClassRemoved');\n\t\t\t}\n\t\t}\n\n\t\tfunction stickHeaderIsHidden(_header, stickyHiddenClass, stickyToppedClass) {\n\t\t\tvar lastScrollTop = 0;
2\n\n\t\t\twindow.addEventListener('scroll', function() {\n\n\t\t\t\t// header topped\n\t\t\t\tif(_header.classList.contains(stickyToppedClass)){\n\t\t\t\t\t_header.classList.remove(stickyHiddenClass);\n\t\t\t\t\tthis.document.body.classList.remove(stickyHiddenClass);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// get scroll vars\n\t\t\t\twindow.headerScrollSensitivity = window.headerScrollSensitivity || 10;\n\t\t\t\tvar currentScrollTop = window.pageYOffset || document.documentElement.scrollTop;\n\t\t\t\tvar scrollChange = Math.abs(currentScrollTop-lastScrollTop);\n\n\t\t\t\t// prevent bounce / over scrolling\n\t\t\t\tif (currentScrollTop <= 0 || currentScrollTop + window.innerHeight >= document.documentElement.scrollHeight) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// User scrolled down\n\t\t\t\tif (currentScrollTop > lastScrollTop) {\n\n\t\t\t\t\tif(scrollChange > window.headerScrollSensitivity){\n\t\t\t\t\t\t_header.classList.add(stickyHiddenClass);\n\t\t\t\t\t\tthis.document.body.classList.add(stickyHiddenClass);\n\t\t\t\t\t}\n\n\t\t\t\t// User scrolled up\n\t\t\t\t} else if (currentScrollTop < lastScrollTop) {\n\n\t\t\t\t\t// change sensitivity\n\t\t\t\t\tif(scrollChange > window.headerScrollSensitivity){\n\t\t\t\t\t\t_header.classList.remove(stickyHiddenClass);\n\t\t\t\t\t\tthis.document.body.classList.remove(stickyHiddenClass);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlastScrollTop = currentScrollTop;\n\t\t\t});\n\n\t\t}\n\n\t}\n});","Idus_Pages/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!Idus_Pages/templates/breadcrumbs.html',\n 'text!Idus_Pages/templates/back.html',\n 'jquery/ui'\n], function ($, mageTemplate, breadcrumbList, tpl_breadcrumbs, tpl_back) {\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 templateBreadcrumbs = mageTemplate(tpl_breadcrumbs),\n templateBack = mageTemplate(tpl_back);\n\n if (crumbs.length == 2 && $('body').hasClass('catalog-product-view')) {\n var rootUrl = window.BASE_URL;\n var uriObject = window.location.href.replace(rootUrl, '').split('/');\n var referrer = false;\n if (uriObject.length <= 1) {\n if(document.referrer.indexOf(rootUrl) != -1){\n referrer = document.referrer.split('?');\n referrer = referrer[0].split('#');\n referrer = referrer[0];\n uriObject = referrer.replace(rootUrl, '').split('/');\n }\n }\n\n if (uriObject.length > 1) {\n var url = rootUrl;\n var first = crumbs[0];\n var last = crumbs[1];\n crumbs = [];\n var index = 0;\n crumbs[index] = first;\n\n\n $.each(uriObject, function (i, v) {\n url += decode
2URI(v);\n var item = $('nav [href=\"' + url + '\"]');\n if (!item.length) {\n item = $('nav [href=\"' + url.replace(rootUrl, '/') + '\"]');\n }\n\n if (item.length) {\n var name = item.attr('title');\n if (name == undefined || name == '') {\n if (item.length == 0) name = item.text().replace(/^\\s+|\\s+$/g, \"\");\n else name = $(item[0]).text().replace(/^\\s+|\\s+$/g, \"\");\n }\n index++;\n crumbs[index] = {};\n crumbs[index]['link'] = item.attr('href');\n crumbs[index]['real_name'] = name;\n crumbs[index]['label'] = name;\n crumbs[index]['name'] = 'category';\n crumbs[index]['title'] = $.mage.__('Back To %1').replace('%1', name);\n }\n url += '/';\n });\n\n if(referrer && !$('nav [href=\"' + referrer + '\"]').length && Object.keys(crumbs).length > 1){\n index++;\n var name = uriObject[uriObject.length - 1];\n name = decodeURI(name);\n crumbs[index] = {};\n crumbs[index]['link'] = referrer;\n crumbs[index]['real_name'] = name;\n crumbs[index]['label'] = name;\n crumbs[index]['name'] = 'category';\n crumbs[index]['title'] = $.mage.__('Back To %1').replace('%1', name);\n }\n\n crumbs[Object.keys(crumbs).length] = last;\n }\n }\n\n if ($('body').hasClass('catalog-product-view')) crumbs = this._appendCategories(crumbs);\n\n this._decorate(crumbs);\n\n window.pages.crumbs = crumbs;\n\n if (window.pages.breadcrumbs == undefined || window.pages.breadcrumbs) {\n html = templateBreadcrumbs({\n 'breadcrumbs': crumbs,\n });\n\n if (html.length) {\n $(this.element).html(html);\n }\n }\n\n if (window.pages.back_button != undefined && window.pages.back_button) {\n var reversed = crumbs.reverse();\n if (reversed.length > 1) {\n reversed[1]['real_name'] = reversed[1]['label'].trim();\n reversed[1]['label'] = $.mage.__('Back To %1').replace('%1', reversed[1]['label']);\n html = $(templateBack({\n 'back': reversed[1],\n }));\n\n if (localStorage.getItem('backData')) {\n\n var backData = JSON.parse(localStorage.getItem('backData'));\n if (backData.page && backData.id) {\n\n $('a', html).attr('href', $('a', html).attr('href') + '?p=' + backData.page + '#' + backData.id);\n localStorage.removeItem('backData');\n }\n }\n\n $(this.element).prepend(html);\n }\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 * Append categories if the category crumb is not a root category\n */\n _appendCategories: function (list) {\n\n var newList = [];\n\n for (var i = 0; i < list.length;
2 i++) {\n\n if (!list[i]) continue;\n\n if (list[i].name === 'category') {\n // get matching nav link element\n var linkEl = $('.nav_link[href=\"' + list[i].link + '\"]:first', '.page-header-navigation-container[role=\"navigation\"]:first');\n\n if (linkEl.length) {\n\n linkEl.closest('.category-item').addClass('selected');\n\n // if we already at root do nothing\n if (linkEl.closest('.category-item').hasClass('level_0')) {\n return list;\n }\n\n // get parents and add them as crumbs\n var parents = linkEl.parent().parents('.category-item');\n if (parents.length) parents = $(parents.get().reverse());\n $.each(parents, function (i, el) {\n\n $(el).addClass('selected');\n\n var linkEl = $('> .nav_link', el);\n\n if (linkEl.length) {\n\n var newCrumb = {\n name: 'category',\n label: linkEl.attr('title'),\n link: linkEl.attr('href'),\n title: ''\n }\n\n newList.push(newCrumb);\n }\n });\n }\n }\n\n newList.push(list[i]);\n }\n\n return newList;\n }\n });\n\n return $.mage.breadcrumbs;\n});"} 3}});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.