{"version":3,"file":"assets/js/pcp_bundle_content.js","mappings":"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","sources":["webpack:///../node_modules/element-remove/index.js","webpack:///../node_modules/eligrey-classlist-js-polyfill/classList.js","webpack:///../node_modules/hammerjs/hammer.js","webpack:///../node_modules/smart-timeout/index.js","webpack:///../node_modules/smart-timeout/lib/timeout.js","webpack:///./typescript/PCF/notification-service.ts","webpack:///./typescript/PCP/Columns/column-header.ts","webpack:///./typescript/PCP/Rows/colors-field.ts","webpack:///./typescript/PCP/Rows/controls-row.ts","webpack:///./typescript/PCP/Rows/priceValuesRow.ts","webpack:///./typescript/PCP/Rows/rowContainer.ts","webpack:///./typescript/PCP/Rows/rowField.ts","webpack:///./typescript/PCP/Rows/valuesRow.ts","webpack:///./typescript/PCP/Rows/valuesSubRow.ts","webpack:///./typescript/PCP/comparison-page-controller.ts","webpack:///./typescript/PCP/debug-controller.ts","webpack:///./typescript/PCP/grid-controller.ts","webpack:///./typescript/PCP/gridCarousel.ts","webpack:///./typescript/PCP/gridColumnLock.ts","webpack:///./typescript/PCP/productsCounter.ts","webpack:///./typescript/PCP/stickyHeaderService.ts","webpack:///./typescript/errorhandler.ts","webpack:///./typescript/helpers/MpcSettings.ts","webpack:///./typescript/helpers/comparePageButtonUrlUpdater.ts","webpack:///./typescript/helpers/deviceDetectionHelper.ts","webpack:///./typescript/helpers/event-bus.ts","webpack:///./typescript/helpers/htmlElementsHelper.ts","webpack:///./typescript/helpers/navigationService.ts","webpack:///./typescript/helpers/polyfills.ts","webpack:///./typescript/helpers/scrollLock.ts","webpack:///./typescript/helpers/toolTip.ts","webpack:///./typescript/helpers/vanillajax.ts","webpack:///./typescript/local-storage-service.ts","webpack:///../node_modules/url-search-params-polyfill/index.js","webpack:///webpack/bootstrap","webpack:///webpack/runtime/global","webpack:///webpack/runtime/make namespace object","webpack:///./pcp-bundle-content.ts"],"sourcesContent":["(function (arr) {\n arr.forEach(function (item) {\n if (item.hasOwnProperty('remove')) {\n return;\n }\n Object.defineProperty(item, 'remove', {\n configurable: true,\n enumerable: true,\n writable: true,\n value: function remove() {\n this.parentNode && this.parentNode.removeChild(this);\n }\n });\n });\n})([Element.prototype, CharacterData.prototype, DocumentType.prototype].filter(Boolean));\n","/*\n * classList.js: Cross-browser full element.classList implementation.\n * 1.2.20180112\n *\n * By Eli Grey, http://eligrey.com\n * License: Dedicated to the public domain.\n * See https://github.com/eligrey/classList.js/blob/master/LICENSE.md\n */\n\n/*global self, document, DOMException */\n\n/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */\n\nif (\"document\" in self) {\n\n// Full polyfill for browsers with no classList support\n// Including IE < Edge missing SVGElement.classList\nif (\n\t !(\"classList\" in document.createElement(\"_\")) \n\t|| document.createElementNS\n\t&& !(\"classList\" in document.createElementNS(\"http://www.w3.org/2000/svg\",\"g\"))\n) {\n\n(function (view) {\n\n\"use strict\";\n\nif (!('Element' in view)) return;\n\nvar\n\t classListProp = \"classList\"\n\t, protoProp = \"prototype\"\n\t, elemCtrProto = view.Element[protoProp]\n\t, objCtr = Object\n\t, strTrim = String[protoProp].trim || function () {\n\t\treturn this.replace(/^\\s+|\\s+$/g, \"\");\n\t}\n\t, arrIndexOf = Array[protoProp].indexOf || function (item) {\n\t\tvar\n\t\t\t i = 0\n\t\t\t, len = this.length\n\t\t;\n\t\tfor (; i < len; i++) {\n\t\t\tif (i in this && this[i] === item) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\t// Vendors: please allow content code to instantiate DOMExceptions\n\t, DOMEx = function (type, message) {\n\t\tthis.name = type;\n\t\tthis.code = DOMException[type];\n\t\tthis.message = message;\n\t}\n\t, checkTokenAndGetIndex = function (classList, token) {\n\t\tif (token === \"\") {\n\t\t\tthrow new DOMEx(\n\t\t\t\t \"SYNTAX_ERR\"\n\t\t\t\t, \"The token must not be empty.\"\n\t\t\t);\n\t\t}\n\t\tif (/\\s/.test(token)) {\n\t\t\tthrow new DOMEx(\n\t\t\t\t \"INVALID_CHARACTER_ERR\"\n\t\t\t\t, \"The token must not contain space characters.\"\n\t\t\t);\n\t\t}\n\t\treturn arrIndexOf.call(classList, token);\n\t}\n\t, ClassList = function (elem) {\n\t\tvar\n\t\t\t trimmedClasses = strTrim.call(elem.getAttribute(\"class\") || \"\")\n\t\t\t, classes = trimmedClasses ? trimmedClasses.split(/\\s+/) : []\n\t\t\t, i = 0\n\t\t\t, len = classes.length\n\t\t;\n\t\tfor (; i < len; i++) {\n\t\t\tthis.push(classes[i]);\n\t\t}\n\t\tthis._updateClassName = function () {\n\t\t\telem.setAttribute(\"class\", this.toString());\n\t\t};\n\t}\n\t, classListProto = ClassList[protoProp] = []\n\t, classListGetter = function () {\n\t\treturn new ClassList(this);\n\t}\n;\n// Most DOMException implementations don't allow calling DOMException's toString()\n// on non-DOMExceptions. Error's toString() is sufficient here.\nDOMEx[protoProp] = Error[protoProp];\nclassListProto.item = function (i) {\n\treturn this[i] || null;\n};\nclassListProto.contains = function (token) {\n\treturn ~checkTokenAndGetIndex(this, token + \"\");\n};\nclassListProto.add = function () {\n\tvar\n\t\t tokens = arguments\n\t\t, i = 0\n\t\t, l = tokens.length\n\t\t, token\n\t\t, updated = false\n\t;\n\tdo {\n\t\ttoken = tokens[i] + \"\";\n\t\tif (!~checkTokenAndGetIndex(this, token)) {\n\t\t\tthis.push(token);\n\t\t\tupdated = true;\n\t\t}\n\t}\n\twhile (++i < l);\n\n\tif (updated) {\n\t\tthis._updateClassName();\n\t}\n};\nclassListProto.remove = function () {\n\tvar\n\t\t tokens = arguments\n\t\t, i = 0\n\t\t, l = tokens.length\n\t\t, token\n\t\t, updated = false\n\t\t, index\n\t;\n\tdo {\n\t\ttoken = tokens[i] + \"\";\n\t\tindex = checkTokenAndGetIndex(this, token);\n\t\twhile (~index) {\n\t\t\tthis.splice(index, 1);\n\t\t\tupdated = true;\n\t\t\tindex = checkTokenAndGetIndex(this, token);\n\t\t}\n\t}\n\twhile (++i < l);\n\n\tif (updated) {\n\t\tthis._updateClassName();\n\t}\n};\nclassListProto.toggle = function (token, force) {\n\tvar\n\t\t result = this.contains(token)\n\t\t, method = result ?\n\t\t\tforce !== true && \"remove\"\n\t\t:\n\t\t\tforce !== false && \"add\"\n\t;\n\n\tif (method) {\n\t\tthis[method](token);\n\t}\n\n\tif (force === true || force === false) {\n\t\treturn force;\n\t} else {\n\t\treturn !result;\n\t}\n};\nclassListProto.replace = function (token, replacement_token) {\n\tvar index = checkTokenAndGetIndex(token + \"\");\n\tif (~index) {\n\t\tthis.splice(index, 1, replacement_token);\n\t\tthis._updateClassName();\n\t}\n}\nclassListProto.toString = function () {\n\treturn this.join(\" \");\n};\n\nif (objCtr.defineProperty) {\n\tvar classListPropDesc = {\n\t\t get: classListGetter\n\t\t, enumerable: true\n\t\t, configurable: true\n\t};\n\ttry {\n\t\tobjCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);\n\t} catch (ex) { // IE 8 doesn't support enumerable:true\n\t\t// adding undefined to fight this issue https://github.com/eligrey/classList.js/issues/36\n\t\t// modernie IE8-MSW7 machine has IE8 8.0.6001.18702 and is affected\n\t\tif (ex.number === undefined || ex.number === -0x7FF5EC54) {\n\t\t\tclassListPropDesc.enumerable = false;\n\t\t\tobjCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);\n\t\t}\n\t}\n} else if (objCtr[protoProp].__defineGetter__) {\n\telemCtrProto.__defineGetter__(classListProp, classListGetter);\n}\n\n}(self));\n\n}\n\n// There is full or partial native classList support, so just check if we need\n// to normalize the add/remove and toggle APIs.\n\n(function () {\n\t\"use strict\";\n\n\tvar testElement = document.createElement(\"_\");\n\n\ttestElement.classList.add(\"c1\", \"c2\");\n\n\t// Polyfill for IE 10/11 and Firefox <26, where classList.add and\n\t// classList.remove exist but support only one argument at a time.\n\tif (!testElement.classList.contains(\"c2\")) {\n\t\tvar createMethod = function(method) {\n\t\t\tvar original = DOMTokenList.prototype[method];\n\n\t\t\tDOMTokenList.prototype[method] = function(token) {\n\t\t\t\tvar i, len = arguments.length;\n\n\t\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\t\ttoken = arguments[i];\n\t\t\t\t\toriginal.call(this, token);\n\t\t\t\t}\n\t\t\t};\n\t\t};\n\t\tcreateMethod('add');\n\t\tcreateMethod('remove');\n\t}\n\n\ttestElement.classList.toggle(\"c3\", false);\n\n\t// Polyfill for IE 10 and Firefox <24, where classList.toggle does not\n\t// support the second argument.\n\tif (testElement.classList.contains(\"c3\")) {\n\t\tvar _toggle = DOMTokenList.prototype.toggle;\n\n\t\tDOMTokenList.prototype.toggle = function(token, force) {\n\t\t\tif (1 in arguments && !this.contains(token) === !force) {\n\t\t\t\treturn force;\n\t\t\t} else {\n\t\t\t\treturn _toggle.call(this, token);\n\t\t\t}\n\t\t};\n\n\t}\n\n\t// replace() polyfill\n\tif (!(\"replace\" in document.createElement(\"_\").classList)) {\n\t\tDOMTokenList.prototype.replace = function (token, replacement_token) {\n\t\t\tvar\n\t\t\t\t tokens = this.toString().split(\" \")\n\t\t\t\t, index = tokens.indexOf(token + \"\")\n\t\t\t;\n\t\t\tif (~index) {\n\t\t\t\ttokens = tokens.slice(index);\n\t\t\t\tthis.remove.apply(this, tokens);\n\t\t\t\tthis.add(replacement_token);\n\t\t\t\tthis.add.apply(this, tokens.slice(1));\n\t\t\t}\n\t\t}\n\t}\n\n\ttestElement = null;\n}());\n\n}","/*! Hammer.JS - v2.0.7 - 2016-04-22\n * http://hammerjs.github.io/\n *\n * Copyright (c) 2016 Jorik Tangelder;\n * Licensed under the MIT license */\n(function(window, document, exportName, undefined) {\n 'use strict';\n\nvar VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];\nvar TEST_ELEMENT = document.createElement('div');\n\nvar TYPE_FUNCTION = 'function';\n\nvar round = Math.round;\nvar abs = Math.abs;\nvar now = Date.now;\n\n/**\n * set a timeout with a given scope\n * @param {Function} fn\n * @param {Number} timeout\n * @param {Object} context\n * @returns {number}\n */\nfunction setTimeoutContext(fn, timeout, context) {\n return setTimeout(bindFn(fn, context), timeout);\n}\n\n/**\n * if the argument is an array, we want to execute the fn on each entry\n * if it aint an array we don't want to do a thing.\n * this is used by all the methods that accept a single and array argument.\n * @param {*|Array} arg\n * @param {String} fn\n * @param {Object} [context]\n * @returns {Boolean}\n */\nfunction invokeArrayArg(arg, fn, context) {\n if (Array.isArray(arg)) {\n each(arg, context[fn], context);\n return true;\n }\n return false;\n}\n\n/**\n * walk objects and arrays\n * @param {Object} obj\n * @param {Function} iterator\n * @param {Object} context\n */\nfunction each(obj, iterator, context) {\n var i;\n\n if (!obj) {\n return;\n }\n\n if (obj.forEach) {\n obj.forEach(iterator, context);\n } else if (obj.length !== undefined) {\n i = 0;\n while (i < obj.length) {\n iterator.call(context, obj[i], i, obj);\n i++;\n }\n } else {\n for (i in obj) {\n obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);\n }\n }\n}\n\n/**\n * wrap a method with a deprecation warning and stack trace\n * @param {Function} method\n * @param {String} name\n * @param {String} message\n * @returns {Function} A new function wrapping the supplied method.\n */\nfunction deprecate(method, name, message) {\n var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\\n' + message + ' AT \\n';\n return function() {\n var e = new Error('get-stack-trace');\n var stack = e && e.stack ? e.stack.replace(/^[^\\(]+?[\\n$]/gm, '')\n .replace(/^\\s+at\\s+/gm, '')\n .replace(/^Object.\\s*\\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';\n\n var log = window.console && (window.console.warn || window.console.log);\n if (log) {\n log.call(window.console, deprecationMessage, stack);\n }\n return method.apply(this, arguments);\n };\n}\n\n/**\n * extend object.\n * means that properties in dest will be overwritten by the ones in src.\n * @param {Object} target\n * @param {...Object} objects_to_assign\n * @returns {Object} target\n */\nvar assign;\nif (typeof Object.assign !== 'function') {\n assign = function assign(target) {\n if (target === undefined || target === null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n var output = Object(target);\n for (var index = 1; index < arguments.length; index++) {\n var source = arguments[index];\n if (source !== undefined && source !== null) {\n for (var nextKey in source) {\n if (source.hasOwnProperty(nextKey)) {\n output[nextKey] = source[nextKey];\n }\n }\n }\n }\n return output;\n };\n} else {\n assign = Object.assign;\n}\n\n/**\n * extend object.\n * means that properties in dest will be overwritten by the ones in src.\n * @param {Object} dest\n * @param {Object} src\n * @param {Boolean} [merge=false]\n * @returns {Object} dest\n */\nvar extend = deprecate(function extend(dest, src, merge) {\n var keys = Object.keys(src);\n var i = 0;\n while (i < keys.length) {\n if (!merge || (merge && dest[keys[i]] === undefined)) {\n dest[keys[i]] = src[keys[i]];\n }\n i++;\n }\n return dest;\n}, 'extend', 'Use `assign`.');\n\n/**\n * merge the values from src in the dest.\n * means that properties that exist in dest will not be overwritten by src\n * @param {Object} dest\n * @param {Object} src\n * @returns {Object} dest\n */\nvar merge = deprecate(function merge(dest, src) {\n return extend(dest, src, true);\n}, 'merge', 'Use `assign`.');\n\n/**\n * simple class inheritance\n * @param {Function} child\n * @param {Function} base\n * @param {Object} [properties]\n */\nfunction inherit(child, base, properties) {\n var baseP = base.prototype,\n childP;\n\n childP = child.prototype = Object.create(baseP);\n childP.constructor = child;\n childP._super = baseP;\n\n if (properties) {\n assign(childP, properties);\n }\n}\n\n/**\n * simple function bind\n * @param {Function} fn\n * @param {Object} context\n * @returns {Function}\n */\nfunction bindFn(fn, context) {\n return function boundFn() {\n return fn.apply(context, arguments);\n };\n}\n\n/**\n * let a boolean value also be a function that must return a boolean\n * this first item in args will be used as the context\n * @param {Boolean|Function} val\n * @param {Array} [args]\n * @returns {Boolean}\n */\nfunction boolOrFn(val, args) {\n if (typeof val == TYPE_FUNCTION) {\n return val.apply(args ? args[0] || undefined : undefined, args);\n }\n return val;\n}\n\n/**\n * use the val2 when val1 is undefined\n * @param {*} val1\n * @param {*} val2\n * @returns {*}\n */\nfunction ifUndefined(val1, val2) {\n return (val1 === undefined) ? val2 : val1;\n}\n\n/**\n * addEventListener with multiple events at once\n * @param {EventTarget} target\n * @param {String} types\n * @param {Function} handler\n */\nfunction addEventListeners(target, types, handler) {\n each(splitStr(types), function(type) {\n target.addEventListener(type, handler, false);\n });\n}\n\n/**\n * removeEventListener with multiple events at once\n * @param {EventTarget} target\n * @param {String} types\n * @param {Function} handler\n */\nfunction removeEventListeners(target, types, handler) {\n each(splitStr(types), function(type) {\n target.removeEventListener(type, handler, false);\n });\n}\n\n/**\n * find if a node is in the given parent\n * @method hasParent\n * @param {HTMLElement} node\n * @param {HTMLElement} parent\n * @return {Boolean} found\n */\nfunction hasParent(node, parent) {\n while (node) {\n if (node == parent) {\n return true;\n }\n node = node.parentNode;\n }\n return false;\n}\n\n/**\n * small indexOf wrapper\n * @param {String} str\n * @param {String} find\n * @returns {Boolean} found\n */\nfunction inStr(str, find) {\n return str.indexOf(find) > -1;\n}\n\n/**\n * split string on whitespace\n * @param {String} str\n * @returns {Array} words\n */\nfunction splitStr(str) {\n return str.trim().split(/\\s+/g);\n}\n\n/**\n * find if a array contains the object using indexOf or a simple polyFill\n * @param {Array} src\n * @param {String} find\n * @param {String} [findByKey]\n * @return {Boolean|Number} false when not found, or the index\n */\nfunction inArray(src, find, findByKey) {\n if (src.indexOf && !findByKey) {\n return src.indexOf(find);\n } else {\n var i = 0;\n while (i < src.length) {\n if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) {\n return i;\n }\n i++;\n }\n return -1;\n }\n}\n\n/**\n * convert array-like objects to real arrays\n * @param {Object} obj\n * @returns {Array}\n */\nfunction toArray(obj) {\n return Array.prototype.slice.call(obj, 0);\n}\n\n/**\n * unique array with objects based on a key (like 'id') or just by the array's value\n * @param {Array} src [{id:1},{id:2},{id:1}]\n * @param {String} [key]\n * @param {Boolean} [sort=False]\n * @returns {Array} [{id:1},{id:2}]\n */\nfunction uniqueArray(src, key, sort) {\n var results = [];\n var values = [];\n var i = 0;\n\n while (i < src.length) {\n var val = key ? src[i][key] : src[i];\n if (inArray(values, val) < 0) {\n results.push(src[i]);\n }\n values[i] = val;\n i++;\n }\n\n if (sort) {\n if (!key) {\n results = results.sort();\n } else {\n results = results.sort(function sortUniqueArray(a, b) {\n return a[key] > b[key];\n });\n }\n }\n\n return results;\n}\n\n/**\n * get the prefixed property\n * @param {Object} obj\n * @param {String} property\n * @returns {String|Undefined} prefixed\n */\nfunction prefixed(obj, property) {\n var prefix, prop;\n var camelProp = property[0].toUpperCase() + property.slice(1);\n\n var i = 0;\n while (i < VENDOR_PREFIXES.length) {\n prefix = VENDOR_PREFIXES[i];\n prop = (prefix) ? prefix + camelProp : property;\n\n if (prop in obj) {\n return prop;\n }\n i++;\n }\n return undefined;\n}\n\n/**\n * get a unique id\n * @returns {number} uniqueId\n */\nvar _uniqueId = 1;\nfunction uniqueId() {\n return _uniqueId++;\n}\n\n/**\n * get the window object of an element\n * @param {HTMLElement} element\n * @returns {DocumentView|Window}\n */\nfunction getWindowForElement(element) {\n var doc = element.ownerDocument || element;\n return (doc.defaultView || doc.parentWindow || window);\n}\n\nvar MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;\n\nvar SUPPORT_TOUCH = ('ontouchstart' in window);\nvar SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;\nvar SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);\n\nvar INPUT_TYPE_TOUCH = 'touch';\nvar INPUT_TYPE_PEN = 'pen';\nvar INPUT_TYPE_MOUSE = 'mouse';\nvar INPUT_TYPE_KINECT = 'kinect';\n\nvar COMPUTE_INTERVAL = 25;\n\nvar INPUT_START = 1;\nvar INPUT_MOVE = 2;\nvar INPUT_END = 4;\nvar INPUT_CANCEL = 8;\n\nvar DIRECTION_NONE = 1;\nvar DIRECTION_LEFT = 2;\nvar DIRECTION_RIGHT = 4;\nvar DIRECTION_UP = 8;\nvar DIRECTION_DOWN = 16;\n\nvar DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;\nvar DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;\nvar DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;\n\nvar PROPS_XY = ['x', 'y'];\nvar PROPS_CLIENT_XY = ['clientX', 'clientY'];\n\n/**\n * create new input type manager\n * @param {Manager} manager\n * @param {Function} callback\n * @returns {Input}\n * @constructor\n */\nfunction Input(manager, callback) {\n var self = this;\n this.manager = manager;\n this.callback = callback;\n this.element = manager.element;\n this.target = manager.options.inputTarget;\n\n // smaller wrapper around the handler, for the scope and the enabled state of the manager,\n // so when disabled the input events are completely bypassed.\n this.domHandler = function(ev) {\n if (boolOrFn(manager.options.enable, [manager])) {\n self.handler(ev);\n }\n };\n\n this.init();\n\n}\n\nInput.prototype = {\n /**\n * should handle the inputEvent data and trigger the callback\n * @virtual\n */\n handler: function() { },\n\n /**\n * bind the events\n */\n init: function() {\n this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);\n this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);\n this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);\n },\n\n /**\n * unbind the events\n */\n destroy: function() {\n this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);\n this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);\n this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);\n }\n};\n\n/**\n * create new input type manager\n * called by the Manager constructor\n * @param {Hammer} manager\n * @returns {Input}\n */\nfunction createInputInstance(manager) {\n var Type;\n var inputClass = manager.options.inputClass;\n\n if (inputClass) {\n Type = inputClass;\n } else if (SUPPORT_POINTER_EVENTS) {\n Type = PointerEventInput;\n } else if (SUPPORT_ONLY_TOUCH) {\n Type = TouchInput;\n } else if (!SUPPORT_TOUCH) {\n Type = MouseInput;\n } else {\n Type = TouchMouseInput;\n }\n return new (Type)(manager, inputHandler);\n}\n\n/**\n * handle input events\n * @param {Manager} manager\n * @param {String} eventType\n * @param {Object} input\n */\nfunction inputHandler(manager, eventType, input) {\n var pointersLen = input.pointers.length;\n var changedPointersLen = input.changedPointers.length;\n var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0));\n var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0));\n\n input.isFirst = !!isFirst;\n input.isFinal = !!isFinal;\n\n if (isFirst) {\n manager.session = {};\n }\n\n // source event is the normalized value of the domEvents\n // like 'touchstart, mouseup, pointerdown'\n input.eventType = eventType;\n\n // compute scale, rotation etc\n computeInputData(manager, input);\n\n // emit secret event\n manager.emit('hammer.input', input);\n\n manager.recognize(input);\n manager.session.prevInput = input;\n}\n\n/**\n * extend the data with some usable properties like scale, rotate, velocity etc\n * @param {Object} manager\n * @param {Object} input\n */\nfunction computeInputData(manager, input) {\n var session = manager.session;\n var pointers = input.pointers;\n var pointersLength = pointers.length;\n\n // store the first input to calculate the distance and direction\n if (!session.firstInput) {\n session.firstInput = simpleCloneInputData(input);\n }\n\n // to compute scale and rotation we need to store the multiple touches\n if (pointersLength > 1 && !session.firstMultiple) {\n session.firstMultiple = simpleCloneInputData(input);\n } else if (pointersLength === 1) {\n session.firstMultiple = false;\n }\n\n var firstInput = session.firstInput;\n var firstMultiple = session.firstMultiple;\n var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;\n\n var center = input.center = getCenter(pointers);\n input.timeStamp = now();\n input.deltaTime = input.timeStamp - firstInput.timeStamp;\n\n input.angle = getAngle(offsetCenter, center);\n input.distance = getDistance(offsetCenter, center);\n\n computeDeltaXY(session, input);\n input.offsetDirection = getDirection(input.deltaX, input.deltaY);\n\n var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);\n input.overallVelocityX = overallVelocity.x;\n input.overallVelocityY = overallVelocity.y;\n input.overallVelocity = (abs(overallVelocity.x) > abs(overallVelocity.y)) ? overallVelocity.x : overallVelocity.y;\n\n input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;\n input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;\n\n input.maxPointers = !session.prevInput ? input.pointers.length : ((input.pointers.length >\n session.prevInput.maxPointers) ? input.pointers.length : session.prevInput.maxPointers);\n\n computeIntervalInputData(session, input);\n\n // find the correct target\n var target = manager.element;\n if (hasParent(input.srcEvent.target, target)) {\n target = input.srcEvent.target;\n }\n input.target = target;\n}\n\nfunction computeDeltaXY(session, input) {\n var center = input.center;\n var offset = session.offsetDelta || {};\n var prevDelta = session.prevDelta || {};\n var prevInput = session.prevInput || {};\n\n if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {\n prevDelta = session.prevDelta = {\n x: prevInput.deltaX || 0,\n y: prevInput.deltaY || 0\n };\n\n offset = session.offsetDelta = {\n x: center.x,\n y: center.y\n };\n }\n\n input.deltaX = prevDelta.x + (center.x - offset.x);\n input.deltaY = prevDelta.y + (center.y - offset.y);\n}\n\n/**\n * velocity is calculated every x ms\n * @param {Object} session\n * @param {Object} input\n */\nfunction computeIntervalInputData(session, input) {\n var last = session.lastInterval || input,\n deltaTime = input.timeStamp - last.timeStamp,\n velocity, velocityX, velocityY, direction;\n\n if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {\n var deltaX = input.deltaX - last.deltaX;\n var deltaY = input.deltaY - last.deltaY;\n\n var v = getVelocity(deltaTime, deltaX, deltaY);\n velocityX = v.x;\n velocityY = v.y;\n velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;\n direction = getDirection(deltaX, deltaY);\n\n session.lastInterval = input;\n } else {\n // use latest velocity info if it doesn't overtake a minimum period\n velocity = last.velocity;\n velocityX = last.velocityX;\n velocityY = last.velocityY;\n direction = last.direction;\n }\n\n input.velocity = velocity;\n input.velocityX = velocityX;\n input.velocityY = velocityY;\n input.direction = direction;\n}\n\n/**\n * create a simple clone from the input used for storage of firstInput and firstMultiple\n * @param {Object} input\n * @returns {Object} clonedInputData\n */\nfunction simpleCloneInputData(input) {\n // make a simple copy of the pointers because we will get a reference if we don't\n // we only need clientXY for the calculations\n var pointers = [];\n var i = 0;\n while (i < input.pointers.length) {\n pointers[i] = {\n clientX: round(input.pointers[i].clientX),\n clientY: round(input.pointers[i].clientY)\n };\n i++;\n }\n\n return {\n timeStamp: now(),\n pointers: pointers,\n center: getCenter(pointers),\n deltaX: input.deltaX,\n deltaY: input.deltaY\n };\n}\n\n/**\n * get the center of all the pointers\n * @param {Array} pointers\n * @return {Object} center contains `x` and `y` properties\n */\nfunction getCenter(pointers) {\n var pointersLength = pointers.length;\n\n // no need to loop when only one touch\n if (pointersLength === 1) {\n return {\n x: round(pointers[0].clientX),\n y: round(pointers[0].clientY)\n };\n }\n\n var x = 0, y = 0, i = 0;\n while (i < pointersLength) {\n x += pointers[i].clientX;\n y += pointers[i].clientY;\n i++;\n }\n\n return {\n x: round(x / pointersLength),\n y: round(y / pointersLength)\n };\n}\n\n/**\n * calculate the velocity between two points. unit is in px per ms.\n * @param {Number} deltaTime\n * @param {Number} x\n * @param {Number} y\n * @return {Object} velocity `x` and `y`\n */\nfunction getVelocity(deltaTime, x, y) {\n return {\n x: x / deltaTime || 0,\n y: y / deltaTime || 0\n };\n}\n\n/**\n * get the direction between two points\n * @param {Number} x\n * @param {Number} y\n * @return {Number} direction\n */\nfunction getDirection(x, y) {\n if (x === y) {\n return DIRECTION_NONE;\n }\n\n if (abs(x) >= abs(y)) {\n return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;\n }\n return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;\n}\n\n/**\n * calculate the absolute distance between two points\n * @param {Object} p1 {x, y}\n * @param {Object} p2 {x, y}\n * @param {Array} [props] containing x and y keys\n * @return {Number} distance\n */\nfunction getDistance(p1, p2, props) {\n if (!props) {\n props = PROPS_XY;\n }\n var x = p2[props[0]] - p1[props[0]],\n y = p2[props[1]] - p1[props[1]];\n\n return Math.sqrt((x * x) + (y * y));\n}\n\n/**\n * calculate the angle between two coordinates\n * @param {Object} p1\n * @param {Object} p2\n * @param {Array} [props] containing x and y keys\n * @return {Number} angle\n */\nfunction getAngle(p1, p2, props) {\n if (!props) {\n props = PROPS_XY;\n }\n var x = p2[props[0]] - p1[props[0]],\n y = p2[props[1]] - p1[props[1]];\n return Math.atan2(y, x) * 180 / Math.PI;\n}\n\n/**\n * calculate the rotation degrees between two pointersets\n * @param {Array} start array of pointers\n * @param {Array} end array of pointers\n * @return {Number} rotation\n */\nfunction getRotation(start, end) {\n return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);\n}\n\n/**\n * calculate the scale factor between two pointersets\n * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out\n * @param {Array} start array of pointers\n * @param {Array} end array of pointers\n * @return {Number} scale\n */\nfunction getScale(start, end) {\n return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);\n}\n\nvar MOUSE_INPUT_MAP = {\n mousedown: INPUT_START,\n mousemove: INPUT_MOVE,\n mouseup: INPUT_END\n};\n\nvar MOUSE_ELEMENT_EVENTS = 'mousedown';\nvar MOUSE_WINDOW_EVENTS = 'mousemove mouseup';\n\n/**\n * Mouse events input\n * @constructor\n * @extends Input\n */\nfunction MouseInput() {\n this.evEl = MOUSE_ELEMENT_EVENTS;\n this.evWin = MOUSE_WINDOW_EVENTS;\n\n this.pressed = false; // mousedown state\n\n Input.apply(this, arguments);\n}\n\ninherit(MouseInput, Input, {\n /**\n * handle mouse events\n * @param {Object} ev\n */\n handler: function MEhandler(ev) {\n var eventType = MOUSE_INPUT_MAP[ev.type];\n\n // on start we want to have the left mouse button down\n if (eventType & INPUT_START && ev.button === 0) {\n this.pressed = true;\n }\n\n if (eventType & INPUT_MOVE && ev.which !== 1) {\n eventType = INPUT_END;\n }\n\n // mouse must be down\n if (!this.pressed) {\n return;\n }\n\n if (eventType & INPUT_END) {\n this.pressed = false;\n }\n\n this.callback(this.manager, eventType, {\n pointers: [ev],\n changedPointers: [ev],\n pointerType: INPUT_TYPE_MOUSE,\n srcEvent: ev\n });\n }\n});\n\nvar POINTER_INPUT_MAP = {\n pointerdown: INPUT_START,\n pointermove: INPUT_MOVE,\n pointerup: INPUT_END,\n pointercancel: INPUT_CANCEL,\n pointerout: INPUT_CANCEL\n};\n\n// in IE10 the pointer types is defined as an enum\nvar IE10_POINTER_TYPE_ENUM = {\n 2: INPUT_TYPE_TOUCH,\n 3: INPUT_TYPE_PEN,\n 4: INPUT_TYPE_MOUSE,\n 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816\n};\n\nvar POINTER_ELEMENT_EVENTS = 'pointerdown';\nvar POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';\n\n// IE10 has prefixed support, and case-sensitive\nif (window.MSPointerEvent && !window.PointerEvent) {\n POINTER_ELEMENT_EVENTS = 'MSPointerDown';\n POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';\n}\n\n/**\n * Pointer events input\n * @constructor\n * @extends Input\n */\nfunction PointerEventInput() {\n this.evEl = POINTER_ELEMENT_EVENTS;\n this.evWin = POINTER_WINDOW_EVENTS;\n\n Input.apply(this, arguments);\n\n this.store = (this.manager.session.pointerEvents = []);\n}\n\ninherit(PointerEventInput, Input, {\n /**\n * handle mouse events\n * @param {Object} ev\n */\n handler: function PEhandler(ev) {\n var store = this.store;\n var removePointer = false;\n\n var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');\n var eventType = POINTER_INPUT_MAP[eventTypeNormalized];\n var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;\n\n var isTouch = (pointerType == INPUT_TYPE_TOUCH);\n\n // get index of the event in the store\n var storeIndex = inArray(store, ev.pointerId, 'pointerId');\n\n // start and mouse must be down\n if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {\n if (storeIndex < 0) {\n store.push(ev);\n storeIndex = store.length - 1;\n }\n } else if (eventType & (INPUT_END | INPUT_CANCEL)) {\n removePointer = true;\n }\n\n // it not found, so the pointer hasn't been down (so it's probably a hover)\n if (storeIndex < 0) {\n return;\n }\n\n // update the event in the store\n store[storeIndex] = ev;\n\n this.callback(this.manager, eventType, {\n pointers: store,\n changedPointers: [ev],\n pointerType: pointerType,\n srcEvent: ev\n });\n\n if (removePointer) {\n // remove from the store\n store.splice(storeIndex, 1);\n }\n }\n});\n\nvar SINGLE_TOUCH_INPUT_MAP = {\n touchstart: INPUT_START,\n touchmove: INPUT_MOVE,\n touchend: INPUT_END,\n touchcancel: INPUT_CANCEL\n};\n\nvar SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';\nvar SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';\n\n/**\n * Touch events input\n * @constructor\n * @extends Input\n */\nfunction SingleTouchInput() {\n this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;\n this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;\n this.started = false;\n\n Input.apply(this, arguments);\n}\n\ninherit(SingleTouchInput, Input, {\n handler: function TEhandler(ev) {\n var type = SINGLE_TOUCH_INPUT_MAP[ev.type];\n\n // should we handle the touch events?\n if (type === INPUT_START) {\n this.started = true;\n }\n\n if (!this.started) {\n return;\n }\n\n var touches = normalizeSingleTouches.call(this, ev, type);\n\n // when done, reset the started state\n if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {\n this.started = false;\n }\n\n this.callback(this.manager, type, {\n pointers: touches[0],\n changedPointers: touches[1],\n pointerType: INPUT_TYPE_TOUCH,\n srcEvent: ev\n });\n }\n});\n\n/**\n * @this {TouchInput}\n * @param {Object} ev\n * @param {Number} type flag\n * @returns {undefined|Array} [all, changed]\n */\nfunction normalizeSingleTouches(ev, type) {\n var all = toArray(ev.touches);\n var changed = toArray(ev.changedTouches);\n\n if (type & (INPUT_END | INPUT_CANCEL)) {\n all = uniqueArray(all.concat(changed), 'identifier', true);\n }\n\n return [all, changed];\n}\n\nvar TOUCH_INPUT_MAP = {\n touchstart: INPUT_START,\n touchmove: INPUT_MOVE,\n touchend: INPUT_END,\n touchcancel: INPUT_CANCEL\n};\n\nvar TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';\n\n/**\n * Multi-user touch events input\n * @constructor\n * @extends Input\n */\nfunction TouchInput() {\n this.evTarget = TOUCH_TARGET_EVENTS;\n this.targetIds = {};\n\n Input.apply(this, arguments);\n}\n\ninherit(TouchInput, Input, {\n handler: function MTEhandler(ev) {\n var type = TOUCH_INPUT_MAP[ev.type];\n var touches = getTouches.call(this, ev, type);\n if (!touches) {\n return;\n }\n\n this.callback(this.manager, type, {\n pointers: touches[0],\n changedPointers: touches[1],\n pointerType: INPUT_TYPE_TOUCH,\n srcEvent: ev\n });\n }\n});\n\n/**\n * @this {TouchInput}\n * @param {Object} ev\n * @param {Number} type flag\n * @returns {undefined|Array} [all, changed]\n */\nfunction getTouches(ev, type) {\n var allTouches = toArray(ev.touches);\n var targetIds = this.targetIds;\n\n // when there is only one touch, the process can be simplified\n if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {\n targetIds[allTouches[0].identifier] = true;\n return [allTouches, allTouches];\n }\n\n var i,\n targetTouches,\n changedTouches = toArray(ev.changedTouches),\n changedTargetTouches = [],\n target = this.target;\n\n // get target touches from touches\n targetTouches = allTouches.filter(function(touch) {\n return hasParent(touch.target, target);\n });\n\n // collect touches\n if (type === INPUT_START) {\n i = 0;\n while (i < targetTouches.length) {\n targetIds[targetTouches[i].identifier] = true;\n i++;\n }\n }\n\n // filter changed touches to only contain touches that exist in the collected target ids\n i = 0;\n while (i < changedTouches.length) {\n if (targetIds[changedTouches[i].identifier]) {\n changedTargetTouches.push(changedTouches[i]);\n }\n\n // cleanup removed touches\n if (type & (INPUT_END | INPUT_CANCEL)) {\n delete targetIds[changedTouches[i].identifier];\n }\n i++;\n }\n\n if (!changedTargetTouches.length) {\n return;\n }\n\n return [\n // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'\n uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true),\n changedTargetTouches\n ];\n}\n\n/**\n * Combined touch and mouse input\n *\n * Touch has a higher priority then mouse, and while touching no mouse events are allowed.\n * This because touch devices also emit mouse events while doing a touch.\n *\n * @constructor\n * @extends Input\n */\n\nvar DEDUP_TIMEOUT = 2500;\nvar DEDUP_DISTANCE = 25;\n\nfunction TouchMouseInput() {\n Input.apply(this, arguments);\n\n var handler = bindFn(this.handler, this);\n this.touch = new TouchInput(this.manager, handler);\n this.mouse = new MouseInput(this.manager, handler);\n\n this.primaryTouch = null;\n this.lastTouches = [];\n}\n\ninherit(TouchMouseInput, Input, {\n /**\n * handle mouse and touch events\n * @param {Hammer} manager\n * @param {String} inputEvent\n * @param {Object} inputData\n */\n handler: function TMEhandler(manager, inputEvent, inputData) {\n var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH),\n isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE);\n\n if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {\n return;\n }\n\n // when we're in a touch event, record touches to de-dupe synthetic mouse event\n if (isTouch) {\n recordTouches.call(this, inputEvent, inputData);\n } else if (isMouse && isSyntheticEvent.call(this, inputData)) {\n return;\n }\n\n this.callback(manager, inputEvent, inputData);\n },\n\n /**\n * remove the event listeners\n */\n destroy: function destroy() {\n this.touch.destroy();\n this.mouse.destroy();\n }\n});\n\nfunction recordTouches(eventType, eventData) {\n if (eventType & INPUT_START) {\n this.primaryTouch = eventData.changedPointers[0].identifier;\n setLastTouch.call(this, eventData);\n } else if (eventType & (INPUT_END | INPUT_CANCEL)) {\n setLastTouch.call(this, eventData);\n }\n}\n\nfunction setLastTouch(eventData) {\n var touch = eventData.changedPointers[0];\n\n if (touch.identifier === this.primaryTouch) {\n var lastTouch = {x: touch.clientX, y: touch.clientY};\n this.lastTouches.push(lastTouch);\n var lts = this.lastTouches;\n var removeLastTouch = function() {\n var i = lts.indexOf(lastTouch);\n if (i > -1) {\n lts.splice(i, 1);\n }\n };\n setTimeout(removeLastTouch, DEDUP_TIMEOUT);\n }\n}\n\nfunction isSyntheticEvent(eventData) {\n var x = eventData.srcEvent.clientX, y = eventData.srcEvent.clientY;\n for (var i = 0; i < this.lastTouches.length; i++) {\n var t = this.lastTouches[i];\n var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y);\n if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {\n return true;\n }\n }\n return false;\n}\n\nvar PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');\nvar NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;\n\n// magical touchAction value\nvar TOUCH_ACTION_COMPUTE = 'compute';\nvar TOUCH_ACTION_AUTO = 'auto';\nvar TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented\nvar TOUCH_ACTION_NONE = 'none';\nvar TOUCH_ACTION_PAN_X = 'pan-x';\nvar TOUCH_ACTION_PAN_Y = 'pan-y';\nvar TOUCH_ACTION_MAP = getTouchActionProps();\n\n/**\n * Touch Action\n * sets the touchAction property or uses the js alternative\n * @param {Manager} manager\n * @param {String} value\n * @constructor\n */\nfunction TouchAction(manager, value) {\n this.manager = manager;\n this.set(value);\n}\n\nTouchAction.prototype = {\n /**\n * set the touchAction value on the element or enable the polyfill\n * @param {String} value\n */\n set: function(value) {\n // find out the touch-action by the event handlers\n if (value == TOUCH_ACTION_COMPUTE) {\n value = this.compute();\n }\n\n if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {\n this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;\n }\n this.actions = value.toLowerCase().trim();\n },\n\n /**\n * just re-set the touchAction value\n */\n update: function() {\n this.set(this.manager.options.touchAction);\n },\n\n /**\n * compute the value for the touchAction property based on the recognizer's settings\n * @returns {String} value\n */\n compute: function() {\n var actions = [];\n each(this.manager.recognizers, function(recognizer) {\n if (boolOrFn(recognizer.options.enable, [recognizer])) {\n actions = actions.concat(recognizer.getTouchAction());\n }\n });\n return cleanTouchActions(actions.join(' '));\n },\n\n /**\n * this method is called on each input cycle and provides the preventing of the browser behavior\n * @param {Object} input\n */\n preventDefaults: function(input) {\n var srcEvent = input.srcEvent;\n var direction = input.offsetDirection;\n\n // if the touch action did prevented once this session\n if (this.manager.session.prevented) {\n srcEvent.preventDefault();\n return;\n }\n\n var actions = this.actions;\n var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];\n var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];\n var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];\n\n if (hasNone) {\n //do not prevent defaults if this is a tap gesture\n\n var isTapPointer = input.pointers.length === 1;\n var isTapMovement = input.distance < 2;\n var isTapTouchTime = input.deltaTime < 250;\n\n if (isTapPointer && isTapMovement && isTapTouchTime) {\n return;\n }\n }\n\n if (hasPanX && hasPanY) {\n // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent\n return;\n }\n\n if (hasNone ||\n (hasPanY && direction & DIRECTION_HORIZONTAL) ||\n (hasPanX && direction & DIRECTION_VERTICAL)) {\n return this.preventSrc(srcEvent);\n }\n },\n\n /**\n * call preventDefault to prevent the browser's default behavior (scrolling in most cases)\n * @param {Object} srcEvent\n */\n preventSrc: function(srcEvent) {\n this.manager.session.prevented = true;\n srcEvent.preventDefault();\n }\n};\n\n/**\n * when the touchActions are collected they are not a valid value, so we need to clean things up. *\n * @param {String} actions\n * @returns {*}\n */\nfunction cleanTouchActions(actions) {\n // none\n if (inStr(actions, TOUCH_ACTION_NONE)) {\n return TOUCH_ACTION_NONE;\n }\n\n var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);\n var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);\n\n // if both pan-x and pan-y are set (different recognizers\n // for different directions, e.g. horizontal pan but vertical swipe?)\n // we need none (as otherwise with pan-x pan-y combined none of these\n // recognizers will work, since the browser would handle all panning\n if (hasPanX && hasPanY) {\n return TOUCH_ACTION_NONE;\n }\n\n // pan-x OR pan-y\n if (hasPanX || hasPanY) {\n return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;\n }\n\n // manipulation\n if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {\n return TOUCH_ACTION_MANIPULATION;\n }\n\n return TOUCH_ACTION_AUTO;\n}\n\nfunction getTouchActionProps() {\n if (!NATIVE_TOUCH_ACTION) {\n return false;\n }\n var touchMap = {};\n var cssSupports = window.CSS && window.CSS.supports;\n ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function(val) {\n\n // If css.supports is not supported but there is native touch-action assume it supports\n // all values. This is the case for IE 10 and 11.\n touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true;\n });\n return touchMap;\n}\n\n/**\n * Recognizer flow explained; *\n * All recognizers have the initial state of POSSIBLE when a input session starts.\n * The definition of a input session is from the first input until the last input, with all it's movement in it. *\n * Example session for mouse-input: mousedown -> mousemove -> mouseup\n *\n * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed\n * which determines with state it should be.\n *\n * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to\n * POSSIBLE to give it another change on the next cycle.\n *\n * Possible\n * |\n * +-----+---------------+\n * | |\n * +-----+-----+ |\n * | | |\n * Failed Cancelled |\n * +-------+------+\n * | |\n * Recognized Began\n * |\n * Changed\n * |\n * Ended/Recognized\n */\nvar STATE_POSSIBLE = 1;\nvar STATE_BEGAN = 2;\nvar STATE_CHANGED = 4;\nvar STATE_ENDED = 8;\nvar STATE_RECOGNIZED = STATE_ENDED;\nvar STATE_CANCELLED = 16;\nvar STATE_FAILED = 32;\n\n/**\n * Recognizer\n * Every recognizer needs to extend from this class.\n * @constructor\n * @param {Object} options\n */\nfunction Recognizer(options) {\n this.options = assign({}, this.defaults, options || {});\n\n this.id = uniqueId();\n\n this.manager = null;\n\n // default is enable true\n this.options.enable = ifUndefined(this.options.enable, true);\n\n this.state = STATE_POSSIBLE;\n\n this.simultaneous = {};\n this.requireFail = [];\n}\n\nRecognizer.prototype = {\n /**\n * @virtual\n * @type {Object}\n */\n defaults: {},\n\n /**\n * set options\n * @param {Object} options\n * @return {Recognizer}\n */\n set: function(options) {\n assign(this.options, options);\n\n // also update the touchAction, in case something changed about the directions/enabled state\n this.manager && this.manager.touchAction.update();\n return this;\n },\n\n /**\n * recognize simultaneous with an other recognizer.\n * @param {Recognizer} otherRecognizer\n * @returns {Recognizer} this\n */\n recognizeWith: function(otherRecognizer) {\n if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {\n return this;\n }\n\n var simultaneous = this.simultaneous;\n otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n if (!simultaneous[otherRecognizer.id]) {\n simultaneous[otherRecognizer.id] = otherRecognizer;\n otherRecognizer.recognizeWith(this);\n }\n return this;\n },\n\n /**\n * drop the simultaneous link. it doesnt remove the link on the other recognizer.\n * @param {Recognizer} otherRecognizer\n * @returns {Recognizer} this\n */\n dropRecognizeWith: function(otherRecognizer) {\n if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {\n return this;\n }\n\n otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n delete this.simultaneous[otherRecognizer.id];\n return this;\n },\n\n /**\n * recognizer can only run when an other is failing\n * @param {Recognizer} otherRecognizer\n * @returns {Recognizer} this\n */\n requireFailure: function(otherRecognizer) {\n if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {\n return this;\n }\n\n var requireFail = this.requireFail;\n otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n if (inArray(requireFail, otherRecognizer) === -1) {\n requireFail.push(otherRecognizer);\n otherRecognizer.requireFailure(this);\n }\n return this;\n },\n\n /**\n * drop the requireFailure link. it does not remove the link on the other recognizer.\n * @param {Recognizer} otherRecognizer\n * @returns {Recognizer} this\n */\n dropRequireFailure: function(otherRecognizer) {\n if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {\n return this;\n }\n\n otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n var index = inArray(this.requireFail, otherRecognizer);\n if (index > -1) {\n this.requireFail.splice(index, 1);\n }\n return this;\n },\n\n /**\n * has require failures boolean\n * @returns {boolean}\n */\n hasRequireFailures: function() {\n return this.requireFail.length > 0;\n },\n\n /**\n * if the recognizer can recognize simultaneous with an other recognizer\n * @param {Recognizer} otherRecognizer\n * @returns {Boolean}\n */\n canRecognizeWith: function(otherRecognizer) {\n return !!this.simultaneous[otherRecognizer.id];\n },\n\n /**\n * You should use `tryEmit` instead of `emit` directly to check\n * that all the needed recognizers has failed before emitting.\n * @param {Object} input\n */\n emit: function(input) {\n var self = this;\n var state = this.state;\n\n function emit(event) {\n self.manager.emit(event, input);\n }\n\n // 'panstart' and 'panmove'\n if (state < STATE_ENDED) {\n emit(self.options.event + stateStr(state));\n }\n\n emit(self.options.event); // simple 'eventName' events\n\n if (input.additionalEvent) { // additional event(panleft, panright, pinchin, pinchout...)\n emit(input.additionalEvent);\n }\n\n // panend and pancancel\n if (state >= STATE_ENDED) {\n emit(self.options.event + stateStr(state));\n }\n },\n\n /**\n * Check that all the require failure recognizers has failed,\n * if true, it emits a gesture event,\n * otherwise, setup the state to FAILED.\n * @param {Object} input\n */\n tryEmit: function(input) {\n if (this.canEmit()) {\n return this.emit(input);\n }\n // it's failing anyway\n this.state = STATE_FAILED;\n },\n\n /**\n * can we emit?\n * @returns {boolean}\n */\n canEmit: function() {\n var i = 0;\n while (i < this.requireFail.length) {\n if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {\n return false;\n }\n i++;\n }\n return true;\n },\n\n /**\n * update the recognizer\n * @param {Object} inputData\n */\n recognize: function(inputData) {\n // make a new copy of the inputData\n // so we can change the inputData without messing up the other recognizers\n var inputDataClone = assign({}, inputData);\n\n // is is enabled and allow recognizing?\n if (!boolOrFn(this.options.enable, [this, inputDataClone])) {\n this.reset();\n this.state = STATE_FAILED;\n return;\n }\n\n // reset when we've reached the end\n if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {\n this.state = STATE_POSSIBLE;\n }\n\n this.state = this.process(inputDataClone);\n\n // the recognizer has recognized a gesture\n // so trigger an event\n if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {\n this.tryEmit(inputDataClone);\n }\n },\n\n /**\n * return the state of the recognizer\n * the actual recognizing happens in this method\n * @virtual\n * @param {Object} inputData\n * @returns {Const} STATE\n */\n process: function(inputData) { }, // jshint ignore:line\n\n /**\n * return the preferred touch-action\n * @virtual\n * @returns {Array}\n */\n getTouchAction: function() { },\n\n /**\n * called when the gesture isn't allowed to recognize\n * like when another is being recognized or it is disabled\n * @virtual\n */\n reset: function() { }\n};\n\n/**\n * get a usable string, used as event postfix\n * @param {Const} state\n * @returns {String} state\n */\nfunction stateStr(state) {\n if (state & STATE_CANCELLED) {\n return 'cancel';\n } else if (state & STATE_ENDED) {\n return 'end';\n } else if (state & STATE_CHANGED) {\n return 'move';\n } else if (state & STATE_BEGAN) {\n return 'start';\n }\n return '';\n}\n\n/**\n * direction cons to string\n * @param {Const} direction\n * @returns {String}\n */\nfunction directionStr(direction) {\n if (direction == DIRECTION_DOWN) {\n return 'down';\n } else if (direction == DIRECTION_UP) {\n return 'up';\n } else if (direction == DIRECTION_LEFT) {\n return 'left';\n } else if (direction == DIRECTION_RIGHT) {\n return 'right';\n }\n return '';\n}\n\n/**\n * get a recognizer by name if it is bound to a manager\n * @param {Recognizer|String} otherRecognizer\n * @param {Recognizer} recognizer\n * @returns {Recognizer}\n */\nfunction getRecognizerByNameIfManager(otherRecognizer, recognizer) {\n var manager = recognizer.manager;\n if (manager) {\n return manager.get(otherRecognizer);\n }\n return otherRecognizer;\n}\n\n/**\n * This recognizer is just used as a base for the simple attribute recognizers.\n * @constructor\n * @extends Recognizer\n */\nfunction AttrRecognizer() {\n Recognizer.apply(this, arguments);\n}\n\ninherit(AttrRecognizer, Recognizer, {\n /**\n * @namespace\n * @memberof AttrRecognizer\n */\n defaults: {\n /**\n * @type {Number}\n * @default 1\n */\n pointers: 1\n },\n\n /**\n * Used to check if it the recognizer receives valid input, like input.distance > 10.\n * @memberof AttrRecognizer\n * @param {Object} input\n * @returns {Boolean} recognized\n */\n attrTest: function(input) {\n var optionPointers = this.options.pointers;\n return optionPointers === 0 || input.pointers.length === optionPointers;\n },\n\n /**\n * Process the input and return the state for the recognizer\n * @memberof AttrRecognizer\n * @param {Object} input\n * @returns {*} State\n */\n process: function(input) {\n var state = this.state;\n var eventType = input.eventType;\n\n var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);\n var isValid = this.attrTest(input);\n\n // on cancel input and we've recognized before, return STATE_CANCELLED\n if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {\n return state | STATE_CANCELLED;\n } else if (isRecognized || isValid) {\n if (eventType & INPUT_END) {\n return state | STATE_ENDED;\n } else if (!(state & STATE_BEGAN)) {\n return STATE_BEGAN;\n }\n return state | STATE_CHANGED;\n }\n return STATE_FAILED;\n }\n});\n\n/**\n * Pan\n * Recognized when the pointer is down and moved in the allowed direction.\n * @constructor\n * @extends AttrRecognizer\n */\nfunction PanRecognizer() {\n AttrRecognizer.apply(this, arguments);\n\n this.pX = null;\n this.pY = null;\n}\n\ninherit(PanRecognizer, AttrRecognizer, {\n /**\n * @namespace\n * @memberof PanRecognizer\n */\n defaults: {\n event: 'pan',\n threshold: 10,\n pointers: 1,\n direction: DIRECTION_ALL\n },\n\n getTouchAction: function() {\n var direction = this.options.direction;\n var actions = [];\n if (direction & DIRECTION_HORIZONTAL) {\n actions.push(TOUCH_ACTION_PAN_Y);\n }\n if (direction & DIRECTION_VERTICAL) {\n actions.push(TOUCH_ACTION_PAN_X);\n }\n return actions;\n },\n\n directionTest: function(input) {\n var options = this.options;\n var hasMoved = true;\n var distance = input.distance;\n var direction = input.direction;\n var x = input.deltaX;\n var y = input.deltaY;\n\n // lock to axis?\n if (!(direction & options.direction)) {\n if (options.direction & DIRECTION_HORIZONTAL) {\n direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT;\n hasMoved = x != this.pX;\n distance = Math.abs(input.deltaX);\n } else {\n direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN;\n hasMoved = y != this.pY;\n distance = Math.abs(input.deltaY);\n }\n }\n input.direction = direction;\n return hasMoved && distance > options.threshold && direction & options.direction;\n },\n\n attrTest: function(input) {\n return AttrRecognizer.prototype.attrTest.call(this, input) &&\n (this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input)));\n },\n\n emit: function(input) {\n\n this.pX = input.deltaX;\n this.pY = input.deltaY;\n\n var direction = directionStr(input.direction);\n\n if (direction) {\n input.additionalEvent = this.options.event + direction;\n }\n this._super.emit.call(this, input);\n }\n});\n\n/**\n * Pinch\n * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).\n * @constructor\n * @extends AttrRecognizer\n */\nfunction PinchRecognizer() {\n AttrRecognizer.apply(this, arguments);\n}\n\ninherit(PinchRecognizer, AttrRecognizer, {\n /**\n * @namespace\n * @memberof PinchRecognizer\n */\n defaults: {\n event: 'pinch',\n threshold: 0,\n pointers: 2\n },\n\n getTouchAction: function() {\n return [TOUCH_ACTION_NONE];\n },\n\n attrTest: function(input) {\n return this._super.attrTest.call(this, input) &&\n (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);\n },\n\n emit: function(input) {\n if (input.scale !== 1) {\n var inOut = input.scale < 1 ? 'in' : 'out';\n input.additionalEvent = this.options.event + inOut;\n }\n this._super.emit.call(this, input);\n }\n});\n\n/**\n * Press\n * Recognized when the pointer is down for x ms without any movement.\n * @constructor\n * @extends Recognizer\n */\nfunction PressRecognizer() {\n Recognizer.apply(this, arguments);\n\n this._timer = null;\n this._input = null;\n}\n\ninherit(PressRecognizer, Recognizer, {\n /**\n * @namespace\n * @memberof PressRecognizer\n */\n defaults: {\n event: 'press',\n pointers: 1,\n time: 251, // minimal time of the pointer to be pressed\n threshold: 9 // a minimal movement is ok, but keep it low\n },\n\n getTouchAction: function() {\n return [TOUCH_ACTION_AUTO];\n },\n\n process: function(input) {\n var options = this.options;\n var validPointers = input.pointers.length === options.pointers;\n var validMovement = input.distance < options.threshold;\n var validTime = input.deltaTime > options.time;\n\n this._input = input;\n\n // we only allow little movement\n // and we've reached an end event, so a tap is possible\n if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) {\n this.reset();\n } else if (input.eventType & INPUT_START) {\n this.reset();\n this._timer = setTimeoutContext(function() {\n this.state = STATE_RECOGNIZED;\n this.tryEmit();\n }, options.time, this);\n } else if (input.eventType & INPUT_END) {\n return STATE_RECOGNIZED;\n }\n return STATE_FAILED;\n },\n\n reset: function() {\n clearTimeout(this._timer);\n },\n\n emit: function(input) {\n if (this.state !== STATE_RECOGNIZED) {\n return;\n }\n\n if (input && (input.eventType & INPUT_END)) {\n this.manager.emit(this.options.event + 'up', input);\n } else {\n this._input.timeStamp = now();\n this.manager.emit(this.options.event, this._input);\n }\n }\n});\n\n/**\n * Rotate\n * Recognized when two or more pointer are moving in a circular motion.\n * @constructor\n * @extends AttrRecognizer\n */\nfunction RotateRecognizer() {\n AttrRecognizer.apply(this, arguments);\n}\n\ninherit(RotateRecognizer, AttrRecognizer, {\n /**\n * @namespace\n * @memberof RotateRecognizer\n */\n defaults: {\n event: 'rotate',\n threshold: 0,\n pointers: 2\n },\n\n getTouchAction: function() {\n return [TOUCH_ACTION_NONE];\n },\n\n attrTest: function(input) {\n return this._super.attrTest.call(this, input) &&\n (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);\n }\n});\n\n/**\n * Swipe\n * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.\n * @constructor\n * @extends AttrRecognizer\n */\nfunction SwipeRecognizer() {\n AttrRecognizer.apply(this, arguments);\n}\n\ninherit(SwipeRecognizer, AttrRecognizer, {\n /**\n * @namespace\n * @memberof SwipeRecognizer\n */\n defaults: {\n event: 'swipe',\n threshold: 10,\n velocity: 0.3,\n direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,\n pointers: 1\n },\n\n getTouchAction: function() {\n return PanRecognizer.prototype.getTouchAction.call(this);\n },\n\n attrTest: function(input) {\n var direction = this.options.direction;\n var velocity;\n\n if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {\n velocity = input.overallVelocity;\n } else if (direction & DIRECTION_HORIZONTAL) {\n velocity = input.overallVelocityX;\n } else if (direction & DIRECTION_VERTICAL) {\n velocity = input.overallVelocityY;\n }\n\n return this._super.attrTest.call(this, input) &&\n direction & input.offsetDirection &&\n input.distance > this.options.threshold &&\n input.maxPointers == this.options.pointers &&\n abs(velocity) > this.options.velocity && input.eventType & INPUT_END;\n },\n\n emit: function(input) {\n var direction = directionStr(input.offsetDirection);\n if (direction) {\n this.manager.emit(this.options.event + direction, input);\n }\n\n this.manager.emit(this.options.event, input);\n }\n});\n\n/**\n * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur\n * between the given interval and position. The delay option can be used to recognize multi-taps without firing\n * a single tap.\n *\n * The eventData from the emitted event contains the property `tapCount`, which contains the amount of\n * multi-taps being recognized.\n * @constructor\n * @extends Recognizer\n */\nfunction TapRecognizer() {\n Recognizer.apply(this, arguments);\n\n // previous time and center,\n // used for tap counting\n this.pTime = false;\n this.pCenter = false;\n\n this._timer = null;\n this._input = null;\n this.count = 0;\n}\n\ninherit(TapRecognizer, Recognizer, {\n /**\n * @namespace\n * @memberof PinchRecognizer\n */\n defaults: {\n event: 'tap',\n pointers: 1,\n taps: 1,\n interval: 300, // max time between the multi-tap taps\n time: 250, // max time of the pointer to be down (like finger on the screen)\n threshold: 9, // a minimal movement is ok, but keep it low\n posThreshold: 10 // a multi-tap can be a bit off the initial position\n },\n\n getTouchAction: function() {\n return [TOUCH_ACTION_MANIPULATION];\n },\n\n process: function(input) {\n var options = this.options;\n\n var validPointers = input.pointers.length === options.pointers;\n var validMovement = input.distance < options.threshold;\n var validTouchTime = input.deltaTime < options.time;\n\n this.reset();\n\n if ((input.eventType & INPUT_START) && (this.count === 0)) {\n return this.failTimeout();\n }\n\n // we only allow little movement\n // and we've reached an end event, so a tap is possible\n if (validMovement && validTouchTime && validPointers) {\n if (input.eventType != INPUT_END) {\n return this.failTimeout();\n }\n\n var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;\n var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;\n\n this.pTime = input.timeStamp;\n this.pCenter = input.center;\n\n if (!validMultiTap || !validInterval) {\n this.count = 1;\n } else {\n this.count += 1;\n }\n\n this._input = input;\n\n // if tap count matches we have recognized it,\n // else it has began recognizing...\n var tapCount = this.count % options.taps;\n if (tapCount === 0) {\n // no failing requirements, immediately trigger the tap event\n // or wait as long as the multitap interval to trigger\n if (!this.hasRequireFailures()) {\n return STATE_RECOGNIZED;\n } else {\n this._timer = setTimeoutContext(function() {\n this.state = STATE_RECOGNIZED;\n this.tryEmit();\n }, options.interval, this);\n return STATE_BEGAN;\n }\n }\n }\n return STATE_FAILED;\n },\n\n failTimeout: function() {\n this._timer = setTimeoutContext(function() {\n this.state = STATE_FAILED;\n }, this.options.interval, this);\n return STATE_FAILED;\n },\n\n reset: function() {\n clearTimeout(this._timer);\n },\n\n emit: function() {\n if (this.state == STATE_RECOGNIZED) {\n this._input.tapCount = this.count;\n this.manager.emit(this.options.event, this._input);\n }\n }\n});\n\n/**\n * Simple way to create a manager with a default set of recognizers.\n * @param {HTMLElement} element\n * @param {Object} [options]\n * @constructor\n */\nfunction Hammer(element, options) {\n options = options || {};\n options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);\n return new Manager(element, options);\n}\n\n/**\n * @const {string}\n */\nHammer.VERSION = '2.0.7';\n\n/**\n * default settings\n * @namespace\n */\nHammer.defaults = {\n /**\n * set if DOM events are being triggered.\n * But this is slower and unused by simple implementations, so disabled by default.\n * @type {Boolean}\n * @default false\n */\n domEvents: false,\n\n /**\n * The value for the touchAction property/fallback.\n * When set to `compute` it will magically set the correct value based on the added recognizers.\n * @type {String}\n * @default compute\n */\n touchAction: TOUCH_ACTION_COMPUTE,\n\n /**\n * @type {Boolean}\n * @default true\n */\n enable: true,\n\n /**\n * EXPERIMENTAL FEATURE -- can be removed/changed\n * Change the parent input target element.\n * If Null, then it is being set the to main element.\n * @type {Null|EventTarget}\n * @default null\n */\n inputTarget: null,\n\n /**\n * force an input class\n * @type {Null|Function}\n * @default null\n */\n inputClass: null,\n\n /**\n * Default recognizer setup when calling `Hammer()`\n * When creating a new Manager these will be skipped.\n * @type {Array}\n */\n preset: [\n // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]\n [RotateRecognizer, {enable: false}],\n [PinchRecognizer, {enable: false}, ['rotate']],\n [SwipeRecognizer, {direction: DIRECTION_HORIZONTAL}],\n [PanRecognizer, {direction: DIRECTION_HORIZONTAL}, ['swipe']],\n [TapRecognizer],\n [TapRecognizer, {event: 'doubletap', taps: 2}, ['tap']],\n [PressRecognizer]\n ],\n\n /**\n * Some CSS properties can be used to improve the working of Hammer.\n * Add them to this method and they will be set when creating a new Manager.\n * @namespace\n */\n cssProps: {\n /**\n * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.\n * @type {String}\n * @default 'none'\n */\n userSelect: 'none',\n\n /**\n * Disable the Windows Phone grippers when pressing an element.\n * @type {String}\n * @default 'none'\n */\n touchSelect: 'none',\n\n /**\n * Disables the default callout shown when you touch and hold a touch target.\n * On iOS, when you touch and hold a touch target such as a link, Safari displays\n * a callout containing information about the link. This property allows you to disable that callout.\n * @type {String}\n * @default 'none'\n */\n touchCallout: 'none',\n\n /**\n * Specifies whether zooming is enabled. Used by IE10>\n * @type {String}\n * @default 'none'\n */\n contentZooming: 'none',\n\n /**\n * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.\n * @type {String}\n * @default 'none'\n */\n userDrag: 'none',\n\n /**\n * Overrides the highlight color shown when the user taps a link or a JavaScript\n * clickable element in iOS. This property obeys the alpha value, if specified.\n * @type {String}\n * @default 'rgba(0,0,0,0)'\n */\n tapHighlightColor: 'rgba(0,0,0,0)'\n }\n};\n\nvar STOP = 1;\nvar FORCED_STOP = 2;\n\n/**\n * Manager\n * @param {HTMLElement} element\n * @param {Object} [options]\n * @constructor\n */\nfunction Manager(element, options) {\n this.options = assign({}, Hammer.defaults, options || {});\n\n this.options.inputTarget = this.options.inputTarget || element;\n\n this.handlers = {};\n this.session = {};\n this.recognizers = [];\n this.oldCssProps = {};\n\n this.element = element;\n this.input = createInputInstance(this);\n this.touchAction = new TouchAction(this, this.options.touchAction);\n\n toggleCssProps(this, true);\n\n each(this.options.recognizers, function(item) {\n var recognizer = this.add(new (item[0])(item[1]));\n item[2] && recognizer.recognizeWith(item[2]);\n item[3] && recognizer.requireFailure(item[3]);\n }, this);\n}\n\nManager.prototype = {\n /**\n * set options\n * @param {Object} options\n * @returns {Manager}\n */\n set: function(options) {\n assign(this.options, options);\n\n // Options that need a little more setup\n if (options.touchAction) {\n this.touchAction.update();\n }\n if (options.inputTarget) {\n // Clean up existing event listeners and reinitialize\n this.input.destroy();\n this.input.target = options.inputTarget;\n this.input.init();\n }\n return this;\n },\n\n /**\n * stop recognizing for this session.\n * This session will be discarded, when a new [input]start event is fired.\n * When forced, the recognizer cycle is stopped immediately.\n * @param {Boolean} [force]\n */\n stop: function(force) {\n this.session.stopped = force ? FORCED_STOP : STOP;\n },\n\n /**\n * run the recognizers!\n * called by the inputHandler function on every movement of the pointers (touches)\n * it walks through all the recognizers and tries to detect the gesture that is being made\n * @param {Object} inputData\n */\n recognize: function(inputData) {\n var session = this.session;\n if (session.stopped) {\n return;\n }\n\n // run the touch-action polyfill\n this.touchAction.preventDefaults(inputData);\n\n var recognizer;\n var recognizers = this.recognizers;\n\n // this holds the recognizer that is being recognized.\n // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED\n // if no recognizer is detecting a thing, it is set to `null`\n var curRecognizer = session.curRecognizer;\n\n // reset when the last recognizer is recognized\n // or when we're in a new session\n if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {\n curRecognizer = session.curRecognizer = null;\n }\n\n var i = 0;\n while (i < recognizers.length) {\n recognizer = recognizers[i];\n\n // find out if we are allowed try to recognize the input for this one.\n // 1. allow if the session is NOT forced stopped (see the .stop() method)\n // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one\n // that is being recognized.\n // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.\n // this can be setup with the `recognizeWith()` method on the recognizer.\n if (session.stopped !== FORCED_STOP && ( // 1\n !curRecognizer || recognizer == curRecognizer || // 2\n recognizer.canRecognizeWith(curRecognizer))) { // 3\n recognizer.recognize(inputData);\n } else {\n recognizer.reset();\n }\n\n // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the\n // current active recognizer. but only if we don't already have an active recognizer\n if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {\n curRecognizer = session.curRecognizer = recognizer;\n }\n i++;\n }\n },\n\n /**\n * get a recognizer by its event name.\n * @param {Recognizer|String} recognizer\n * @returns {Recognizer|Null}\n */\n get: function(recognizer) {\n if (recognizer instanceof Recognizer) {\n return recognizer;\n }\n\n var recognizers = this.recognizers;\n for (var i = 0; i < recognizers.length; i++) {\n if (recognizers[i].options.event == recognizer) {\n return recognizers[i];\n }\n }\n return null;\n },\n\n /**\n * add a recognizer to the manager\n * existing recognizers with the same event name will be removed\n * @param {Recognizer} recognizer\n * @returns {Recognizer|Manager}\n */\n add: function(recognizer) {\n if (invokeArrayArg(recognizer, 'add', this)) {\n return this;\n }\n\n // remove existing\n var existing = this.get(recognizer.options.event);\n if (existing) {\n this.remove(existing);\n }\n\n this.recognizers.push(recognizer);\n recognizer.manager = this;\n\n this.touchAction.update();\n return recognizer;\n },\n\n /**\n * remove a recognizer by name or instance\n * @param {Recognizer|String} recognizer\n * @returns {Manager}\n */\n remove: function(recognizer) {\n if (invokeArrayArg(recognizer, 'remove', this)) {\n return this;\n }\n\n recognizer = this.get(recognizer);\n\n // let's make sure this recognizer exists\n if (recognizer) {\n var recognizers = this.recognizers;\n var index = inArray(recognizers, recognizer);\n\n if (index !== -1) {\n recognizers.splice(index, 1);\n this.touchAction.update();\n }\n }\n\n return this;\n },\n\n /**\n * bind event\n * @param {String} events\n * @param {Function} handler\n * @returns {EventEmitter} this\n */\n on: function(events, handler) {\n if (events === undefined) {\n return;\n }\n if (handler === undefined) {\n return;\n }\n\n var handlers = this.handlers;\n each(splitStr(events), function(event) {\n handlers[event] = handlers[event] || [];\n handlers[event].push(handler);\n });\n return this;\n },\n\n /**\n * unbind event, leave emit blank to remove all handlers\n * @param {String} events\n * @param {Function} [handler]\n * @returns {EventEmitter} this\n */\n off: function(events, handler) {\n if (events === undefined) {\n return;\n }\n\n var handlers = this.handlers;\n each(splitStr(events), function(event) {\n if (!handler) {\n delete handlers[event];\n } else {\n handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);\n }\n });\n return this;\n },\n\n /**\n * emit event to the listeners\n * @param {String} event\n * @param {Object} data\n */\n emit: function(event, data) {\n // we also want to trigger dom events\n if (this.options.domEvents) {\n triggerDomEvent(event, data);\n }\n\n // no handlers, so skip it all\n var handlers = this.handlers[event] && this.handlers[event].slice();\n if (!handlers || !handlers.length) {\n return;\n }\n\n data.type = event;\n data.preventDefault = function() {\n data.srcEvent.preventDefault();\n };\n\n var i = 0;\n while (i < handlers.length) {\n handlers[i](data);\n i++;\n }\n },\n\n /**\n * destroy the manager and unbinds all events\n * it doesn't unbind dom events, that is the user own responsibility\n */\n destroy: function() {\n this.element && toggleCssProps(this, false);\n\n this.handlers = {};\n this.session = {};\n this.input.destroy();\n this.element = null;\n }\n};\n\n/**\n * add/remove the css properties as defined in manager.options.cssProps\n * @param {Manager} manager\n * @param {Boolean} add\n */\nfunction toggleCssProps(manager, add) {\n var element = manager.element;\n if (!element.style) {\n return;\n }\n var prop;\n each(manager.options.cssProps, function(value, name) {\n prop = prefixed(element.style, name);\n if (add) {\n manager.oldCssProps[prop] = element.style[prop];\n element.style[prop] = value;\n } else {\n element.style[prop] = manager.oldCssProps[prop] || '';\n }\n });\n if (!add) {\n manager.oldCssProps = {};\n }\n}\n\n/**\n * trigger dom event\n * @param {String} event\n * @param {Object} data\n */\nfunction triggerDomEvent(event, data) {\n var gestureEvent = document.createEvent('Event');\n gestureEvent.initEvent(event, true, true);\n gestureEvent.gesture = data;\n data.target.dispatchEvent(gestureEvent);\n}\n\nassign(Hammer, {\n INPUT_START: INPUT_START,\n INPUT_MOVE: INPUT_MOVE,\n INPUT_END: INPUT_END,\n INPUT_CANCEL: INPUT_CANCEL,\n\n STATE_POSSIBLE: STATE_POSSIBLE,\n STATE_BEGAN: STATE_BEGAN,\n STATE_CHANGED: STATE_CHANGED,\n STATE_ENDED: STATE_ENDED,\n STATE_RECOGNIZED: STATE_RECOGNIZED,\n STATE_CANCELLED: STATE_CANCELLED,\n STATE_FAILED: STATE_FAILED,\n\n DIRECTION_NONE: DIRECTION_NONE,\n DIRECTION_LEFT: DIRECTION_LEFT,\n DIRECTION_RIGHT: DIRECTION_RIGHT,\n DIRECTION_UP: DIRECTION_UP,\n DIRECTION_DOWN: DIRECTION_DOWN,\n DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,\n DIRECTION_VERTICAL: DIRECTION_VERTICAL,\n DIRECTION_ALL: DIRECTION_ALL,\n\n Manager: Manager,\n Input: Input,\n TouchAction: TouchAction,\n\n TouchInput: TouchInput,\n MouseInput: MouseInput,\n PointerEventInput: PointerEventInput,\n TouchMouseInput: TouchMouseInput,\n SingleTouchInput: SingleTouchInput,\n\n Recognizer: Recognizer,\n AttrRecognizer: AttrRecognizer,\n Tap: TapRecognizer,\n Pan: PanRecognizer,\n Swipe: SwipeRecognizer,\n Pinch: PinchRecognizer,\n Rotate: RotateRecognizer,\n Press: PressRecognizer,\n\n on: addEventListeners,\n off: removeEventListeners,\n each: each,\n merge: merge,\n extend: extend,\n assign: assign,\n inherit: inherit,\n bindFn: bindFn,\n prefixed: prefixed\n});\n\n// this prevents errors when Hammer is loaded in the presence of an AMD\n// style loader but by script tag, not by the loader.\nvar freeGlobal = (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {})); // jshint ignore:line\nfreeGlobal.Hammer = Hammer;\n\nif (typeof define === 'function' && define.amd) {\n define(function() {\n return Hammer;\n });\n} else if (typeof module != 'undefined' && module.exports) {\n module.exports = Hammer;\n} else {\n window[exportName] = Hammer;\n}\n\n})(window, document, 'Hammer');\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar timeout_1 = require(\"./lib/timeout\");\nmodule.exports = timeout_1.Timeout;\n//# sourceMappingURL=index.js.map\n","\"use strict\";\nvar __spreadArrays = (this && this.__spreadArrays) || function () {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar MetadataRecord = /** @class */ (function () {\n function MetadataRecord(callback, key, ms, params) {\n this.callback = callback;\n this.key = key;\n this.ms = ms;\n this.params = params;\n this.paused = false;\n this.startTime = new Date().getTime();\n this.timeSpentWaiting = 0;\n }\n return MetadataRecord;\n}());\nvar Timeout = /** @class */ (function () {\n function Timeout() {\n }\n /**\n * clear timeout and optionally erase all knowledge of its existence\n * @param key\n * @param erase\n */\n Timeout.clear = function (key, erase) {\n if (erase === void 0) { erase = true; }\n clearTimeout(Timeout.keyId[key]);\n delete Timeout.keyId[key];\n delete Timeout.keyCall[key];\n if (erase) {\n delete Timeout.metadata[key];\n delete Timeout.originalMs[key];\n }\n };\n Timeout.set = function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n var key;\n var ms;\n var params;\n var callback;\n if (args.length === 0) {\n throw Error('Timeout.set() requires at least one argument');\n }\n if (typeof args[1] === 'function') {\n key = args[0], callback = args[1], ms = args[2], params = args.slice(3);\n }\n else {\n callback = args[0], ms = args[1], params = args.slice(2);\n key = callback.toString();\n }\n if (!callback) {\n throw Error('Timeout.set() requires a callback parameter');\n }\n Timeout.clear(key);\n var invoke = function () {\n Timeout.metadata[key].executedTime = new Date().getTime();\n callback.apply(void 0, params);\n };\n Timeout.keyId[key] = setTimeout(invoke, ms || 0);\n Timeout.keyCall[key] = function () { return callback.apply(void 0, params); };\n Timeout.originalMs[key] = Timeout.originalMs[key] || ms;\n Timeout.metadata[key] = new MetadataRecord(callback, key, ms, params);\n return function () { return Timeout.executed(key); };\n };\n Timeout.create = function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n if (args.length === 0) {\n throw Error('Timeout.create() requires at least one argument');\n }\n var key;\n if (typeof args[1] === 'function') {\n key = args[0];\n }\n else {\n var callback = args[0];\n key = callback.toString();\n }\n return Timeout.exists(key) ? false : Timeout.set.apply(Timeout, args);\n };\n /**\n * elapsed time since the timeout was created\n * @param key\n */\n Timeout.elapsed = function (key) {\n var metaDataRecord = Timeout.metadata[key];\n if (!metaDataRecord)\n return 0;\n return Math.max(0, new Date().getTime() - metaDataRecord.startTime);\n };\n /**\n * timeout has been created\n * @param key\n */\n Timeout.exists = function (key) {\n return key in Timeout.keyId || (Timeout.metadata)[key] !== undefined;\n };\n /**\n * fire the callback on demand, without affecting the timeout or meta data (execution time)\n * @param key\n * @returns {(false|any)} false if timeout does not exist or the return value of the callback\n */\n Timeout.call = function (key) {\n return Timeout.exists(key) && (Timeout.keyCall)[key]();\n };\n /**\n * test if a timeout has run\n * @param key\n */\n Timeout.executed = function (key) {\n return Timeout.exists(key) && !!Timeout.metadata[key].executedTime;\n };\n /**\n * when timeout was last executed\n * @param key\n */\n Timeout.lastExecuted = function (key) {\n return !Timeout.executed(key)\n ? null\n : new Date(Timeout.metadata[key].executedTime);\n };\n /**\n * metadata about a timeout\n * @param key\n */\n Timeout.meta = function (key) {\n return Timeout.metadata[key];\n };\n /**\n * timeout does exist, but has not yet run\n * @param key\n */\n Timeout.pending = function (key) {\n return Timeout.exists(key) && !Timeout.executed(key);\n };\n /**\n * timeout does exist, but will not execute because it is paused\n * @param key\n */\n Timeout.paused = function (key) {\n return Timeout.exists(key)\n && !Timeout.executed(key)\n && Timeout.metadata[key].paused;\n };\n /**\n * remaining time until timeout will occur\n * @param key\n */\n Timeout.remaining = function (key) {\n if (!Timeout.metadata[key])\n return 0;\n var metaDataRecord = Timeout.metadata[key];\n return Timeout.paused(key)\n ? metaDataRecord.ms - metaDataRecord.timeSpentWaiting\n : Math.max(0, metaDataRecord.startTime + metaDataRecord.ms - new Date().getTime());\n };\n /**\n * set timeout anew, optionally with new time and params\n * @param key\n * @param ms new millisecs before execution\n * @param params new parameters to callback\n */\n Timeout.reset = function (key, ms) {\n var params = [];\n for (var _i = 2; _i < arguments.length; _i++) {\n params[_i - 2] = arguments[_i];\n }\n var metaDataRecord = Timeout.metadata[key];\n if (!metaDataRecord)\n return false;\n Timeout.clear(key, false);\n if (metaDataRecord.paused) {\n metaDataRecord.paused = false;\n }\n return Timeout.set.apply(Timeout, __spreadArrays([key,\n metaDataRecord.callback, ms !== null && ms !== void 0 ? ms : Timeout.originalMs[key]], (params || metaDataRecord.params)));\n };\n /**\n * restart timeout with original time\n * @param key\n * @param force restart even even if not yet executed\n */\n Timeout.restart = function (key, force) {\n if (force === void 0) { force = false; }\n if (!Timeout.metadata[key] || (!force && Timeout.executed(key)))\n return false;\n var metaDataRecord = Timeout.metadata[key];\n Timeout.clear(key, false);\n if (metaDataRecord.paused) {\n metaDataRecord.paused = false;\n }\n return Timeout.set.apply(Timeout, __spreadArrays([key, metaDataRecord.callback, Timeout.originalMs[key]], metaDataRecord.params));\n };\n /**\n * pause our execution countdown until we're ready for it to resume\n * @param key\n */\n Timeout.pause = function (key) {\n if (!Timeout.metadata[key] || Timeout.paused(key) || Timeout.executed(key))\n return false;\n Timeout.clear(key, false);\n var metaDataRecord = Timeout.metadata[key];\n metaDataRecord.paused = true;\n metaDataRecord.timeSpentWaiting = new Date().getTime() - metaDataRecord.startTime;\n return metaDataRecord.timeSpentWaiting;\n };\n /**\n * resume paused Timeout with the remaining time\n * @param key\n */\n Timeout.resume = function (key) {\n if (!Timeout.metadata[key] || Timeout.executed(key))\n return false;\n var metaDataRecord = Timeout.metadata[key];\n if (!metaDataRecord.paused)\n return false;\n var originalMs = Timeout.originalMs[key];\n var remainingTime = metaDataRecord.ms - metaDataRecord.timeSpentWaiting;\n var result = Timeout.set.apply(Timeout, __spreadArrays([key, metaDataRecord.callback, remainingTime], metaDataRecord.params));\n Timeout.originalMs[key] = originalMs;\n return result;\n };\n Timeout.instantiate = function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n var key;\n var ms;\n var params;\n var callback;\n if (args.length === 0) {\n throw Error('Timeout.set() requires at least one argument');\n }\n var linkToExisting = args.length === 1 && typeof args[0] !== 'function';\n // hooking up to an existing timeout\n if (linkToExisting) {\n key = args[0];\n var metadata = Timeout.meta(key);\n if (!metadata) {\n throw Error('Timeout.instantiate() attempted to link to nonexistent object by key');\n }\n ms = metadata.ms;\n params = metadata.params;\n callback = metadata.callback;\n }\n else if (typeof args[1] === 'function') {\n key = args[0], callback = args[1], ms = args[2], params = args.slice(3);\n }\n else {\n callback = args[0], ms = args[1], params = args.slice(2);\n key = (\"\" + Math.random() + callback).replace(/\\s/g, '');\n }\n if (!callback) {\n throw Error('Timeout.instantiate() requires a function parameter');\n }\n if (!linkToExisting) {\n Timeout.set.apply(Timeout, __spreadArrays([key, callback, ms], params));\n }\n return {\n call: function () { return Timeout.call(key); },\n clear: function (erase) {\n if (erase === void 0) { erase = true; }\n return Timeout.clear(key, erase);\n },\n elapsed: function () { return Timeout.elapsed(key); },\n executed: function () { return Timeout.executed(key); },\n exists: function () { return Timeout.exists(key); },\n lastExecuted: function () { return Timeout.lastExecuted(key); },\n meta: function () { return Timeout.meta(key); },\n pause: function () { return Timeout.pause(key); },\n paused: function () { return Timeout.paused(key); },\n pending: function () { return Timeout.pending(key); },\n remaining: function () { return Timeout.remaining(key); },\n reset: function (ms) {\n var params = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n params[_i - 1] = arguments[_i];\n }\n return Timeout.reset.apply(Timeout, __spreadArrays([key, ms], params));\n },\n restart: function () { return Timeout.restart(key); },\n resume: function () { return Timeout.resume(key); },\n set: function (newCallback, newMs) {\n if (newMs === void 0) { newMs = 0; }\n var newParams = [];\n for (var _i = 2; _i < arguments.length; _i++) {\n newParams[_i - 2] = arguments[_i];\n }\n return Timeout.set.apply(Timeout, __spreadArrays([key, newCallback, newMs], newParams));\n },\n };\n };\n Timeout.keyId = {};\n Timeout.keyCall = {};\n Timeout.originalMs = {};\n Timeout.metadata = {};\n return Timeout;\n}());\nexports.Timeout = Timeout;\n//# sourceMappingURL=timeout.js.map","import { MPCIFlyoutContentController } from \"../typings/iFlyoutContentController\";\nimport { MPCDeviceDetectionHelper } from \"../helpers/deviceDetectionHelper\";\nimport { MPCScrollLock } from \"../helpers/scrollLock\";\nconst SmartTimeout = require(\"smart-timeout\");\nconst ArrowRightIcon = require(\"../../images/arrow-right.svg\") as string;\n\nexport module MPCNotificationService {\n import IFlyoutContentController = MPCIFlyoutContentController.IFlyoutContentController;\n import DeviceDetectionHelper = MPCDeviceDetectionHelper.DeviceDetectionHelper;\n import ScrollLock = MPCScrollLock.ScrollLock;\n\n export class NotificationService {\n private readonly scope: HTMLElement;\n public flyoutContentController: IFlyoutContentController;\n private static _instance: NotificationService;\n private existingNotificationTimeout: any;\n private deviceDetectionHelper : DeviceDetectionHelper;\n private flyoutContainer: HTMLElement;\n private scrollLock: ScrollLock;\n\n private maxProductsCountNotification: HTMLElement;\n private newProductNotification: HTMLElement;\n private emptyListNotification: HTMLElement;\n private flyoutIconContainer: HTMLElement;\n\n static get instance() {\n return this._instance || (this._instance = new this());\n }\n\n constructor() {\n this.scope = document.querySelector('.pcf-scope');\n\n if(this.scope)\n {\n this.init();\n }\n }\n \n private init(): void {\n this.deviceDetectionHelper = DeviceDetectionHelper.instance;\n this.scrollLock = ScrollLock.instance;\n this.flyoutContainer = this.scope.querySelector('.flyout-container');\n const notifications = this.flyoutContainer.querySelectorAll(\".notification\");\n\n for (let notification of notifications) {\n const closeBtns = notification.querySelectorAll('.close-flyout-btn'); //multiple because there is the x for Web and the footer button for Mobile\n const openFlyoutBtns = notification.querySelectorAll('.open-flyout-button');//multiple because \"new-product' has two (Web has a compact layout without footer)\n const navigationBtn = notification.querySelector('.navigate-to-products-button');\n\n for (let comparisonListButton of openFlyoutBtns) {\n const iconSlot: HTMLElement = comparisonListButton.querySelector('.open-flyout-button-icon');\n iconSlot.innerHTML = ArrowRightIcon;\n comparisonListButton.addEventListener('click', ()=> { this.goToFlyoutComparisonList(notification); });\n }\n\n for (let closeBtn of closeBtns) {\n closeBtn.addEventListener('click', () => { this.closeNotification(notification); });\n }\n\n if (navigationBtn != null) {\n const iconSlot: HTMLElement = navigationBtn.querySelector('.navigate-products-button-icon');\n iconSlot.innerHTML = ArrowRightIcon;\n }\n }\n \n this.maxProductsCountNotification = this.scope.querySelector('.max-products-count-notification');\n this.newProductNotification = this.scope.querySelector('.new-product-notification');\n this.emptyListNotification = this.scope.querySelector('.empty-list-notification');\n this.flyoutIconContainer = this.scope.querySelector('.flyout-icon-container');\n\n // close any active notification flyout if any other flyout is opening from headR:\n // we need it because notification flyouts are not fragments and headR is not responsible for them\n window.shell.subscribeTo('ESMKT.HeadR.FlyoutOpening', () => { this.closeAnyActiveNotification(); }, 'ESMKT.HeadR.FlyoutOpening');\n }\n\n notifyNewProductAdded(title: string, mainImage: string, altTag: string): void {\n this.showNotification(this.newProductNotification, () => {\n this.replaceNotificationContent(title, mainImage, altTag);\n });\n }\n \n notifyMaximumProductsCountReached(): void {\n this.showNotification(this.maxProductsCountNotification, null);\n }\n\n notifyEmptyList(): void {\n this.initializeNavigationButtonOnEmptyNotificationOnce(); //Workaround because this class exists twice (PCF & PCP)\n this.showNotification(this.emptyListNotification, null);\n }\n\n closeAnyActiveNotification(): void {\n if (this.maxProductsCountNotification.classList.contains('show-notification'))\n this.closeNotification(this.maxProductsCountNotification);\n\n if (this.newProductNotification.classList.contains('show-notification'))\n this.closeNotification(this.newProductNotification);\n \n if (this.emptyListNotification.classList.contains('show-notification'))\n this.closeNotification(this.emptyListNotification);\n }\n\n private initializeNavigationButtonOnEmptyNotificationOnce(): void {\n const navigationBtn = this.emptyListNotification.querySelector('.navigate-to-products-button');\n\n const eventFunction: EventListener = () => {\n this.showMobileHeaderMenu();\n this.closeNotification(this.emptyListNotification);\n navigationBtn.removeEventListener('click', eventFunction);\n }\n\n if (navigationBtn != null && window.headrapi)\n navigationBtn.addEventListener('click', eventFunction);\n }\n\n private showMobileHeaderMenu(): void {\n if (window.headrapi)\n window.headrapi.toggleMenu();\n }\n\n private replaceNotificationContent(title: string, mainImage: string, altTag: string): void {\n const productInfoContainer: HTMLElement\n = this.newProductNotification.querySelector('.product-info-container');\n\n productInfoContainer.querySelector('.description-container')\n .querySelector('.title').innerHTML = title;\n productInfoContainer.querySelector('.image-slot').setAttribute('src', mainImage);\n productInfoContainer.querySelector('.image-slot').setAttribute('alt', altTag);\n }\n\n private goToFlyoutComparisonList(notification: HTMLElement): void {\n this.closeNotification(notification);\n\n window.shell.publishTo('ESMKT.HeadR.ToggleFlyout', 'ManualProductComparison');\n }\n\n private closeExistingNotification(): void {\n const existingNotification: HTMLElement = this.flyoutContainer.querySelector('.show-notification');\n\n if (existingNotification) {\n SmartTimeout.clear(this.closeExistingNotification);\n existingNotification.classList.remove('show-notification');\n this.renderFlyoutContainerOverlay(false);\n }\n }\n\n private closeNotification(notification: HTMLElement): void {\n SmartTimeout.clear(this.closeExistingNotification);\n notification.classList.remove('show-notification');\n this.flyoutIconContainer.classList.remove('notification_background');\n this.renderFlyoutContainerOverlay(false);\n }\n\n private showNotification(notification: HTMLElement, updateNotificationContent?: () => void): void {\n this.triggerAppShellPublish();\n\n // on category page, you can click many compare buttons fast, so check for older notification\n let deferNotification = false;\n if (this.existingNotificationTimeout ||\n notification.classList.contains('show-notification')) {\n this.closeExistingNotification();\n deferNotification = true;\n } \n\n let showInner = () => {\n if (this.flyoutContentController)\n this.flyoutContentController.hideFlyoutContent();\n\n if (updateNotificationContent)\n updateNotificationContent();\n\n this.renderFlyoutContainerOverlay(true);\n\n notification.classList.add('show-notification');\n this.flyoutIconContainer.classList.add('notification_background');\n\n if (!this.deviceDetectionHelper.isMobileShop()) {\n // close new product notification after 4500 ms\n this.existingNotificationTimeout =\n SmartTimeout.set(() => { this.closeNotification(notification) }, 4500);\n }\n };\n\n if(deferNotification)\n SmartTimeout.set(showInner, 500);\n else \n showInner();\n }\n\n private triggerAppShellPublish(): void {\n // close modal dialogs in legacy WF\n if (window.shell) {\n window.shell.publishTo('mpc.close-modal', '');\n window.shell.publishTo('ESPP.OrderModal.Close', '');\n }\n }\n\n private renderFlyoutContainerOverlay(renderOverlay: boolean): void {\n if(this.deviceDetectionHelper.isMobileShop()) {\n if(renderOverlay) {\n this.scope.classList.add('render-overlay');\n this.scope.ontouchmove = (event: TouchEvent) => { event.preventDefault(); }; // iOS ScrollLock\n this.scrollLock.lock();\n }\n else {\n if(this.scope.classList.contains('render-overlay')) {\n this.scope.classList.remove('render-overlay');\n this.scope.ontouchmove = () => { };\n this.scrollLock.unlock();\n }\n }\n }\n }\n\n }\n}","import { MPCIOrderModalPayload } from \"../typings/iOrderModalPayload\";\nimport { MPCLocalStorageService } from \"../../local-storage-service\";\nimport { MPCNotificationService } from \"../../PCF/notification-service\";\nimport { MPCDeviceDetectionHelper } from \"../../helpers/deviceDetectionHelper\";\n\nexport module MPCColumnHeader {\n import OrderModalPayload = MPCIOrderModalPayload.IOrderModalPayload;\n import ProductComparisonModelManager = MPCLocalStorageService.ProductComparisonModelManager;\n import NotificationService = MPCNotificationService.NotificationService;\n import DeviceDetectionHelper = MPCDeviceDetectionHelper.DeviceDetectionHelper;\n\n export class ColumnHeader {\n private header: HTMLElement;\n private grid: HTMLElement;\n private recycleBtn: HTMLElement;\n private orderModalBtn: HTMLElement;\n private emptyHeaderContainer: HTMLElement;\n private productComparisonModelManager: ProductComparisonModelManager;\n private notificationService: NotificationService;\n private deviceDetectionHelper: DeviceDetectionHelper;\n private categoryName: string;\n private navigationOrder: number;\n\n public init(header: HTMLElement, grid: HTMLElement, lastColumn: boolean, firstColumn: boolean): void {\n this.header = header;\n this.grid = grid;\n this.productComparisonModelManager = ProductComparisonModelManager.instance;\n this.notificationService = NotificationService.instance;\n this.deviceDetectionHelper = DeviceDetectionHelper.instance;\n this.categoryName = this.grid.getAttribute('data-pcp-navigation-key');\n this.navigationOrder = Number(this.grid.getAttribute('data-navigation-order'));\n\n if(firstColumn)\n this.header.classList.add('first-column');\n\n if(lastColumn)\n this.header.classList.add('last-column');\n\n this.handleEmptyContainer = this.handleEmptyContainer.bind(this);\n\n this.registerEvents();\n }\n\n private registerEvents(): void {\n const imageContainer = this.header.querySelector('.image-container');\n this.recycleBtn = this.header.querySelector('.mpc-recycle');\n this.orderModalBtn = this.header.querySelector('.order-modal-button');\n this.emptyHeaderContainer = this.header.querySelector('.empty-header');\n \n if (imageContainer) {\n imageContainer.addEventListener('keydown', (event: any) => {\n // prevent page jump down on Space btn., click\n if (event.code === 'Space')\n event.preventDefault(); \n });\n }\n\n if (this.recycleBtn) {\n this.recycleBtn.addEventListener('click', () => { this.handleRecycleBtnClick(); });\n\n this.recycleBtn.addEventListener('keydown', (event: any) => {\n // prevent page jump down on Space btn., click\n if (event.code === 'Space')\n event.preventDefault(); \n });\n }\n\n if (this.orderModalBtn) {\n this.orderModalBtn.addEventListener('click', () => { this.setupOrderModalEvent(); });\n\n this.orderModalBtn.addEventListener('keydown', (event: any) => {\n // prevent page jump down on Space btn., click\n if (event.code === 'Space')\n event.preventDefault();\n });\n }\n\n if (this.emptyHeaderContainer) {\n this.emptyHeaderContainer.addEventListener('click', this.handleEmptyContainer);\n }\n }\n\n private setupOrderModalEvent() {\n const splittedSavKey: string[] = this.header.getAttribute('data-savKey').split('-');\n\n const orderModalPayload: OrderModalPayload = {\n salesArticleNo: splittedSavKey[0],\n masterArticleNo: parseInt(this.header.getAttribute('data-masterArticle')),\n colorCode: splittedSavKey.length >= 2 ? parseInt(splittedSavKey[1]) : null,\n sizeCode: splittedSavKey.length >= 3 ? parseInt(splittedSavKey[2]) : null,\n itemOrigin: 'productcomparison',\n };\n\n if (window.shell)\n window.shell.publishTo('ESPP.OrderModal.Open', orderModalPayload);\n }\n\n private handleRecycleBtnClick(): void {\n // collect all column rows and clear them:\n const columnId: string = this.header.getAttribute('data-savKey');\n\n // prepare new url:\n let currentUrl: string = window.location.href;\n const urlParam: string = '&savKeys=' + columnId;\n currentUrl = currentUrl.replace(urlParam, '');\n\n // clear local storage:\n this.productComparisonModelManager.removeProduct(this.categoryName, columnId);\n\n // look for existing savKeys, if it was the last one update active tab in flyout.\n const savKeysExists: number = currentUrl.indexOf('&savKeys');\n\n // store this tab in local storage like empty:\n if (savKeysExists <= 0) {\n this.productComparisonModelManager.storeEmptyNavigationTab(this.categoryName, this.navigationOrder);\n\n this.productComparisonModelManager.getModel().then(model => {\n var hasProducts = model.products.length > 0;\n if (hasProducts) {\n this.productComparisonModelManager.setActiveNavigationTab(model.products[0].categoryName);\n }\n });\n }\n\n // clear locked column info:\n if (this.deviceDetectionHelper.isMobileShop()) {\n this.productComparisonModelManager.clearLockedColumnIndex();\n }\n\n // refresh page with new url:\n location.replace(currentUrl);\n }\n\n private handleEmptyContainer(event: any): void {\n if(this.deviceDetectionHelper.isMobileShop()) {\n event.preventDefault();\n\n this.productComparisonModelManager.getModel().then(model => {\n var hasProducts = model.products.length > 0;\n if (!hasProducts) {\n this.notificationService.notifyEmptyList();\n } else {\n window.location.href = this.emptyHeaderContainer.getAttribute('href');\n }\n });\n }\n }\n }\n}","import { MPCLocalStorageService } from \"../../local-storage-service\";\r\nimport { Product } from \"../../../../Models/Product.generated\";\r\n\r\nexport module MPCColorsField {\r\n import ProductComparisonModelManager = MPCLocalStorageService.ProductComparisonModelManager;\r\n\r\n export class ColorsField {\r\n private colors: HTMLElement;\r\n private productComparisonModelManager: ProductComparisonModelManager;\r\n private selectedColorSavKey: string;\r\n private categoryName: string;\r\n\r\n public init(colorContainer: HTMLElement, categoryName: string): void {\r\n this.colors = colorContainer;\r\n this.productComparisonModelManager = ProductComparisonModelManager.instance;\r\n this.categoryName = categoryName;\r\n\r\n this.registerEvents();\r\n }\r\n\r\n private registerEvents(): void {\r\n const colors: NodeListOf = this.colors.querySelectorAll('.color-container');\r\n const colorsArray: Array = Array.prototype.slice.call(colors);\r\n\r\n for (const color of colorsArray) {\r\n const savKey: string = color.getAttribute('data-salesarticlevariantkey');\r\n const colorIcon: HTMLElement = color.querySelector('.color-icon');\r\n colorIcon.addEventListener('click', ()=>{this.changeProductVariant(savKey);});\r\n\r\n color.addEventListener('keydown', (event: any) => {\r\n // prevent page jump down on Space btn., click\r\n if (event.code === 'Space') {\r\n event.preventDefault(); \r\n this.changeProductVariant(savKey);\r\n }\r\n\r\n if (event.code === 'Enter') {\r\n this.changeProductVariant(savKey);\r\n }\r\n\r\n if(!window.shell.tabNav)\r\n return;\r\n \r\n if (event.code === 'ArrowRight' && event.target.nextElementSibling) {\r\n window.shell.tabNav.focus(event.target.nextElementSibling);\r\n }\r\n \r\n if (event.code === 'ArrowLeft' && event.target.previousElementSibling) {\r\n window.shell.tabNav.focus(event.target.previousElementSibling);\r\n }\r\n });\r\n\r\n\r\n if(colorIcon.classList.contains('selectedColor')) {\r\n this.selectedColorSavKey = savKey\r\n }\r\n }\r\n }\r\n\r\n public colorsContent(): string {\r\n const colors: NodeListOf = this.colors.querySelectorAll('.color-container');\r\n const colorsArray: Array = Array.prototype.slice.call(colors);\r\n const colorCodes = colorsArray.map(x => x.getAttribute('data-colorcode'));\r\n const colorCodesJoined = colorCodes.join();\r\n return colorCodesJoined;\r\n }\r\n\r\n private async changeProductVariant(savKey: string): Promise {\r\n // prepare new url:\r\n let currentUrl: string = window.location.href;\r\n\r\n // prepare new url:\r\n currentUrl = currentUrl.replace(this.selectedColorSavKey, savKey);\r\n\r\n // remove old product from local storage:\r\n const removed: Product = this.productComparisonModelManager.removeProduct(this.categoryName, this.selectedColorSavKey);\r\n\r\n const origin = removed ? removed.origin : \"Deeplink\";\r\n const originNavigationKeyPath = removed ? removed.originNavigationKeyPath : undefined;\r\n\r\n // add new one:\r\n const productAdded = await this.productComparisonModelManager.addProductBySavKey(savKey, \"Unknown\", origin, \r\n originNavigationKeyPath);\r\n\r\n if(productAdded)\r\n // refresh page with new url:\r\n location.replace(currentUrl);\r\n }\r\n }\r\n}","import { MPCIGridRow } from \"../typings/iGridRow\";\nimport { MPCEventBus } from \"../../helpers/event-bus\";\nimport { MPCDeviceDetectionHelper } from \"../../helpers/deviceDetectionHelper\";\nimport { MPCGridController } from \"../grid-controller\";\nconst ArrowUpIcon = require(\"../../../images/arrow-up.svg\") as string;\nconst Checkbox = require(\"../../../images/checkbox.svg\") as string;\n\nexport module MPCControlsRow {\n import IGridRow = MPCIGridRow.IGridRow;\n import EventBus = MPCEventBus.EventBus;\n import DeviceDetectionHelper = MPCDeviceDetectionHelper.DeviceDetectionHelper;\n import GridController = MPCGridController.GridController;\n\n export class ControlsRow {\n private readonly overlayDelay: number = 1000;\n\n private gridRowsArray: Array;\n private collapseAll: boolean;\n private identicalPropertiesHidden: boolean;\n private eventBus: EventBus;\n private deviceDetectionHelper: DeviceDetectionHelper;\n private arrowUp: HTMLElement;\n private filterOnlyDifferencesBtn: HTMLElement;\n private filterOnlyDifferencesCheckBox: HTMLElement;\n private collapseAllTitle: HTMLElement;\n private expandAllTitle: HTMLElement;\n private gridController: GridController;\n private overlay: HTMLElement;\n private collapseAllBtn: HTMLElement\n private firstColumnHeader: HTMLElement;\n\n public init(controlsRow: HTMLElement, gridRowsArray: Array, emptyColumnsAmount: number,\n gridController: GridController, firstColumnHeader: HTMLElement): void {\n this.gridRowsArray = gridRowsArray;\n this.gridController = gridController;\n this.firstColumnHeader = firstColumnHeader;\n this.collapseAll = true;\n this.eventBus = MPCEventBus.EventBus.instance;\n this.deviceDetectionHelper = MPCDeviceDetectionHelper.DeviceDetectionHelper.instance;\n this.eventBus.subscribe('filter-row.is-expanded', (oneRowExpanded: boolean) => { this.updateCollapseAllButtonState(oneRowExpanded) });\n this.filterOnlyDifferencesBtn = controlsRow.querySelector('.filter-only-differences');\n this.filterOnlyDifferencesCheckBox = this.filterOnlyDifferencesBtn.querySelector('.only-diff-chb');\n this.filterOnlyDifferencesCheckBox.innerHTML = Checkbox;\n\n this.overlay = gridController.gridHtmlElement().querySelector('.mpc-loading-overlay');\n\n this.collapseAllBtn = controlsRow.querySelector('.collapse-all');\n this.arrowUp = this.collapseAllBtn.querySelector('.mpc-arrow-up');\n this.arrowUp.innerHTML = ArrowUpIcon;\n\n this.collapseAllTitle = this.collapseAllBtn.querySelector('.collapse-all-title');\n this.expandAllTitle = this.collapseAllBtn.querySelector('.expand-all-title');\n this.collapseAllBtn.addEventListener('click', () => { this.handleCollapseAllClick(); });\n this.collapseAllBtn.addEventListener('keydown', (event: any) => {\n // prevent page jump down on Space btn., click\n if (event.code === 'Space')\n event.preventDefault(); \n });\n\n this.filterOnlyDifferencesBtn.addEventListener('keydown', (event: any) => {\n // prevent page jump down on Space btn., click\n if (event.code === 'Space')\n event.preventDefault(); \n });\n\n this.disableControlButtons(emptyColumnsAmount);\n }\n\n private disableControlButtons(emptyColumnsAmount: number): void {\n if (emptyColumnsAmount >= 3) {\n this.filterOnlyDifferencesBtn.classList.add('disable-diff-btn');\n this.filterOnlyDifferencesCheckBox.classList.add('disable-diff-chb');\n\n // expand collapse button should be disabled only there is no articles in comparison list:\n if (emptyColumnsAmount === 4 )\n this.collapseAllBtn.classList.add('disable-hide-all-btn');\n }\n else {\n // Check does the all grid rows has the same values:\n let allRowValuesAreEqual: boolean = true;\n for (const gridRow of this.gridRowsArray) {\n if (!gridRow.getRowValuesAreEqual()) {\n allRowValuesAreEqual = false;\n break;\n }\n } \n\n if (allRowValuesAreEqual) {\n this.filterOnlyDifferencesBtn.classList.add('disable-diff-btn');\n this.filterOnlyDifferencesCheckBox.classList.add('disable-diff-chb');\n }\n else {\n this.filterOnlyDifferencesBtn.addEventListener('click', () => { \n // this.calculateOverlayHeight(); \n this.handleFilterOnlyDifferencesBtnClick(); \n });\n }\n }\n }\n\n private handleCollapseAllClick(): void {\n const isSlowBrowser: boolean = this.deviceDetectionHelper.isMicrosoftBrowser();\n this.arrowUp.classList.toggle('rotate-arrow');\n this.collapseAllTitle.classList.toggle('show');\n this.expandAllTitle.classList.toggle('show');\n\n for (const gridRow of this.gridRowsArray) {\n gridRow.triggerCollapseExpandRow(this.collapseAll, isSlowBrowser);\n }\n\n this.collapseAll = !this.collapseAll;\n }\n\n async handleFilterOnlyDifferencesBtnClick() {\n if (this.identicalPropertiesHidden) {\n this.filterOnlyDifferencesCheckBox.classList.remove('only-diff-chb-checked');\n } else {\n this.filterOnlyDifferencesCheckBox.classList.add('only-diff-chb-checked');\n }\n\n this.loadingSpinner(true);\n const hidingFinished = await this.hideIdenticalProperties();\n\n if (hidingFinished) {\n this.gridController.setFirstAndLastClass();\n this.loadingSpinner(false);\n }\n }\n\n private loadingSpinner(open: boolean): void {\n if (open) {\n this.overlay.classList.add('open');\n } else {\n setTimeout(() => { this.overlay.classList.remove('open'); }, this.overlayDelay);\n }\n }\n\n private hideIdenticalProperties() {\n return new Promise(it => {\n if (this.identicalPropertiesHidden) {\n // otherwise show all rows:\n for (const gridRow of this.gridRowsArray) {\n gridRow.showOnlyDifferences(false);\n }\n\n this.identicalPropertiesHidden = false;\n }\n else {\n // hide rows with same values if checkbox checked:\n for (const gridRow of this.gridRowsArray) {\n gridRow.showOnlyDifferences(true);\n }\n\n this.identicalPropertiesHidden = true;\n }\n\n it('true')\n });\n }\n\n private updateCollapseAllButtonState(oneRowExpanded: boolean): void {\n // if all filter rows are collapsed and later one of the was expanded by customer.\n // Button expand all should return to previous state hide all.\n\n if (oneRowExpanded) {\n this.arrowUp.classList.remove('rotate-arrow');\n this.collapseAllTitle.classList.add('show');\n this.expandAllTitle.classList.remove('show');\n this.collapseAll = oneRowExpanded;\n }\n }\n }\n}","import { MPCDeviceDetectionHelper } from \"../../helpers/deviceDetectionHelper\";\n\nexport module MPCPriceValuesRowModule {\n import DeviceDetectionHelper = MPCDeviceDetectionHelper.DeviceDetectionHelper;\n\n export class PriceValuesRow {\n public htmlElementOrNull: HTMLElement;\n private deviceDetectionHelper: DeviceDetectionHelper;\n private grid: HTMLElement;\n\n public constructor() {\n const scope: HTMLElement = document.querySelector('.mpc-scope');\n this.grid = scope.querySelector('.grid');\n if (!scope && !this.grid){\n return;\n }\n\n this.init();\n }\n\n private init(): void {\n this.deviceDetectionHelper = DeviceDetectionHelper.instance;\n this.htmlElementOrNull = this.grid.querySelector('.prices');\n\n if (this.deviceDetectionHelper.isMobileShop() || !this.htmlElementOrNull)\n return;\n\n if (window.shell) {\n window.shell.subscribeTo('ESPP1.ManualProductComparison.PriceModeClassAdded', this.measureValuesRowHeight.bind(this), undefined);\n }\n }\n\n private measureValuesRowHeight(): void {\n const rowHeight: number = this.htmlElementOrNull.clientHeight;\n this.htmlElementOrNull.style.height = rowHeight + \"px\";\n }\n }\n}","import { MPCIGridRow } from \"../typings/iGridRow\";\nimport { MPCEventBus } from \"../../helpers/event-bus\";\nimport { MPCValuesRowModule } from \"./valuesRow\";\nimport { MPCRowField } from \"./rowField\";\nimport { MPCToolTip } from \"../../helpers/toolTip\";\nconst ArrowUpIcon = require(\"../../../images/arrow-up.svg\") as string;\n\nexport module MPCRowContainerModule {\n import IGridRow = MPCIGridRow.IGridRow;\n import EventBus = MPCEventBus.EventBus;\n import ValuesRow = MPCValuesRowModule.ValuesRow;\n import ToolTip = MPCToolTip.ToolTip;\n\n export class RowContainer implements IGridRow {\n private htmlElement: HTMLElement;\n public headLineTitleHtmlElement: HTMLElement;\n private eventBus: EventBus;\n private arrowUp: HTMLElement;\n private valuesRowArray: ValuesRow[];\n public rowValuesAreEqual: boolean;\n public mpcModalContainer: HTMLElement;\n\n public init(rowContainer: HTMLElement, filledColumns: number, mpcModalContainer: HTMLElement, categoryName: string): void {\n this.htmlElement = rowContainer;\n this.headLineTitleHtmlElement = this.htmlElement.querySelector('.head-line-title');\n this.mpcModalContainer = mpcModalContainer;\n\n const valuesRows: NodeListOf = this.htmlElement.querySelectorAll('.row-values');\n const valuesRowArray: Array = Array.prototype.slice.call(valuesRows);\n\n this.valuesRowArray = valuesRowArray.map(row => {\n const rowValues = new ValuesRow();\n rowValues.resolveRowFields(row, filledColumns, this, categoryName);\n return rowValues;\n });\n\n this.eventBus = MPCEventBus.EventBus.instance;\n\n // header row do not have title:\n if(!this.headLineTitleHtmlElement) return;\n\n this.arrowUp = this.headLineTitleHtmlElement.querySelector('.mpc-arrow-up');\n \n if(this.arrowUp)\n this.arrowUp.innerHTML = ArrowUpIcon;\n\n this.registerEvents();\n this.hideRowWhereAllValuesAreEmpty();\n }\n\n private registerEvents(): void {\n // add toolTip hover event handlers:\n if(!this.headLineTitleHtmlElement.classList.contains(MPCRowField.PermanentlyHidden)) {\n const tooltipContainer: HTMLElement = this.headLineTitleHtmlElement.querySelector('.tooltip-container');\n\n if (tooltipContainer) {\n new ToolTip(tooltipContainer, this.mpcModalContainer);\n }\n }\n\n this.headLineTitleHtmlElement.addEventListener('click', () => { this.handleArrowClick(); });\n this.headLineTitleHtmlElement.addEventListener('keydown', (event: any) => {\n // prevent page jump down on Space btn., click\n if (event.code === 'Space')\n event.preventDefault(); \n });\n }\n\n private handleArrowClick(): void {\n this.arrowUp.classList.toggle('rotate-arrow');\n const collapseRow: boolean = this.arrowUp.classList.contains('rotate-arrow');\n this.collapseExpandValuesRow(collapseRow, false);\n this.eventBus.publish('filter-row.is-expanded', !collapseRow);\n }\n\n public triggerCollapseExpandRow(collapseRow: boolean, delayExecution: boolean = false): void {\n // sub filter does not have arrow icon\n if (this.arrowUp) {\n if (collapseRow) {\n this.arrowUp.classList.add('rotate-arrow');\n }\n else {\n this.arrowUp.classList.remove('rotate-arrow');\n }\n\n this.collapseExpandValuesRow(collapseRow, delayExecution);\n }\n }\n\n private collapseExpandValuesRow(collapseRow: boolean, delayExecution: boolean = false): void {\n let delay = 0;\n let step = 10;\n\n for (const valuesRow of this.valuesRowArray) {\n if (delayExecution) {\n // This way is needed to fix some slow browser animation trouble\n setTimeout(() => { valuesRow.collapseExpandRow(collapseRow); }, delay);\n delay = delay + step;\n } else {\n valuesRow.collapseExpandRow(collapseRow);\n }\n }\n }\n\n public showOnlyDifferences(newState: boolean): void {\n const allSubRowsHidden: boolean = this.valuesRowArray.map((row) => {\n \n // do not hide controls row:\n if(row.htmlElementOrNull && row.htmlElementOrNull.classList.contains('controls')) {\n return false;\n }\n\n const hidden = row.showOnlyDifferences(newState);\n return hidden\n }).reduce((prev, curr) => prev && curr, true);\n\n // header row do not have title:\n if(!this.headLineTitleHtmlElement)\n return;\n\n if (allSubRowsHidden) \n this.headLineTitleHtmlElement.classList.add(MPCRowField.UserHidden);\n else \n this.headLineTitleHtmlElement.classList.remove(MPCRowField.UserHidden);\n }\n\n private hideRowWhereAllValuesAreEmpty(): void {\n const allSubRowsHidden = this.valuesRowArray.map((row) => {\n const hidden = row.hideRowsWhereAllValuesAreEmpty();\n return hidden\n }).reduce((prev, curr) => prev && curr, true);\n\n if (allSubRowsHidden) {\n this.headLineTitleHtmlElement.classList.add(MPCRowField.PermanentlyHidden);\n }\n }\n\n public getRowValuesAreEqual(): boolean {\n //this method is used to disable the 'only differences' button\n if (this.rowValuesAreEqual === undefined) {\n this.rowValuesAreEqual = false;\n }\n return this.rowValuesAreEqual;\n }\n\n public setFirstAndLastClass(): void {\n const visible = this.valuesRowArray.filter(row => \n !row.htmlElementOrNull.classList.contains(MPCRowField.PermanentlyHidden) &&\n !row.htmlElementOrNull.classList.contains(MPCRowField.UserHidden)\n );\n\n this.valuesRowArray.forEach((row) => {\n row.htmlElementOrNull.classList.remove(\"first\", \"last\");\n });\n\n if (visible.length > 0) {\n visible[0].htmlElementOrNull.classList.add(\"first\");\n visible[visible.length - 1].htmlElementOrNull.classList.add(\"last\");\n }\n }\n }\n}","import { MPCColorsField } from \"./colors-field\";\n\nexport module MPCRowField {\n import ColorsField = MPCColorsField.ColorsField;\n export const PermanentlyHidden: string = 'permanently-hidden-row';\n export const UserHidden: string = 'user-hidden-row';\n\n export class RowField {\n public parentHtmlElement: HTMLElement;\n public rowFieldHtmlElement: HTMLElement;\n public fieldValue: any;\n public imagePath: string;\n public colors: ColorsField;\n public price: string;\n public textModule: string;\n public heading: RowField;\n }\n}\n","import { MPCRowField } from \"./rowField\";\nimport { MPCColorsField } from \"./colors-field\";\nimport { MPCRowContainerModule } from \"./rowContainer\";\nimport { MPCToolTip } from \"../../helpers/toolTip\";\nimport { MPCDeviceDetectionHelper } from \"../../helpers/deviceDetectionHelper\";\nimport { MPCValuesSubRowModule } from \"./valuesSubRow\";\nconst MinusIcon = require(\"../../../images/icon_minus.svg\") as string;\n\nexport module MPCValuesRowModule {\n import RowField = MPCRowField.RowField;\n import ColorsField = MPCColorsField.ColorsField;\n import ToolTip = MPCToolTip.ToolTip;\n import DeviceDetectionHelper = MPCDeviceDetectionHelper.DeviceDetectionHelper;\n import RowContainer = MPCRowContainerModule.RowContainer;\n import SubValuesRow = MPCValuesSubRowModule.SubValuesRow;\n\n export class ValuesRow {\n public htmlElementOrNull: HTMLElement;\n private toolTips: Array = new Array();\n public rowFieldsArray: Array;\n public subRowColumnHeaderArray: Array;\n public rowFieldsGroupedBySubRowId: { [id: number]: Array };\n private deviceDetectionHelper: DeviceDetectionHelper;\n private parentRowContainer: RowContainer;\n private heightIsSet: boolean;\n\n public resolveRowFields(valuesRow: HTMLElement, filledColumns: number, parentMainHeadlineRow: RowContainer, categoryName: string): void {\n this.htmlElementOrNull = valuesRow;\n this.deviceDetectionHelper = DeviceDetectionHelper.instance;\n this.parentRowContainer = parentMainHeadlineRow;\n\n const subValuesRowElement : HTMLElement = valuesRow.querySelector('.sub-filter');\n if (subValuesRowElement) {\n const subValuesRow: SubValuesRow = new SubValuesRow();\n subValuesRow.init(subValuesRowElement, this.parentRowContainer.mpcModalContainer);\n }\n\n const rowFields: NodeListOf = valuesRow.querySelectorAll('.row-field');\n const tmpRowFieldsArray: Array = Array.prototype.slice.call(rowFields);\n this.rowFieldsArray = this.collectRowFieldValues(tmpRowFieldsArray, categoryName, filledColumns);\n }\n\n private collectRowFieldValues(tmpRowFieldsArray: Array, categoryName: string, filledColumns: number): Array {\n let rowField: RowField;\n let rowFieldsArray = new Array();\n\n let columnIndex: number = 1;\n for (const tmpRowField of tmpRowFieldsArray) {\n\n // set no-values-field icon:\n const noValuesField: HTMLElement = tmpRowField.querySelector('.no-values-field');\n if (noValuesField) {\n noValuesField.innerHTML = MinusIcon;\n }\n\n // add toolTip hover event handlers:\n const tooltipContainers: NodeListOf = tmpRowField.querySelectorAll('.tooltip-container');\n if (tooltipContainers.length) {\n this.registerToolTipEvents(tooltipContainers);\n }\n\n rowField = new RowField();\n rowField.rowFieldHtmlElement = tmpRowField;\n rowField.fieldValue = tmpRowField.innerHTML;\n\n this.checkCustomRowFieldValues(tmpRowField, categoryName, rowField);\n rowFieldsArray.push(rowField);\n\n // The last quarter of the field array contains all fields for the last column\n if (filledColumns === 4 && columnIndex > tmpRowFieldsArray.length * 0.75) {\n tmpRowField.classList.add('last-column');\n }\n\n columnIndex++;\n }\n\n return rowFieldsArray;\n }\n\n private checkCustomRowFieldValues(tmpRowField: HTMLElement, categoryName: string, rowField: RowField): void {\n // collect price values:\n if (tmpRowField.classList.contains('price')) {\n rowField.price = tmpRowField.innerHTML;\n }\n\n // collect color values:\n if (tmpRowField.classList.contains('colors')) {\n const colorField: ColorsField = new ColorsField();\n colorField.init(tmpRowField, categoryName);\n rowField.colors = colorField;\n }\n\n // collect textModules:\n if (tmpRowField.classList.contains('textModules')) {\n rowField.textModule = tmpRowField.innerHTML;\n }\n\n // image value container:\n if (tmpRowField.classList.contains('image-container')) {\n rowField.fieldValue = tmpRowField.innerHTML;\n }\n\n // collect gloves:\n if (tmpRowField.classList.contains('gloves')) {\n const glovesRating: HTMLElement = tmpRowField.querySelector('.gloves-rating');\n\n if (glovesRating) {\n rowField.fieldValue = glovesRating.getAttribute('data-filtervalue');\n }\n }\n }\n\n private registerToolTipEvents(tooltipContainers: NodeListOf): void {\n tooltipContainers.forEach((tooltipContainer: HTMLElement) => {\n this.toolTips.push(new ToolTip(tooltipContainer, this.parentRowContainer.mpcModalContainer));\n });\n }\n\n public collapseExpandRow(collapseRow: boolean): void {\n if (this.htmlElementOrNull) {\n\n if(!this.deviceDetectionHelper.isMobileShop() && \n !this.heightIsSet && !this.htmlElementOrNull.classList.contains('prices')) {\n this.measureValuesRowHeight();\n setTimeout(() => { this.collapseExpand(true); }, 100);\n }\n else \n this.collapseExpand(collapseRow);\n }\n }\n\n private measureValuesRowHeight(): void {\n const rowHeight: number = this.htmlElementOrNull.clientHeight;\n\n if(rowHeight > 0) {\n this.htmlElementOrNull.style.height = rowHeight + \"px\";\n this.heightIsSet = true;\n }\n }\n\n private collapseExpand(collapseRow: boolean): void {\n if (collapseRow) \n this.htmlElementOrNull.classList.add('row-collapsed');\n else\n this.htmlElementOrNull.classList.remove('row-collapsed');\n }\n\n private rowFieldsAreEqual(): boolean {\n if (this.htmlElementOrNull && this.htmlElementOrNull.classList.contains(MPCRowField.PermanentlyHidden))\n {\n return true;\n }\n\n let firstRowField: RowField;\n let allFieldsInRowAreEqual = true;\n for (const subRowField of this.rowFieldsArray) {\n if (firstRowField) {\n let isEqual: boolean = true;\n if (firstRowField.price) {\n if (firstRowField.price != subRowField.price) {\n isEqual = false;\n }\n }\n if (isEqual && firstRowField.colors) {\n if (firstRowField.colors.colorsContent() != subRowField.colors.colorsContent()) {\n isEqual = false;\n }\n }\n if (isEqual && firstRowField.textModule) {\n if (firstRowField.textModule != subRowField.textModule) {\n isEqual = false;\n }\n }\n if (isEqual && firstRowField.fieldValue !== subRowField.fieldValue) {\n isEqual = false;\n }\n if (!isEqual) {\n allFieldsInRowAreEqual = false;\n break;\n }\n } else {\n firstRowField = subRowField;\n continue;\n }\n }\n\n return allFieldsInRowAreEqual;\n }\n\n public showOnlyDifferences(newState: boolean): boolean {\n if (newState) {\n let allRowsAreEqual = this.rowFieldsAreEqual()\n if (allRowsAreEqual) {\n // hide row heading\n if (this.htmlElementOrNull)\n this.htmlElementOrNull.classList.add(MPCRowField.UserHidden);\n for (const rowField of this.rowFieldsArray) {\n rowField.rowFieldHtmlElement.classList.add(MPCRowField.UserHidden);\n }\n }\n return allRowsAreEqual;\n } else {\n //show all\n if (this.htmlElementOrNull)\n this.htmlElementOrNull.classList.remove(MPCRowField.UserHidden);\n for (const rowField of this.rowFieldsArray) {\n rowField.rowFieldHtmlElement.classList.remove(MPCRowField.UserHidden);\n }\n return false;\n }\n }\n\n public hideRowsWhereAllValuesAreEmpty(): boolean {\n let allValuesAreEmpty: boolean = true;\n\n for (const field of this.rowFieldsArray) {\n if (!field.rowFieldHtmlElement.classList.contains('no-values')) {\n allValuesAreEmpty = false;\n }\n }\n\n // hide all row fields if necessary:\n if (allValuesAreEmpty) {\n for (const field of this.rowFieldsArray) {\n\n // dummy sub filter titles are undefined:\n if (this.htmlElementOrNull)\n this.htmlElementOrNull.classList.add(MPCRowField.PermanentlyHidden);\n\n field.rowFieldHtmlElement.classList.add(MPCRowField.PermanentlyHidden);\n }\n }\n\n return allValuesAreEmpty;\n }\n }\n}","import { MPCToolTip } from \"../../helpers/toolTip\";\n\nexport module MPCValuesSubRowModule {\n import ToolTip = MPCToolTip.ToolTip;\n\n export class SubValuesRow {\n public subFilterTitleContainer: HTMLElement;\n public tooltipContainer: HTMLElement;\n\n public init(subValuesRow: HTMLElement, mpcModalContainer: HTMLElement): void {\n this.subFilterTitleContainer = subValuesRow.querySelector('.sub-filter-title-container');\n this.tooltipContainer = this.subFilterTitleContainer.querySelector('.tooltip-container');\n\n // Register toolTip features:\n if (this.tooltipContainer) {\n this.registerToolTipEvents(this.tooltipContainer, mpcModalContainer);\n }\n }\n\n private registerToolTipEvents(tooltipContainer: HTMLElement, mpcModalContainer: HTMLElement): void {\n new ToolTip(tooltipContainer, mpcModalContainer);\n };\n }\n}","import { MPCGridController } from \"./grid-controller\";\r\nimport { ProductComparisonModel, Product, PageViewContext, ProductStatisticsContext } from \"../../../Models/Product.generated\";\r\nimport { StatisticsResponse } from \"../../../Models/StatisticsResponse\";\r\nimport { MPCLocalStorageService } from \"../local-storage-service\";\r\nimport { MPCNavigationService } from \"../helpers/navigationService\";\r\nimport { MPCStickyHeaderService } from \"./stickyHeaderService\";\r\nimport { MPCDebugController } from \"./debug-controller\";\r\nimport { MPCDeviceDetectionHelper } from \"../helpers/deviceDetectionHelper\";\r\nimport { MPCComparePageButtonUrlUpdater } from \"../helpers/comparePageButtonUrlUpdater\";\r\nimport { MpcSettingsModule } from \"../helpers/MpcSettings\";\r\nimport { NlVanillajax, INlVanillajaxParams } from \"../helpers/vanillajax\";\r\nconst RecommendIcon = require(\"../../images/recommend.svg\") as string;\r\nconst ScaleIcon2021 = require(\"../../images/scale-2021.svg\") as string;\r\nconst PrintIcon2021 = require(\"../../images/print-2021.svg\") as string;\r\nimport 'url-search-params-polyfill';\r\n\r\nnamespace MPC {\r\n import GridController = MPCGridController.GridController;\r\n import ProductComparisonModelManager = MPCLocalStorageService.ProductComparisonModelManager;\r\n import NavigationService = MPCNavigationService.NavigationService;\r\n import StickyHeaderService = MPCStickyHeaderService.StickyHeaderService;\r\n import DeviceDetectionHelper = MPCDeviceDetectionHelper.DeviceDetectionHelper;\r\n import ComparePageButtonUrlUpdater = MPCComparePageButtonUrlUpdater.ComparePageButtonUrlUpdater;\r\n import MpcSettings = MpcSettingsModule.MpcSettings;\r\n import DebugController = MPCDebugController.DebugController;\r\n\r\n export class ComparisonPageController {\r\n private productComparisonModelManager: ProductComparisonModelManager;\r\n private static _instance: ComparisonPageController;\r\n private readonly scope: HTMLElement;\r\n private navigationService: NavigationService;\r\n private stickyHeader: StickyHeaderService;\r\n private deviceDetectionHelper : DeviceDetectionHelper;\r\n private comparePageButtonUrlUpdater: ComparePageButtonUrlUpdater;\r\n private urlParams: URLSearchParams;\r\n private grid: HTMLElement;\r\n private mpcPrintPage: HTMLElement;\r\n\r\n static get instance() {\r\n return this._instance || (this._instance = new this());\r\n }\r\n\r\n public constructor() {\r\n this.scope = document.querySelector('.mpc-scope');\r\n this.grid = this.scope.querySelector('.grid');\r\n if (!this.scope && !this.grid){\r\n return;\r\n }\r\n\r\n this.init();\r\n }\r\n\r\n private init(skipNavigation : boolean = false): void {\r\n // because of comparison page is a content-service, \r\n // It does not trigger legacy sniff feature which fullyFills user device and browser information.\r\n // So we have to do it by our self:\r\n this.deviceDetectionHelper = DeviceDetectionHelper.instance;\r\n MpcSettings.instance.init(this.scope);\r\n this.productComparisonModelManager = ProductComparisonModelManager.instance;\r\n DebugController.instance.init(this.scope);\r\n\r\n this.productComparisonModelManager.getModel().then(model => {\r\n if (this.checkComparePageUrl(model))\r\n return;\r\n\r\n // removed because of ESPP-4706\r\n // if(!this.deviceDetectionHelper.isMobileShop())\r\n // this.deviceDetectionHelper.adaptLegacySniff();\r\n\r\n this.urlParams = new URLSearchParams(location.search);\r\n this.mpcPrintPage = this.scope.querySelector('.mpc-print-page');\r\n const navigationContainer: HTMLElement = this.scope.querySelector('.navigation-container');\r\n if (!skipNavigation) {\r\n this.navigationService = NavigationService.instance;\r\n this.navigationService.init(navigationContainer, 'data-pcp-navigation-key', null);\r\n }\r\n\r\n this.comparePageButtonUrlUpdater = ComparePageButtonUrlUpdater.instance;\r\n this.comparePageButtonUrlUpdater.init(this.scope);\r\n\r\n new GridController(this.scope);\r\n \r\n this.checkCurrentLocalStorage(model);\r\n this.stickyHeader = new StickyHeaderService();\r\n\r\n this.loadComparisonPageIcons();\r\n this.registerEvents();\r\n\r\n //when navigating to comparison page, unmark item in mobile header\r\n if (window.shell) \r\n window.shell.publishTo('ESMKT.MegaMenu.UnmarkItem', \"mpc\");\r\n });\r\n }\r\n\r\n private loadComparisonPageIcons(): void {\r\n this.scope.querySelector('.article-recommendation-icon').innerHTML = RecommendIcon;\r\n this.scope.querySelector('.mpc-print-icon').innerHTML = PrintIcon2021;\r\n \r\n if (this.deviceDetectionHelper.isMobileShop()) {\r\n this.scope.querySelector('.title-icon').innerHTML = ScaleIcon2021;\r\n }\r\n }\r\n\r\n private logPageLoadEvent(shownProducts: ProductStatisticsContext[], rootCategoryName: string): void {\r\n if (shownProducts.length == 0 || !rootCategoryName) {\r\n return; //we don't log an empty page\r\n }\r\n\r\n // Call statistics controller via POST ajax (because page maybe served from cache/cdn and we wouldn't log it)\r\n let params: INlVanillajaxParams = {};\r\n params.url = MpcSettingsModule.MpcSettings.instance.apiUrl + \"Statistics/PageLoad\";\r\n\r\n let context = {} as PageViewContext;\r\n context.rootCategoryName = rootCategoryName;\r\n context.viewedProducts = shownProducts;\r\n params.data = JSON.stringify(context);\r\n \r\n let nlVanillajax = new NlVanillajax(params);\r\n nlVanillajax.postWithPromise()\r\n .then((response: StatisticsResponse) => {\r\n if (response.correlationId) {\r\n document.documentElement.setAttribute(\"data-page-view-log-data-id\", response.correlationId);\r\n }\r\n if (!response.success) {\r\n console.error('error processing statistics ' + response.message);\r\n }\r\n })\r\n .catch((err) => {\r\n console.error('Could not post statistics', err.statusText);\r\n throw err;\r\n });\r\n }\r\n\r\n private checkCurrentLocalStorage(model: ProductComparisonModel): void {\r\n if (model) {\r\n const categoryParam = this.urlParams.get('category');\r\n const categoryFromUrl: string = categoryParam ? decodeURIComponent(categoryParam) : null;\r\n const orderOfCategoryFromUrl = parseInt(this.scope.querySelector('.navigation-container').getAttribute(\"data-navigation-order\"));\r\n\r\n if (model.clearStoredEmptyNavigationTabs) {\r\n this.productComparisonModelManager.removeStoredEmptyNavigationTabs();\r\n this.productComparisonModelManager.setClearStoredEmptyNavigationTabs(false);\r\n } else {\r\n const emptyNavigationTabs = model.emptyNavigationTabs;\r\n\r\n // create empty navigation tabs:\r\n if (emptyNavigationTabs) {\r\n for (const emptyNavigationTab of emptyNavigationTabs) {\r\n this.navigationService.createOrUpdateNavigationTab(emptyNavigationTab.name, 0,\r\n emptyNavigationTab.navigationOrder, null, true);\r\n }\r\n }\r\n }\r\n\r\n // create navTabs according tp localStorage content\r\n for (const storageProduct of model.products) {\r\n\r\n // but only for categories that are not from the URL,\r\n // because when you deepLink (mail-recommendation or bookmark) the localStorage might have conflicting data\r\n if (storageProduct.categoryName === categoryFromUrl) {\r\n continue;\r\n }\r\n\r\n this.navigationService.createOrUpdateNavigationTab(storageProduct.categoryName, 1,\r\n storageProduct.navigationOrder, storageProduct.articleId.salesArticleVariantKey);\r\n }\r\n\r\n let savKeys = this.urlParams.getAll('savKeys');\r\n // add articles from URL\r\n for (const savKey of savKeys) {\r\n this.navigationService.createOrUpdateNavigationTab(categoryFromUrl, 1,\r\n orderOfCategoryFromUrl, savKey);\r\n }\r\n\r\n // log statistics of shown articles (i.e. those in the url for the current page/category root)\r\n const shownProducts = new Array();\r\n\r\n let fromStorage = false;\r\n for (const savKey of savKeys) {\r\n for (const storageProduct of model.products) {\r\n if (storageProduct.categoryName === categoryFromUrl && storageProduct.articleId.salesArticleVariantKey === savKey) {\r\n shownProducts.push(this.map(storageProduct));\r\n fromStorage = true;\r\n break;\r\n }\r\n }\r\n\r\n if (!fromStorage) {\r\n const context = {} as ProductStatisticsContext;\r\n context.salesArticleVariantKey = savKey;\r\n context.origin = \"Deeplink\";\r\n context.originNavigationKeyPath = \"Unknown\";\r\n shownProducts.push(context);\r\n }\r\n }\r\n\r\n // log page load event\r\n this.logPageLoadEvent(shownProducts, categoryFromUrl);\r\n\r\n this.navigationService.markActiveNavigationTab(categoryFromUrl);\r\n this.navigationService.updateSelectCategoryButtonVisibility();\r\n }\r\n }\r\n\r\n private map(source: Product): ProductStatisticsContext {\r\n const context = {} as ProductStatisticsContext;\r\n context.salesArticleVariantKey = source.articleId.salesArticleVariantKey;\r\n context.origin = source.origin;\r\n context.originNavigationKeyPath = source.originNavigationKeyPath;\r\n return context;\r\n }\r\n\r\n private registerEvents(): void {\r\n this.stickyHeader.init(this.scope);\r\n\r\n if(this.mpcPrintPage)\r\n this.mpcPrintPage.addEventListener('click', () => { this.preparePrintPage(); });\r\n\r\n document.addEventListener('DOMContentLoaded', () => {\r\n this.setNavTabFocus();\r\n });\r\n }\r\n\r\n private setNavTabFocus(): void {\r\n // focus to first navigation tab:\r\n if(window.shell.tabNav && this.mpcPrintPage) {\r\n window.shell.tabNav.focus(this.mpcPrintPage);\r\n }\r\n }\r\n\r\n private checkComparePageUrl(model: ProductComparisonModel): boolean {\r\n // check url for sav keys:\r\n const urlParams: URLSearchParams = new URLSearchParams(location.search);\r\n let currentUrl: string = window.location.href;\r\n const savKeysExists: number = currentUrl.indexOf('&savKeys');\r\n let urlParam: string;\r\n let categoryFromUrl: string = urlParams.get('category');\r\n\r\n // if it does not exists load them from local storage by category name:\r\n if (savKeysExists <= 0 && model && model.products.length > 0) {\r\n // update pcp url:\r\n if (!categoryFromUrl) {\r\n categoryFromUrl = model.products[0].categoryName;\r\n currentUrl = currentUrl + '?category=' + categoryFromUrl;\r\n }\r\n\r\n const productsArray: Array = model.products.filter(it=>it.categoryName == categoryFromUrl);\r\n\r\n if (this.deviceDetectionHelper.isMobileShop) {\r\n this.productComparisonModelManager.clearCarouselScrollIndex();\r\n this.productComparisonModelManager.clearLockedColumnIndex();\r\n }\r\n\r\n if(productsArray.length > 0) {\r\n for(const product of productsArray) {\r\n urlParam = '&savKeys=' + product.articleId.salesArticleVariantKey;\r\n currentUrl = currentUrl + urlParam;\r\n }\r\n\r\n // reload page with updated url:\r\n location.replace(currentUrl);\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n private preparePrintPage(): void {\r\n const printPageLink: string = this.mpcPrintPage.getAttribute('data-print-page-link');\r\n const clone: HTMLElement = this.grid.cloneNode(true);\r\n clone.classList.add('flex-grid');\r\n\r\n this.productComparisonModelManager.storePrintPageContent(clone);\r\n\r\n if(navigator.userAgent.indexOf('MSIE')!==-1 || navigator.appVersion.indexOf('Trident/') > -1) {\r\n window.open(printPageLink); // for ie11\r\n }\r\n else {\r\n window.open(printPageLink, '_blank', 'noopener');\r\n }\r\n }\r\n }\r\n}\r\n\r\nMPC.ComparisonPageController.instance;","\n\nexport module MPCDebugController {\n\n export class DebugController {\n private scope: HTMLElement;\n private static _instance: DebugController;\n \n static get instance() {\n return this._instance || (this._instance = new this());\n }\n\n public init(scope: HTMLElement): void {\n this.scope = scope.querySelector('.grid');\n const highlightSourceButton: HTMLElement = this.scope.querySelector('.hightlight-source');\n\n if(highlightSourceButton)\n highlightSourceButton.addEventListener('click', () => { this.handleFlyoutIconClick(); });\n }\n\n handleFlyoutIconClick(): any {\n if (this.scope.classList.contains('debug-enabled'))\n this.scope.classList.remove('debug-enabled');\n else\n this.scope.classList.add('debug-enabled');\n }\n }\n}","import { MPCRowContainerModule } from \"./Rows/rowContainer\";\nimport { MPCControlsRow } from \"./Rows/controls-row\";\nimport { MPCColumnHeader } from \"./Columns/column-header\";\nimport { MPCDeviceDetectionHelper } from \"../helpers/deviceDetectionHelper\";\nimport { MPGridColumnLock } from \"./gridColumnLock\";\nimport { MPCGridCarousel } from \"./gridCarousel\";\nimport { MPCProductsCounter } from \"./productsCounter\";\nimport { MPCPriceValuesRowModule } from \"./Rows/priceValuesRow\";\nimport { MPCScrollLock } from \"../helpers/scrollLock\";\nconst PlusIcon2021 = require(\"../../images/plus-2021.svg\") as string;\nconst BasketIcon2021 = require(\"../../images/basket-2021.svg\") as string;\nconst RecycleBinIcon = require(\"../../images/icon_remove.svg\") as string;\nconst LockedIcon = require(\"../../images/locked.svg\") as string;\n\nexport module MPCGridController {\n import RowContainer = MPCRowContainerModule.RowContainer;\n import ControlsRow = MPCControlsRow.ControlsRow;\n import ColumnHeader = MPCColumnHeader.ColumnHeader;\n import DeviceDetectionHelper = MPCDeviceDetectionHelper.DeviceDetectionHelper;\n import GridColumnLockHelper = MPGridColumnLock.GridColumnLock;\n import GridCarousel = MPCGridCarousel.GridCarousel;\n import ProductsCounter = MPCProductsCounter.ProductsCounter;\n import PriceValuesRow = MPCPriceValuesRowModule.PriceValuesRow;\n import ScrollLock = MPCScrollLock.ScrollLock;\n\n export class GridController {\n private scope: HTMLElement;\n private rowContainers: Array = new Array();\n private grid: HTMLElement;\n private columnHeadersArray: Array;\n private gridCarousel : GridCarousel;\n private deviceDetectionHelper : DeviceDetectionHelper;\n private filledColumns: number;\n private categoryName: string;\n private orderModalExists: boolean;\n private scrollLock: ScrollLock;\n\n constructor(scope: HTMLElement) {\n this.scope = scope;\n this.init();\n }\n\n public gridHtmlElement(): HTMLElement {\n return this.grid;\n }\n\n private init(): void {\n this.deviceDetectionHelper = DeviceDetectionHelper.instance;\n this.scrollLock = ScrollLock.instance;\n this.grid = this.scope.querySelector('.grid');\n\n // Collect grid column headers:\n const columnHeaders: NodeListOf = this.grid.querySelectorAll('.column-header-container');\n this.columnHeadersArray = Array.prototype.slice.call(columnHeaders);\n\n if (!this.grid) {\n return;\n }\n\n this.initOrderModalMutationObserver();\n this.filledColumns = this.grid.querySelectorAll('.header:not(.empty-header)').length;\n\n if(this.deviceDetectionHelper.isMobileShop()) {\n const tmpCarouselElement: HTMLElement = this.scope.querySelector('.navigation-container');\n this.gridCarousel = new GridCarousel(this.scope, tmpCarouselElement);\n \n new ProductsCounter(tmpCarouselElement).updateProductsCounter(this.filledColumns);\n new GridColumnLockHelper(this.scope, this.gridCarousel);\n }\n\n this.categoryName = this.grid.getAttribute('data-pcp-navigation-key');\n\n this.registerEvents();\n this.setFirstAndLastClass();\n scrollTo();\n this.loadGridIcons();\n\n // update prices row. This is only for prices row:\n new PriceValuesRow();\n }\n\n // Dedicated for quick order modal.\n // This element is added to dom dynamically so we that tracking when it is done and locking background.\n // This feature, more/ or less, dedicated for tablet devices, but is suitable for desktop too.\n private initOrderModalMutationObserver(): void {\n const observer: MutationObserver = new MutationObserver(() => {\n const orderModal = document.body.querySelector('.modal-scrollable');\n let quickOrderModalExists: boolean = document.body.contains(orderModal);\n\n if (quickOrderModalExists && !this.orderModalExists) {\n this.scrollLock.lock();\n this.orderModalExists = true;\n }\n else if (this.orderModalExists && !quickOrderModalExists) {\n this.scrollLock.unlock();\n this.orderModalExists = false;\n }\n });\n\n observer.observe(document.body, { childList: true });\n }\n\n private loadGridIcons(): void {\n const filledColumnsHeaders: NodeListOf = this.grid.querySelectorAll('.header:not(.empty-header)');\n const filledColumnsHeadersArray: Array = Array.prototype.slice.call(filledColumnsHeaders);\n const emptyColumnsHeaders: NodeListOf = this.grid.querySelectorAll('.empty-header');\n const emptyColumnsHeadersArray: Array = Array.prototype.slice.call(emptyColumnsHeaders);\n const emptySlides: NodeListOf = this.scope.querySelectorAll('.empty-slide');\n const emptySlidesArray: Array = Array.prototype.slice.call(emptySlides);\n\n const lockedColumnIcons: NodeListOf = this.scope.querySelectorAll('.mpc-locked-column');\n const lockedColumnIconsArray: Array = Array.prototype.slice.call(lockedColumnIcons);\n\n for (const tmpColumnHeader of filledColumnsHeadersArray) {\n tmpColumnHeader.querySelector('.mpc-basket').innerHTML = BasketIcon2021;\n tmpColumnHeader.querySelector('.mpc-recycle').innerHTML = RecycleBinIcon;\n }\n\n for (const tmpColumnHeader of emptyColumnsHeadersArray) {\n tmpColumnHeader.querySelector('.mpc-plus').innerHTML = PlusIcon2021;\n\n tmpColumnHeader.addEventListener('keydown', (event: any) => {\n // prevent page jump down on Space btn., click\n if (event.code === 'Space')\n event.preventDefault(); \n });\n }\n\n for (const emptySlide of emptySlidesArray) {\n emptySlide.querySelector('.mpc-plus').innerHTML = PlusIcon2021;\n }\n\n for (const lockColumnIcon of lockedColumnIconsArray) {\n lockColumnIcon.innerHTML = LockedIcon;\n }\n }\n\n private registerEvents(): void {\n let columnNumber: number = 1;\n let lastColumn: boolean;\n let firstColumn: boolean;\n for (const tmpColumnHeader of this.columnHeadersArray) {\n let columnHeader: ColumnHeader = new ColumnHeader();\n\n if(columnNumber == 1)\n firstColumn = true;\n\n if(columnNumber == 4)\n lastColumn = true;\n\n columnHeader.init(tmpColumnHeader, this.grid, lastColumn, firstColumn);\n columnNumber++;\n firstColumn = false;\n lastColumn = false;\n }\n\n // register simple row events:\n const rowContainers: NodeListOf = this.grid.querySelectorAll('.row-container');\n const rowContainersArray: Array = Array.prototype.slice.call(rowContainers);\n\n const mpcModalContainer: HTMLElement = this.scope.querySelector('.mpc-modal-container');\n\n for (const rowContainer of rowContainersArray) {\n const gridRow: RowContainer = new RowContainer();\n gridRow.init(rowContainer, this.filledColumns, mpcModalContainer, this.categoryName);\n this.rowContainers.push(gridRow);\n }\n\n // registers control rows events:\n const controlsRowHtml: HTMLElement = this.grid.querySelector('.controls');\n\n if (controlsRowHtml) {\n const controlsRow: ControlsRow = new ControlsRow();\n controlsRow.init(controlsRowHtml, this.rowContainers,\n this.columnHeadersArray.filter(it => it.querySelector('.header').classList.contains('empty-header')).length, this, this.columnHeadersArray[0]);\n }\n }\n\n public setFirstAndLastClass(): void {\n for (const mainHeadlineRow of this.rowContainers) {\n mainHeadlineRow.setFirstAndLastClass();\n }\n }\n }\n}","import { MPCIGridCarousel } from \"./typings/iGridCarousel\";\nimport { MPCLocalStorageService } from \"../local-storage-service\";\nconst Hammer = require(\"hammerjs\");\nconst SmartTimeout = require(\"smart-timeout\");\nconst ArrowRightIcon = require(\"../../images/arrow-right.svg\") as string;\n\nexport module MPCGridCarousel {\n import IGridCarousel = MPCIGridCarousel.IGridCarousel;\n import ProductComparisonModelManager = MPCLocalStorageService.ProductComparisonModelManager;\n\n export class GridCarousel implements IGridCarousel {\n private grid: HTMLElement;\n private navigationContainer: HTMLElement;\n private scrollLeftArrow: HTMLElement;\n private scrollLeftArrowShrinked: HTMLElement;\n private scrollRightArrow: HTMLElement;\n private carouselScrollIndex: number;\n private columnsAmount: number;\n private leftSideColumnIndex: number;\n private carousel: HTMLElement;\n private pagerDotsArray: Array;\n private stickyHeaderPagerDotsArray: Array;\n private stickyHeader: HTMLElement;\n private scope: HTMLElement;\n private hammerJs: any;\n private hammerManager: HammerManager;\n private productComparisonModelManager: ProductComparisonModelManager;\n private overlay: HTMLElement;\n\n constructor(scope: HTMLElement, navigationContainer: HTMLElement) {\n this.overlay = scope.querySelector('.mpc-grid-loading-overlay');\n this.grid = scope.querySelector('.grid');\n this.stickyHeader = scope.querySelector('.sticky-header');\n this.scope = scope;\n this.navigationContainer = navigationContainer;\n this.carouselScrollIndex = 1;\n this.leftSideColumnIndex = 1;\n this.columnsAmount = 4;\n\n if (this.grid.classList.contains(\"empty-grid\"))\n return;\n\n this.init();\n }\n\n private init(): void {\n this.productComparisonModelManager = ProductComparisonModelManager.instance;\n this.setCurrentSlideClass();\n\n this.carousel = this.navigationContainer.querySelector('.grid-carousel-container');\n this.scrollLeftArrow = this.navigationContainer.querySelector('.scroll-left-arrow');\n this.scrollLeftArrowShrinked = this.navigationContainer.querySelector('.scroll-left-arrow-shrinked');\n this.scrollRightArrow = this.navigationContainer.querySelector('.scroll-right-arrow');\n\n // swiping for grid:\n this.hammerManager = new Hammer.Manager(this.grid, {\n domEvents: true,\n recognizers: [\n [Hammer.Swipe, { direction: Hammer.DIRECTION_HORIZONTAL, threshold: 5, velocity: 0.1 }]\n ],\n drag_block_vertical: true\n });\n\n // swiping for sticky header:\n if (this.stickyHeader)\n this.hammerJs = new Hammer(this.stickyHeader);\n\n const tmpPagerDots: NodeListOf = this.carousel.querySelectorAll('.pager-dot');\n this.pagerDotsArray = Array.prototype.slice.call(tmpPagerDots);\n\n const stickyHeaderContainer: HTMLElement = this.scope.querySelector('.sticky-header-container');\n\n if (stickyHeaderContainer) {\n const tmpStickyHeaderPagerDots: NodeListOf = stickyHeaderContainer.querySelectorAll('.pager-dot');\n this.stickyHeaderPagerDotsArray = Array.prototype.slice.call(tmpStickyHeaderPagerDots);\n }\n\n this.loadComparisonPageIcons();\n this.registerEvents();\n this.showHideArrows();\n this.updateActivePagerDot();\n\n if (this.overlay)\n SmartTimeout.set(() => { this.overlay.classList.add('hidde-loading-overlay'); }, 1200);\n }\n\n private loadComparisonPageIcons(): void {\n this.scrollLeftArrow.innerHTML = ArrowRightIcon;\n this.scrollLeftArrowShrinked.innerHTML = ArrowRightIcon;\n this.scrollRightArrow.innerHTML = ArrowRightIcon;\n }\n\n private registerEvents(): void {\n this.scrollLeftArrow.addEventListener('click', ()=> { this.handleLeftArrowClick(); });\n this.scrollLeftArrowShrinked.addEventListener('click', ()=> { this.handleLeftArrowClick(); });\n this.scrollRightArrow.addEventListener('click', () => { this.handleRightArrowClick(); });\n\n this.hammerManager.on('swipe', (event: HammerInput) => {\n let gestureAngle: number = Math.abs(event.angle);\n\n if (gestureAngle >= 0 && gestureAngle <= 45) {\n //swipe to right, within a cone of +/-45deg\n this.handleLeftArrowClick();\n }\n else if (gestureAngle >= 135 && gestureAngle <= 180) {\n //swipe to left, within a cone of +/-45deg\n this.handleRightArrowClick();\n }\n });\n\n if (this.hammerJs) {\n this.hammerJs.on('swipeleft', () => { this.handleRightArrowClick(); });\n this.hammerJs.on('swiperight', () => { this.handleLeftArrowClick(); });\n }\n }\n\n public shrinkCarousel(shrink: boolean): void {\n if(shrink) {\n this.carousel.classList.add('shrinked');\n }\n else {\n this.carousel.classList.remove('shrinked');\n }\n\n this.showHideArrows();\n }\n\n public swipeLeft(): void {\n // if carouse scroll index value is default 1 that it means there is not stored value in localStorage:\n for (let i: number = this.carouselScrollIndex; i >= this.carouselScrollIndex; i--) {\n this.handleLeftArrowClick();\n }\n }\n\n public restorePreviousSlidePosition(storedCarouselScrollIndex: number): void {\n for (let i: number = 1; i < storedCarouselScrollIndex; i++) {\n this.handleRightArrowClick();\n }\n }\n\n private handleLeftArrowClick(): void {\n const previousIndex: number = this.carouselScrollIndex;\n this.carouselScrollIndex -= 1; // next carousel scroll index\n this.leftSideColumnIndex -= 1;\n\n if (this.leftSideColumnIndex < 1)\n this.leftSideColumnIndex = 1;\n \n if(this.carouselScrollIndex < 1)\n {\n // revert carousel scroll index\n this.carouselScrollIndex = 1;\n }\n else {\n this.setCurrentSlideClass(previousIndex);\n }\n\n this.showHideArrows();\n this.updateActivePagerDot();\n this.storeCarouselScrollIndex();\n }\n\n private handleRightArrowClick(): void {\n const previousIndex: number = this.carouselScrollIndex;\n this.carouselScrollIndex += 1; // next column on the right\n this.leftSideColumnIndex += 1;\n\n if(this.leftSideColumnIndex > 3)\n this.leftSideColumnIndex = 3;\n\n if(this.carouselScrollIndex > 3)\n {\n // revert carousel scroll index\n this.carouselScrollIndex = 3;\n }\n else {\n this.setCurrentSlideClass(previousIndex);\n }\n\n this.showHideArrows();\n this.updateActivePagerDot();\n this.storeCarouselScrollIndex();\n }\n\n private setCurrentSlideClass(previousIndex: number = 0): void {\n for (let i: number = 1; i <= this.columnsAmount; i++) {\n const nextVisibleElements: Array = this.getNextVisibleElements(i);\n\n for (const nextVisibleElement of nextVisibleElements) {\n if (!nextVisibleElement.classList.contains('locked-column')) {\n nextVisibleElement.classList.remove('slide-' + previousIndex);\n nextVisibleElement.classList.add('slide-' + this.carouselScrollIndex);\n }\n }\n }\n }\n \n private getNextVisibleElements(gridColumnIndex: number): Array {\n const selector: string = `[grid-column-index=\"${gridColumnIndex}\"]`;\n\n const gridElements: NodeListOf = this.grid.querySelectorAll(selector);\n const gridArray: Array = Array.prototype.slice.call(gridElements);\n\n let result: Array = gridArray;\n\n if (this.stickyHeader) {\n const headerElements: NodeListOf = this.stickyHeader.querySelectorAll(selector);\n const headerArray: Array = Array.prototype.slice.call(headerElements);\n\n result = result.concat(headerArray);\n }\n\n return result;\n }\n \n private showHideArrows(): void {\n this.hideScrollArrow(this.scrollLeftArrowShrinked, 1);\n this.hideScrollArrow(this.scrollLeftArrow, 1);\n this.hideScrollArrow(this.scrollRightArrow, 3);\n }\n\n private hideScrollArrow(arrow: Element, indexToHideFor: number): void {\n const hideScrollArrow: boolean = this.carouselScrollIndex === indexToHideFor;\n\n if (hideScrollArrow)\n arrow.classList.add('hidden-arrow');\n else\n arrow.classList.remove('hidden-arrow');\n }\n\n private updateActivePagerDot(): void {\n for(const pagerDot of this.pagerDotsArray) {\n pagerDot.classList.remove('current-dot');\n }\n\n this.pagerDotsArray[this.carouselScrollIndex - 1].classList.add('current-dot');\n\n\n if (this.stickyHeaderPagerDotsArray) {\n for (const pagerDot of this.stickyHeaderPagerDotsArray) {\n pagerDot.classList.remove('current-dot');\n }\n\n this.stickyHeaderPagerDotsArray[this.carouselScrollIndex - 1].classList.add('current-dot');\n }\n }\n\n private storeCarouselScrollIndex(): void {\n this.productComparisonModelManager.storeCarouselScrollIndex(this.carouselScrollIndex);\n }\n }\n}","import { MPCIGridCarousel } from \"./typings/iGridCarousel\";\nimport { MPCLocalStorageService } from \"../local-storage-service\";\nconst SmartTimeout = require(\"smart-timeout\");\n\nexport module MPGridColumnLock {\n import IGridCarousel = MPCIGridCarousel.IGridCarousel;\n import ProductComparisonModelManager = MPCLocalStorageService.ProductComparisonModelManager;\n\n export class GridColumnLock {\n private productComparisonModelManager: ProductComparisonModelManager;\n private readonly grid: HTMLElement;\n private readonly stickyHeader: HTMLElement;\n private currentLockedColumnIndex: number;\n private columnIsLocked: boolean;\n private readonly gridCarousel: IGridCarousel;\n private lockUnLockColumnEvent: EventListenerOrEventListenerObject;\n private lockInProgressTimeOut: number = 1000;\n private lockInProgress: boolean = false;\n\n constructor(scope: HTMLElement, gridCarousel: IGridCarousel) {\n this.grid = scope.querySelector('.grid');\n this.stickyHeader = scope.querySelector('.sticky-header-container');\n this.gridCarousel = gridCarousel;\n this.init();\n }\n\n private init(): void {\n this.currentLockedColumnIndex = 0;\n this.lockUnLockColumnEvent = (event: Event) => { this.handleLockUnlockColumnClick(event);}\n this.registerEvents();\n this.productComparisonModelManager = ProductComparisonModelManager.instance;\n\n if(!this.grid.classList.contains('empty-grid'))\n this.loadStoredLockedColumnInfo();\n }\n\n private registerEvents(): void {\n const columnHeaders: NodeListOf = this.grid.querySelectorAll('.column-header-container');\n const columnHeadersArray: Array = Array.prototype.slice.call(columnHeaders);\n\n for (const columnHeader of columnHeadersArray) {\n if(!columnHeader.querySelector('.header').classList.contains('empty-header')) {\n columnHeader.querySelector('.mpc-locked-column').addEventListener('click', this.lockUnLockColumnEvent );\n }\n }\n }\n\n private loadStoredLockedColumnInfo(): void {\n // check locked column data:\n const lockedColumnIndex: number = this.productComparisonModelManager.getLockedColumnIndex();\n\n if (lockedColumnIndex) {\n let columnHeader: HTMLElement = this.getColumnHeader(lockedColumnIndex);\n\n if (columnHeader) {\n const storedCarouselScrollIndex: number = this.productComparisonModelManager.getCarouselScrollIndex();\n\n this.lockUnLockColumn(columnHeader.querySelector('.mpc-locked-column'), lockedColumnIndex);\n \n if(storedCarouselScrollIndex) {\n this.gridCarousel.restorePreviousSlidePosition(storedCarouselScrollIndex);\n }\n }\n }\n }\n\n private handleLockUnlockColumnClick(event: Event): void {\n const currentButtonContainer: HTMLElement = event.currentTarget as HTMLElement;\n const selectedColumnIndex: number = parseInt(currentButtonContainer.getAttribute('column-index'));\n this.lockUnLockColumn(currentButtonContainer, selectedColumnIndex);\n }\n\n private lockUnLockColumn(currentButtonContainer: HTMLElement, selectedColumnIndex: number): void {\n\n // avoid random fast lock unlock clicks:\n if (this.lockInProgress)\n return;\n\n // store selected column:\n let selectedColumn: Array = this.getColumn(selectedColumnIndex);\n\n // store sticky header slide:\n let selectedSlide: HTMLElement = this.getStickyHeaderSlide(selectedColumnIndex);\n\n // remove lock events:\n this.removeRegisteredEvents();\n\n // scroll grid to the primary position till the first column is visible on the left side:\n this.gridCarousel.swipeLeft();\n\n if(this.currentLockedColumnIndex == selectedColumnIndex) {\n this.changeLockIcon(currentButtonContainer.parentElement, false);\n this.changeLockIcon(selectedSlide, false);\n\n if(selectedColumnIndex > 1) {\n // unlock columns and restore it primary positions:\n this.unLockAndRestoreColumn(selectedColumn, selectedSlide);\n }\n else {\n this.unlockColumn(selectedColumn, selectedSlide);\n }\n\n this.currentLockedColumnIndex = 0;\n this.columnIsLocked = false;\n\n // restore grid carousel size:\n this.gridCarousel.shrinkCarousel(false);\n\n // clear locked column info:\n this.productComparisonModelManager.clearLockedColumnIndex();\n }\n else {\n this.changeLockIcon(currentButtonContainer.parentElement, true);\n this.changeLockIcon(selectedSlide, true);\n\n // if user clicks lock on another product, but previous one was not unlocked yet:\n if(this.columnIsLocked) {\n const previousLockedColumn: Array = this.getColumn(this.currentLockedColumnIndex);\n const previousLockedSlide: HTMLElement = this.getStickyHeaderSlide(this.currentLockedColumnIndex);\n\n const tmpColumnHeaderArray: Array = previousLockedColumn.filter(\n it => it.classList.contains('column-header-container'));\n\n this.changeLockIcon(tmpColumnHeaderArray[0].querySelector('.lock-unLock-container'), false);\n this.changeLockIcon(previousLockedSlide, false);\n\n if (this.currentLockedColumnIndex > 1) {\n // unlock columns and restore it primary positions:\n this.unLockAndRestoreColumn(previousLockedColumn, previousLockedSlide);\n }\n else {\n this.unlockColumn(previousLockedColumn, previousLockedSlide);\n }\n\n this.columnIsLocked = false;\n\n // re select selected column:\n selectedColumn = this.getColumn(selectedColumnIndex);\n\n // re sticky header slide:\n selectedSlide = this.getStickyHeaderSlide(selectedColumnIndex);\n }\n\n if(selectedColumnIndex > 1) {\n // lock column and replace it with first one:\n this.lockAndMoveColumn(selectedColumn, selectedSlide, selectedColumnIndex);\n }\n else {\n this.lockColumn(selectedColumn, selectedSlide);\n }\n\n // shrink grid carousel:\n this.gridCarousel.shrinkCarousel(true);\n\n this.currentLockedColumnIndex = selectedColumnIndex;\n this.columnIsLocked = true;\n\n // store locked column cookie info:\n this.productComparisonModelManager.storeLockedColumnIndex(selectedColumnIndex);\n }\n\n // register lock events again:\n this.registerEvents();\n this.lockInProgress = true;\n\n SmartTimeout.set(() => { this.lockInProgress = false; }, this.lockInProgressTimeOut);\n }\n\n private unLockAndRestoreColumn(lockedColumn: Array, lockedSlide: HTMLElement): void {\n let previousFirstSlideField: string;\n let lockedSlideTempField: string;\n\n // store first column, which takes places in locked column position:\n const previousFirstColumn: Array = this.getColumn(1);\n const previousFirstSlide: HTMLElement = this.getStickyHeaderSlide(1);\n const previousColumnIndex: number = this.getGridColumnIndex(lockedColumn[0]);\n\n for(let i: number = 0; i < previousFirstColumn.length; i++) {\n // unlock column:\n lockedColumn[i].classList.remove('locked-column');\n lockedColumn[i].classList.remove('grid-column-1');\n lockedColumn[i].classList.add('grid-column-' + previousColumnIndex);\n\n // rollback first column:\n previousFirstColumn[i].classList.remove('grid-column-' + previousColumnIndex);\n previousFirstColumn[i].classList.add('grid-column-1');\n }\n\n // unlock slide:\n lockedSlide.classList.remove('locked-column');\n\n previousFirstSlideField = previousFirstSlide.outerHTML;\n lockedSlideTempField = lockedSlide.outerHTML;\n\n // rollback slide data:\n previousFirstSlide.outerHTML = lockedSlideTempField;\n lockedSlide.outerHTML = previousFirstSlideField;\n }\n\n private lockAndMoveColumn(selectedColumns: Array, selectedSlide: HTMLElement, selectedColumnIndex: number): void {\n let firstSlideTempField: string;\n let selectedSlideTempField: string;\n const tmpFirstColumn: Array = this.getColumn(1);\n const tmpFirstSlide: HTMLElement = this.getStickyHeaderSlide(1);\n\n // replace selected column content with first column:\n for(let i: number = 0; i < tmpFirstColumn.length; i++) {\n // lock column:\n selectedColumns[i].classList.add('locked-column');\n\n // remove his own grid-column-??? class\n selectedColumns[i].classList.remove('grid-column-' + selectedColumnIndex);\n\n // move selected column to first position:\n selectedColumns[i].classList.add('grid-column-1')\n\n // remove his own grid-column-1 class\n tmpFirstColumn[i].classList.remove('grid-column-1');\n\n // move first column to selected position:\n tmpFirstColumn[i].classList.add('grid-column-' + selectedColumnIndex);\n }\n\n // replace selected slide content with first slide:\n selectedSlide.classList.add('locked-column');\n\n firstSlideTempField = tmpFirstSlide.outerHTML;\n selectedSlideTempField = selectedSlide.outerHTML;\n\n tmpFirstSlide.outerHTML = selectedSlideTempField;\n selectedSlide.outerHTML = firstSlideTempField;\n }\n\n private lockColumn(selectedColumns: Array, selectedSlide: HTMLElement): void {\n // lock defined column:\n for (const selectedColumn of selectedColumns) {\n selectedColumn.classList.add('locked-column');\n }\n\n // lock defined sticky header slide:\n selectedSlide.classList.add('locked-column');\n }\n\n private unlockColumn(selectedColumns: Array, selectedSlide: HTMLElement): void {\n // unlock column:\n for (const selectedColumn of selectedColumns) {\n selectedColumn.classList.remove('locked-column');\n }\n\n selectedSlide.classList.remove('locked-column');\n }\n\n private getColumn(gridColumnIndex: number): Array {\n const selectedColumn: NodeListOf = this.grid.querySelectorAll('[grid-column-index=\"'+ gridColumnIndex +'\"]');\n return Array.prototype.slice.call(selectedColumn);\n }\n\n private getColumnHeader(gridColumnIndex: number): HTMLElement {\n const columnHeaders: NodeListOf = this.grid.querySelectorAll('.column-header-container');\n const columnHeadersArray: Array = Array.prototype.slice.call(columnHeaders);\n const columnHeader: HTMLElement = columnHeadersArray.filter(it => it.getAttribute('grid-column-index') == gridColumnIndex.toString())[0];\n\n return columnHeader;\n }\n\n private getStickyHeaderSlide(gridColumnIndex: number): HTMLElement {\n return this.stickyHeader.querySelector('[grid-column-index=\"' + gridColumnIndex + '\"]');\n }\n\n private getGridColumnIndex(columnHeader: HTMLElement): number {\n return parseInt(columnHeader.getAttribute('grid-column-index'));\n }\n\n private removeRegisteredEvents(): void {\n const columnHeaders: NodeListOf = this.grid.querySelectorAll('.column-header-container');\n const columnHeadersArray: Array = Array.prototype.slice.call(columnHeaders);\n\n for (const columnHeader of columnHeadersArray) {\n const tmpLockedColumn: HTMLElement = columnHeader.querySelector('.mpc-locked-column');\n \n if(tmpLockedColumn)\n tmpLockedColumn.removeEventListener('click', this.lockUnLockColumnEvent );\n \n const tmpUnLockedColumn: HTMLElement = columnHeader.querySelector('.mpc-locked-column');\n \n if(tmpUnLockedColumn)\n tmpUnLockedColumn.removeEventListener('click', this.lockUnLockColumnEvent );\n }\n }\n\n private changeLockIcon(parentContainer: HTMLElement, showLocked: boolean): void {\n const lockedColumn: Element = parentContainer.querySelector('.mpc-locked-column');\n\n if (showLocked) {\n lockedColumn.classList.add('locked');\n }\n else {\n lockedColumn.classList.remove('locked');\n }\n }\n }\n}","export module MPCProductsCounter {\n ///count might be changed later by ajax loading\n ///e.g. when you navigate via MHS to the page, the URL has no savKey parameter, and the page then ajax-loads the localStorage data and updates the counter\n export class ProductsCounter {\n private productsCounterValue: HTMLElement;\n\n constructor(carousel: HTMLElement) {\n this.productsCounterValue = carousel.querySelector('.products-counter .counter-value');\n }\n\n public updateProductsCounter(value: number): void {\n this.productsCounterValue.innerHTML = value.toString();\n }\n }\n}","import { MPCDeviceDetectionHelper } from \"../helpers/deviceDetectionHelper\";\n\nexport module MPCStickyHeaderService {\n import DeviceDetectionHelper = MPCDeviceDetectionHelper.DeviceDetectionHelper;\n\n export class StickyHeaderService {\n private scope: HTMLElement;\n private headerDistance: number;\n private shrinkModeActive: boolean;\n private deviceDetectionHelper: DeviceDetectionHelper;\n private gridContainer: HTMLElement;\n private overlay: HTMLElement;\n private respect_glb: boolean = false;\n\n public init(scope: HTMLElement): void {\n this.scope = scope;\n this.deviceDetectionHelper = DeviceDetectionHelper.instance;\n this.gridContainer = this.scope.querySelector('.grid');\n this.overlay = this.gridContainer.querySelector('.mpc-loading-overlay');\n\n const gridEmptyHeaders: NodeListOf = this.scope.querySelectorAll('.empty-header');\n if (gridEmptyHeaders.length >= 4) {\n return;\n }\n\n if (this.deviceDetectionHelper.isMobileShop()) {\n this.headerDistance = 400;\n window.addEventListener('scroll', () => { this.handleMobileGridHeaderOnScroll() });\n }\n else {\n this.headerDistance = 600;\n window.addEventListener('scroll', () => { this.handleGridHeaderOnScroll() });\n }\n\n if (this.gridContainer && this.gridContainer.dataset.portalmandanttoken \n && this.gridContainer.dataset.portalmandanttoken === \"GLB\") {\n this.respect_glb = true;\n }\n }\n\n private handleGridHeaderOnScroll(): void {\n if (!this.gridContainer) {\n return;\n }\n\n const columnHeaderContainers: NodeListOf = this.gridContainer.querySelectorAll('.column-header-container');\n const columnHeaderContainersArray: Array = Array.prototype.slice.call(columnHeaderContainers);\n const verticalDistance: number = window.pageYOffset || document.documentElement.scrollTop;\n \n if (this.gridContainer.clientHeight > window.innerHeight || this.shrinkModeActive) {\n for (const columnHeaderContainer of columnHeaderContainersArray) {\n const headerFadeArea: HTMLElement = columnHeaderContainer.querySelector('.header-fade-area');\n\n if (verticalDistance > this.headerDistance) {\n columnHeaderContainer.classList.add('shrink-header');\n\n this.overlay.classList.remove('normal-top-distance');\n this.overlay.classList.add('top-distance-on-shrink');\n setTimeout(() => { headerFadeArea.style.opacity = \"1\"; }, 100);\n this.shrinkModeActive = true;\n } else {\n headerFadeArea.style.opacity = \"0\";\n columnHeaderContainer.classList.remove('shrink-header');\n\n this.overlay.classList.add('normal-top-distance');\n this.overlay.classList.remove('top-distance-on-shrink');\n this.shrinkModeActive = false;\n }\n }\n }\n }\n\n private handleMobileGridHeaderOnScroll(): void {\n const gridCarousel: HTMLElement = this.scope.querySelector('.grid-carousel-container');\n\n if (!gridCarousel)\n return;\n\n const stickyHeaderContainer: HTMLElement = this.scope.querySelector('.sticky-header-container');\n\n if (!stickyHeaderContainer)\n return;\n\n const slideSlots: NodeListOf = stickyHeaderContainer.querySelectorAll('.slide-slot');\n const slideSlotsArray: Array = Array.prototype.slice.call(slideSlots);\n const verticalDistance: number = window.pageYOffset || document.documentElement.scrollTop;\n const lockedColumnExists: boolean = slideSlotsArray.filter(it => it.classList.contains('locked-column')).length > 0;\n\n if (verticalDistance > this.headerDistance) {\n stickyHeaderContainer.classList.add('shrink-header');\n\n if(this.respect_glb)\n stickyHeaderContainer.classList.add('respect_glb');\n\n gridCarousel.classList.add('normal-size-carousel');\n\n if (lockedColumnExists) {\n gridCarousel.classList.add('display-extras-for-sticky-header');\n stickyHeaderContainer.classList.add('display-extras-for-sticky-header');\n }\n }\n else {\n stickyHeaderContainer.classList.remove('shrink-header');\n \n if(this.respect_glb)\n stickyHeaderContainer.classList.remove('respect_glb');\n\n gridCarousel.classList.remove('normal-size-carousel');\n\n if (lockedColumnExists) {\n gridCarousel.classList.remove('display-extras-for-sticky-header');\n stickyHeaderContainer.classList.remove('display-extras-for-sticky-header');\n }\n }\n }\n }\n}","import { MpcSettingsModule } from \"./helpers/MpcSettings\";\r\nimport { NlVanillajax, INlVanillajaxParams, ContentType } from \"./helpers/vanillajax\";\r\nimport { ErrorMessage } from \"../../Models/ErrorMessage.generated\"\r\n\r\ndeclare const window: Window;\r\n\r\nexport module MPCErrorHandlerModule {\r\n import MpcSettings = MpcSettingsModule.MpcSettings;\r\n\r\n export class ErrorHandlerManager {\r\n private static _instance: ErrorHandlerManager;\r\n private static _errorCount: number = 0;\r\n private _settings: MpcSettings;\r\n\r\n static get instance() {\r\n return this._instance || (this._instance = new this());\r\n }\r\n\r\n constructor() {\r\n this.Init();\r\n }\r\n\r\n public Init(): void {\r\n this._settings = MpcSettings.instance;\r\n window.onerror = (msg, url, line, col, error) => {\r\n ErrorHandlerManager._errorCount++;\r\n if (ErrorHandlerManager._errorCount > 10) {\r\n return true;\r\n }\r\n\r\n const string = msg.toString().toLowerCase();\r\n const substring = \"script error\";\r\n if (string.indexOf(substring) === 0) {\r\n console.warn(\"cannot handle JS error. probably CORS issue.\");\r\n return false;\r\n }\r\n\r\n if (typeof (msg) !== \"string\") {\r\n let errorEvent: ErrorEvent = (msg);\r\n if (errorEvent.error) {\r\n msg = errorEvent.error.message + \"\\n\"+ errorEvent.error.stack;\r\n line = errorEvent.lineno;\r\n col = errorEvent.colno;\r\n url = errorEvent.filename;\r\n } else {\r\n msg = JSON.stringify(msg);\r\n }\r\n }\r\n //log error to service\r\n let errStr: string = undefined;\r\n if(error)\r\n errStr = JSON.stringify(error);\r\n const errorMsg = {\r\n message: msg,\r\n url: url,\r\n line: line,\r\n col: col,\r\n error: errStr\r\n };\r\n this.LogError(errorMsg);\r\n\r\n // for development, we want to see errors in console \r\n const suppressDefaultErrorHandlerAkaConsolePrint = !this._settings.isDevelopment;\r\n \r\n return suppressDefaultErrorHandlerAkaConsolePrint;\r\n };\r\n }\r\n\r\n public LogError(error: ErrorMessage): Promise {\r\n // handle only mpc errors:\r\n\r\n // source off error has to be known, if there is bundle/ file url, skip this logging:\r\n if (!error.url)\r\n return;\r\n\r\n // asset url has to contain mpc scope name\r\n if(error.url.indexOf('manualproductcomparison') === -1)\r\n return;\r\n \r\n // MPC is made on pure html and ts, we are not responsible for any react or other frameworks:\r\n if(error.message.indexOf('ReactDOM') > 0)\r\n return;\r\n \r\n // read local storage and stringify it. This will help to solve problems and get better feeling what data was used on exception:\r\n const mpcLocalStorage = this.collectAllLocalStorageObjects();\r\n if (mpcLocalStorage && Object.keys(mpcLocalStorage).length > 0) {\r\n error.mpcLocalStorage = JSON.stringify(mpcLocalStorage);\r\n }\r\n else {\r\n error.mpcLocalStorage = 'local storage was not found';\r\n }\r\n\r\n let params: INlVanillajaxParams = {};\r\n params.url = MpcSettingsModule.MpcSettings.instance.apiUrl +\r\n 'Debug/LogJavascriptError';\r\n params.data = JSON.stringify(error);\r\n\r\n return new NlVanillajax(params).postWithPromise()\r\n .then(() => {\r\n })\r\n .catch((reason) => {\r\n console.log(\"error could not be logged to service. reason: \"+reason.status+\" \"+reason.statusText);\r\n });\r\n }\r\n\r\n private collectAllLocalStorageObjects(): Record {\r\n const oldPrefix = 'productComparison'; //no ref to LocalStorageAbstraction to avoid circular ref\r\n const combinedData: Record = {};\r\n\r\n for (let i = 0; i < localStorage.length; i++) {\r\n const key = localStorage.key(i);\r\n if (key && key.startsWith(oldPrefix)) {\r\n const itemStr = localStorage.getItem(key);\r\n if (itemStr) {\r\n combinedData[key] = itemStr;\r\n }\r\n }\r\n }\r\n\r\n return combinedData;\r\n }\r\n }\r\n}\r\n\r\nMPCErrorHandlerModule.ErrorHandlerManager.instance.Init();","export module MpcSettingsModule {\n export class MpcSettings {\n private static _instance: MpcSettings;\n private static initDone: boolean = false;\n\n static get instance() {\n return this._instance || (this._instance = new this());\n }\n\n public init(scope: HTMLElement): void {\n this._culture = scope.getAttribute(\"data-culture\");\n this._portal = scope.getAttribute(\"data-portal\");\n this._portalMandantToken = scope.getAttribute(\"data-portalmandanttoken\");\n this._maxProducts = parseInt(scope.getAttribute(\"data-maxProducts\"));\n this._isLoggedIn = scope.getAttribute(\"data-isLoggedIn\") === \"true\";\n this._isDevelopment = scope.getAttribute(\"data-isDevelopment\") === \"true\";\n this._apiUrl = scope.getAttribute(\"data-apiUrl\");\n \n MpcSettings.initDone = true;\n }\n\n private _culture:string;\n get culture():string {\n if (!MpcSettings.initDone) throw new Error(\"MpcSettings: init not called yet\");\n return this._culture;\n }\n\n private _portalMandantToken: string;\n get portalMandantToken(): string {\n if (!MpcSettings.initDone) throw new Error(\"MpcSettings: init not called yet\");\n return this._portalMandantToken;\n }\n\n private _apiUrl: string;\n get apiUrl(): string {\n if (!MpcSettings.initDone) throw new Error(\"MpcSettings: init not called yet\");\n return this._apiUrl;\n }\n \n private _maxProducts:number;\n get maxProducts():number {\n if (!MpcSettings.initDone) throw new Error(\"MpcSettings: init not called yet\");\n return this._maxProducts;\n }\n\n private _isLoggedIn: boolean;\n get isLoggedIn(): boolean {\n if (!MpcSettings.initDone) throw new Error(\"MpcSettings: init not called yet\");\n return this._isLoggedIn;\n }\n \n private _isDevelopment: boolean;\n get isDevelopment(): boolean {\n if (!MpcSettings.initDone) throw new Error(\"MpcSettings: init not called yet\");\n return this._isDevelopment;\n }\n\n private _portal:string;\n get portal():string {\n if (!MpcSettings.initDone) throw new Error(\"MpcSettings: init not called yet\");\n return this._portal;\n }\n\n public MobileCategoryNavKey: string;\n\n }\n}","import { ProductComparisonModel } from \"../../../Models/Product.generated\";\n\nexport module MPCComparePageButtonUrlUpdater {\n export class ComparePageButtonUrlUpdater {\n private static _instance: ComparePageButtonUrlUpdater;\n private scope: HTMLElement;\n private comparisonPageBaseUri: string;\n\n public init(scope: HTMLElement): void {\n this.scope = scope;\n this.comparisonPageBaseUri = scope.getAttribute('data-comparisonpage-baseurl');\n }\n\n static get instance() {\n return this._instance || (this._instance = new this());\n }\n\n private _comparePageUrl:string = \"\";\n get ComparePageUrl():string {\n return this._comparePageUrl;\n }\n\n public onUpdatedModel(model : ProductComparisonModel): void {\n let result: string = \"\";\n\n if(model && model.activeNavigationTab) {\n const activeNavigationTab = model.activeNavigationTab;\n\n let comparisonPageUri: string = '?category=' + encodeURIComponent(activeNavigationTab);\n\n for (const storageProduct of model.products) {\n if (storageProduct.categoryName === activeNavigationTab) {\n comparisonPageUri = comparisonPageUri + '&savKeys=' + storageProduct.articleId.salesArticleVariantKey;\n }\n }\n\n result = comparisonPageUri;\n }\n\n if(!this.scope || this.scope === null) {\n // get root mpc place holder:\n this.scope = document.querySelector('.pcf-scope');\n this.comparisonPageBaseUri = this.scope.getAttribute('data-comparisonpage-baseurl');\n }\n\n this._comparePageUrl = this.comparisonPageBaseUri+result;\n\n if (this.scope) {\n const links = this.scope.querySelectorAll(\".comparison-page-link\");\n\n for (let link of links) {\n link.setAttribute('href', this._comparePageUrl);\n }\n }\n }\n }\n}","export module MPCDeviceDetectionHelper {\r\n export class DeviceDetectionHelper {\r\n private static _instance: DeviceDetectionHelper;\r\n private isTabletHandHeldDeviceEnvironment: boolean;\r\n private isMobileShopEnvironment: boolean;\r\n private isMicrosoftBrowserEnvironment: boolean;\r\n private sniffJson: HTMLElement;\r\n\r\n constructor() {\r\n this.init();\r\n }\r\n\r\n static get instance() {\r\n return this._instance || (this._instance = new this());\r\n }\r\n\r\n private init(): void {\r\n this.isTabletHandHeldDeviceEnvironment = \r\n document.documentElement.className.indexOf('tablet') >= 0 || document.documentElement.className.indexOf('handheld') >= 0;\r\n\r\n this.isMobileShopEnvironment = \r\n document.documentElement.className.indexOf('mobileshop') >= 0;\r\n\r\n this.isMicrosoftBrowserEnvironment =\r\n document.documentElement.classList.contains(\"isMsie\") || document.documentElement.classList.contains(\"isEdge\");\r\n\r\n this.sniffJson = document.getElementById(\"sniff\");\r\n if (!this.sniffJson)\r\n return;\r\n\r\n const sniffJsonResult = JSON.parse(this.sniffJson.innerHTML);\r\n let resultingClasses: string = '';\r\n if (sniffJsonResult.isTablet) {\r\n document.body.dataset.cap = \"IsHandheld=true,IsLowendDevice=false\";\r\n resultingClasses += ' tablet';\r\n }\r\n if (sniffJsonResult.isPhone) \r\n resultingClasses = ' phone';\r\n if (sniffJsonResult.isHandheld) \r\n resultingClasses += ' handheld';\r\n if (sniffJsonResult.isAndroid) \r\n resultingClasses += ' android';\r\n if (sniffJsonResult.isIOS) \r\n resultingClasses += ' ios';\r\n if (!resultingClasses)\r\n return;\r\n\r\n const htmlClasses: string = document.documentElement.className;\r\n document.documentElement.className = htmlClasses.replace('desktop', resultingClasses);\r\n\r\n if (sniffJsonResult.isMsie)\r\n document.documentElement.classList.add('isMsie');\r\n if (sniffJsonResult.isEdge)\r\n document.documentElement.classList.add('isEdge');\r\n }\r\n\r\n public isTabletHandHeldDevice(): boolean {\r\n return this.isTabletHandHeldDeviceEnvironment;\r\n }\r\n\r\n public isMobileShop(): boolean {\r\n return this.isMobileShopEnvironment;\r\n }\r\n\r\n public isMicrosoftBrowser(): boolean {\r\n return this.isMicrosoftBrowserEnvironment;\r\n }\r\n\r\n // removed because of ESPP-4706\r\n // public adaptLegacySniff(): void {\r\n // const deviceDetector = new DeviceDetector();\r\n // const device: DeviceDetector.DeviceDetectorResult = \r\n // deviceDetector.parse(window.navigator.userAgent);\r\n\r\n // let resultingClasses: string = '';\r\n // let sniffResult: string = '{';\r\n\r\n // if (device.device.type === 'desktop')\r\n // sniffResult += '\"isDesktop\": true';\r\n // else \r\n // sniffResult += '\"isDesktop\": false';\r\n\r\n // if (device.device.type === 'tablet') {\r\n // document.body.dataset.cap = \"IsHandheld=true,IsLowendDevice=false\";\r\n // resultingClasses = 'tablet';\r\n // sniffResult += ', \"isTablet\": true';\r\n // }\r\n // else \r\n // sniffResult += ', \"isTablet\": false';\r\n\r\n // if (device.device.model === 'iPad')\r\n // sniffResult += ', \"isIPad\": true';\r\n // else \r\n // sniffResult += ', \"isIPad\": false';\r\n \r\n // sniffResult += '}';\r\n\r\n // if (resultingClasses) {\r\n // const htmlClasses: string = document.documentElement.className;\r\n // document.documentElement.className = htmlClasses.replace('desktop', resultingClasses);\r\n // }\r\n\r\n // this.sniffJson.innerHTML = sniffResult;\r\n // }\r\n }\r\n}","import { MPCIEventBus } from \"../typings/iEventBus\";\r\n\r\nexport module MPCEventBus {\r\n import IEventBus = MPCIEventBus.IEventBus;\r\n import EventName = MPCIEventBus.EventName;\r\n import CallbackLists = MPCIEventBus.CallbackLists;\r\n import ICallback = MPCIEventBus.ICallback;\r\n import ISubscription = MPCIEventBus.ISubscription;\r\n import ISubscriptionId = MPCIEventBus.ISubscriptionId;\r\n\r\n export class EventBus implements IEventBus {\r\n private static _instance: EventBus;\r\n private callbackLists: CallbackLists;\r\n\r\n private constructor() {\r\n this.callbackLists = [];\r\n }\r\n\r\n static get instance() {\r\n return this._instance || (this._instance = new this());\r\n }\r\n\r\n subscribe(eventName: EventName | EventName[], callback: ICallback): ISubscriptionId[] {\r\n if (this.isArray(eventName)) {\r\n const subscriptionsIds: ISubscriptionId[] = [];\r\n\r\n for (const message of eventName) {\r\n subscriptionsIds.push(this.createSubscription(message, callback));\r\n }\r\n\r\n return subscriptionsIds;\r\n } else {\r\n return [this.createSubscription(eventName, callback)];\r\n }\r\n }\r\n\r\n subscribeMultiple(subscriptions: ISubscription[]): ISubscriptionId[] {\r\n const subscriptionIds: ISubscriptionId[] = [];\r\n\r\n if (!subscriptions) {\r\n return subscriptionIds;\r\n }\r\n\r\n for (const subscription of subscriptions) {\r\n const subscriptionId: ISubscriptionId = this.addSubscription(subscription);\r\n\r\n subscriptionIds.push(subscriptionId);\r\n }\r\n return subscriptionIds;\r\n }\r\n\r\n unsubscribe(subscriptionId: ISubscriptionId | ISubscriptionId[]): void {\r\n if (this.isArray(subscriptionId)) {\r\n this.unSubscribeMultiple(subscriptionId);\r\n } else {\r\n this.removeSubscription(subscriptionId);\r\n }\r\n }\r\n\r\n publish(eventName: EventName, payload?: any): void {\r\n if (!this.callbackLists[eventName]) {\r\n return;\r\n }\r\n\r\n // to prevent to also iterate over subscriptions, which are created while iterating\r\n const callbacksClone: ICallback[] = this.callbackLists[eventName].slice(0);\r\n for (const callback of callbacksClone) {\r\n if (callback) {\r\n callback(payload);\r\n }\r\n }\r\n }\r\n\r\n private createSubscription(eventName: EventName, callback: ICallback): ISubscriptionId {\r\n return this.addSubscription({\r\n eventName: eventName,\r\n callback: callback\r\n });\r\n }\r\n\r\n private addSubscription(subscription: ISubscription): ISubscriptionId {\r\n if (!this.callbackLists[subscription.eventName]) {\r\n this.callbackLists[subscription.eventName] = [];\r\n }\r\n\r\n const subscriptionId: ISubscriptionId = {\r\n eventName: subscription.eventName,\r\n id: (this.callbackLists[subscription.eventName].push(subscription.callback)) - 1\r\n };\r\n\r\n return subscriptionId;\r\n }\r\n\r\n private unSubscribeMultiple(subscriptionIds: ISubscriptionId[]): void {\r\n for (const subscriptionId of subscriptionIds) {\r\n this.removeSubscription(subscriptionId);\r\n }\r\n }\r\n\r\n private removeSubscription(subscriptionId: ISubscriptionId): void {\r\n const subscription: ICallback = this.callbackLists[subscriptionId.eventName][subscriptionId.id];\r\n if (subscription) {\r\n this.callbackLists[subscriptionId.eventName][subscriptionId.id] = undefined;\r\n }\r\n }\r\n\r\n private isArray(element: any): element is any[] {\r\n return Array.isArray(element);\r\n }\r\n }\r\n}","export module MPCElementsHelper {\n export class HtmlElementsHelper {\n public static appendChildAtIndex(child: HTMLElement, index: number, parent: HTMLElement): void {\n if(index >= parent.children.length) {\n parent.appendChild(child);\n }\n else {\n parent.insertBefore(child, parent.children[index]);\n }\n }\n }\n}","import {MPCElementsHelper} from \"../helpers/htmlElementsHelper\";\nimport {MPCINavigationService} from \"../typings/iNavigationService\";\nimport { MPCIAbstractContent } from \"../typings/iAbstractContent\";\nimport { MPCNotificationService } from \"../PCF/notification-service\";\nimport { NavigationTab } from \"../../../Models/Product.generated\";\nimport { MPCDeviceDetectionHelper } from \"../helpers/deviceDetectionHelper\";\nimport { MPCLocalStorageService } from \"../local-storage-service\";\n\nexport module MPCNavigationService {\n import INavigationService = MPCINavigationService.INavigationService;\n import HtmlElementsHelper = MPCElementsHelper.HtmlElementsHelper;\n import IAbstractContent = MPCIAbstractContent.IAbstractContent;\n import NotificationService = MPCNotificationService.NotificationService;\n import DeviceDetectionHelper = MPCDeviceDetectionHelper.DeviceDetectionHelper;\n import ProductComparisonModelManager = MPCLocalStorageService.ProductComparisonModelManager;\n\n //extend the service interface by some properties that are only used in TS\n interface NavigationTabTs extends NavigationTab {\n domNode: HTMLElement;\n savKeys: string[];\n }\n\n export class NavigationService implements INavigationService {\n private static _instance: NavigationService;\n private navigationTabs: HTMLElement;\n private selectCategoryButton: HTMLElement;\n private navigationTabsArray: Array;\n private activeNavigationTab: NavigationTabTs;\n private parentElement: HTMLElement;\n private navigationTabKeyName: string;\n private abstractContent: IAbstractContent;\n private notificationService: NotificationService;\n private deviceDetectionHelper: DeviceDetectionHelper;\n private productComparisonModelManager: ProductComparisonModelManager;\n\n static get instance() {\n return this._instance || (this._instance = new this());\n }\n\n init(parentElement: HTMLElement, navigationTabKeyName: string, abstractContent: IAbstractContent): void {\n\n if (parentElement) {\n this.deviceDetectionHelper = DeviceDetectionHelper.instance;\n this.notificationService = NotificationService.instance;\n this.parentElement = parentElement;\n this.selectCategoryButton = this.parentElement.querySelector('.select-category-button');\n this.navigationTabs = this.parentElement.querySelector('.navigation-tabs');\n this.navigationTabsArray = new Array();\n this.navigationTabKeyName = navigationTabKeyName;\n this.abstractContent = abstractContent;\n this.registerButtonEvent();\n }\n }\n\n private registerButtonEvent(): void {\n if (this.selectCategoryButton)\n this.selectCategoryButton.addEventListener('click', () => {\n this.notificationService.notifyEmptyList();\n });\n }\n\n private switchNavigationTab(newActiveNavigationTab: NavigationTabTs): void {\n if (this.activeNavigationTab) {\n this.activeNavigationTab.domNode.classList.remove('active-tab');\n\n const newActiveNavigationTabName: string = newActiveNavigationTab.name;\n const oldNavigationTabName: string = this.activeNavigationTab.name;\n\n if (this.deviceDetectionHelper.isMobileShop()) {\n // clear locked column info:\n this.productComparisonModelManager = ProductComparisonModelManager.instance;\n this.productComparisonModelManager.clearLockedColumnIndex();\n this.productComparisonModelManager.clearCarouselScrollIndex();\n }\n\n if (this.abstractContent) {\n this.abstractContent.updateContainerListVisibility(newActiveNavigationTabName, oldNavigationTabName);\n }\n }\n\n this.activeNavigationTab = newActiveNavigationTab;\n newActiveNavigationTab.domNode.classList.add('active-tab');\n }\n\n private scrollToNavigationTab(newActiveNavigationTab: NavigationTabTs): void {\n const buttonLeftEdgePosition = newActiveNavigationTab.domNode.getBoundingClientRect().left;\n const buttonRightEdgePosition = buttonLeftEdgePosition + newActiveNavigationTab.domNode.offsetWidth;\n const rightMargin = 10;\n\n if (buttonRightEdgePosition > window.innerWidth) {\n this.navigationTabs.scrollLeft = buttonRightEdgePosition + rightMargin - window.innerWidth;\n }\n }\n\n public createOrUpdateNavigationTab(categoryName: string, counterNumber: number, navigationOrder: number,\n salesArticleVariantKey: string, createEmptyNavTab: boolean = false): void {\n let isNew: boolean = true;\n \n // look for existing tab:\n for(const navigationTab of this.navigationTabsArray) {\n const currentNavigationTabName = navigationTab.domNode.getAttribute(this.navigationTabKeyName);\n if(currentNavigationTabName === categoryName) {\n if (navigationTab.savKeys.indexOf(salesArticleVariantKey) >= 0) {\n return; //sav already added (happens when ajax reloads)\n }\n if (counterNumber > 0) {\n navigationTab.savKeys.push(salesArticleVariantKey);\n if(!this.abstractContent)//that URL is only used from PCP\n this.appendSavKeyToNavTabUrl(navigationTab, salesArticleVariantKey);\n } else if (counterNumber < 0) {\n navigationTab.savKeys = navigationTab.savKeys.slice(navigationTab.savKeys.indexOf(salesArticleVariantKey), 1);\n //no removal from url nessesary because that URL is only used from PCP, where articles are only added \n //(when loading the page, remove triggers a page reload)\n }\n this.updateCounter(navigationTab, counterNumber);\n\n isNew = false;\n break;\n }\n }\n\n if (isNew) {\n const newNavigationTab: NavigationTabTs = this.createNavigationTab(categoryName, salesArticleVariantKey,\n navigationOrder, createEmptyNavTab);\n this.updateCounter(newNavigationTab, counterNumber);\n let indexToInsert = 0;\n for (let navigationTab of this.navigationTabsArray) {\n if (navigationOrder < navigationTab.navigationOrder) {\n break;\n }\n indexToInsert++;\n }\n\n this.navigationTabsArray.splice(indexToInsert, 0, newNavigationTab);\n \n // tab navigation:\n newNavigationTab.domNode.setAttribute('focusable', '');\n\n HtmlElementsHelper.appendChildAtIndex(newNavigationTab.domNode, indexToInsert, this.navigationTabs);\n newNavigationTab.domNode.addEventListener('click', () => {\n this.switchNavigationTab(newNavigationTab);\n });\n\n if (window.shell.tabNav !== undefined)\n window.shell.tabNav.onActivated('.navigation-tab .has-focus', \n () => { this.switchNavigationTab(newNavigationTab); });\n }\n }\n\n public updateSelectCategoryButtonVisibility(): void {\n if (!this.selectCategoryButton)\n return;\n\n if (!this.isAnyProductCounted())\n this.selectCategoryButton.classList.remove(\"hidden\");\n }\n\n private isAnyProductCounted(): boolean {\n let productFound = false;\n this.navigationTabsArray.forEach((tab: NavigationTabTs) => {\n if (this.getCounterNumber(tab)) {\n productFound = true;\n return;\n }\n });\n\n return productFound;\n }\n\n private updateCounter(navigationTab: NavigationTabTs, counterNumber: number): void {\n const productsCounter: HTMLElement = navigationTab.domNode.querySelector('.products-counter');\n let counter: number = Number(productsCounter.textContent.trim());\n \n counter += counterNumber;\n productsCounter.innerText = counter.toString();\n }\n\n private getCounterNumber(navigationTab: NavigationTabTs): number {\n const productsCounter: HTMLElement = navigationTab.domNode.querySelector('.products-counter');\n return Number(productsCounter.innerText);\n }\n \n private appendSavKeyToNavTabUrl(navigationTab: NavigationTabTs, salesArticleVariantKey: string): void {\n let comparisonPageUri: string = navigationTab.domNode.getAttribute('href');\n comparisonPageUri = comparisonPageUri + '&savKeys=' + salesArticleVariantKey;\n navigationTab.domNode.setAttribute('href', comparisonPageUri);\n }\n\n private createNavigationTab(categoryName: string, salesArticleVariantKey: string, order: number,\n createEmptyNavTab: boolean): NavigationTabTs {\n let newNavigationTab: NavigationTabTs = {} as NavigationTabTs;\n newNavigationTab.navigationOrder = order;\n newNavigationTab.name = categoryName;\n newNavigationTab.savKeys = [salesArticleVariantKey];\n let newNavigationTabHtml: HTMLElement;\n\n if (salesArticleVariantKey || createEmptyNavTab) {\n // create navigation ab from comparison page:\n newNavigationTabHtml = document.createElement('a');\n\n // comparisonPageUri is used in PCP page, flyout does not need it:\n let comparisonPageUri: string;\n if (!this.abstractContent) {\n comparisonPageUri = '?category=' + encodeURIComponent(categoryName);\n if (salesArticleVariantKey) {\n comparisonPageUri += '&savKeys=' + salesArticleVariantKey;\n }\n } else {\n comparisonPageUri = 'javascript:';\n }\n\n newNavigationTabHtml.setAttribute('href', comparisonPageUri);\n }\n else {\n // create navigation tab for flyout:\n newNavigationTabHtml = document.createElement('div');\n }\n \n const newCategoryName: HTMLElement = document.createElement('div');\n const newArticlesCounter: HTMLElement = document.createElement('div');\n\n newNavigationTabHtml.className = 'navigation-tab';\n newNavigationTabHtml.setAttribute(this.navigationTabKeyName, categoryName);\n newCategoryName.className = 'category-name';\n newCategoryName.innerText = categoryName;\n newArticlesCounter.className = 'products-counter';\n \n newNavigationTabHtml.appendChild(newCategoryName);\n newNavigationTabHtml.appendChild(newArticlesCounter);\n\n newNavigationTabHtml.addEventListener('keydown', (event: any) => {\n // prevent page jump down on Space btn., click\n if (event.code === 'Space')\n event.preventDefault();\n\n if(!window.shell.tabNav)\n return;\n \n if (event.code === 'ArrowRight' && event.target.nextElementSibling) {\n window.shell.tabNav.focus(event.target.nextElementSibling);\n }\n \n if (event.code === 'ArrowLeft' && event.target.previousElementSibling) {\n window.shell.tabNav.focus(event.target.previousElementSibling);\n }\n });\n\n newNavigationTab.domNode = newNavigationTabHtml;\n return newNavigationTab;\n }\n\n public removeEmptyNavigationTabs(): void {\n if(this.navigationTabsArray) {\n let removableNavigationTabs: Array = new Array();\n\n for (const navigationTab of this.navigationTabsArray) {\n const productsCounter: HTMLElement = navigationTab.domNode.querySelector('.products-counter');\n const counter: number = Number(productsCounter.innerText);\n\n if (counter == 0) {\n removableNavigationTabs.push(navigationTab);\n \n // remove highlight from last navigation tab:\n // temporary disabled by customer: ESPP-1523\n /* if (this.navigationTabsArray.length == 1) {\n this.navigationTabsArray[0].classList.remove('active-tab');\n } */\n }\n }\n\n for (const tmpTab of removableNavigationTabs) {\n this.navigationTabs.removeChild(tmpTab.domNode);\n this.navigationTabsArray.splice(this.navigationTabsArray.indexOf(tmpTab), 1);\n }\n }\n }\n\n public markActiveNavigationTab(categoryName: string): boolean {\n let newTabActivated: boolean;\n for (const navigationTab of this.navigationTabsArray) {\n let navigationTabName: string = navigationTab.domNode.getAttribute(this.navigationTabKeyName);\n\n if (navigationTabName === categoryName) {\n this.switchNavigationTab(navigationTab);\n this.scrollToNavigationTab(navigationTab);\n newTabActivated = true;\n break;\n }\n }\n\n return newTabActivated;\n }\n\n public markAnyNavigationTabActive(): string {\n // after category was cleared, active tab is not selected.\n // Need to define last one o first one navigation tab from navigation service container.\n let newActiveTabCatName: string;\n\n if (this.navigationTabsArray && this.navigationTabsArray.length > 0) {\n const newActiveTab: NavigationTabTs =\n this.navigationTabsArray[this.navigationTabsArray.length - 1];\n\n newActiveTabCatName = newActiveTab.name;\n this.switchNavigationTab(newActiveTab);\n this.scrollToNavigationTab(newActiveTab);\n }\n\n return newActiveTabCatName;\n }\n\n public getFirstNavigationTab(): HTMLElement {\n if (this.navigationTabsArray && this.navigationTabsArray.length > 0) {\n const firstTab: NavigationTabTs = this.navigationTabsArray[0];\n\n return firstTab.domNode;\n }\n\n return;\n }\n }\n}","//IE polyfills\nimport 'eligrey-classlist-js-polyfill';\nimport 'element-remove';\nif (typeof NodeList.prototype.forEach !== \"function\" && typeof Array.prototype.forEach === \"function\")\n NodeList.prototype.forEach = ((Array.prototype.forEach) as any);","export module MPCScrollLock {\n export class ScrollLock\n {\n private static _instance: ScrollLock;\n private bodyScrollPosition: number = 0;\n\n static get instance() {\n return this._instance || (this._instance = new this());\n }\n\n public lock(): void {\n const webContainer = document.querySelector('.container');\n const mobileContainer = document.querySelector('.page-container');\n this.bodyScrollPosition = window.pageYOffset;\n \n if (webContainer || mobileContainer)\n document.body.setAttribute(\n 'style',\n 'overflow: hidden !important; position: fixed !important; top: -' +\n this.bodyScrollPosition +\n 'px;'\n );\n }\n \n public unlock(): void {\n const webContainer = document.querySelector('.container');\n const mobileContainer = document.querySelector('.page-container');\n \n if (webContainer || mobileContainer) {\n document.body.removeAttribute('style');\n window.scrollTo(0, this.bodyScrollPosition);\n }\n }\n }\n}","import { MPCDeviceDetectionHelper } from \"../helpers/deviceDetectionHelper\";\r\nimport { MPCScrollLock } from \"../helpers/scrollLock\";\r\nconst SmartTimeout = require(\"smart-timeout\");\r\nconst InfoIcon = require(\"../../images/info.svg\") as string;\r\n\r\nexport module MPCToolTip {\r\n import DeviceDetectionHelper = MPCDeviceDetectionHelper.DeviceDetectionHelper;\r\n import ScrollLock = MPCScrollLock.ScrollLock;\r\n\r\n export class ToolTip {\r\n private tooltipContainer: HTMLElement;\r\n private mpcToolTip: HTMLElement;\r\n private toolTipHeight: number;\r\n private deviceDetectionHelper : DeviceDetectionHelper;\r\n private scrollLock: ScrollLock;\r\n private toolTipIsVisible: boolean;\r\n private tooltipId: string;\r\n private existingScrollEvent: EventListenerOrEventListenerObject;\r\n private mpcModalContainer: HTMLElement;\r\n\r\n public constructor(tooltipContainer: HTMLElement, mpcModalContainer: HTMLElement) {\r\n this.mpcModalContainer = mpcModalContainer;\r\n this.scrollLock = ScrollLock.instance;\r\n this.tooltipContainer = tooltipContainer;\r\n this.mpcToolTip = this.tooltipContainer.querySelector('.mpc-tooltip');\r\n this.tooltipContainer.querySelector('.mpc-info').innerHTML = InfoIcon;\r\n this.deviceDetectionHelper = DeviceDetectionHelper.instance;\r\n\r\n this.init();\r\n }\r\n\r\n private init(): void {\r\n this.toolTipIsVisible = false;\r\n this.setId();\r\n this.registerEvents();\r\n }\r\n\r\n private get supportsNativeSmoothScroll() {\r\n return 'scrollBehavior' in document.documentElement.style;\r\n }\r\n \r\n private registerEvents(): void {\r\n if(this.deviceDetectionHelper.isMobileShop()) {\r\n this.tooltipContainer.querySelector('.mpc-info').addEventListener('click', ()=> { this.openToolTipOverlay(); });\r\n this.mpcModalContainer.querySelector('.close-tooltip-btn').addEventListener('click', () => { this.closeToolTipOverlay(); });\r\n this.mpcModalContainer.querySelector('.close-tootlip-overlay').addEventListener('click', () => { this.closeToolTipOverlay(); });\r\n }\r\n else {\r\n this.existingScrollEvent = () => { this.hideToolTipOnScroll() };\r\n this.tooltipContainer.addEventListener('mouseover', (event: MouseEvent) => { this.handleMouseOverTooltipEvent(event); });\r\n\r\n this.tooltipContainer.addEventListener('mouseleave', (event: MouseEvent) => { this.handleMouseLeaveTooltipEvent(event); });\r\n }\r\n }\r\n\r\n private openToolTipOverlay(): void {\r\n let modalToolTipText: HTMLElement = this.mpcModalContainer.querySelector('.tooltip-text');\r\n const currentTooltipText: HTMLElement = this.mpcToolTip.querySelector('.tooltip-text');\r\n if (modalToolTipText && currentTooltipText) {\r\n modalToolTipText.innerHTML = currentTooltipText.innerHTML;\r\n }\r\n\r\n // Check rtf container:\r\n const richtextRoot: HTMLElement = this.mpcToolTip.querySelector('.richtext-root');\r\n if (richtextRoot && modalToolTipText) {\r\n modalToolTipText.innerHTML = richtextRoot.outerHTML;\r\n }\r\n\r\n let modalToolTipTitle: HTMLElement = this.mpcModalContainer.querySelector('.tooltip-title');\r\n const currentTooltipTitle: HTMLElement = this.mpcToolTip.querySelector('.tooltip-title');\r\n if (modalToolTipTitle && currentTooltipTitle) {\r\n modalToolTipTitle.innerHTML = currentTooltipTitle.innerHTML;\r\n }\r\n\r\n this.mpcModalContainer.classList.add('render-tooltip-overlay');\r\n\r\n const tooltTipeHeight: number = this.mpcModalContainer.querySelector('.tooltip-content').clientHeight;\r\n const calculatedWindowsSize: number = window.outerHeight - (window.outerHeight * 0.3);\r\n\r\n if (tooltTipeHeight <= calculatedWindowsSize) {\r\n this.mpcModalContainer.classList.add('no-touch-action');\r\n this.mpcModalContainer.ontouchmove = (event: TouchEvent) => { event.preventDefault(); }; // iOS ScrollLock\r\n }\r\n\r\n this.scrollLock.lock();\r\n }\r\n\r\n private closeToolTipOverlay(): void {\r\n this.mpcModalContainer.classList.remove('render-tooltip-overlay');\r\n this.mpcModalContainer.classList.remove('no-touch-action');\r\n this.mpcModalContainer.ontouchmove = () => {};\r\n this.scrollLock.unlock();\r\n }\r\n\r\n private handleMouseOverTooltipEvent(event: MouseEvent): void {\r\n if (!this.toolTipIsVisible) {\r\n this.mpcToolTip.classList.add('show-mpc-tooltip');\r\n const halfToolTipHeight: number = this.mpcToolTip.clientHeight / 2;\r\n const currentToolTipBottom: number = halfToolTipHeight + event.clientY;\r\n this.toolTipHeight = this.mpcToolTip.clientHeight;\r\n\r\n this.triggerAppShellPublish();\r\n this.toolTipIsVisible = true;\r\n\r\n if (window.innerHeight < currentToolTipBottom) {\r\n this.centerTooltip(currentToolTipBottom - window.innerHeight + 20);\r\n } else if (halfToolTipHeight > event.clientY) {\r\n this.centerTooltip(event.clientY - halfToolTipHeight - 20);\r\n }\r\n\r\n // attach to wheel event:\r\n document.addEventListener('wheel', this.existingScrollEvent);\r\n }\r\n }\r\n\r\n private centerTooltip(topPosition: number): void {\r\n if (this.supportsNativeSmoothScroll) {\r\n window.scrollBy({\r\n \"behavior\": \"smooth\",\r\n \"top\": topPosition\r\n });\r\n }\r\n else {\r\n // only for IE11\r\n let scrollTo: number = topPosition;\r\n\r\n if(scrollTo > 0) {\r\n for (let index = 1; index <= scrollTo; index++) {\r\n this.smoothScrollTo(1);\r\n }\r\n }\r\n else {\r\n for (let index = 1; index >= scrollTo; scrollTo++) {\r\n this.smoothScrollTo(-1);\r\n }\r\n }\r\n }\r\n }\r\n\r\n private handleMouseLeaveTooltipEvent(event: MouseEvent): void {\r\n const currentToolTipHeight: number = this.toolTipHeight + event.clientY;\r\n\r\n if (window.innerHeight < currentToolTipHeight || event.clientY < 224 && this.toolTipHeight > event.clientY) {\r\n if (!this.deviceDetectionHelper.isMobileShop() && window.shell)\r\n window.shell.subscribeTo('mpc.close-visible-tooltip', (tooltipId: string) => { this.forceToCloseCurrentTooltip(tooltipId); }, undefined);\r\n\r\n this.hideTooltipAfter2Seconds();\r\n }\r\n else {\r\n this.mpcToolTip.classList.remove('show-mpc-tooltip');\r\n this.toolTipIsVisible = false;\r\n this.hideToolTipOnScroll();\r\n }\r\n }\r\n\r\n private hideToolTipOnScroll(): void {\r\n if (this.toolTipIsVisible) {\r\n this.mpcToolTip.classList.remove('show-mpc-tooltip');\r\n this.toolTipIsVisible = false;\r\n }\r\n\r\n // remove attached scroll event:\r\n document.removeEventListener('wheel', this.existingScrollEvent);\r\n }\r\n private hideTooltipAfter2Seconds(): void {\r\n SmartTimeout.set(() => {\r\n this.mpcToolTip.classList.remove('show-mpc-tooltip');\r\n if (!this.deviceDetectionHelper.isMobileShop() && window.shell)\r\n window.shell.unsubscribeFrom('mpc.close-visible-tooltip', (tooltipId: string) => { this.forceToCloseCurrentTooltip(tooltipId); });\r\n this.toolTipIsVisible = false;\r\n }, 2000);\r\n }\r\n \r\n private smoothScrollTo(index: number): void { \r\n // for the IE11 we still need old setTimeout\r\n setTimeout(() => { window.scrollBy(0, index) }, 50);\r\n }\r\n\r\n private triggerAppShellPublish(): void {\r\n // close any other tooltip if it is open:\r\n if (window.shell) \r\n window.shell.publishTo('mpc.close-visible-tooltip', this.tooltipId);\r\n }\r\n\r\n private forceToCloseCurrentTooltip(tooltipId: string): void {\r\n if (this.toolTipIsVisible && this.tooltipId != tooltipId) {\r\n SmartTimeout.clear(this.handleMouseLeaveTooltipEvent);\r\n this.mpcToolTip.classList.remove('show-mpc-tooltip');\r\n this.toolTipIsVisible = false;\r\n }\r\n }\r\n\r\n private setId(): void {\r\n this.tooltipId = Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36);\r\n }\r\n }\r\n}\r\n\r\n","export interface INlVanillajaxParams {\n query?: string;\n data?: any;\n url: string;\n contentType: ContentType;\n}\n\nexport enum ContentType {\n JSON,\n Plain\n}\n\nexport interface HtmlResult {\n Html: string;\n}\n\nexport class NlVanillajax {\n headers: any[];\n private params: INlVanillajaxParams;\n private req: XMLHttpRequest;\n\n constructor(params: INlVanillajaxParams) {\n this.headers = [\n { \"name\": \"Accept\", \"value\": \"text/html,application/json\" },\n { \"name\": \"Content-Type\", \"value\": \"application/json\" }\n ];\n this.params = params;\n this.params.query = params.query || \"\";\n this.params.data = params.data || null;\n this.params.contentType = params.contentType || ContentType.JSON;\n this.req = this.xhr(window);\n }\n\n post(callback: Function): NlVanillajax {\n this.open(this.req, \"POST\", this.params.url + (this.params.query.length ? \"?\" + this.params.query : \"\"));\n this.setHeaders(this.req, this.headers);\n this.onReadyStateChange(this.req, callback);\n this.send(this.req, this.params.data);\n\n return this;\n }\n\n postWithPromise(): Promise {\n let self = this;\n return new Promise(function (resolve, reject) {\n self.open(self.req, \"POST\", self.params.url + (self.params.query.length ? \"?\" + self.params.query : \"\"));\n self.setHeaders(self.req, self.headers);\n self.req.onload = function () {\n if (this.status >= 200 && this.status < 300) {\n let result = self.getResult(self.req);\n if (result)\n resolve(result);\n else\n reject({\n status: this.status,\n statusText: \"response not interpretable\"\n });\n } else {\n reject({\n status: this.status,\n statusText: self.req.statusText\n });\n }\n };\n self.req.onerror = function () {\n reject({\n status: this.status,\n statusText: self.req.statusText\n });\n };\n self.send(self.req, self.params.data);\n });\n }\n\n getWithPromise(): Promise {\n let self = this;\n return new Promise(function (resolve, reject) {\n self.open(self.req, \"GET\", self.params.url);\n self.setHeaders(self.req, self.headers);\n //self.req.withCredentials = true;\n self.req.onload = function () {\n if (this.status >= 200 && this.status < 300) {\n let result = self.getHtmlResult(self.req);\n if(result)\n resolve(result);\n else\n reject({\n status: this.status,\n statusText: \"response not interpretable\"\n });\n } else {\n reject({\n status: this.status,\n statusText: self.req.statusText\n });\n }\n };\n self.req.onerror = function () {\n reject({\n status: this.status,\n statusText: self.req.statusText\n });\n };\n self.sendGet(self.req);\n });\n }\n\n private xhr(win: any): XMLHttpRequest {\n return new win.XMLHttpRequest();\n }\n\n private open(req: XMLHttpRequest, method: string, url: string): any {\n req.open(method, url);\n\n return req;\n }\n\n private setHeaders(req: XMLHttpRequest, headers: any[]): XMLHttpRequest {\n headers.forEach(header => req.setRequestHeader(header.name, header.value));\n\n return req;\n }\n\n private onReadyStateChange(req: XMLHttpRequest, callback: Function): XMLHttpRequest {\n req.onreadystatechange = () => {\n\n if (req.readyState === XMLHttpRequest.DONE) {\n let result = this.getResult(req);\n\n callback(result, req.status);\n }\n }\n\n return req;\n }\n\n private getHtmlResult(req: XMLHttpRequest): HtmlResult {\n let json: HtmlResult;\n\n if (req.responseText) {\n json = { \"Html\": req.responseText };\n } else {\n json = null;\n }\n\n return json;\n }\n\n private getResult(req: XMLHttpRequest): T {\n let json: T;\n try {\n json = JSON.parse(req.responseText);\n } catch (e) {\n json = null;\n }\n\n return json;\n }\n\n private send(req: XMLHttpRequest, data: any): XMLHttpRequest {\n req.send(data);\n\n return req;\n }\n\n private sendGet(req: XMLHttpRequest): XMLHttpRequest {\n req.send();\n\n return req;\n }\n}","import { MPCNotificationService } from \"./PCF/notification-service\";\r\nimport { ProductComparisonModel, Product, NavigationTab } from \"../../Models/Product.generated\";\r\nimport { ErrorMessage } from \"../../Models/ErrorMessage.generated\";\r\nimport { NlVanillajax, INlVanillajaxParams } from \"./helpers/vanillajax\";\r\nimport { MPCComparePageButtonUrlUpdater } from \"./helpers/comparePageButtonUrlUpdater\";\r\nimport { MPCAddElementContext } from \"./typings/addElementContext\";\r\nimport { MPCErrorHandlerModule } from \"./errorhandler\";\r\nimport { MpcSettingsModule } from \"./helpers/MpcSettings\";\r\n\r\nexport module MPCLocalStorageService {\r\n import AddElementContext = MPCAddElementContext.AddElementContext;\r\n import NotificationService = MPCNotificationService.NotificationService;\r\n import ErrorHandlerManager = MPCErrorHandlerModule.ErrorHandlerManager;\r\n import ComparePageButtonUrlUpdater = MPCComparePageButtonUrlUpdater.ComparePageButtonUrlUpdater;\r\n import MpcSettings = MpcSettingsModule.MpcSettings;\r\n\r\n export enum AddResult {\r\n Added,\r\n Replaced,\r\n RejectedCapacity,\r\n RejectedDuplicate\r\n }\r\n\r\n export class ProductComparisonModelManager {\r\n private static _instance: ProductComparisonModelManager;\r\n private notificationService: NotificationService;\r\n private localStorageAbstraction: LocalStorageAbstraction;\r\n private localStorageCache: ProductComparisonModel;\r\n private runningServiceCall: Promise;\r\n private comparePageButtonUrlUpdater: ComparePageButtonUrlUpdater;\r\n private readonly DuplicateNotFound: number = -1;\r\n private readonly DuplicateExact: number = -2;\r\n\r\n static get instance() {\r\n return this._instance || (this._instance = new this());\r\n }\r\n\r\n constructor() {\r\n this.init();\r\n }\r\n\r\n private init(): void {\r\n this.notificationService = NotificationService.instance;\r\n this.localStorageAbstraction = LocalStorageAbstraction.instance;\r\n this.localStorageCache = this.localStorageAbstraction.readLocalStorage();\r\n this.comparePageButtonUrlUpdater = ComparePageButtonUrlUpdater.instance;\r\n // here we load the model (from localStorage and with server-sync if deemed necessary) \r\n // for later usage by all the components\r\n this.getModel();\r\n }\r\n\r\n public getModel(): Promise {\r\n if (this.runningServiceCall) {\r\n // this service call is a singleton, avoid useless parallel calls \r\n return this.runningServiceCall;\r\n }\r\n this.runningServiceCall = new Promise((resolve, reject) => {\r\n try {\r\n this.localStorageCache = this.localStorageAbstraction.readLocalStorage();\r\n if (this.localStorageCache && this.localStorageCache.products.length > 0 \r\n && !this.localStorageCache.activeNavigationTab) {\r\n this.localStorageCache.activeNavigationTab = this.localStorageCache.products[0].categoryName;\r\n }\r\n if (this.localStorageCache && typeof this.localStorageCache.mobileEnabledCategories != \"object\") {\r\n this.localStorageCache.mobileEnabledCategories = [];\r\n }\r\n this.validateLocalStorage();\r\n } catch (err) {\r\n ErrorHandlerManager.instance.LogError({\r\n message: \"resetting mpc localStorage because: \" +\r\n err +\r\n \", localStorage: \" +\r\n JSON.stringify(this.localStorageCache)\r\n }); \r\n this.localStorageCache = undefined;\r\n }\r\n\r\n const isNewlyLoggedOut = !MpcSettings.instance.isLoggedIn && this.localStorageCache && !!this.localStorageCache.isLoggedIn;\r\n if (!this.localStorageCache || ProductComparisonModelManager.isTimedOut(this.localStorageCache) \r\n || isNewlyLoggedOut) {\r\n this.createNewLocalStorage();\r\n resolve(this.localStorageCache);\r\n return;\r\n }\r\n if (MpcSettings.instance.isLoggedIn && !this.localStorageCache.isLoggedIn) {\r\n this.localStorageCache.isLoggedInNewly = true;\r\n }\r\n this.localStorageCache.isLoggedIn = MpcSettings.instance.isLoggedIn;\r\n const needsValidation = this.needsValidation();\r\n if (!needsValidation) {\r\n if (this.localStorageCache.pageLanguage !== MpcSettings.instance.culture) { // if for logical readability :)\r\n this.localStorageCache.pageLanguage = MpcSettings.instance.culture;\r\n }\r\n \r\n this.onUpdatedModel(true);\r\n \r\n resolve(this.localStorageCache);\r\n return;\r\n }\r\n\r\n this.sync()\r\n .then((model)=>resolve(model))\r\n .catch((error)=>reject(error));\r\n });\r\n this.runningServiceCall.then((model) => {\r\n this.runningServiceCall = null;\r\n })\r\n return this.runningServiceCall;\r\n }\r\n\r\n private sync(): Promise {\r\n const printPageContent = this.localStorageCache.printPageContent;\r\n this.localStorageCache.printPageContent = null;\r\n\r\n let params: INlVanillajaxParams = {};\r\n params.url = MpcSettingsModule.MpcSettings.instance.apiUrl +\r\n 'Products/Sync';\r\n params.data = JSON.stringify(this.localStorageCache);\r\n\r\n const countBefore = this.localStorageCache.products.length;\r\n\r\n return new NlVanillajax(params).postWithPromise()\r\n .then((model) => {\r\n if (!model || !model.products) {\r\n this.localStorageCache.printPageContent = printPageContent;\r\n return Promise.reject(\"service returned no useful result\");\r\n //throw new Error(\"service returned no useful result\");\r\n }\r\n // false will not be send over the wire, but we don't want undefined values\r\n model.clearStoredEmptyNavigationTabs = !!model.clearStoredEmptyNavigationTabs;\r\n model.hasClientSideChange = false;\r\n this.localStorageCache = model;\r\n this.localStorageCache.printPageContent = printPageContent;\r\n this.onUpdatedModel(true); //skipSaving=true, because 'validate' saves internally\r\n const countAfter = model.products.length;\r\n if (countBefore === 0 && countAfter > 0) {\r\n this.setMobileHeaderMarkerOn();\r\n } else if (countBefore > 0 && countAfter === 0) {\r\n this.setMobileHeaderMarkerOff();\r\n }\r\n return this.localStorageCache;\r\n })\r\n .catch((err) => {\r\n this.localStorageCache.printPageContent = printPageContent;\r\n return Promise.reject(err);\r\n });\r\n }\r\n\r\n private validateLocalStorage(): void {\r\n //there were some problems with old/invalid localStorage contents, so we detect and reset them\r\n if (this.localStorageCache) {\r\n if (!Array.isArray(this.localStorageCache.products))\r\n throw \"localStorage is corrupted - products is no array\";\r\n if (!this.localStorageCache.lastUpdateTime)\r\n throw \"localStorage is corrupted - lastUpdateTime is not set\";\r\n if (typeof this.localStorageCache.lastUpdateTime !== \"number\")\r\n throw \"localStorage is corrupted - lastUpdateTime is no number\";\r\n if (this.localStorageCache.products.length > 0) {\r\n if (!this.localStorageCache.activeNavigationTab)\r\n throw \"localStorage is corrupted - activeNavigationTab is not set\";\r\n if (typeof this.localStorageCache.activeNavigationTab !== \"string\")\r\n throw \"localStorage is corrupted - activeNavigationTab is no string\";\r\n }\r\n if (!this.localStorageCache.pageLanguage)\r\n throw \"localStorage is corrupted - pageLanguage is not set\";\r\n if (typeof this.localStorageCache.pageLanguage !== \"string\")\r\n throw \"localStorage is corrupted - pageLanguage is no string\";\r\n if (typeof this.localStorageCache.clearStoredEmptyNavigationTabs !== \"boolean\")\r\n throw \"localStorage is corrupted - clearStoredEmptyNavigationTabs is no boolean\";\r\n if (!Array.isArray(this.localStorageCache.emptyNavigationTabs))\r\n throw \"localStorage is corrupted - emptyNavigationTabs is no array\";\r\n if (this.localStorageCache.products.length > 0) {\r\n if (!this.localStorageCache.products[0].articleId.masterArticleNo) {\r\n throw \"localStorage is corrupted - products[0].articleId.masterArticleNo is not set\";\r\n }\r\n if (!this.localStorageCache.products[0].articleId.salesArticleVariantKey) {\r\n throw \"localStorage is corrupted - products[0].articleId.salesArticleVariantKey is not set\";\r\n }\r\n if (!this.localStorageCache.products[0].articleId.seoDescription) {\r\n throw \"localStorage is corrupted - products[0].articleId.seoDescription is not set\";\r\n }\r\n if (!this.localStorageCache.products[0].articleId.seoSlug) {\r\n throw \"localStorage is corrupted - products[0].articleId.seoSlug is not set\";\r\n }\r\n if (!this.localStorageCache.products[0].categoryName) {\r\n throw \"localStorage is corrupted - products[0].categoryName is not set\";\r\n }\r\n if (!this.localStorageCache.products[0].categoryUrl) {\r\n throw \"localStorage is corrupted - products[0].categoryUrl is not set\";\r\n }\r\n if (!this.localStorageCache.products[0].detailsPageUrl) {\r\n throw \"localStorage is corrupted - products[0].detailsPageUrl is not set\";\r\n }\r\n if (!this.localStorageCache.products[0].mainImage) {\r\n throw \"localStorage is corrupted - products[0].mainImage is not set\";\r\n }\r\n if (!this.localStorageCache.products[0].originNavigationKeyPath) {\r\n throw \"localStorage is corrupted - products[0].originNavigationKeyPath is not set\";\r\n }\r\n if (typeof this.localStorageCache.products[0].navigationOrder !== \"number\") {\r\n throw \"localStorage is corrupted - products[0].mainImage is not set\";\r\n }\r\n if (!this.localStorageCache.products[0].title) {\r\n throw \"localStorage is corrupted - products[0].mainImage is not set\";\r\n }\r\n }\r\n }\r\n }\r\n \r\n public setActiveNavigationTab(activeNavigationTab: string): void {\r\n if(!this.localStorageCache)\r\n this.getModel();\r\n if (this.localStorageCache.activeNavigationTab !== activeNavigationTab) {\r\n this.localStorageCache.activeNavigationTab = activeNavigationTab;\r\n this.onUpdatedModel(true); //don't save, who cares\r\n }\r\n }\r\n \r\n public activateOnMobileCategory(categoryNavKey: string): void {\r\n if(!this.localStorageCache)\r\n this.getModel();\r\n\r\n this.localStorageCache.mobileEnabledCategories.push(categoryNavKey);\r\n this.onUpdatedModel(true);//dont save, who cares\r\n }\r\n\r\n public isActivatedOnMobileCategory(categoryNavKey: string): boolean {\r\n if(!this.localStorageCache)\r\n this.getModel();\r\n\r\n return this.localStorageCache.mobileEnabledCategories &&\r\n this.localStorageCache.mobileEnabledCategories.indexOf(categoryNavKey) >= 0;\r\n }\r\n\r\n public deactivateOnMobileCategory(categoryNavKey: string): void {\r\n if(!this.localStorageCache)\r\n this.getModel();\r\n\r\n const idx = this.localStorageCache.mobileEnabledCategories.indexOf(categoryNavKey);\r\n this.localStorageCache.mobileEnabledCategories.splice(idx, idx >= 0 ? 1 : 0);\r\n this.onUpdatedModel(true);//dont save, who cares\r\n }\r\n\r\n public addProduct(product: Product): AddResult {\r\n if (this.localStorageCache) {\r\n this.setActiveNavigationTab(product.categoryName);\r\n\r\n const duplicateCheckResult = this.checkDuplicateProductPerCategory(\r\n product.articleId.salesArticleVariantKey,\r\n product.categoryName,\r\n product.articleId.masterArticleNo\r\n );\r\n if (duplicateCheckResult === this.DuplicateNotFound && this.isAlreadyAtLimit(product.categoryName)) {\r\n this.notificationService.notifyMaximumProductsCountReached();\r\n return AddResult.RejectedCapacity;\r\n }\r\n \r\n if (duplicateCheckResult === this.DuplicateNotFound) {\r\n this.appendProductToList(product, false);\r\n return AddResult.Added;\r\n }\r\n else {\r\n if (duplicateCheckResult !== this.DuplicateExact) {\r\n this.localStorageCache.products[duplicateCheckResult] = product;\r\n this.localStorageCache.hasClientSideChange = true;\r\n this.onUpdatedModel(false);\r\n }\r\n\r\n // just show new product notification, because product is already added:\r\n this.notificationService.notifyNewProductAdded(product.title, product.mainImage, product.altTag);\r\n\r\n if (duplicateCheckResult !== this.DuplicateExact) {\r\n return AddResult.Replaced;\r\n } else {\r\n return AddResult.RejectedDuplicate;\r\n }\r\n }\r\n }\r\n else {\r\n this.createNewLocalStorage();\r\n\r\n this.appendProductToList(product, false);\r\n\r\n return AddResult.Added;\r\n }\r\n }\r\n\r\n private onUpdatedModel(skipSaving: boolean): Promise {\r\n return new Promise((resolve, reject) => {\r\n const afterSave = (model: ProductComparisonModel) => {\r\n this.comparePageButtonUrlUpdater.onUpdatedModel(model);\r\n this.localStorageAbstraction.writeLocalStorage(model);\r\n }\r\n\r\n if (!skipSaving && this.localStorageCache.isLoggedIn) {\r\n this.sync()\r\n .then((syncedModel) => {\r\n afterSave(syncedModel);\r\n resolve(syncedModel);\r\n })\r\n .catch((error) => {\r\n reject(error);\r\n });\r\n } else {\r\n afterSave(this.localStorageCache);\r\n }\r\n });\r\n }\r\n\r\n public removeAllProductsOfCategory(categoryName: string): Promise {\r\n return new Promise((resolve, reject) => {\r\n let articleRemoved: boolean = false;\r\n const productsAfter: Product[] = [];\r\n for (let i = 0; i < this.localStorageCache.products.length; i++) {\r\n const tmpProduct: Product = this.localStorageCache.products[i];\r\n if (tmpProduct.categoryName !== categoryName) {\r\n productsAfter.push(tmpProduct);\r\n } else {\r\n articleRemoved = true;\r\n }\r\n }\r\n if (productsAfter.length == 0) {\r\n //unmarks when removing the last\r\n this.setMobileHeaderMarkerOff();\r\n }\r\n\r\n this.localStorageCache.products = productsAfter;\r\n if (this.localStorageCache.products.length > 0) {\r\n this.setActiveNavigationTab(this.localStorageCache.products[0].categoryName);\r\n } else {\r\n this.setActiveNavigationTab(null);\r\n }\r\n\r\n if (articleRemoved) {\r\n this.localStorageCache.hasClientSideChange = true;\r\n this.onUpdatedModel(false);\r\n }\r\n });\r\n }\r\n \r\n private setMobileHeaderMarkerOn(): void {\r\n if (window.shell)\r\n window.shell.publishTo('ESMKT.MegaMenu.MarkItem', \"mpc\");\r\n }\r\n\r\n private setMobileHeaderMarkerOff(): void {\r\n if (window.shell)\r\n window.shell.publishTo('ESMKT.MegaMenu.UnmarkItem', \"mpc\");\r\n }\r\n\r\n public removeProduct(categoryName: string, salesArticleVariantKey: string): Product {\r\n let articleRemoved: Product = null;\r\n\r\n for (let i = 0; i < this.localStorageCache.products.length; i++) {\r\n const tmpProduct: Product = this.localStorageCache.products[i];\r\n\r\n if (tmpProduct.articleId.salesArticleVariantKey === salesArticleVariantKey\r\n && tmpProduct.categoryName === categoryName) {\r\n this.localStorageCache.products.splice(i, 1);\r\n //unmarks when removing the last\r\n if (this.localStorageCache.products.length === 0) {\r\n this.setMobileHeaderMarkerOff();\r\n }\r\n articleRemoved = tmpProduct;\r\n\r\n break;\r\n }\r\n }\r\n if (!this.localStorageCache.products.some(p => p.categoryName === categoryName)) {\r\n if (this.localStorageCache.products.length > 0) {\r\n this.setActiveNavigationTab(this.localStorageCache.products[0].categoryName);\r\n } else {\r\n this.setActiveNavigationTab(null);\r\n }\r\n }\r\n\r\n if (articleRemoved) {\r\n this.localStorageCache.hasClientSideChange = true;\r\n this.onUpdatedModel(false);\r\n }\r\n\r\n return articleRemoved;\r\n }\r\n \r\n public addProductBySavKey(salesArticleVariantKey: string, seoSlug: string, origin: string, originNavKeyPathOverride: string = undefined): Promise {\r\n const context: AddElementContext = new class implements AddElementContext {\r\n salesArticleVariantKey: string;\r\n originSeoSlug: string;\r\n origin: string;\r\n };\r\n\r\n context.salesArticleVariantKey = salesArticleVariantKey;\r\n context.originSeoSlug = seoSlug;\r\n context.origin = origin;\r\n\r\n // Call controller method, via ajax, and get image and text info from MPC\r\n let params: INlVanillajaxParams = {};\r\n params.url = MpcSettingsModule.MpcSettings.instance.apiUrl +\"Products/GetProductInfo\";\r\n params.data = JSON.stringify(context);\r\n\r\n let nlVanillajax = new NlVanillajax(params);\r\n let postWithPromise = nlVanillajax.postWithPromise();\r\n\r\n postWithPromise.then((productDataFromService: Product) => {\r\n if (productDataFromService) {\r\n if (originNavKeyPathOverride) {\r\n productDataFromService.originNavigationKeyPath = originNavKeyPathOverride;\r\n }\r\n this.appendProductToList(productDataFromService, true);\r\n }\r\n })\r\n .catch((err) => {\r\n ErrorHandlerManager.instance.LogError({\r\n message: \"error getting product info because: \" +\r\n err +\r\n \", salesArticleVariantKey: \" +\r\n salesArticleVariantKey\r\n }); \r\n });\r\n\r\n return postWithPromise;\r\n }\r\n\r\n private checkDuplicateProductPerCategory(salesArticleVariantKey: string, categoryName: string, masterArticleNo: number): number {\r\n for (let i = 0; i < this.localStorageCache.products.length; i++) {\r\n const product: Product = this.localStorageCache.products[i];\r\n\r\n // avoid duplicate products\r\n if (product.articleId.masterArticleNo === masterArticleNo\r\n && product.categoryName === categoryName) {\r\n if (product.articleId.salesArticleVariantKey === salesArticleVariantKey) {\r\n return this.DuplicateExact;\r\n } else {\r\n return i; //same MaNo but different SavKey -> this product will be replaced by the new variant\r\n }\r\n }\r\n }\r\n\r\n return this.DuplicateNotFound;\r\n }\r\n\r\n private isAlreadyAtLimit(categoryName: string): boolean {\r\n let productsAmount: number = 0;\r\n let result: boolean = false;\r\n\r\n for (let i = 0; i < this.localStorageCache.products.length; i++) {\r\n const product: Product = this.localStorageCache.products[i];\r\n\r\n // avoid more then 4 products per category\r\n if (product.categoryName === categoryName) {\r\n productsAmount++;\r\n\r\n if (productsAmount === MpcSettings.instance.maxProducts) {\r\n result = true;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n \r\n private createNewLocalStorage(): void {\r\n const localStorageModel = {} as ProductComparisonModel;\r\n localStorageModel.products = new Array();\r\n localStorageModel.emptyNavigationTabs = new Array();\r\n localStorageModel.clearStoredEmptyNavigationTabs = false;\r\n localStorageModel.activeNavigationTab = null;\r\n localStorageModel.pageLanguage = MpcSettings.instance.culture;\r\n localStorageModel.hasClientSideChange = false;\r\n localStorageModel.lastUpdateTime = new Date().getTime(); // we define an empty model to be synced\r\n localStorageModel.isLoggedIn = MpcSettings.instance.isLoggedIn;\r\n localStorageModel.mobileEnabledCategories = [];\r\n localStorageModel.mobileLockedColumnIndex = null;\r\n localStorageModel.mobileCarouselScrollIndex = null;\r\n localStorageModel.usedNavTabForCarouselOrLockedColumn = null;\r\n localStorageModel.printPageContent = null;\r\n this.localStorageCache = localStorageModel;\r\n this.onUpdatedModel(false);\r\n }\r\n\r\n private needsValidation(): boolean {\r\n if (this.localStorageCache.isLoggedIn || MpcSettings.instance.isLoggedIn) return true;\r\n const noProducts = this.localStorageCache.products.length === 0;\r\n if (noProducts) return false;\r\n const languageWasSwitched = this.localStorageCache.pageLanguage !== MpcSettings.instance.culture;\r\n if (languageWasSwitched) return true;\r\n const expiration5MinutesAfterLastUpdate = new Date(this.localStorageCache.lastUpdateTime+(1000*60*5));\r\n const olderThan5Minutes = new Date().getTime() > expiration5MinutesAfterLastUpdate.getTime();\r\n return olderThan5Minutes;\r\n }\r\n\r\n private static isTimedOut(model: ProductComparisonModel): boolean {\r\n const expirationDate = new Date(model.lastUpdateTime + (1000 * 60 * 60 * 24 * 30));\r\n return new Date().getTime() > expirationDate.getTime();\r\n }\r\n\r\n private appendProductToList(product: Product, avoidNotification: boolean): void {\r\n this.localStorageCache.products.push(product);\r\n this.localStorageCache.hasClientSideChange = true;\r\n this.onUpdatedModel(false);\r\n\r\n if(!avoidNotification)\r\n this.notificationService.notifyNewProductAdded(product.title, product.mainImage, product.altTag);\r\n\r\n // it should only mark when adding the first article\r\n if (this.localStorageCache.products.length === 1) {\r\n this.setMobileHeaderMarkerOn();\r\n }\r\n }\r\n \r\n public checkIsProductAlreadyAdded(salesArticleVariantKey: string): boolean {\r\n let productExists: boolean = false;\r\n\r\n if (window.localStorage) {\r\n\r\n if (this.localStorageCache) {\r\n for (let i = 0; i < this.localStorageCache.products.length; i++) {\r\n const tmpProduct: Product = this.localStorageCache.products[i];\r\n\r\n if (tmpProduct.articleId.salesArticleVariantKey == salesArticleVariantKey) {\r\n productExists = true;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return productExists;\r\n }\r\n\r\n public storeEmptyNavigationTab(categoryName: string, navigationOrder: number): void {\r\n if(!this.localStorageCache.emptyNavigationTabs) {\r\n this.localStorageCache.emptyNavigationTabs = new Array();\r\n }\r\n\r\n let emptyNavigationTab: NavigationTab = {} as NavigationTab;\r\n emptyNavigationTab.name = categoryName;\r\n emptyNavigationTab.navigationOrder = navigationOrder;\r\n\r\n this.localStorageCache.emptyNavigationTabs.push(emptyNavigationTab);\r\n this.localStorageAbstraction.writeLocalStorage(this.localStorageCache);\r\n }\r\n\r\n public removeStoredEmptyNavigationTabs(): void {\r\n if(!this.localStorageCache)\r\n this.getModel();\r\n\r\n this.localStorageCache.emptyNavigationTabs = new Array();\r\n this.localStorageAbstraction.writeLocalStorage(this.localStorageCache);\r\n }\r\n\r\n public setClearStoredEmptyNavigationTabs(clearStoredEmptyNavigationTabs: boolean): void {\r\n if(!this.localStorageCache)\r\n this.getModel();\r\n\r\n this.localStorageCache.clearStoredEmptyNavigationTabs = clearStoredEmptyNavigationTabs;\r\n this.onUpdatedModel(true); //don't save, who cares\r\n }\r\n\r\n public getCarouselScrollIndex(): number {\r\n if (!this.localStorageCache) {\r\n this.getModel();\r\n }\r\n\r\n const currentCatName: string = this.getCurrentCategoryName();\r\n if (!this.localStorageCache.usedNavTabForCarouselOrLockedColumn || currentCatName != this.localStorageCache.usedNavTabForCarouselOrLockedColumn) {\r\n this.clearLockedColumnIndex();\r\n this.clearCarouselScrollIndex();\r\n }\r\n\r\n return this.localStorageCache.mobileCarouselScrollIndex;\r\n }\r\n\r\n public clearCarouselScrollIndex(): void {\r\n this.localStorageCache.mobileCarouselScrollIndex = null;\r\n this.localStorageCache.usedNavTabForCarouselOrLockedColumn = null;\r\n this.localStorageAbstraction.writeLocalStorage(this.localStorageCache);\r\n }\r\n\r\n public storeCarouselScrollIndex(value: number): void {\r\n this.localStorageCache.mobileCarouselScrollIndex = value;\r\n this.localStorageCache.usedNavTabForCarouselOrLockedColumn = this.getCurrentCategoryName();\r\n this.localStorageAbstraction.writeLocalStorage(this.localStorageCache);\r\n }\r\n\r\n public getLockedColumnIndex(): number {\r\n if (!this.localStorageCache) {\r\n this.getModel();\r\n }\r\n\r\n return this.localStorageCache.mobileLockedColumnIndex;\r\n }\r\n\r\n public clearLockedColumnIndex(): void {\r\n this.localStorageCache.mobileLockedColumnIndex = null;\r\n this.localStorageAbstraction.writeLocalStorage(this.localStorageCache);\r\n }\r\n\r\n public storeLockedColumnIndex(value: number): void {\r\n this.localStorageCache.mobileLockedColumnIndex = value;\r\n this.localStorageCache.usedNavTabForCarouselOrLockedColumn = this.getCurrentCategoryName();\r\n this.localStorageAbstraction.writeLocalStorage(this.localStorageCache);\r\n }\r\n\r\n private getCurrentCategoryName(): string {\r\n const urlParams: URLSearchParams = new URLSearchParams(location.search);\r\n return urlParams.get('category');\r\n }\r\n\r\n public storePrintPageContent(content: HTMLElement): void {\r\n this.localStorageCache.printPageContent = content.outerHTML;\r\n this.localStorageAbstraction.writeLocalStorage(this.localStorageCache);\r\n }\r\n\r\n public getPrintPageContentCached(): string {\r\n //there was a race condition with a Sync call, but we dont need to wait for server sync really\r\n const modelDirectlyFromLocalStorage = this.localStorageAbstraction.readLocalStorage();\r\n if (!modelDirectlyFromLocalStorage) return null;\r\n return modelDirectlyFromLocalStorage.printPageContent;\r\n }\r\n }\r\n\r\n export class LocalStorageAbstraction {\r\n private static _instance: LocalStorageAbstraction;\r\n public unsupported: boolean = true;\r\n \r\n private static mpcLocalStorageKeyOld: string = 'productComparison';\r\n public static mpcLocalStorageKeyNew: string;\r\n\r\n static get instance() {\r\n //TODO after migration period is over (i suggest 01.01.2026)\r\n // clean this up and just:\r\n // return this._instance || (this._instance = new this());\r\n return this._instance || LocalStorageAbstraction.getNewInstanceAndMigrate();\r\n }\r\n\r\n private static getNewInstanceAndMigrate(): LocalStorageAbstraction {\r\n LocalStorageAbstraction.mpcLocalStorageKeyNew = LocalStorageAbstraction.mpcLocalStorageKeyOld+\"_\"+MpcSettings.instance.portal;\r\n LocalStorageAbstraction.migrate();\r\n this._instance = new this();\r\n return this._instance;\r\n }\r\n\r\n constructor() {\r\n if (!window.localStorage) {\r\n //ErrorHandlerManager.instance.LogError({ message: \"localStorage not supported\" });\r\n //TODO user notification\r\n } else {\r\n this.unsupported = false;\r\n }\r\n }\r\n\r\n public writeLocalStorage(localStorage: ProductComparisonModel): void {\r\n if (this.unsupported) return;\r\n const tmpLocalStorageObject: string = JSON.stringify(localStorage);\r\n window.localStorage.setItem(LocalStorageAbstraction.mpcLocalStorageKeyNew, tmpLocalStorageObject);\r\n }\r\n\r\n public readLocalStorage(): ProductComparisonModel {\r\n if (this.unsupported) return null;\r\n const mpcLocalStorageJson = window.localStorage.getItem(LocalStorageAbstraction.mpcLocalStorageKeyNew);\r\n if (mpcLocalStorageJson) {\r\n return JSON.parse(mpcLocalStorageJson);\r\n }\r\n return null;\r\n }\r\n\r\n private static migrate(){\r\n if(window.localStorage.getItem(LocalStorageAbstraction.mpcLocalStorageKeyOld)){\r\n const oldKeyData = window.localStorage.getItem(LocalStorageAbstraction.mpcLocalStorageKeyOld);\r\n window.localStorage.setItem(LocalStorageAbstraction.mpcLocalStorageKeyNew, oldKeyData);\r\n window.localStorage.removeItem(LocalStorageAbstraction.mpcLocalStorageKeyOld);\r\n }\r\n }\r\n }\r\n}","/**\n *\n *\n * @author Jerry Bendy \n * @licence MIT\n *\n */\n\n(function(self) {\n 'use strict';\n\n var nativeURLSearchParams = (self.URLSearchParams && self.URLSearchParams.prototype.get) ? self.URLSearchParams : null,\n isSupportObjectConstructor = nativeURLSearchParams && (new nativeURLSearchParams({a: 1})).toString() === 'a=1',\n // There is a bug in safari 10.1 (and earlier) that incorrectly decodes `%2B` as an empty space and not a plus.\n decodesPlusesCorrectly = nativeURLSearchParams && (new nativeURLSearchParams('s=%2B').get('s') === '+'),\n __URLSearchParams__ = \"__URLSearchParams__\",\n // Fix bug in Edge which cannot encode ' &' correctly\n encodesAmpersandsCorrectly = nativeURLSearchParams ? (function() {\n var ampersandTest = new nativeURLSearchParams();\n ampersandTest.append('s', ' &');\n return ampersandTest.toString() === 's=+%26';\n })() : true,\n prototype = URLSearchParamsPolyfill.prototype,\n iterable = !!(self.Symbol && self.Symbol.iterator);\n\n if (nativeURLSearchParams && isSupportObjectConstructor && decodesPlusesCorrectly && encodesAmpersandsCorrectly) {\n return;\n }\n\n\n /**\n * Make a URLSearchParams instance\n *\n * @param {object|string|URLSearchParams} search\n * @constructor\n */\n function URLSearchParamsPolyfill(search) {\n search = search || \"\";\n\n // support construct object with another URLSearchParams instance\n if (search instanceof URLSearchParams || search instanceof URLSearchParamsPolyfill) {\n search = search.toString();\n }\n this [__URLSearchParams__] = parseToDict(search);\n }\n\n\n /**\n * Appends a specified key/value pair as a new search parameter.\n *\n * @param {string} name\n * @param {string} value\n */\n prototype.append = function(name, value) {\n appendTo(this [__URLSearchParams__], name, value);\n };\n\n /**\n * Deletes the given search parameter, and its associated value,\n * from the list of all search parameters.\n *\n * @param {string} name\n */\n prototype['delete'] = function(name) {\n delete this [__URLSearchParams__] [name];\n };\n\n /**\n * Returns the first value associated to the given search parameter.\n *\n * @param {string} name\n * @returns {string|null}\n */\n prototype.get = function(name) {\n var dict = this [__URLSearchParams__];\n return name in dict ? dict[name][0] : null;\n };\n\n /**\n * Returns all the values association with a given search parameter.\n *\n * @param {string} name\n * @returns {Array}\n */\n prototype.getAll = function(name) {\n var dict = this [__URLSearchParams__];\n return name in dict ? dict [name].slice(0) : [];\n };\n\n /**\n * Returns a Boolean indicating if such a search parameter exists.\n *\n * @param {string} name\n * @returns {boolean}\n */\n prototype.has = function(name) {\n return name in this [__URLSearchParams__];\n };\n\n /**\n * Sets the value associated to a given search parameter to\n * the given value. If there were several values, delete the\n * others.\n *\n * @param {string} name\n * @param {string} value\n */\n prototype.set = function set(name, value) {\n this [__URLSearchParams__][name] = ['' + value];\n };\n\n /**\n * Returns a string containg a query string suitable for use in a URL.\n *\n * @returns {string}\n */\n prototype.toString = function() {\n var dict = this[__URLSearchParams__], query = [], i, key, name, value;\n for (key in dict) {\n name = encode(key);\n for (i = 0, value = dict[key]; i < value.length; i++) {\n query.push(name + '=' + encode(value[i]));\n }\n }\n return query.join('&');\n };\n\n // There is a bug in Safari 10.1 and `Proxy`ing it is not enough.\n var forSureUsePolyfill = !decodesPlusesCorrectly;\n var useProxy = (!forSureUsePolyfill && nativeURLSearchParams && !isSupportObjectConstructor && self.Proxy)\n /*\n * Apply polifill to global object and append other prototype into it\n */\n Object.defineProperty(self, 'URLSearchParams', {\n value: (useProxy ?\n // Safari 10.0 doesn't support Proxy, so it won't extend URLSearchParams on safari 10.0\n new Proxy(nativeURLSearchParams, {\n construct: function(target, args) {\n return new target((new URLSearchParamsPolyfill(args[0]).toString()));\n }\n }) :\n URLSearchParamsPolyfill)\n });\n\n var USPProto = self.URLSearchParams.prototype;\n\n USPProto.polyfill = true;\n\n /**\n *\n * @param {function} callback\n * @param {object} thisArg\n */\n USPProto.forEach = USPProto.forEach || function(callback, thisArg) {\n var dict = parseToDict(this.toString());\n Object.getOwnPropertyNames(dict).forEach(function(name) {\n dict[name].forEach(function(value) {\n callback.call(thisArg, value, name, this);\n }, this);\n }, this);\n };\n\n /**\n * Sort all name-value pairs\n */\n USPProto.sort = USPProto.sort || function() {\n var dict = parseToDict(this.toString()), keys = [], k, i, j;\n for (k in dict) {\n keys.push(k);\n }\n keys.sort();\n\n for (i = 0; i < keys.length; i++) {\n this['delete'](keys[i]);\n }\n for (i = 0; i < keys.length; i++) {\n var key = keys[i], values = dict[key];\n for (j = 0; j < values.length; j++) {\n this.append(key, values[j]);\n }\n }\n };\n\n /**\n * Returns an iterator allowing to go through all keys of\n * the key/value pairs contained in this object.\n *\n * @returns {function}\n */\n USPProto.keys = USPProto.keys || function() {\n var items = [];\n this.forEach(function(item, name) {\n items.push(name);\n });\n return makeIterator(items);\n };\n\n /**\n * Returns an iterator allowing to go through all values of\n * the key/value pairs contained in this object.\n *\n * @returns {function}\n */\n USPProto.values = USPProto.values || function() {\n var items = [];\n this.forEach(function(item) {\n items.push(item);\n });\n return makeIterator(items);\n };\n\n /**\n * Returns an iterator allowing to go through all key/value\n * pairs contained in this object.\n *\n * @returns {function}\n */\n USPProto.entries = USPProto.entries || function() {\n var items = [];\n this.forEach(function(item, name) {\n items.push([name, item]);\n });\n return makeIterator(items);\n };\n\n\n if (iterable) {\n USPProto[self.Symbol.iterator] = USPProto[self.Symbol.iterator] || USPProto.entries;\n }\n\n\n function encode(str) {\n var replace = {\n '!': '%21',\n \"'\": '%27',\n '(': '%28',\n ')': '%29',\n '~': '%7E',\n '%20': '+',\n '%00': '\\x00'\n };\n return encodeURIComponent(str).replace(/[!'\\(\\)~]|%20|%00/g, function(match) {\n return replace[match];\n });\n }\n\n function decode(str) {\n return decodeURIComponent(str.replace(/\\+/g, ' '));\n }\n\n function makeIterator(arr) {\n var iterator = {\n next: function() {\n var value = arr.shift();\n return {done: value === undefined, value: value};\n }\n };\n\n if (iterable) {\n iterator[self.Symbol.iterator] = function() {\n return iterator;\n };\n }\n\n return iterator;\n }\n\n function parseToDict(search) {\n var dict = {};\n\n if (typeof search === \"object\") {\n for (var key in search) {\n if (search.hasOwnProperty(key)) {\n appendTo(dict, key, search[key])\n }\n }\n\n } else {\n // remove first '?'\n if (search.indexOf(\"?\") === 0) {\n search = search.slice(1);\n }\n\n var pairs = search.split(\"&\");\n for (var j = 0; j < pairs.length; j++) {\n var value = pairs [j],\n index = value.indexOf('=');\n\n if (-1 < index) {\n appendTo(dict, decode(value.slice(0, index)), decode(value.slice(index + 1)));\n\n } else {\n if (value) {\n appendTo(dict, decode(value), '');\n }\n }\n }\n }\n\n return dict;\n }\n\n function appendTo(dict, name, value) {\n var val = typeof value === 'string' ? value : (\n value !== null && value !== undefined && typeof value.toString === 'function' ? value.toString() : JSON.stringify(value)\n )\n\n if (name in dict) {\n dict[name].push(val);\n } else {\n dict[name] = [val];\n }\n }\n\n})(typeof global !== 'undefined' ? global : (typeof window !== 'undefined' ? window : this));\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","//product comparison page\nimport './typescript/errorhandler';\nimport './typescript/helpers/polyfills';\n//scss\nimport './styles/mpc-shared-basics.scss';\nimport './styles/comparison-page.scss';\nimport './styles/comparison-page-header.scss';\nimport './styles/comparison-page-head-line.scss';\nimport './styles/comparison-page-controls.scss';\nimport './styles/comparison-page-row-container.scss';\nimport './styles/comparison-page-row-field.scss';\nimport './styles/comparison-page-missing-properties.scss';\nimport './styles/comparison-page-tooltip.scss';\nimport './styles/comparison-page-sticky-header.scss';\nimport './styles/comparison-page.printPage.scss';\n\nimport './typescript/PCP/comparison-page-controller';\n"],"names":["Element","prototype","CharacterData","DocumentType","filter","Boolean","forEach","item","hasOwnProperty","Object","defineProperty","configurable","enumerable","writable","value","this","parentNode","removeChild","self","document","createElement","createElementNS","view","classListProp","protoProp","elemCtrProto","objCtr","strTrim","String","trim","replace","arrIndexOf","Array","indexOf","i","len","length","DOMEx","type","message","name","code","DOMException","checkTokenAndGetIndex","classList","token","test","call","ClassList","elem","trimmedClasses","getAttribute","classes","split","push","_updateClassName","setAttribute","toString","classListProto","classListGetter","Error","contains","add","tokens","arguments","l","updated","remove","index","splice","toggle","force","result","method","replacement_token","join","classListPropDesc","get","ex","undefined","number","__defineGetter__","testElement","createMethod","original","DOMTokenList","_toggle","slice","apply","window","exportName","assign","VENDOR_PREFIXES","TEST_ELEMENT","TYPE_FUNCTION","round","Math","abs","now","Date","setTimeoutContext","fn","timeout","context","setTimeout","bindFn","invokeArrayArg","arg","isArray","each","obj","iterator","deprecate","deprecationMessage","e","stack","log","console","warn","target","TypeError","output","source","nextKey","extend","dest","src","merge","keys","inherit","child","base","properties","childP","baseP","create","constructor","_super","boolOrFn","val","args","ifUndefined","val1","val2","addEventListeners","types","handler","splitStr","addEventListener","removeEventListeners","removeEventListener","hasParent","node","parent","inStr","str","find","inArray","findByKey","toArray","uniqueArray","key","sort","results","values","a","b","prefixed","property","prefix","prop","camelProp","toUpperCase","_uniqueId","getWindowForElement","element","doc","ownerDocument","defaultView","parentWindow","SUPPORT_TOUCH","SUPPORT_POINTER_EVENTS","SUPPORT_ONLY_TOUCH","navigator","userAgent","INPUT_TYPE_TOUCH","INPUT_TYPE_MOUSE","COMPUTE_INTERVAL","INPUT_START","INPUT_END","INPUT_CANCEL","DIRECTION_NONE","DIRECTION_LEFT","DIRECTION_RIGHT","DIRECTION_UP","DIRECTION_DOWN","DIRECTION_HORIZONTAL","DIRECTION_VERTICAL","DIRECTION_ALL","PROPS_XY","PROPS_CLIENT_XY","Input","manager","callback","options","inputTarget","domHandler","ev","enable","init","inputHandler","eventType","input","pointersLen","pointers","changedPointersLen","changedPointers","isFirst","isFinal","session","pointersLength","firstInput","simpleCloneInputData","firstMultiple","offsetCenter","center","getCenter","timeStamp","deltaTime","angle","getAngle","distance","getDistance","offset","offsetDelta","prevDelta","prevInput","x","deltaX","y","deltaY","computeDeltaXY","offsetDirection","getDirection","start","end","overallVelocity","getVelocity","overallVelocityX","overallVelocityY","scale","rotation","getRotation","maxPointers","velocity","velocityX","velocityY","direction","last","lastInterval","v","computeIntervalInputData","srcEvent","computeInputData","emit","recognize","clientX","clientY","p1","p2","props","sqrt","atan2","PI","evEl","evTarget","evWin","destroy","MOUSE_INPUT_MAP","mousedown","mousemove","mouseup","MOUSE_ELEMENT_EVENTS","MOUSE_WINDOW_EVENTS","MouseInput","pressed","button","which","pointerType","POINTER_INPUT_MAP","pointerdown","pointermove","pointerup","pointercancel","pointerout","IE10_POINTER_TYPE_ENUM","POINTER_ELEMENT_EVENTS","POINTER_WINDOW_EVENTS","PointerEventInput","store","pointerEvents","MSPointerEvent","PointerEvent","removePointer","eventTypeNormalized","toLowerCase","isTouch","storeIndex","pointerId","SINGLE_TOUCH_INPUT_MAP","touchstart","touchmove","touchend","touchcancel","SingleTouchInput","started","normalizeSingleTouches","all","touches","changed","changedTouches","concat","TOUCH_INPUT_MAP","TOUCH_TARGET_EVENTS","TouchInput","targetIds","getTouches","allTouches","identifier","targetTouches","changedTargetTouches","touch","DEDUP_TIMEOUT","TouchMouseInput","mouse","primaryTouch","lastTouches","recordTouches","eventData","setLastTouch","lastTouch","lts","isSyntheticEvent","t","dx","dy","inputEvent","inputData","isMouse","sourceCapabilities","firesTouchEvents","PREFIXED_TOUCH_ACTION","style","NATIVE_TOUCH_ACTION","TOUCH_ACTION_COMPUTE","TOUCH_ACTION_AUTO","TOUCH_ACTION_MANIPULATION","TOUCH_ACTION_NONE","TOUCH_ACTION_PAN_X","TOUCH_ACTION_PAN_Y","TOUCH_ACTION_MAP","touchMap","cssSupports","CSS","supports","getTouchActionProps","TouchAction","set","compute","actions","update","touchAction","recognizers","recognizer","getTouchAction","hasPanX","hasPanY","cleanTouchActions","preventDefaults","prevented","preventDefault","hasNone","isTapPointer","isTapMovement","isTapTouchTime","preventSrc","STATE_POSSIBLE","STATE_FAILED","Recognizer","defaults","id","state","simultaneous","requireFail","stateStr","directionStr","getRecognizerByNameIfManager","otherRecognizer","AttrRecognizer","PanRecognizer","pX","pY","PinchRecognizer","PressRecognizer","_timer","_input","RotateRecognizer","SwipeRecognizer","TapRecognizer","pTime","pCenter","count","Hammer","preset","Manager","handlers","oldCssProps","inputClass","toggleCssProps","recognizeWith","requireFailure","cssProps","dropRecognizeWith","dropRequireFailure","hasRequireFailures","canRecognizeWith","event","additionalEvent","tryEmit","canEmit","inputDataClone","reset","process","attrTest","optionPointers","isRecognized","isValid","threshold","directionTest","hasMoved","inOut","time","validPointers","validMovement","validTime","clearTimeout","taps","interval","posThreshold","validTouchTime","failTimeout","validInterval","validMultiTap","tapCount","VERSION","domEvents","userSelect","touchSelect","touchCallout","contentZooming","userDrag","tapHighlightColor","stop","stopped","curRecognizer","existing","on","events","off","data","gestureEvent","createEvent","initEvent","gesture","dispatchEvent","triggerDomEvent","INPUT_MOVE","STATE_BEGAN","STATE_CHANGED","STATE_ENDED","STATE_RECOGNIZED","STATE_CANCELLED","Tap","Pan","Swipe","Pinch","Rotate","Press","exports","timeout_1","module","Timeout","__spreadArrays","s","il","r","k","j","jl","MetadataRecord","ms","params","paused","startTime","getTime","timeSpentWaiting","clear","erase","keyId","keyCall","metadata","originalMs","_i","executedTime","executed","exists","elapsed","metaDataRecord","max","lastExecuted","meta","pending","remaining","restart","pause","resume","remainingTime","instantiate","linkToExisting","random","newCallback","newMs","newParams","MPCNotificationService","DeviceDetectionHelper","ScrollLock","SmartTimeout","ArrowRightIcon","MPCDeviceDetectionHelper","MPCScrollLock","scope","querySelector","_instance","deviceDetectionHelper","instance","scrollLock","flyoutContainer","notification","closeBtns","querySelectorAll","openFlyoutBtns","navigationBtn","comparisonListButton","innerHTML","goToFlyoutComparisonList","closeNotification","maxProductsCountNotification","newProductNotification","emptyListNotification","flyoutIconContainer","shell","subscribeTo","closeAnyActiveNotification","notifyNewProductAdded","title","mainImage","altTag","showNotification","replaceNotificationContent","notifyMaximumProductsCountReached","notifyEmptyList","initializeNavigationButtonOnEmptyNotificationOnce","eventFunction","showMobileHeaderMenu","headrapi","toggleMenu","productInfoContainer","publishTo","closeExistingNotification","existingNotification","renderFlyoutContainerOverlay","updateNotificationContent","triggerAppShellPublish","deferNotification","existingNotificationTimeout","showInner","flyoutContentController","hideFlyoutContent","isMobileShop","renderOverlay","ontouchmove","lock","unlock","NotificationService","MPCColumnHeader","ProductComparisonModelManager","MPCLocalStorageService","header","grid","lastColumn","firstColumn","productComparisonModelManager","notificationService","categoryName","navigationOrder","Number","handleEmptyContainer","bind","registerEvents","imageContainer","recycleBtn","orderModalBtn","emptyHeaderContainer","handleRecycleBtnClick","setupOrderModalEvent","splittedSavKey","orderModalPayload","salesArticleNo","masterArticleNo","parseInt","colorCode","sizeCode","itemOrigin","columnId","currentUrl","location","href","urlParam","removeProduct","storeEmptyNavigationTab","getModel","then","model","products","setActiveNavigationTab","clearLockedColumnIndex","ColumnHeader","MPCColorsField","colorContainer","colors","colorsArray","color","savKey","colorIcon","changeProductVariant","tabNav","nextElementSibling","focus","previousElementSibling","selectedColorSavKey","colorsContent","map","removed","origin","originNavigationKeyPath","addProductBySavKey","ColorsField","MPCControlsRow","ArrowUpIcon","Checkbox","overlayDelay","controlsRow","gridRowsArray","emptyColumnsAmount","gridController","firstColumnHeader","collapseAll","eventBus","MPCEventBus","EventBus","subscribe","oneRowExpanded","updateCollapseAllButtonState","filterOnlyDifferencesBtn","filterOnlyDifferencesCheckBox","overlay","gridHtmlElement","collapseAllBtn","arrowUp","collapseAllTitle","expandAllTitle","handleCollapseAllClick","disableControlButtons","allRowValuesAreEqual","getRowValuesAreEqual","handleFilterOnlyDifferencesBtnClick","isSlowBrowser","isMicrosoftBrowser","triggerCollapseExpandRow","identicalPropertiesHidden","loadingSpinner","hideIdenticalProperties","setFirstAndLastClass","open","Promise","it","showOnlyDifferences","ControlsRow","MPCPriceValuesRowModule","htmlElementOrNull","measureValuesRowHeight","rowHeight","clientHeight","height","PriceValuesRow","MPCRowContainerModule","ValuesRow","ToolTip","MPCValuesRowModule","MPCToolTip","rowContainer","filledColumns","mpcModalContainer","htmlElement","headLineTitleHtmlElement","valuesRows","valuesRowArray","row","rowValues","resolveRowFields","hideRowWhereAllValuesAreEmpty","MPCRowField","PermanentlyHidden","tooltipContainer","handleArrowClick","collapseRow","collapseExpandValuesRow","publish","delayExecution","delay","valuesRow","collapseExpandRow","newState","allSubRowsHidden","reduce","prev","curr","UserHidden","hideRowsWhereAllValuesAreEmpty","rowValuesAreEqual","visible","RowContainer","RowField","SubValuesRow","MinusIcon","MPCValuesSubRowModule","toolTips","parentMainHeadlineRow","parentRowContainer","subValuesRowElement","rowFields","tmpRowFieldsArray","rowFieldsArray","collectRowFieldValues","rowField","columnIndex","tmpRowField","noValuesField","tooltipContainers","registerToolTipEvents","rowFieldHtmlElement","fieldValue","checkCustomRowFieldValues","price","colorField","textModule","glovesRating","heightIsSet","collapseExpand","rowFieldsAreEqual","firstRowField","allFieldsInRowAreEqual","subRowField","isEqual","allRowsAreEqual","allValuesAreEmpty","field","subValuesRow","subFilterTitleContainer","MPC","RecommendIcon","ScaleIcon2021","PrintIcon2021","GridController","MPCGridController","NavigationService","MPCNavigationService","StickyHeaderService","MPCStickyHeaderService","ComparePageButtonUrlUpdater","MPCComparePageButtonUrlUpdater","MpcSettings","MpcSettingsModule","DebugController","MPCDebugController","skipNavigation","checkComparePageUrl","urlParams","URLSearchParams","search","mpcPrintPage","navigationContainer","navigationService","comparePageButtonUrlUpdater","checkCurrentLocalStorage","stickyHeader","loadComparisonPageIcons","logPageLoadEvent","shownProducts","rootCategoryName","url","apiUrl","viewedProducts","JSON","stringify","NlVanillajax","postWithPromise","response","correlationId","documentElement","success","error","catch","err","statusText","categoryParam","categoryFromUrl","decodeURIComponent","orderOfCategoryFromUrl","clearStoredEmptyNavigationTabs","removeStoredEmptyNavigationTabs","setClearStoredEmptyNavigationTabs","emptyNavigationTabs","emptyNavigationTab","createOrUpdateNavigationTab","storageProduct","articleId","salesArticleVariantKey","savKeys","getAll","fromStorage","markActiveNavigationTab","updateSelectCategoryButtonVisibility","preparePrintPage","setNavTabFocus","savKeysExists","productsArray","clearCarouselScrollIndex","printPageLink","clone","cloneNode","storePrintPageContent","appVersion","ComparisonPageController","highlightSourceButton","handleFlyoutIconClick","GridColumnLockHelper","GridCarousel","ProductsCounter","PlusIcon2021","BasketIcon2021","RecycleBinIcon","LockedIcon","MPGridColumnLock","GridColumnLock","MPCGridCarousel","MPCProductsCounter","rowContainers","columnHeaders","columnHeadersArray","initOrderModalMutationObserver","tmpCarouselElement","gridCarousel","updateProductsCounter","scrollTo","loadGridIcons","MutationObserver","orderModal","body","quickOrderModalExists","orderModalExists","observe","childList","filledColumnsHeaders","filledColumnsHeadersArray","emptyColumnsHeaders","emptyColumnsHeadersArray","emptySlides","emptySlidesArray","lockedColumnIcons","lockedColumnIconsArray","tmpColumnHeader","columnNumber","rowContainersArray","gridRow","controlsRowHtml","carouselScrollIndex","leftSideColumnIndex","columnsAmount","setCurrentSlideClass","carousel","scrollLeftArrow","scrollLeftArrowShrinked","scrollRightArrow","hammerManager","drag_block_vertical","hammerJs","tmpPagerDots","pagerDotsArray","stickyHeaderContainer","tmpStickyHeaderPagerDots","stickyHeaderPagerDotsArray","showHideArrows","updateActivePagerDot","handleLeftArrowClick","handleRightArrowClick","gestureAngle","shrinkCarousel","shrink","swipeLeft","restorePreviousSlidePosition","storedCarouselScrollIndex","previousIndex","storeCarouselScrollIndex","getNextVisibleElements","nextVisibleElement","gridColumnIndex","selector","gridElements","headerElements","headerArray","hideScrollArrow","arrow","indexToHideFor","lockInProgressTimeOut","lockInProgress","currentLockedColumnIndex","lockUnLockColumnEvent","handleLockUnlockColumnClick","loadStoredLockedColumnInfo","columnHeader","lockedColumnIndex","getLockedColumnIndex","getColumnHeader","getCarouselScrollIndex","lockUnLockColumn","currentButtonContainer","currentTarget","selectedColumnIndex","selectedColumn","getColumn","selectedSlide","getStickyHeaderSlide","removeRegisteredEvents","changeLockIcon","parentElement","unLockAndRestoreColumn","unlockColumn","columnIsLocked","previousLockedColumn","previousLockedSlide","tmpColumnHeaderArray","lockAndMoveColumn","lockColumn","storeLockedColumnIndex","lockedColumn","lockedSlide","previousFirstSlideField","lockedSlideTempField","previousFirstColumn","previousFirstSlide","previousColumnIndex","getGridColumnIndex","outerHTML","selectedColumns","firstSlideTempField","selectedSlideTempField","tmpFirstColumn","tmpFirstSlide","tmpLockedColumn","tmpUnLockedColumn","parentContainer","showLocked","productsCounterValue","respect_glb","gridContainer","headerDistance","handleMobileGridHeaderOnScroll","handleGridHeaderOnScroll","dataset","portalmandanttoken","columnHeaderContainers","columnHeaderContainersArray","verticalDistance","pageYOffset","scrollTop","innerHeight","shrinkModeActive","columnHeaderContainer","headerFadeArea","opacity","slideSlots","slideSlotsArray","lockedColumnExists","MPCErrorHandlerModule","Init","_settings","onerror","msg","line","col","ErrorHandlerManager","_errorCount","errorEvent","lineno","colno","filename","errStr","errorMsg","LogError","isDevelopment","mpcLocalStorage","collectAllLocalStorageObjects","reason","status","combinedData","localStorage","startsWith","itemStr","getItem","_culture","_portal","_portalMandantToken","_maxProducts","_isLoggedIn","_isDevelopment","_apiUrl","initDone","_comparePageUrl","comparisonPageBaseUri","onUpdatedModel","activeNavigationTab","comparisonPageUri","encodeURIComponent","isTabletHandHeldDeviceEnvironment","className","isMobileShopEnvironment","isMicrosoftBrowserEnvironment","sniffJson","getElementById","sniffJsonResult","parse","resultingClasses","isTablet","cap","isPhone","isHandheld","isAndroid","isIOS","htmlClasses","isMsie","isEdge","isTabletHandHeldDevice","callbackLists","eventName","subscriptionsIds","createSubscription","subscribeMultiple","subscriptions","subscriptionIds","subscription","subscriptionId","addSubscription","unsubscribe","unSubscribeMultiple","removeSubscription","payload","MPCElementsHelper","appendChildAtIndex","children","appendChild","insertBefore","HtmlElementsHelper","navigationTabKeyName","abstractContent","selectCategoryButton","navigationTabs","navigationTabsArray","registerButtonEvent","switchNavigationTab","newActiveNavigationTab","domNode","newActiveNavigationTabName","oldNavigationTabName","updateContainerListVisibility","scrollToNavigationTab","buttonRightEdgePosition","getBoundingClientRect","left","offsetWidth","innerWidth","scrollLeft","counterNumber","createEmptyNavTab","isNew","navigationTab","appendSavKeyToNavTabUrl","updateCounter","createNavigationTab","indexToInsert","onActivated","isAnyProductCounted","productFound","tab","getCounterNumber","productsCounter","counter","textContent","innerText","order","newNavigationTabHtml","newNavigationTab","newCategoryName","newArticlesCounter","removeEmptyNavigationTabs","removableNavigationTabs","tmpTab","newTabActivated","markAnyNavigationTabActive","newActiveTabCatName","newActiveTab","getFirstNavigationTab","NodeList","bodyScrollPosition","webContainer","mobileContainer","removeAttribute","InfoIcon","mpcToolTip","toolTipIsVisible","setId","openToolTipOverlay","closeToolTipOverlay","existingScrollEvent","hideToolTipOnScroll","handleMouseOverTooltipEvent","handleMouseLeaveTooltipEvent","modalToolTipText","currentTooltipText","richtextRoot","modalToolTipTitle","currentTooltipTitle","outerHeight","halfToolTipHeight","currentToolTipBottom","toolTipHeight","centerTooltip","topPosition","supportsNativeSmoothScroll","scrollBy","smoothScrollTo","currentToolTipHeight","tooltipId","forceToCloseCurrentTooltip","hideTooltipAfter2Seconds","unsubscribeFrom","substring","ContentType","headers","query","contentType","req","xhr","post","setHeaders","onReadyStateChange","send","resolve","reject","onload","getResult","getWithPromise","getHtmlResult","sendGet","win","XMLHttpRequest","setRequestHeader","onreadystatechange","readyState","DONE","responseText","json","AddResult","DuplicateNotFound","DuplicateExact","localStorageAbstraction","LocalStorageAbstraction","localStorageCache","readLocalStorage","runningServiceCall","mobileEnabledCategories","validateLocalStorage","isNewlyLoggedOut","isLoggedIn","isTimedOut","createNewLocalStorage","isLoggedInNewly","needsValidation","sync","pageLanguage","culture","printPageContent","countBefore","hasClientSideChange","countAfter","setMobileHeaderMarkerOn","setMobileHeaderMarkerOff","lastUpdateTime","seoDescription","seoSlug","categoryUrl","detailsPageUrl","activateOnMobileCategory","categoryNavKey","isActivatedOnMobileCategory","deactivateOnMobileCategory","idx","addProduct","product","duplicateCheckResult","checkDuplicateProductPerCategory","isAlreadyAtLimit","RejectedCapacity","appendProductToList","Added","Replaced","RejectedDuplicate","skipSaving","afterSave","writeLocalStorage","syncedModel","removeAllProductsOfCategory","articleRemoved","productsAfter","tmpProduct","some","p","originNavKeyPathOverride","originSeoSlug","productDataFromService","productsAmount","maxProducts","localStorageModel","mobileLockedColumnIndex","mobileCarouselScrollIndex","usedNavTabForCarouselOrLockedColumn","expiration5MinutesAfterLastUpdate","expirationDate","avoidNotification","checkIsProductAlreadyAdded","productExists","currentCatName","getCurrentCategoryName","content","getPrintPageContentCached","modelDirectlyFromLocalStorage","unsupported","getNewInstanceAndMigrate","mpcLocalStorageKeyNew","mpcLocalStorageKeyOld","portal","migrate","tmpLocalStorageObject","setItem","mpcLocalStorageJson","oldKeyData","removeItem","ampersandTest","nativeURLSearchParams","isSupportObjectConstructor","decodesPlusesCorrectly","__URLSearchParams__","encodesAmpersandsCorrectly","append","URLSearchParamsPolyfill","iterable","Symbol","appendTo","dict","has","encode","useProxy","Proxy","construct","USPProto","polyfill","thisArg","parseToDict","getOwnPropertyNames","items","makeIterator","entries","match","decode","arr","next","shift","done","pairs","g","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","globalThis","Function","toStringTag"],"sourceRoot":""}