{"version":3,"file":"left-menu.js","mappings":"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","sources":["webpack://waves/webpack/bootstrap","webpack://waves/webpack/runtime/compat get default export","webpack://waves/webpack/runtime/define property getters","webpack://waves/webpack/runtime/hasOwnProperty shorthand","webpack://waves/external var \"React\"","webpack://waves/./src/domain/common.ts","webpack://waves/external var \"ReactDOM\"","webpack://waves/./node_modules/@babel/runtime/helpers/esm/extends.js","webpack://waves/./node_modules/@babel/runtime/helpers/esm/defineProperty.js","webpack://waves/./src/ui/svg/common/arrow.tsx","webpack://waves/./src/ui/svg/svg-provider.ts","webpack://waves/./src/projects/shopping-cart/cart-bridger-pay/enums/cart-steps.ts","webpack://waves/./src/projects/products/enums/product-department-enum.ts","webpack://waves/./src/projects/shopping-cart/cart-bridger-pay/enums/last-payment-option-enum.ts","webpack://waves/./src/projects/shopping-cart/cart-bridger-pay/enums/payment-tabs-enum.ts","webpack://waves/./src/projects/shopping-cart/cart-bridger-pay/enums/credit-card-service-enum.ts","webpack://waves/./src/projects/shopping-cart/cart-bridger-pay/enums/credit-card-tab.ts","webpack://waves/./src/domain/validation/validation.ts","webpack://waves/./src/domain/marketing/gtm-provider.ts","webpack://waves/./src/projects/menus/list-menu/menu/menu.tsx","webpack://waves/./src/projects/menus/list-menu/services/list-menu-provider.ts","webpack://waves/./src/domain/animations/animations-provider.ts","webpack://waves/./src/ui/svg/common/close.tsx","webpack://waves/./src/projects/menus/list-menu/menu/mobile-menu.tsx","webpack://waves/./src/projects/menus/list-menu/app.tsx","webpack://waves/./src/projects/left-menu/index.tsx"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","const __WEBPACK_NAMESPACE_OBJECT__ = React;","/**\r\n * get JSON from HTML element on the page\r\n */\r\nimport React, {useEffect, useState} from \"react\";\r\n\r\n\r\nexport const getJSONFromHtml = ($el: HTMLElement|null) => {\r\n if(!$el || !$el.textContent) return null;\r\n\r\n let json = null;\r\n\r\n try{\r\n json = JSON.parse($el.textContent);\r\n }\r\n catch(ex){}\r\n\r\n return json;\r\n};\r\n\r\n/**\r\n * get setting fromHTML\r\n *
...
\r\n */\r\nexport const getSettingFromHtml = (id: string) => {\r\n const $div = document.querySelector(`#${ id }`);\r\n if(!$div || !$div.textContent) return '';\r\n return $div.textContent.trim();\r\n};\r\n\r\n/**\r\n * helper: get GUID\r\n */\r\nconst guidHelper = () => {\r\n return Math.floor((1 + Math.random()) * 0x10000)\r\n .toString(16)\r\n .substring(1);\r\n};\r\n\r\n/**\r\n * get GUID\r\n */\r\nexport const guid = () => {\r\n return guidHelper() + guidHelper() + '-' + guidHelper() + '-' + guidHelper() + '-' + guidHelper() + '-' + guidHelper() + guidHelper() + guidHelper();\r\n};\r\n\r\n/**\r\n * timeout in milliseconds\r\n */\r\nexport const timeout = (ms: number) => {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n};\r\n\r\n/**\r\n * get page node GUID from meta tag printed in HTML\r\n *
67633544-c1c1-4096-a3cc-880a96fe4713
\r\n */\r\nexport const getPageNodeGUID = () => {\r\n const $div = document.querySelector('#nodeguid');\r\n if(!$div || !$div.textContent) return '';\r\n return $div.textContent.trim();\r\n};\r\n\r\n/**\r\n * get img CDN domain\r\n */\r\nexport const getImgCDNDomain = () => {\r\n const $box = document.getElementById('img-cdn-domain');\r\n const domain = $box?.textContent || '';\r\n return domain.trim().toLowerCase();\r\n};\r\n\r\ndeclare const window: any;\r\nexport const isMobile = () => {\r\n let check = false;\r\n\r\n // eslint-disable-next-line\r\n (function(a){if(/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(a.substr(0,4))) check = true;})( navigator.userAgent||navigator.vendor||window.opera);\r\n return check;\r\n};\r\nexport const isTablet_NOTWORK = () => {\r\n const userAgent = navigator.userAgent.toLowerCase();\r\n const isTablet = /(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/.test(userAgent);\r\n return isTablet;\r\n};\r\nexport const isTablet = () => {\r\n const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;\r\n if (isTouchDevice && !isMobile()) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n};\r\n\r\nexport const stopAllYouTubeVideos = () => {\r\n // eslint-disable-next-line\r\n document.querySelectorAll('iframe').forEach(v => { v.src = v.src;});\r\n const cnt = document.querySelectorAll('iframe')?.length;\r\n if(cnt > 0){\r\n window.setTimeout(() => {\r\n window.history.go(cnt-1);\r\n }, 200);\r\n }\r\n //window.history.go(-1);\r\n}\r\n\r\n\r\nexport const getHashByPrefix = (toFind:string, indexToFind:number = 0) => {\r\n let result = \"\";\r\n const _hash = window.location.hash.substring(1);\r\n if(!_hash || _hash === '')\r\n return result;\r\n var a = decodeURIComponent(_hash).split(\"|\"),\r\n i;\r\n\r\n for (i = 0; i < a.length; i++) {\r\n\r\n if(i < indexToFind)\r\n continue;\r\n\r\n if(a[i].startsWith(toFind) || toFind === ''){\r\n result = a[i];\r\n return result;\r\n }\r\n }\r\n\r\n return result;\r\n};\r\n\r\nexport const getParents = (elem: any) => {\r\n\r\n // Set up a parent array\r\n var parents = [];\r\n\r\n // Push each parent element to the array\r\n for ( ; elem && elem !== document; elem = elem.parentNode ) {\r\n parents.push(elem);\r\n }\r\n\r\n // Return our parent array\r\n return parents;\r\n\r\n};\r\nexport const isChildOfElementById = (elem: any, parentId: string) => {\r\n\r\n let res = false;\r\n // Push each parent element to the array\r\n for ( ; elem && elem !== document; elem = elem.parentNode ) {\r\n if(elem.id && elem.id === parentId)\r\n res = true;\r\n }\r\n\r\n // Return our parent array\r\n return res;\r\n\r\n};\r\n//Hook for dynamic window size\r\nexport const useWindowSize = () => {\r\n\r\n // Initialize state with undefined width/height so server and client renders match\r\n // Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/\r\n const [windowSize, setWindowSize] = useState({\r\n width: undefined,\r\n height: undefined,\r\n });\r\n useEffect(() => {\r\n // Handler to call on window resize\r\n function handleResize() {\r\n // Set window width/height to state\r\n setWindowSize({\r\n width: window.innerWidth,\r\n height: window.innerHeight,\r\n });\r\n }\r\n // Add event listener\r\n window.addEventListener(\"resize\", handleResize);\r\n // Call handler right away so state gets updated with initial window size\r\n handleResize();\r\n // Remove event listener on cleanup\r\n return () => window.removeEventListener(\"resize\", handleResize);\r\n }, []); // Empty array ensures that effect is only run on mount\r\n\r\n return windowSize;\r\n\r\n};\r\n//Hook for detect if HTML element is overflow\r\nexport const useIsOverflow = (ref : any) => {\r\n const [isOverflow, setIsOverflow] = React.useState(false);\r\n\r\n React.useLayoutEffect(() => {\r\n const { current } = ref;\r\n\r\n const trigger = () => {\r\n const hasOverflow = current.scrollWidth > current.clientWidth;\r\n\r\n setIsOverflow(hasOverflow);\r\n\r\n //if (callback) callback(hasOverflow);\r\n };\r\n\r\n if (current) {\r\n trigger();\r\n }\r\n }, [ ref]);\r\n\r\n return isOverflow;\r\n};\r\n\r\nexport const openWindowPopup = (url: string, title: string, width: number, height: number) => {\r\n const left = (window.screen.width / 2) - (width / 2);\r\n const top = (window.screen.height / 2) - (height / 2);\r\n return window.open(\r\n url,\r\n title,\r\n `toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=${ width }, height=${ height }, top=${ top }, left=${ left }`\r\n );\r\n};","const __WEBPACK_NAMESPACE_OBJECT__ = ReactDOM;","export default function _extends() {\n _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n };\n\n return _extends.apply(this, arguments);\n}","export default function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}","import React, { CSSProperties, useEffect, useState } from 'react';\r\nimport { getSVGHeight } from '../svg-provider';\r\nimport { IIconProps } from '../interfaces';\r\n\r\nconst ArrowIcon = (props: IIconProps) => {\r\n\r\n const [ height, setHeight ] = useState(props.height);\r\n const [ style, setStyle ] = useState();\r\n\r\n const { width, rotationAngle } = props;\r\n\r\n useEffect(() => {\r\n\r\n // if height property is not defined, and width & height should be defined in px ->\r\n // calculate the height dynamically, keeping the aspect ratio using the viewport\r\n if(height === undefined && width.endsWith('px')){\r\n setHeight(getSVGHeight(width, 11, 7));\r\n }\r\n\r\n if(!isNaN(Number(rotationAngle))){\r\n const angle = `rotate(${ rotationAngle }deg)`;\r\n\r\n const style = props.style ? { ...props.style } : {};\r\n style.WebkitTransform = angle;\r\n style.msTransform = angle;\r\n style.transform = angle;\r\n\r\n setStyle(style)\r\n }\r\n }, [height, width, rotationAngle, props.style]);\r\n\r\n return (\r\n \r\n { props.title && { props.title } }\r\n \r\n )\r\n};\r\n\r\nexport default ArrowIcon;\r\n","/**\r\n * get image height based on width and viewport\r\n */\r\nexport const getSVGHeight = (width: string, viewPortWidth: number, viewPortHeight: number) => {\r\n const widthNum = Number(width.replace('px', ''));\r\n return`${ widthNum * viewPortHeight / viewPortWidth }px`;\r\n};","export enum CartSteps {\r\n First = 1,\r\n Second = 2,\r\n Third = 3,\r\n}","export enum ProductDepartmentEnum {\r\n Bundles = 1,\r\n Plugins = 2,\r\n General = 5,\r\n Books = 6,\r\n InactiveItems = 7,\r\n LiveSound = 8,\r\n Hardware = 9,\r\n Software = 10,\r\n Subscription = 12,\r\n Consumer = 13,\r\n RentToOwnDynamic = 14,\r\n RentToOwnStatic = 15,\r\n Merch = 16,\r\n WavesUpdatePlan = 17,\r\n Upgrades = 18,\r\n Courses = 19,\r\n SubscriptionDynamic = 20,\r\n Gifts = 21,\r\n CoursesWithSoftware = 22,\r\n SubscriptionNonRecurring = 23,\r\n Mastering = 24,\r\n}","/**\r\n * https://wavesaudio.atlassian.net/browse/DSWEB-3278\r\n * ap = alipay, pp = paypal, cc = credit card, null = no previous purchase\r\n */\r\nexport enum LastPaymentOption {\r\n NONE = '',\r\n CreditCard = 'cc',\r\n PayPal = 'pp',\r\n AliPay = 'ap',\r\n}","export enum PaymentTabsEnum {\r\n CreditCard = 1,\r\n PayPal = 2,\r\n AliPay = 3,\r\n}","export enum CreditCardServiceEnum {\r\n None = 0,\r\n FirstData = 1,\r\n Pinnacle = 2,\r\n Stripe = 3\r\n}","export enum CreditCardTabTabsEnum {\r\n NewCreditCard = 1,\r\n SavedCreditCards = 2,\r\n}","import { IValidationRules } from './interfaces';\r\nimport { ClipboardEvent, Dispatch } from 'react';\r\nimport { IFormControl } from '../../ui/forms/interfaces';\r\nimport { getDecimalPlaces, isNumber } from '../math-provider';\r\n\r\n/**\r\n * Validation\r\n * ----------\r\n const userNameControl = createControl('userName', '', {\r\n required: true // required also can be a function\r\n requiredMessage: '...', // optional\r\n\r\n regex: string,\r\n regexMessage: '...', // optional\r\n\r\n email: true,\r\n emailMessage: '...', // optional\r\n\r\n name: true,\r\n nameMessage: '...', // optional\r\n\r\n password: true,\r\n passwordMessage: '...', // optional\r\n\r\n minlength: number, // minlength also can be a function\r\n minlengthMessage: '...', // optional\r\n\r\n maxlength: number, // maxlength also can be a function\r\n maxlengthMessage: '...', // optional\r\n\r\n minValue: number,\r\n minValueMessage: '...', // optional\r\n\r\n maxValue: number,\r\n maxValueMessage: '...', // optional\r\n\r\n length: number,\r\n lengthMessage: '...', // optional\r\n\r\n phone: true,\r\n phoneMessage: '...', // optional\r\n\r\n int: true,\r\n intMessage: '...', // optional\r\n\r\n number: true,\r\n numberMessage: '...', // optional\r\n\r\n general: (control) => false,\r\n generalMessage: '...',\r\n\r\n decimalPlaces: 2,\r\n decimalPlacesMessage: '...', // optional\r\n });\r\n const [userName, setUserName] = useState(userNameControl);\r\n */\r\n\r\nconst defaultMessages = {\r\n requiredMessage: 'This field is required.',\r\n regexMessage: 'This field is wrong.',\r\n emailMessage: 'Please enter a valid email address. Use letters (a-z), numbers, and the following characters: + - _ @ . only',\r\n nameMessage: 'Please use letters (a-z), numbers, spaces, and the following characters: - _ . ,\\' / # \" only.',\r\n passwordMessage: 'Please enter a mix of at least 8 characters, including at least one of each group: a-z, A-Z, 0-9, special characters (e.g. ! @ #).',\r\n minlengthMessage: 'Please enter at least $1 character$2.',\r\n maxlengthMessage: 'Please enter at most $1 character$2.',\r\n lengthMessage: 'Please enter $1 character$2.',\r\n phoneMessage: 'Invalid phone number.',\r\n intMessage: 'Please enter a valid number.',\r\n dateMessage: 'Please enter a valid date.',\r\n numberMessage: 'Please enter a valid number.',\r\n generalMessage: 'An error has occurred.',\r\n atLeastOneDigitMessage: 'At least one letter or digit is required.',\r\n handleMessage: 'Please use letters letters (a-z), numbers, and the following characters: - _ . only.',\r\n decimalPlacesMessage: 'Number of decimal places should be no more than $1.',\r\n maxValueMessage: 'The maximum value cannot exceed $1',\r\n minValueMessage: 'The minimum value cannot be less than $1',\r\n};\r\n\r\nexport const emailRegex = '^([a-zA-Z0-9_\\\\.\\\\-\\\\+]+)@([a-zA-Z0-9_\\\\-\\\\+\\\\.]+)((\\\\.([a-zA-Z0-9_\\\\-\\\\+]){2,20})+)$';\r\n\r\n/**\r\n * create form control\r\n */\r\nexport const createControl = (id: string, initialValue: any, rules: IValidationRules) : IFormControl => {\r\n return {\r\n id,\r\n value: initialValue,\r\n touched: false,\r\n isValid: true,\r\n error: '',\r\n rules: rules || []\r\n }\r\n};\r\n\r\n/**\r\n * validate form control\r\n */\r\nexport const validateControl = (control: IFormControl) : IFormControl => {\r\n\r\n const updatedControl : IFormControl = {\r\n ...control,\r\n isValid: true,\r\n error: '',\r\n };\r\n \r\n const rules = control.rules;\r\n\r\n // required ---------------------\r\n if(updatedControl.isValid && rules.required){\r\n if(typeof rules.required === 'function'){\r\n updatedControl.isValid = updatedControl.isValid && rules.required(updatedControl);\r\n }\r\n else{\r\n const _value = (typeof updatedControl.value === 'string') ? (updatedControl.value || '').trim() : updatedControl.value;\r\n updatedControl.isValid = updatedControl.isValid && !!_value;\r\n }\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.requiredMessage || defaultMessages.requiredMessage;\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // handle ---------------------\r\n if(updatedControl.isValid && rules.handle){\r\n\r\n const handleRegex = '^[a-zA-Z0-9-_\\\\.]+$';\r\n const re = new RegExp(handleRegex);\r\n\r\n updatedControl.isValid = updatedControl.isValid && (updatedControl.value.toString().trim() === '' || re.test(updatedControl.value));\r\n\r\n if(!updatedControl.isValid){\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.handleMessage || defaultMessages.handleMessage;\r\n return updatedControl;\r\n }\r\n\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // minlength -------------------------\r\n if(updatedControl.isValid && rules.minlength){\r\n\r\n const minlength = typeof rules.minlength === 'function' ? rules.minlength() : rules.minlength;\r\n updatedControl.isValid = updatedControl.isValid && (updatedControl.value.length <= 0 || updatedControl.value.length >= minlength);\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.minlengthMessage || defaultMessages.minlengthMessage;\r\n updatedControl.error = updatedControl.error.replace('$1', minlength.toString());\r\n updatedControl.error = updatedControl.error.replace('$2', minlength === 1 ? '' : 's');\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // maxlength ---------------------\r\n if(updatedControl.isValid && rules.maxlength){\r\n\r\n const maxlength = typeof rules.maxlength === 'function' ? rules.maxlength() : rules.maxlength;\r\n updatedControl.isValid = updatedControl.isValid && (updatedControl.value.length <= maxlength);\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.maxlengthMessage || defaultMessages.maxlengthMessage;\r\n updatedControl.error = updatedControl.error.replace('$1', maxlength.toString());\r\n updatedControl.error = updatedControl.error.replace('$2', maxlength === 1 ? '' : 's');\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // length ---------------------\r\n if(updatedControl.isValid && rules.length){\r\n\r\n updatedControl.isValid = updatedControl.isValid && (updatedControl.value.length === rules.length);\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.lengthMessage || defaultMessages.lengthMessage;\r\n updatedControl.error = updatedControl.error.replace('$1', rules.length.toString());\r\n updatedControl.error = updatedControl.error.replace('$2', rules.length === 1 ? '' : 's');\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // decimalPlaces ---------------------\r\n if(updatedControl.isValid && rules.decimalPlaces !== undefined && Number.isInteger(rules.decimalPlaces)){\r\n\r\n updatedControl.isValid = updatedControl.isValid && (getDecimalPlaces(Number(updatedControl.value)) <= rules.decimalPlaces);\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.decimalPlacesMessage || defaultMessages.decimalPlacesMessage;\r\n updatedControl.error = updatedControl.error.replace('$1', rules.decimalPlaces.toString());\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // email ---------------------\r\n if(updatedControl.isValid && rules.email){\r\n const re = new RegExp(emailRegex);\r\n updatedControl.isValid = updatedControl.isValid && (updatedControl.value.trim() === '' || re.test(updatedControl.value));\r\n\r\n if(updatedControl.isValid){\r\n updatedControl.isValid = updatedControl.value.indexOf('..') === -1;\r\n }\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.emailMessage || defaultMessages.emailMessage;\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // name ---------------------\r\n if(updatedControl.isValid && rules.name){\r\n\r\n const nameRegex = '^[a-zA-Z0-9-_\\\\.\\\\,\\\\/#\\'\\\\\" ]+$';\r\n const re = new RegExp(nameRegex);\r\n\r\n updatedControl.isValid = updatedControl.isValid && (updatedControl.value.trim() === '' || re.test(updatedControl.value));\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.nameMessage || defaultMessages.nameMessage;\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // password ---------------------\r\n if(updatedControl.isValid && rules.password){\r\n\r\n let isValid = true;\r\n\r\n if(updatedControl.value.length < 8){\r\n isValid = false;\r\n }\r\n else{\r\n const regexes = [/[0-9]+/, /[a-z]+/, /[A-Z]+/, /[^A-Za-z0-9]+/];\r\n\r\n for (let r = 0; r < regexes.length; r++){\r\n\r\n if ((updatedControl.value.match(regexes[r]) || []).length <= 0){\r\n isValid = false;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n updatedControl.isValid = updatedControl.isValid && (updatedControl.value.trim() === '' || isValid);\r\n\r\n if(!updatedControl.isValid){\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.passwordMessage || defaultMessages.passwordMessage;\r\n return updatedControl;\r\n }\r\n\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // regex ---------------------\r\n if(updatedControl.isValid && rules.regex){\r\n\r\n const re = new RegExp(rules.regex);\r\n\r\n updatedControl.isValid = updatedControl.isValid && (updatedControl.value.trim() === '' || re.test(updatedControl.value));\r\n\r\n if(!updatedControl.isValid){\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.regexMessage || defaultMessages.regexMessage;\r\n return updatedControl;\r\n }\r\n\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // phone ---------------------\r\n if(updatedControl.isValid && rules.phone){\r\n\r\n const intRegex = /^[0-9]{5,12}$/;\r\n const onlyZerosRegex = /^0+$/;\r\n\r\n updatedControl.isValid = updatedControl.isValid && (updatedControl.value.toString().trim() === '' || (intRegex.test(updatedControl.value) && !onlyZerosRegex.test(updatedControl.value)));\r\n\r\n if(!updatedControl.isValid){\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.phoneMessage || defaultMessages.phoneMessage;\r\n return updatedControl;\r\n }\r\n\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // number ---------------------\r\n if(updatedControl.isValid && rules.number){\r\n\r\n const isNumeric = !isNaN(parseFloat(updatedControl.value)) && isFinite(updatedControl.value);\r\n updatedControl.isValid = updatedControl.isValid && (updatedControl.value.toString().trim() === '' || isNumeric);\r\n\r\n if(!updatedControl.isValid){\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.numberMessage || defaultMessages.numberMessage;\r\n return updatedControl;\r\n }\r\n\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // int ---------------------\r\n if(updatedControl.isValid && rules.int){\r\n\r\n const intRegex = '^[0-9]+$';\r\n const re = new RegExp(intRegex);\r\n\r\n updatedControl.isValid = updatedControl.isValid && (updatedControl.value.toString().trim() === '' || re.test(updatedControl.value));\r\n\r\n if(!updatedControl.isValid){\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.intMessage || defaultMessages.intMessage;\r\n return updatedControl;\r\n }\r\n\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // minDate - min date value ---------------------\r\n if(updatedControl.isValid && rules.minDate){\r\n //if the field is required and the filed is empty or null --> valid\r\n const validEmpty = (updatedControl.value === null || updatedControl.value.length === 0) && !rules.required;\r\n\r\n if(validEmpty){\r\n updatedControl.isValid = true;\r\n }else{\r\n const min = new Date(rules.minDate);\r\n updatedControl.isValid = min < new Date(updatedControl.value);\r\n }\r\n\r\n if(!updatedControl.isValid){\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.minDateMessage || defaultMessages.dateMessage;\r\n return updatedControl;\r\n }\r\n\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // maxDate - max date value ---------------------\r\n if(updatedControl.isValid && rules.maxDate){\r\n //if the field is required and the filed is empty or null --> valid\r\n const validEmpty = (updatedControl.value === null || updatedControl.value.length === 0) && !rules.required;\r\n\r\n if(validEmpty){\r\n updatedControl.isValid = true;\r\n }else{\r\n const max = new Date(rules.maxDate);\r\n updatedControl.isValid = max > new Date(updatedControl.value);\r\n }\r\n\r\n\r\n if(!updatedControl.isValid){\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.maxDateMessage || defaultMessages.dateMessage;\r\n return updatedControl;\r\n }\r\n\r\n return updatedControl;\r\n }\r\n }\r\n\r\n\r\n // maxValue ---------------------\r\n if(updatedControl.isValid && rules.maxValue){\r\n\r\n const maxValue = typeof rules.maxValue === 'function' ? rules.maxValue() : rules.maxValue;\r\n updatedControl.isValid = updatedControl.isValid && (updatedControl.value <= maxValue);\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.maxValueMessage || defaultMessages.maxValueMessage;\r\n updatedControl.error = updatedControl.error.replace('$1', maxValue.toString());\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // minValue ---------------------\r\n if(updatedControl.isValid && isNumber(rules.minValue)){\r\n\r\n const minValue = typeof rules.minValue === 'function' ? rules.minValue() : (rules.minValue ?? 0);\r\n updatedControl.isValid = updatedControl.isValid && (updatedControl.value >= minValue);\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.minValueMessage || defaultMessages.minValueMessage;\r\n updatedControl.error = updatedControl.error.replace('$1', minValue.toString());\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // general ---------------------\r\n if(updatedControl.isValid && rules.general){\r\n\r\n if(typeof rules.general === 'function'){\r\n updatedControl.isValid = updatedControl.isValid && rules.general(updatedControl);\r\n }\r\n\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.generalMessage || defaultMessages.generalMessage;\r\n return updatedControl;\r\n }\r\n }\r\n\r\n // atLeastOneDigit ---------------------\r\n if(updatedControl.isValid && rules.atLeastOneDigit){\r\n\r\n const atLeastOneDigitRegex = '.*[A-Za-z0-9].*';\r\n const re = new RegExp(atLeastOneDigitRegex);\r\n\r\n updatedControl.isValid = updatedControl.isValid && (updatedControl.value.toString().trim() === '' || re.test(updatedControl.value));\r\n\r\n if(!updatedControl.isValid){\r\n if(!updatedControl.isValid){\r\n updatedControl.error = rules.atLeastOneDigitMessage || defaultMessages.atLeastOneDigitMessage;\r\n return updatedControl;\r\n }\r\n\r\n return updatedControl;\r\n }\r\n }\r\n\r\n return updatedControl;\r\n};\r\n\r\n/**\r\n * validate form\r\n */\r\nexport const validateForm = (params: ([IFormControl, Dispatch])[], errorControlsListHolder: IFormControl[] = []) => {\r\n\r\n let isValid = true;\r\n\r\n for(let i=0; i= 2){\r\n const setControl = param[1] as Dispatch;\r\n if(typeof setControl === 'function'){\r\n setControl(control);\r\n }\r\n }\r\n\r\n if(!control.isValid){\r\n // console.log('Non valid control', control)\r\n isValid = false;\r\n errorControlsListHolder.push(control);\r\n }\r\n }\r\n\r\n return isValid;\r\n};\r\n\r\n/**\r\n * update form control\r\n */\r\nexport const updateControl = (control: IFormControl, updatedValue: any, validate = false, reset = false) : IFormControl => {\r\n\r\n let updatedControl: IFormControl = {\r\n ...control,\r\n touched: true,\r\n value: updatedValue\r\n };\r\n\r\n if(reset) {\r\n updatedControl.touched = false;\r\n updatedControl.isValid = true;\r\n updatedControl.error = '';\r\n }\r\n\r\n if(validate) {\r\n // perform control validation, update the relevant properties\r\n updatedControl = validateControl(updatedControl);\r\n }\r\n\r\n return updatedControl;\r\n};\r\n\r\n/**\r\n * scroll to the first error\r\n */\r\nexport const scrollToFirstErrorControl = (errorControls: IFormControl[]) => {\r\n\r\n if(!errorControls || errorControls.length <= 0) return;\r\n\r\n const firstErrorControl = errorControls[0];\r\n const $control = document.getElementById(firstErrorControl.id);\r\n\r\n if(!$control) return;\r\n\r\n $control.scrollIntoView({\r\n behavior: 'smooth',\r\n block: 'center',\r\n inline: 'nearest'\r\n });\r\n\r\n $control.focus();\r\n};\r\n\r\n// eslint-disable-next-line\r\nconst invisibleCharactersRegex = /[\\0-\\x09\\x0B\\x0C\\x0E-\\x1F\\x7F-\\x9F\\xAD\\u0378\\u0379\\u037F-\\u0383\\u038B\\u038D\\u03A2\\u0528-\\u0530\\u0557\\u0558\\u0560\\u0588\\u058B-\\u058E\\u0590\\u05C8-\\u05CF\\u05EB-\\u05EF\\u05F5-\\u0605\\u061C\\u061D\\u06DD\\u070E\\u070F\\u074B\\u074C\\u07B2-\\u07BF\\u07FB-\\u07FF\\u082E\\u082F\\u083F\\u085C\\u085D\\u085F-\\u089F\\u08A1\\u08AD-\\u08E3\\u08FF\\u0978\\u0980\\u0984\\u098D\\u098E\\u0991\\u0992\\u09A9\\u09B1\\u09B3-\\u09B5\\u09BA\\u09BB\\u09C5\\u09C6\\u09C9\\u09CA\\u09CF-\\u09D6\\u09D8-\\u09DB\\u09DE\\u09E4\\u09E5\\u09FC-\\u0A00\\u0A04\\u0A0B-\\u0A0E\\u0A11\\u0A12\\u0A29\\u0A31\\u0A34\\u0A37\\u0A3A\\u0A3B\\u0A3D\\u0A43-\\u0A46\\u0A49\\u0A4A\\u0A4E-\\u0A50\\u0A52-\\u0A58\\u0A5D\\u0A5F-\\u0A65\\u0A76-\\u0A80\\u0A84\\u0A8E\\u0A92\\u0AA9\\u0AB1\\u0AB4\\u0ABA\\u0ABB\\u0AC6\\u0ACA\\u0ACE\\u0ACF\\u0AD1-\\u0ADF\\u0AE4\\u0AE5\\u0AF2-\\u0B00\\u0B04\\u0B0D\\u0B0E\\u0B11\\u0B12\\u0B29\\u0B31\\u0B34\\u0B3A\\u0B3B\\u0B45\\u0B46\\u0B49\\u0B4A\\u0B4E-\\u0B55\\u0B58-\\u0B5B\\u0B5E\\u0B64\\u0B65\\u0B78-\\u0B81\\u0B84\\u0B8B-\\u0B8D\\u0B91\\u0B96-\\u0B98\\u0B9B\\u0B9D\\u0BA0-\\u0BA2\\u0BA5-\\u0BA7\\u0BAB-\\u0BAD\\u0BBA-\\u0BBD\\u0BC3-\\u0BC5\\u0BC9\\u0BCE\\u0BCF\\u0BD1-\\u0BD6\\u0BD8-\\u0BE5\\u0BFB-\\u0C00\\u0C04\\u0C0D\\u0C11\\u0C29\\u0C34\\u0C3A-\\u0C3C\\u0C45\\u0C49\\u0C4E-\\u0C54\\u0C57\\u0C5A-\\u0C5F\\u0C64\\u0C65\\u0C70-\\u0C77\\u0C80\\u0C81\\u0C84\\u0C8D\\u0C91\\u0CA9\\u0CB4\\u0CBA\\u0CBB\\u0CC5\\u0CC9\\u0CCE-\\u0CD4\\u0CD7-\\u0CDD\\u0CDF\\u0CE4\\u0CE5\\u0CF0\\u0CF3-\\u0D01\\u0D04\\u0D0D\\u0D11\\u0D3B\\u0D3C\\u0D45\\u0D49\\u0D4F-\\u0D56\\u0D58-\\u0D5F\\u0D64\\u0D65\\u0D76-\\u0D78\\u0D80\\u0D81\\u0D84\\u0D97-\\u0D99\\u0DB2\\u0DBC\\u0DBE\\u0DBF\\u0DC7-\\u0DC9\\u0DCB-\\u0DCE\\u0DD5\\u0DD7\\u0DE0-\\u0DF1\\u0DF5-\\u0E00\\u0E3B-\\u0E3E\\u0E5C-\\u0E80\\u0E83\\u0E85\\u0E86\\u0E89\\u0E8B\\u0E8C\\u0E8E-\\u0E93\\u0E98\\u0EA0\\u0EA4\\u0EA6\\u0EA8\\u0EA9\\u0EAC\\u0EBA\\u0EBE\\u0EBF\\u0EC5\\u0EC7\\u0ECE\\u0ECF\\u0EDA\\u0EDB\\u0EE0-\\u0EFF\\u0F48\\u0F6D-\\u0F70\\u0F98\\u0FBD\\u0FCD\\u0FDB-\\u0FFF\\u10C6\\u10C8-\\u10CC\\u10CE\\u10CF\\u1249\\u124E\\u124F\\u1257\\u1259\\u125E\\u125F\\u1289\\u128E\\u128F\\u12B1\\u12B6\\u12B7\\u12BF\\u12C1\\u12C6\\u12C7\\u12D7\\u1311\\u1316\\u1317\\u135B\\u135C\\u137D-\\u137F\\u139A-\\u139F\\u13F5-\\u13FF\\u169D-\\u169F\\u16F1-\\u16FF\\u170D\\u1715-\\u171F\\u1737-\\u173F\\u1754-\\u175F\\u176D\\u1771\\u1774-\\u177F\\u17DE\\u17DF\\u17EA-\\u17EF\\u17FA-\\u17FF\\u180F\\u181A-\\u181F\\u1878-\\u187F\\u18AB-\\u18AF\\u18F6-\\u18FF\\u191D-\\u191F\\u192C-\\u192F\\u193C-\\u193F\\u1941-\\u1943\\u196E\\u196F\\u1975-\\u197F\\u19AC-\\u19AF\\u19CA-\\u19CF\\u19DB-\\u19DD\\u1A1C\\u1A1D\\u1A5F\\u1A7D\\u1A7E\\u1A8A-\\u1A8F\\u1A9A-\\u1A9F\\u1AAE-\\u1AFF\\u1B4C-\\u1B4F\\u1B7D-\\u1B7F\\u1BF4-\\u1BFB\\u1C38-\\u1C3A\\u1C4A-\\u1C4C\\u1C80-\\u1CBF\\u1CC8-\\u1CCF\\u1CF7-\\u1CFF\\u1DE7-\\u1DFB\\u1F16\\u1F17\\u1F1E\\u1F1F\\u1F46\\u1F47\\u1F4E\\u1F4F\\u1F58\\u1F5A\\u1F5C\\u1F5E\\u1F7E\\u1F7F\\u1FB5\\u1FC5\\u1FD4\\u1FD5\\u1FDC\\u1FF0\\u1FF1\\u1FF5\\u1FFF\\u200B-\\u200F\\u202A-\\u202E\\u2060-\\u206F\\u2072\\u2073\\u208F\\u209D-\\u209F\\u20BB-\\u20CF\\u20F1-\\u20FF\\u218A-\\u218F\\u23F4-\\u23FF\\u2427-\\u243F\\u244B-\\u245F\\u2700\\u2B4D-\\u2B4F\\u2B5A-\\u2BFF\\u2C2F\\u2C5F\\u2CF4-\\u2CF8\\u2D26\\u2D28-\\u2D2C\\u2D2E\\u2D2F\\u2D68-\\u2D6E\\u2D71-\\u2D7E\\u2D97-\\u2D9F\\u2DA7\\u2DAF\\u2DB7\\u2DBF\\u2DC7\\u2DCF\\u2DD7\\u2DDF\\u2E3C-\\u2E7F\\u2E9A\\u2EF4-\\u2EFF\\u2FD6-\\u2FEF\\u2FFC-\\u2FFF\\u3040\\u3097\\u3098\\u3100-\\u3104\\u312E-\\u3130\\u318F\\u31BB-\\u31BF\\u31E4-\\u31EF\\u321F\\u32FF\\u4DB6-\\u4DBF\\u9FCD-\\u9FFF\\uA48D-\\uA48F\\uA4C7-\\uA4CF\\uA62C-\\uA63F\\uA698-\\uA69E\\uA6F8-\\uA6FF\\uA78F\\uA794-\\uA79F\\uA7AB-\\uA7F7\\uA82C-\\uA82F\\uA83A-\\uA83F\\uA878-\\uA87F\\uA8C5-\\uA8CD\\uA8DA-\\uA8DF\\uA8FC-\\uA8FF\\uA954-\\uA95E\\uA97D-\\uA97F\\uA9CE\\uA9DA-\\uA9DD\\uA9E0-\\uA9FF\\uAA37-\\uAA3F\\uAA4E\\uAA4F\\uAA5A\\uAA5B\\uAA7C-\\uAA7F\\uAAC3-\\uAADA\\uAAF7-\\uAB00\\uAB07\\uAB08\\uAB0F\\uAB10\\uAB17-\\uAB1F\\uAB27\\uAB2F-\\uABBF\\uABEE\\uABEF\\uABFA-\\uABFF\\uD7A4-\\uD7AF\\uD7C7-\\uD7CA\\uD7FC-\\uF8FF\\uFA6E\\uFA6F\\uFADA-\\uFAFF\\uFB07-\\uFB12\\uFB18-\\uFB1C\\uFB37\\uFB3D\\uFB3F\\uFB42\\uFB45\\uFBC2-\\uFBD2\\uFD40-\\uFD4F\\uFD90\\uFD91\\uFDC8-\\uFDEF\\uFDFE\\uFDFF\\uFE1A-\\uFE1F\\uFE27-\\uFE2F\\uFE53\\uFE67\\uFE6C-\\uFE6F\\uFE75\\uFEFD-\\uFF00\\uFFBF-\\uFFC1\\uFFC8\\uFFC9\\uFFD0\\uFFD1\\uFFD8\\uFFD9\\uFFDD-\\uFFDF\\uFFE7\\uFFEF-\\uFFFB\\uFFFE\\uFFFF]/g;\r\n\r\n/**\r\n * remove invisible characters;\r\n * used on paste events in forms\r\n */\r\nexport const removeInvisibleChars = (text: string) => {\r\n return text.replace(invisibleCharactersRegex, '');\r\n};\r\n\r\n/**\r\n * remove invisible characters;\r\n * used on paste events in forms\r\n */\r\nexport const removeInvisibleCharsOnPaste = (evt: ClipboardEvent) => {\r\n evt.preventDefault();\r\n\r\n const $target = evt.target as HTMLInputElement;\r\n const currentFieldValue = $target ? ($target.value ?? '') : '';\r\n\r\n // get clipboard data if exists --------\r\n // @ts-ignore\r\n const clipboardData = evt.clipboardData || window.clipboardData;\r\n if(!clipboardData) return currentFieldValue;\r\n\r\n const data = evt.clipboardData.getData('text');\r\n if(!data) return '';\r\n\r\n const pasteText = removeInvisibleChars(data.trim());\r\n\r\n // handle partial and whole selections ----------\r\n const start = currentFieldValue.substring(0, $target.selectionStart ?? 0);\r\n const end = currentFieldValue.substring($target.selectionEnd ?? currentFieldValue.length, currentFieldValue.length);\r\n return start + pasteText + end;\r\n};\r\n\r\n/* let paste = (event.clipboardData || window.clipboardData).getData('text');\r\n paste = paste.toUpperCase();\r\n const selection = window.getSelection();\r\n if (!selection.rangeCount) return;\r\n selection.deleteFromDocument();\r\n selection.getRangeAt(0).insertNode(document.createTextNode(paste));\r\n selection.collapseToEnd();*/","/**\r\n * Allows to TypeScript recognize google tag manager namespace\r\n */\r\nimport {IListItem} from \"../../projects/list-page/interfaces/interfaces\";\r\nimport { CartSteps } from '../../projects/shopping-cart/cart-bridger-pay/enums/cart-steps';\r\nimport { ICartData } from '../../projects/shopping-cart/cart-bridger-pay/interfaces';\r\nimport { getHiddenDataNumber, getHiddenDataString } from '../hidden-data-provider';\r\nimport { IOrder } from '../../projects/shopping-cart/cart-thank-you/interfaces';\r\nimport { getExpectedLTV } from '../../projects/shopping-cart/cart-bridger-pay/domain/shopping-cart-provider';\r\n\r\ndeclare global {\r\n interface Window {\r\n dataLayer: any;\r\n }\r\n}\r\n\r\ninterface IGAProduct{\r\n name: string,\r\n id: string,\r\n price: number,\r\n category: string,\r\n variant: string,\r\n list: string,\r\n}\r\n\r\ninterface IGAImpression {\r\n name: string,\r\n id: string,\r\n price: number,\r\n category: string,\r\n variant: string,\r\n list: string,\r\n position: number,\r\n}\r\n\r\ninterface IActionField{\r\n list: string,\r\n}\r\n\r\ninterface ICheckoutActionField {\r\n step: number,\r\n option?: number,\r\n}\r\n\r\n/**\r\n * send data to GTM after registration\r\n */\r\nexport const gtmCreateAccount = (referrer = 'from Signup form') => {\r\n if(!window.dataLayer) return;\r\n\r\n window.dataLayer.push({\r\n 'GA_event_category': 'Registration',\r\n 'GA_event_action': 'New account',\r\n 'GA_event_label': referrer,\r\n 'event': 'GTM event To GA'\r\n });\r\n};\r\n\r\n/**\r\n * send google analytics track event\r\n * @param {string} eventTitle - event title (data-gaevent=\"Click\")\r\n * @param {string} eventValue - event value (data-gavalue=\"...\")\r\n */\r\nexport const sendGAEvent = (eventTitle: string, eventValue: string) => {\r\n\r\n if(!window.dataLayer) return;\r\n\r\n window.dataLayer.push({\r\n 'GA_event_action': eventTitle\r\n , 'GA_event_category': window.location.pathname\r\n , 'GA_event_label': eventValue\r\n , 'event': 'GTM event To GA'\r\n });\r\n};\r\n\r\n/**\r\n * get category from url\r\n */\r\nexport const getCategoryFromURL = (url: string) => {\r\n\r\n if(!url) return '';\r\n\r\n const idx = url.lastIndexOf('/');\r\n\r\n if(idx !== -1){\r\n return url.substring(0, url.lastIndexOf('/')).replace('/', '');\r\n }\r\n\r\n return '';\r\n};\r\n\r\n/**\r\n * send product clicks to the gtm\r\n */\r\nexport const sendGaEventImpressions = (impressions: IGAImpression[]) => {\r\n\r\n if(!window.dataLayer || !impressions || impressions.length <= 0) return;\r\n\r\n window.dataLayer.push({\r\n event: 'ProductImpression'\r\n ,ecommerce: {\r\n currencyCode: 'USD' //local currency is optional\r\n ,impressions: impressions\r\n }\r\n });\r\n};\r\n\r\n/**\r\n * send product details to the gtm\r\n */\r\nexport const sendGaEventProductDetails = (analyticsData: { price: number; name: string; id: string; category: string }[]) => {\r\n\r\n if(!window.dataLayer || !analyticsData || analyticsData.length <= 0) return;\r\n\r\n window.dataLayer.push({\r\n event: 'productDetail'\r\n ,ecommerce: {\r\n detail: {\r\n products: analyticsData\r\n }\r\n }\r\n });\r\n};\r\n\r\n/**\r\n * send product clicks to the gtm\r\n * actionField - {list: 'List Page'} (Product Page Tab / List Page / Shopping Cart Gallery / Homepage)\r\n */\r\nexport const sendGaEventProductClick = (actionField: IActionField, products: IGAProduct[]) => {\r\n\r\n if(!window.dataLayer || !products || products.length <= 0) return;\r\n\r\n window.dataLayer.push({\r\n event: 'productClick'\r\n ,ecommerce: {\r\n click: {\r\n actionField: actionField\r\n ,products: products\r\n }\r\n }\r\n });\r\n};\r\n\r\n/**\r\n * send Google Analytics list page event\r\n */\r\nexport const sendGAListPageEvent = (product: IListItem, listName: string = 'List Page') => {\r\n\r\n const title = product.title ? product.title : listName;\r\n\r\n const item = {\r\n name: product.documentName\r\n ,id: product.skuNumber\r\n ,price: product.skuPrice\r\n ,category: getCategoryFromURL(product.documentUrlPath)\r\n ,variant: 'NONE'\r\n ,list: title\r\n };\r\n\r\n sendGaEventProductClick({list: title}, [item]);\r\n};\r\n\r\n/**\r\n * send page type event to google analytics according to the following meta on the page:\r\n * \r\n */\r\nexport const sendGAPageTypeEvent = () => {\r\n\r\n if(!window.dataLayer) return;\r\n\r\n const $meta = document.querySelector('meta[property=\"google-ecomm-pagetype\"]');\r\n if(!$meta) return;\r\n\r\n window.dataLayer.push({\r\n pageType: $meta.getAttribute('content') || '',\r\n });\r\n};\r\n\r\n/**\r\n * send GA user guid event from the following hidden field:\r\n *
@ViewBag.LayoutModel.GA_GUID
\r\n */\r\nexport const sendGAWavesUserGuidEvent = (gaGuid = '') => {\r\n if(!window.dataLayer) return;\r\n\r\n window['dataLayer'].push({\r\n 'waves-user-guid': gaGuid || getHiddenDataString('ga-user-guid'),\r\n });\r\n};\r\n\r\n/**\r\n * This event is sent when user clicks on 'proceed to checkout' button on each cart step.\r\n */\r\nexport const sendGaCheckoutEvent = (cartStep: CartSteps, cartData: ICartData) => {\r\n\r\n if(!window.dataLayer) return;\r\n\r\n if(cartStep === CartSteps.Third){\r\n\r\n window.dataLayer.push({\r\n 'GA_event_action': 'Payment Method'\r\n ,'GA_event_category': document.location.pathname\r\n ,'GA_event_label': 'Credit Card'\r\n ,'event': 'GTM event To GA'\r\n });\r\n }\r\n\r\n const actionField: ICheckoutActionField = {\r\n step: cartStep,\r\n };\r\n\r\n if(cartStep === CartSteps.First) {\r\n actionField.option = cartData.cartItems.reduce((total, cur) => total + cur.skuUnits, 0);\r\n }\r\n\r\n const products: any[] = cartData.cartItems.filter(cartItem => cartItem.isActive).map(cartItem => {\r\n return {\r\n skuid:\tcartItem.skuid,\r\n skuDepartment:\tcartItem.skuDepartmentID,\r\n skuDepartmentName:\tcartItem.departmentName, //'plugins',\r\n skuguid: cartItem.skuguid,\r\n name: cartItem.skuName,\r\n skunumber:\tcartItem.skuNumber,\r\n skuNeedsShipping:\tcartItem.skuNeedsShipping,\r\n //isSBL:\tfalse,\r\n //isPDL:\tfalse,\r\n //img:\t'/1lib/images/products/plugins/tiny/clarity-vx.png',\r\n thumb:\tcartItem.skuThumb,\r\n quantity:\tcartItem.skuUnits,\r\n price:\tcartItem.priceData.price,\r\n upsell:\tcartItem.priceData.discount,\r\n msrp:\tcartItem.skU_MSRP,\r\n yousave: cartItem.priceData.discount,\t//119.01,\r\n producttotal: cartItem.priceData.price * cartItem.skuUnits,\r\n link:\tcartItem.documentUrlPath,\r\n cartComment: cartItem.cartComment,\r\n skuEnabled:\tcartItem.skuEnabled,\r\n //mvrDiscountPrice:\t0,\r\n //mvrItemDiscount:\t0,\r\n pricega: cartItem.priceData.price,\r\n }\r\n })\r\n\r\n window['dataLayer'].push({\r\n event: 'checkout',\r\n CartValue: cartData.priceData.totalPrice,\r\n ecommerce: {\r\n checkout: {\r\n actionField: actionField,\r\n products,\r\n }\r\n }\r\n });\r\n};\r\n\r\nexport const sendGATransactionTriggerEventHelper = (orderData: IOrder) => {\r\n\r\n if(!window.dataLayer) return;\r\n\r\n const products: any[] = [];\r\n\r\n for(let orderItem of orderData.orderItems){\r\n products.push({\r\n 'name': orderItem.orderItemSKUName,\r\n 'id': orderItem.skuNumber,\r\n 'price': orderItem.discountPrice,\r\n 'brand': 'Waves',\r\n 'category': (orderItem.departmentDisplayName ?? '').toLowerCase(),\r\n 'quantity': orderItem.orderItemUnitCount,\r\n });\r\n }\r\n\r\n if(orderData.upsellDiscount > 0){\r\n\r\n products.push({\r\n 'name': 'Discount',\r\n 'price': -orderData.upsellDiscount,\r\n 'brand': 'Waves',\r\n 'quantity': 1,\r\n });\r\n }\r\n\r\n window.dataLayer.push({\r\n event: 'TransactionTrigger'\r\n ,PaymentMethod: orderData.fundSourceType // 'Credit Card / PayPal / AliPay / Splitit'\r\n\r\n ,ecommerce: {\r\n purchase: {\r\n 'actionField': {\r\n 'id': orderData.wavesReceiptID,\r\n 'affiliation': 'Online Store',\r\n 'revenue': orderData.totalPrice - orderData.taxPrice - orderData.shippingTaxPrice,\r\n 'tax': orderData.taxPrice + orderData.shippingTaxPrice,\r\n 'shipping': orderData.shippingPrice,\r\n },\r\n products,\r\n }\r\n }\r\n });\r\n\r\n};\r\n\r\n/**\r\n * This event is sent on 'thank you' page only after the real purchase.\r\n */\r\nexport const sendGATransactionTriggerEvent = (orderData: IOrder) => {\r\n sendGATransactionTriggerEventHelper(orderData);\r\n\r\n window.dataLayer.push({\r\n event: getExpectedLTV(orderData) > 0 ? 'TransactionTriggerSBS' : 'TransactionTriggerPerpetual',\r\n });\r\n};\r\n\r\nexport const sendThankYouDataToGTM = (orderData: IOrder) => {\r\n if(!window.dataLayer) return;\r\n\r\n const quantity = orderData.orderItems.reduce(\r\n (previousQty, orderItem) => previousQty + orderItem.orderItemUnitCount,\r\n 0\r\n );\r\n\r\n window.dataLayer.push({\r\n 'quantity': quantity,\r\n 'receiptid': orderData.wavesReceiptID,\r\n 'priceWithoutTaxAndShipping': getHiddenDataNumber('price-without-tax-and-shipping'),\r\n 'OrderID': orderData.orderID,\r\n 'email': orderData.email,\r\n 'yotpo-api-key': getHiddenDataString('yotpo-api-key'),\r\n 'expectedLTV': getExpectedLTV(orderData),\r\n });\r\n};\r\n\r\n/**\r\n * send data to gtm every time when product is added to cart\r\n */\r\nexport const sendGAEventAddToCart = (\r\n documentName: string,\r\n skuNumber: string,\r\n skuPrice: number,\r\n documentUrlPath: string,\r\n list: string = '',\r\n) => {\r\n\r\n if(!window.dataLayer) return;\r\n\r\n const data = {\r\n event: 'addToCart'\r\n ,ecommerce: {\r\n currencyCode: 'USD'\r\n ,add: {\r\n products: [\r\n {\r\n name: documentName\r\n ,id: skuNumber\r\n ,price: skuPrice\r\n ,variant: 'NONE'\r\n ,quantity: 1\r\n ,category: getCategoryFromURL(documentUrlPath)\r\n }\r\n ],\r\n }\r\n }\r\n };\r\n\r\n if(list){\r\n // @ts-ignore\r\n data.ecommerce.add.actionField = { list, };\r\n }\r\n\r\n window.dataLayer.push(data);\r\n};\r\n\r\n/**\r\n * https://wavesaudio.atlassian.net/browse/DSWEB-1143\r\n * Edited by Raz Liveyatan, 04.11.2021\r\n * Migrated by Raz Liveyatan, 27.06.2022\r\n * send page view to the gtm\r\n * @param {any} PageViewObject\r\n */\r\nexport const sendGaPageView = (PageViewObject:any) => {\r\n\r\n if(!window.dataLayer || !PageViewObject) return;\r\n\r\n window.dataLayer.push({\r\n event: 'pageview',\r\n page: {\r\n path: PageViewObject.pageLocation,\r\n title: PageViewObject.title\r\n }\r\n });\r\n};\r\n\r\n","import { IListCategory, IListMenuProps } from '../services/interfaces';\r\nimport {MouseEvent, useRef, useState} from 'react';\r\nimport {prepareData, MAX_VISIBLE_ITEMS } from '../services/list-menu-provider';\r\nimport ArrowIcon from '../../../../ui/svg/common/arrow';\r\nimport { isWebAnimationSupported } from '../../../../domain/animations/animations-provider';\r\nimport {sendGAEvent} from \"../../../../domain/marketing/gtm-provider\";\r\n\r\nconst READ_MORE_DURATION = 200; // ms\r\n\r\n/**\r\n * The menu.\r\n */\r\nconst Menu = (props: IListMenuProps) => {\r\n\r\n const showMoreButtonRef = useRef(null);\r\n const showLessButtonRef = useRef(null);\r\n\r\n const [data, setData] = useState(prepareData(props.menuData));\r\n\r\n const isAnimationSupported = isWebAnimationSupported();\r\n const rootRef = useRef(null);\r\n\r\n /* --------------------------- ANIMATIONS --------------------------- */\r\n\r\n /**\r\n * get max height of category items div for animation\r\n */\r\n const getHeight = ($box: HTMLElement, showElementsClass: string) => {\r\n return new Promise((resolve, reject) => {\r\n\r\n // disable the height if exists\r\n $box.style.height = 'auto';\r\n\r\n window.setTimeout(() => {\r\n\r\n // make all content visible for a second\r\n $box.classList.add(showElementsClass);\r\n window.setTimeout(() => {\r\n\r\n // calculate the actual container height\r\n const height = $box.clientHeight;\r\n\r\n // restore the initial content height\r\n $box.classList.remove(showElementsClass);\r\n\r\n window.setTimeout(() => {\r\n resolve(height);\r\n }, 0);\r\n\r\n }, 0);\r\n }, 0);\r\n });\r\n };\r\n\r\n /**\r\n * read more: create animation object\r\n * it should be created only when animation goes down;\r\n * when animation goes up the same object is reused (with reverse method)\r\n */\r\n const animateReadMoreOpen = async ($box: HTMLElement, showElementsClass: string) => {\r\n\r\n // this is the height of the container when some links are invisible\r\n const minHeight = Math.max($box.scrollHeight, $box.offsetHeight, $box.clientHeight);\r\n\r\n // this is the height of the container when all links are visible\r\n const maxHeight = await getHeight($box, showElementsClass);\r\n\r\n // apply the smaller height and then animate to the bigger height\r\n $box.style.height = `${ minHeight }px`;\r\n const animation = $box.animate(\r\n [\r\n { height: `${ maxHeight }px` },\r\n ], {\r\n fill: 'forwards',\r\n duration: READ_MORE_DURATION\r\n }\r\n );\r\n\r\n // don't play the animation now, use it later\r\n animation.pause();\r\n return animation;\r\n };\r\n\r\n /**\r\n * open / close toggle: create animation object\r\n * it should be created only when animation goes up;\r\n * when animation goes down the same object is reused (with reverse method)\r\n */\r\n const animateClose = async ($box: HTMLElement, showElementsClass: string) => {\r\n\r\n // this is the height of the container when all links are visible\r\n const maxHeight = await getHeight($box, showElementsClass);\r\n\r\n // apply the bigger height and then animate to the smaller height\r\n $box.style.height = `${ maxHeight }px`;\r\n const animation = $box.animate(\r\n [\r\n { height: `${ 0 }px` },\r\n ], {\r\n fill: 'forwards',\r\n duration: READ_MORE_DURATION\r\n }\r\n );\r\n\r\n // don't play the animation now, use it later\r\n animation.pause();\r\n return animation;\r\n };\r\n\r\n /**\r\n * animate item container height (read more)\r\n */\r\n const animateReadMore = async (categoryName: string, shouldSlideDown: boolean, categoryIndex: number) => {\r\n\r\n if(!rootRef || !rootRef.current) return;\r\n\r\n const $box = rootRef.current.querySelector(`[data-list-menus-block=\"${ categoryIndex }\"]`) as HTMLElement;\r\n if(!$box) return null;\r\n\r\n // find the proper container in data\r\n const copy = [...data];\r\n const foundIndex = copy.findIndex(item => item && item.categoryName === categoryName);\r\n if(foundIndex === -1) return;\r\n\r\n // the container data item\r\n const item = copy[foundIndex];\r\n\r\n // if the animation should go down -> get animation object, otherwise reuse the same animation object stored in the data\r\n const animation = !shouldSlideDown ? item.readMoreAnimation : await animateReadMoreOpen($box, 'list-menu-items-visible');\r\n if(!animation) return;\r\n\r\n item.showReadMore = !shouldSlideDown;\r\n item.readMoreAnimation = animation;\r\n\r\n if(shouldSlideDown){\r\n animation.play();\r\n setData(copy);\r\n }\r\n else{\r\n animation.reverse();\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n window.setTimeout(() => {\r\n\r\n // first animate backwards, and only then hide the items\r\n // otherwise there is a 'blank' space\r\n setData(copy);\r\n resolve();\r\n }, READ_MORE_DURATION);\r\n })\r\n };\r\n\r\n /**\r\n * on 'read more' click\r\n */\r\n const handleReadMoreClick = async (evt: MouseEvent, categoryName: string, shouldSlideDown: boolean, categoryIndex: number) => {\r\n\r\n evt.preventDefault();\r\n evt.stopPropagation();\r\n\r\n if(isAnimationSupported) {\r\n await animateReadMore(categoryName, shouldSlideDown, categoryIndex);\r\n }\r\n else{\r\n const copy = [...data];\r\n const foundIndex = copy.findIndex(item => item && item.categoryName === categoryName);\r\n if(foundIndex === -1) return;\r\n\r\n const item = copy[foundIndex];\r\n item.showReadMore = !shouldSlideDown;\r\n setData(copy);\r\n }\r\n\r\n if(shouldSlideDown) {\r\n showLessButtonRef.current?.focus();\r\n }\r\n else{\r\n showMoreButtonRef.current?.focus();\r\n }\r\n };\r\n\r\n /**\r\n * animate open / close\r\n */\r\n const openCloseAnimation = async (categoryName: string, isOpened: boolean, categoryIndex: number) => {\r\n\r\n if(!rootRef || !rootRef.current) return;\r\n\r\n const $box = rootRef.current.querySelector(`[data-list-content=\"${ categoryIndex }\"]`) as HTMLElement;\r\n if(!$box) return null;\r\n\r\n // find the proper container in data\r\n const copy = [...data];\r\n const foundIndex = copy.findIndex(item => item && item.categoryName === categoryName);\r\n if(foundIndex === -1) return;\r\n\r\n // the container data item\r\n const item = copy[foundIndex];\r\n\r\n // if the animation should go down -> get animation object, otherwise reuse the same animation object stored in the data\r\n const animation = isOpened ? await animateClose($box, 'dummy') : item.toggleAnimation; // no class is needed\r\n if(!animation) return;\r\n\r\n if(isOpened){\r\n animation.play();\r\n }\r\n else{\r\n animation.reverse();\r\n }\r\n\r\n item.isOpened = !item.isOpened;\r\n item.toggleAnimation = animation;\r\n\r\n return new Promise((resolve, reject) => {\r\n window.setTimeout(() => {\r\n\r\n // first animate backwards, and only then hide the items\r\n // otherwise there is a 'blank' space\r\n setData(copy);\r\n\r\n if(!isOpened){\r\n $box.style.height = 'auto';\r\n }\r\n\r\n resolve();\r\n }, READ_MORE_DURATION);\r\n })\r\n };\r\n\r\n /**\r\n * on arrow click\r\n */\r\n const handleArrowClick = async (evt: MouseEvent, categoryName: string, isOpened: boolean, categoryIndex: number) => {\r\n\r\n evt.preventDefault();\r\n evt.stopPropagation();\r\n\r\n if(isAnimationSupported) {\r\n await openCloseAnimation(categoryName, isOpened, categoryIndex);\r\n }\r\n else{\r\n const copy = [...data];\r\n const foundIndex = copy.findIndex(item => item && item.categoryName === categoryName);\r\n if(foundIndex === -1) return;\r\n\r\n const item = copy[foundIndex];\r\n item.isOpened = !item.isOpened;\r\n setData(copy);\r\n }\r\n };\r\n\r\n return (\r\n
\r\n {\r\n data.map((item, catIndex) => {\r\n\r\n const categoriesCount = data.length;\r\n\r\n // show read more when:\r\n // - number of links > defined minimum\r\n // - there are more than 1 category\r\n // - the state of category is 'closed' (by default)\r\n // - in all other cases all links are visible as plain list\r\n const showReadMore = item.showReadMore && item.linkItems.length > MAX_VISIBLE_ITEMS && categoriesCount > 1;\r\n\r\n // show 'less' when:\r\n // - number of links > defined minimum\r\n // - there are more than 1 category\r\n // - the state of category is 'opened' (by default)\r\n // - in all other cases all links are visible as plain list\r\n const showLess = !item.showReadMore && item.linkItems.length > MAX_VISIBLE_ITEMS && categoriesCount > 1;\r\n\r\n const closedClass = item.isOpened ? ' list-menu-opened ' : ' list-menu-closed ';\r\n\r\n return (\r\n
\r\n\r\n {/*--------- category name and arrow ----------*/}\r\n {\r\n await handleArrowClick(evt, item.categoryName, item.isOpened, catIndex);\r\n }}>\r\n
{ item.categoryName }
\r\n
\r\n \r\n
\r\n \r\n\r\n
\r\n\r\n {/*--------- category items & gradient ----------*/}\r\n
\r\n {\r\n item.linkItems.map((linkItem, linkIndex) => {\r\n const notVisible = showReadMore && linkIndex > MAX_VISIBLE_ITEMS;\r\n return (\r\n \r\n { linkItem.documentName } { !!linkItem.tagCount && ({ linkItem.tagCount }) }\r\n \r\n )\r\n })\r\n }\r\n\r\n {/*--------- gradient ----------*/}\r\n { showReadMore &&
}\r\n
\r\n\r\n {/*--------- read more / less ----------*/}\r\n {\r\n showReadMore && // eslint-disable-next-line\r\n {\r\n await handleReadMoreClick(evt, item.categoryName, true, catIndex);\r\n sendGAEvent('list page side menu', `${ item.categoryName } show more`);\r\n }}>Show more\r\n }\r\n\r\n {\r\n showLess && // eslint-disable-next-line\r\n {\r\n await handleReadMoreClick(evt, item.categoryName, false, catIndex);\r\n sendGAEvent('list page side menu', `${ item.categoryName } show less`);\r\n }}>Show less\r\n }\r\n
\r\n\r\n {/*--------- divider ----------*/}\r\n { (catIndex !== data.length - 1) &&
}\r\n
\r\n )\r\n })\r\n }\r\n
\r\n )\r\n};\r\n\r\nexport default Menu;","import {IListCategory, IListMenuItem} from './interfaces';\r\n\r\nexport const MAX_VISIBLE_ITEMS = 7;\r\nexport const EVENT_LIST_MENU_MOBILE_OPEN = 'event-list-menu-mobile-open';\r\n\r\n/**\r\n * open mobil list menu from outside\r\n */\r\nexport const sendOpenMobileListMenuEvent = () => {\r\n document.dispatchEvent(new Event(EVENT_LIST_MENU_MOBILE_OPEN));\r\n};\r\n\r\n/**\r\n * menu data is received from SP 'as-is' and pasted on the page as JSON.\r\n * this function should group all menu elements by category, and perform other data fixes / preperations.\r\n */\r\nexport const prepareData = (data: IListMenuItem[]) => {\r\n\r\n if(!data) return [];\r\n\r\n const copy = JSON.parse(JSON.stringify(data));\r\n const map = new Map();\r\n\r\n for(let i=0; i MAX_VISIBLE_ITEMS;\r\n map.set(item.categoryName, category);\r\n }\r\n else{\r\n const category: IListCategory = {\r\n categoryName: item.categoryName,\r\n linkItems: [item],\r\n showReadMore: false,\r\n isOpened: true,\r\n };\r\n map.set(item.categoryName, category);\r\n }\r\n }\r\n\r\n return Array.from(map.values()) as unknown as IListCategory[];\r\n};","import { useEffect, useRef, useState } from 'react';\r\n\r\n// <= 767 - defined as mobile (iphone etc.)\r\nexport const MOBILE_BREAKPOINT = 767;\r\n\r\n// tablet range [768, 1023]\r\nexport const TABLET_BREAKPOINT_START = 768;\r\nexport const TABLET_BREAKPOINT_END = 1023;\r\n\r\n// DESKTOP >= 1024\r\nexport const DESKTOP_BREAKPOINT = 1024;\r\n\r\n/**\r\n * checks if Web Animation API is supported\r\n */\r\nexport const isWebAnimationSupported = () => {\r\n return 'animate' in document.createElement('div');\r\n};\r\n/**\r\n * if resize observer is supported\r\n * https://web.dev/resize-observer/\r\n */\r\nexport const isResizeObserverSupported = () => {\r\n return 'ResizeObserver' in window;\r\n};\r\n\r\n/**\r\n * get viewport width\r\n */\r\nexport const getViewportWidth = () => {\r\n return Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);\r\n};\r\n\r\n/**\r\n * get window width / height\r\n */\r\nexport const getWindowDimensions = () => {\r\n return {\r\n width: window.innerWidth,\r\n height: window.innerHeight,\r\n }\r\n};\r\n\r\n/**\r\n * window resize observer hook\r\n * returns width and height on window resize\r\n * usage:\r\n * -------\r\n * const [width, height] = useWindowResizeObserver();\r\n * console.log(width, height);\r\n */\r\nexport const useWindowResizeObserver = () => {\r\n\r\n const [width, setWidth] = useState(document.body.clientWidth);\r\n const [height, setHeight] = useState(document.body.clientWidth);\r\n\r\n const observer = useRef(isResizeObserverSupported() ?\r\n new ResizeObserver(entries => {\r\n\r\n if(!entries || entries.length <= 0) return;\r\n\r\n const { width, height } = entries[0].contentRect;\r\n setWidth(width);\r\n setHeight(height);\r\n }) : null\r\n );\r\n\r\n useEffect(() => {\r\n\r\n observer?.current?.observe(document.body);\r\n\r\n return () => { // eslint-disable-next-line\r\n observer?.current?.unobserve(document.body);\r\n }\r\n }, []);\r\n\r\n return [\r\n width,\r\n height,\r\n ];\r\n};\r\n\r\nexport const getWidth = async ($el: HTMLElement) : Promise => {\r\n return new Promise((resolve, reject) => {\r\n const width = $el.style.getPropertyValue('width');\r\n $el.style.removeProperty('width');\r\n window.setTimeout(() => {\r\n const offsetWidth = $el.offsetWidth;\r\n $el.style.setProperty('width', width);\r\n window.setTimeout(() => {\r\n resolve(offsetWidth);\r\n }, 0);\r\n }, 0);\r\n });\r\n};","import React from 'react';\r\nimport { IIconProps } from '../interfaces';\r\n\r\nconst CloseIcon = (props: IIconProps) => {\r\n\r\n return (\r\n \r\n Close\r\n \r\n \r\n )\r\n};\r\n\r\nexport default CloseIcon;\r\n","import { IListMenuProps } from '../services/interfaces';\r\nimport { useEffect, useState, useRef } from 'react';\r\nimport { EVENT_LIST_MENU_MOBILE_OPEN } from '../services/list-menu-provider';\r\nimport Menu from './menu';\r\nimport CloseIcon from '../../../../ui/svg/common/close';\r\n\r\n/**\r\n * Mobile menu should be hidden by default.\r\n * On button click it slides from the right.\r\n */\r\nconst MobileMenu = (props: IListMenuProps) => {\r\n\r\n const [isVisible, setIsVisible] = useState(false);\r\n\r\n const asideRef = useRef(null);\r\n\r\n /**\r\n * open mobile menu from outside\r\n */\r\n useEffect(() => {\r\n document.addEventListener(EVENT_LIST_MENU_MOBILE_OPEN, () => {\r\n setIsVisible(true);\r\n });\r\n }, []);\r\n\r\n useEffect(() => {\r\n if(!isVisible || !asideRef.current) return;\r\n\r\n setTimeout(() => {\r\n asideRef.current?.focus();\r\n }, 160);\r\n }, [isVisible]);\r\n\r\n /**\r\n * close menu\r\n */\r\n const close = () => {\r\n setIsVisible(false);\r\n };\r\n\r\n return (\r\n \r\n\r\n \r\n\r\n
\r\n\r\n {/* ------- top panel --------*/}\r\n
\r\n { props.mobileTitle && {props.mobileTitle} }\r\n \r\n \r\n \r\n
\r\n\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n \r\n )\r\n};\r\n\r\nexport default MobileMenu;","import { IListMenuProps } from './services/interfaces';\r\nimport Menu from './menu/menu';\r\nimport MobileMenu from './menu/mobile-menu';\r\n\r\n/**\r\n * List menu app.\r\n * Usage example:\r\n *
\r\n */\r\nconst ListMenuApp = (props: IListMenuProps) => {\r\n\r\n const desktopMenuProps = JSON.parse(JSON.stringify(props));\r\n const mobileMenuProps = JSON.parse(JSON.stringify(props));\r\n\r\n return (\r\n <>\r\n
\r\n \r\n
\r\n \r\n \r\n )\r\n};\r\n\r\nexport default ListMenuApp;","import { getJSONFromHtml } from '../../domain/common';\r\nimport { IListMenuItem } from '../menus/list-menu/services/interfaces';\r\nimport ReactDOM from 'react-dom';\r\nimport React from 'react';\r\nimport ListMenuApp from '../menus/list-menu/app';\r\n\r\n/**\r\n * init product lists menus (left aside)\r\n * usage:\r\n * -------\r\n *
\r\n * Here data-json contains a path to the HTML element with JSON data.\r\n */\r\nconst handleListMenus = () => {\r\n const $placeholders = document.querySelectorAll('[data-list-menu]');\r\n\r\n for(let i=0; i<$placeholders.length; i++){\r\n const $placeholder = $placeholders[i];\r\n\r\n const jsonPath = $placeholder.getAttribute('data-json');\r\n if(!jsonPath) continue;\r\n\r\n const $json = document.querySelector(jsonPath) as HTMLElement;\r\n if(!$json) continue;\r\n\r\n const menuData = getJSONFromHtml($json) as IListMenuItem[];\r\n const mobileTitle = $placeholder.getAttribute('data-mobile-title') || '';\r\n\r\n const desktopClasses = $placeholder.getAttribute('data-desktop-classes') || '';\r\n\r\n ReactDOM.render(\r\n \r\n \r\n ,\r\n $placeholder\r\n );\r\n }\r\n};\r\n\r\ndocument.addEventListener('DOMContentLoaded', () => {\r\n handleListMenus();\r\n});"],"names":["__webpack_require__","module","getter","__esModule","d","a","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","React","getJSONFromHtml","$el","textContent","json","JSON","parse","ex","ReactDOM","_extends","assign","target","i","arguments","length","source","apply","this","value","configurable","writable","props","height","setHeight","useState","style","setStyle","width","rotationAngle","useEffect","undefined","endsWith","viewPortWidth","viewPortHeight","widthNum","Number","replace","getSVGHeight","isNaN","angle","WebkitTransform","msTransform","transform","className","classes","viewBox","xmlns","xmlnsXlink","title","id","fill","color","xlinkHref","fillRule","CartSteps","ProductDepartmentEnum","LastPaymentOption","PaymentTabsEnum","CreditCardServiceEnum","CreditCardTabTabsEnum","sendGAEvent","eventTitle","eventValue","window","dataLayer","push","location","pathname","READ_MORE_DURATION","showMoreButtonRef","useRef","showLessButtonRef","data","setData","copy","stringify","map","Map","item","has","categoryName","category","linkItems","showReadMore","set","isOpened","Array","from","values","prepareData","menuData","isAnimationSupported","document","createElement","rootRef","getHeight","$box","showElementsClass","Promise","resolve","reject","setTimeout","classList","add","clientHeight","remove","handleReadMoreClick","async","evt","shouldSlideDown","categoryIndex","preventDefault","stopPropagation","current","querySelector","foundIndex","findIndex","animation","minHeight","Math","max","scrollHeight","offsetHeight","maxHeight","animate","duration","pause","animateReadMoreOpen","readMoreAnimation","play","reverse","animateReadMore","focus","ref","catIndex","categoriesCount","showLess","closedClass","type","onClick","animateClose","toggleAnimation","openCloseAnimation","handleArrowClick","linkItem","linkIndex","notVisible","documentName","href","documentUrlPath","display","tagCount","isVisible","setIsVisible","asideRef","addEventListener","close","tabIndex","mobileTitle","desktopMenuProps","mobileMenuProps","desktopClasses","$placeholders","querySelectorAll","$placeholder","jsonPath","getAttribute","$json","handleListMenus"],"sourceRoot":""}