{"version":3,"file":"main.min.js","sources":["../../../Frontend/js/utils/onReady.js","../../../Frontend/js/utils/elementProperties.js","../../../Frontend/js/utils/scrollLock.js","../../../Frontend/js/utils/scroll.js","../../../Frontend/js/components/nav.js","../../../Frontend/js/utils/stickyNavOnScroll.js","../../../Frontend/js/utils/windowResize.js","../../../Frontend/js/utils/lazyImage.js","../../../Frontend/js/utils/animation.js","../../../Frontend/js/components/accordion.js","../../../Frontend/js/utils/helpers.js","../../../Frontend/js/utils/scrollTo.js","../../../Frontend/js/components/video.js","../../../Frontend/js/components/anchors.js","../../../Frontend/js/components/filter.js","../../../Frontend/js/components/overlay.js","../../../Frontend/js/components/tabs.js","../../../Frontend/js/components/slider.js","../../../Frontend/js/components/intersect.js","../../../Frontend/js/main.js","../../../Frontend/js/components/productentrance.js","../../../Frontend/js/components/collage-element.js","../../../Frontend/js/components/form.js"],"sourcesContent":["/**\n * Handler to trigger callbacks once the browser is ready for them.\n *\n * You can keep adding references using onReady() even after the page is loaded. In that case they will be\n * run at once.\n *\n * @example\n * import { onReady } from './utils/events/onReady';\n *\n * onReady(yourFunctionHere);\n *\n */\n\nlet functionReferences = [];\n\n// Set the initial readyState based on the browser's current state. If the script has been loaded\n// asynchronously, the DOM might be ready for us already, in which case there's no reason to delay\n// any further processing. The following will evaluate as true if the DOM is ready, or the page is\n// complete.\nlet readyState = document.readyState === 'interactive' || document.readyState === 'complete';\n\n// Defines whether or not the window.onReady event has been bound, so we won't do it twice. That\n// would just be stupid.\nlet readyEventBound = false;\n\n/**\n * Run the given array of callback functions.\n *\n * @private\n * @param {Array} funcArray\n */\nfunction runFunctionArray(funcArray) {\n funcArray.forEach(funcRef => funcRef());\n}\n\n/**\n * Empty the callback arrays\n *\n * @private\n */\nfunction emptyCallbackArrays() {\n // Keep iterating through the function references until there are none left.\n while (functionReferences.length) {\n // Set up a temporary array that mirrors the list of callbacks, and empty the real one.\n const tempArray = functionReferences.slice(0);\n functionReferences = [];\n\n // Run the callbacks. The callbacks themselves may set up more callbacks, which\n // is why we keep looping the array until we're done.\n runFunctionArray(tempArray);\n }\n\n // At this point we'll assume we're ready for anything!\n readyState = true;\n}\n\n/**\n * Make sure the \"ready\"-event is set.\n *\n * @private\n */\nfunction bindReadyEvent() {\n if (!readyEventBound) {\n if (document.readyState === 'loading') {\n // loading yet, wait for the event\n document.addEventListener('DOMContentLoaded', emptyCallbackArrays);\n } else {\n // DOM is ready!\n emptyCallbackArrays();\n }\n\n readyEventBound = true;\n }\n}\n\n/**\n * Register a function to run when the page is ready.\n *\n * @param {Function} functionReference - The function you want to run.\n */\nexport function onReady(functionReference) {\n if (typeof functionReference === 'function') {\n if (readyState) {\n functionReference();\n } else {\n bindReadyEvent();\n\n functionReferences.push(functionReference);\n }\n }\n}\n","/**\n * Utilities for checking properties and states of elements.\n */\n\n/**\n * Check if an element is empty.\n *\n * @param {Node} element - Check if this element is empty.\n * @param {boolean} [strict=true] - Set this to **false** to ignore nodes with whitespace.\n * @returns {boolean} **True** if the element is empty.\n */\nexport function elementIsEmpty(element, strict = true) {\n return strict ? !element.childNodes.length : !element.innerHTML.trim().length;\n}\n\n/**\n * Check if an element is hidden in the DOM with `display: none;`\n *\n * @param {HTMLElement} element - The element to check.\n * @returns {boolean} **True** if element is hidden, otherwise **false**.\n */\nexport function elementIsHidden(element) {\n return element.offsetParent === null;\n}\n\n/**\n * Check if an element is in the viewport\n * \n * @param {HTMLElement} elem - The element to check \n */\nexport function isVisible(elem) {\n return !!elem && !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);\n}\n\n/**\n * Find out whether or not the given argument is an element that would react somewhat normally to DOM-manipulations.\n *\n * @param {*} element - The element to check.\n * @returns {boolean} `true` if the given argument is an element (or document, or window), and `false` otherwise.\n */\nexport function isElement(element) {\n return element instanceof Element || element instanceof Document || element instanceof Window;\n}\n\n/**\n * Return the position of an element\n *\n * @param {Element|String} element - The HTML element to work with or its ID\n * @param {Element|String|Window} [relativeTo=window] - The HTML element to return the position relative to or its ID\n * @returns {{top: Number, left: Number}} An object with top and left positions in pixels\n *\n *\n * @example Basic usage:\n * import { getElementPosition } from './utils/dom/elementProperties';\n *\n * const element = document.querySelector('.anElement');\n * getElementPosition(element);\n *\n *\n * @example Perform a search for an element with an ID equal to the string, i.e. 'elementId', and get the position of that:\n * import { getElementPosition } from './utils/dom/elementProperties';\n *\n * getElementPosition('elementId');\n */\nexport function getElementPosition(element, relativeTo = window) {\n const useElement = typeof element === 'string' ? document.getElementById(element) : element;\n\n // Throw error if element wasn't found\n if (!useElement) {\n throw 'getElementPosition did not find an element.';\n }\n\n const useRelativeTo = typeof relativeTo === 'string' ? document.getElementById(relativeTo) : relativeTo;\n\n // Throw error if relative element wasn't found\n if (!useRelativeTo) {\n throw 'getElementPosition did not find an element to show the position relative to.';\n }\n\n if (relativeTo === window) {\n // Return position relative to window\n const rect = useElement.getBoundingClientRect();\n return {\n top: rect.top + (window.pageYOffset || document.documentElement.scrollTop),\n left: rect.left + (window.pageXOffset || document.documentElement.scrollLeft)\n };\n } else {\n // Return position relative to declared element\n return {\n top: useElement.offsetTop - relativeTo.offsetTop,\n left: useElement.offsetLeft - relativeTo.offsetLeft\n };\n }\n}\n\n/**\n * Get the current scroll values of the given element (or window). Will return an object containing\n * \"left\" and \"top\" properties, which are set to the scroll values, or false if no compatible element\n * was given.\n *\n * @param {Element|Window} [element=window]\n * @returns {{ left: number, top: number } | boolean}\n */\nexport function getElementScroll(element = window) {\n if (isElement(element)) {\n if (element instanceof Window) {\n return {\n left: element.pageXOffset || document.documentElement.scrollLeft,\n top: element.pageYOffset || document.documentElement.scrollTop\n };\n } else {\n return {\n left: element.scrollX || element.scrollLeft,\n top: element.scrollY || element.scrollTop\n };\n }\n } else {\n console.warn('Can\\'t get scroll-position or given argument type.');\n return false;\n }\n}\n\n/**\n * Get both width and height of element\n *\n * @param {Element} element - The HTML element to work with\n * @param {Object} [options={}] - Object of options\n * @param {boolean} [options.includePadding=false] - Get size including padding (defaults to true)\n * @param {boolean} [options.includeBorder=false] - Get size including border (defaults to true)\n * @param {boolean} [options.includeMargin=true] - Get size including margin (defaults to false)\n * @param {null|':before'|':after'} [options.pseudoElement=null] - Get size of pseudo element ':before' or ':after'\n * @returns {{width: number, height: number}} An object with the width and height as numbers\n */\nexport function getElementSize(element, options = {}) {\n // Get styles\n const elementStyle = window.getComputedStyle(element, options.pseudoElement);\n\n return {\n width: getElementWidth(element, options, elementStyle),\n height: getElementHeight(element, options, elementStyle)\n };\n}\n\n/**\n * Get width of element\n *\n * @param {Element} element - The HTML element to work with\n * @param {Object} [options={}] - Object of options\n * @param {boolean} [options.includeMargin=false] - Get width including margin (defaults to false)\n * @param {boolean} [options.includeBorder=true] - Get width including border (defaults to true)\n * @param {boolean} [options.includePadding=true] - Get width including padding (defaults to true)\n * @param {null|':before'|':after'} [options.pseudoElement=null] - Get width of pseudo element ':before' or ':after'\n * @param {CSSStyleDeclaration} [elementStyle] - Style declaration of element (in case you already have called .getComputedStyle(), pass its returned value here)\n * @returns {number} The width as a number\n */\nexport function getElementWidth(element, options = {}, elementStyle = null) {\n // Keep supplied values or set to defaults\n options.includeMargin = options.includeMargin === true;\n options.includeBorder = options.includeBorder !== false;\n options.includePadding = options.includePadding !== false;\n\n // Get styles\n const style = elementStyle || window.getComputedStyle(element, options.pseudoElement);\n\n // Get width including border and padding\n let width = element.offsetWidth;\n\n // Calculate width with margin\n if (options.includeMargin) {\n width += parseFloat(style.marginLeft) + parseFloat(style.marginRight);\n }\n\n // Calculate width without border\n if (!options.includeBorder) {\n width -= parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth);\n }\n\n // Calculate width without padding\n if (!options.includePadding) {\n width -= parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);\n }\n\n return width;\n}\n\n/**\n * Get height of element\n *\n * @param {Element} element - The HTML element to work with\n * @param {Object} [options={}] - Object of options\n * @param {boolean} [options.includeMargin=false] - Get height including margin (defaults to false)\n * @param {boolean} [options.includeBorder=true] - Get height including border (defaults to true)\n * @param {boolean} [options.includePadding=true] - Get height including padding (defaults to true)\n * @param {null|':before'|':after'} [options.pseudoElement=null] - Get height of pseudo element ':before' or ':after'\n * @param {CSSStyleDeclaration} [elementStyle] - Style declaration of element (in case you already have called .getComputedStyle(), pass its returned value here)\n * @returns {number} The height as a number\n */\nexport function getElementHeight(element, options = {}, elementStyle = null) {\n // Keep supplied values or set to defaults\n options.includeMargin = options.includeMargin === true;\n options.includeBorder = options.includeBorder !== false;\n options.includePadding = options.includePadding !== false;\n\n // Get styles\n const style = elementStyle || window.getComputedStyle(element, options.pseudoElement);\n\n // Get height including border and padding\n let height = element.offsetHeight;\n\n // Calculate height with margin\n if (options.includeMargin) {\n height += parseFloat(style.marginTop) + parseFloat(style.marginBottom);\n }\n\n // Calculate height without border\n if (!options.includeBorder) {\n height -= parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);\n }\n\n // Calculate height without padding\n if (!options.includePadding) {\n height -= parseFloat(style.paddingTop) + parseFloat(style.paddingBottom);\n }\n\n return height;\n}\n","/**\n * A utility to **lock the viewport** at the current position in order to **stop scrolling**.\n *\n * @example Basic usage\n * import { enableScrollLock, disableScrollLock } from './utils/dom/scrollLock';\n *\n * enableScrollLock();\n * window.setTimeout(disableScrollLock, 3000);\n */\n\nimport { getElementScroll } from './elementProperties';\n\nconst className = 'scroll-lock';\nlet scrollTop = 0;\n\n/**\n * Get the current state of the scroll lock. `true` if the scroll lock is enabled, otherwise `false`.\n *\n * @type {boolean}\n */\nexport let scrollLocked = false;\n\n/**\n * Enable the scroll lock.\n */\nexport function enableScrollLock() {\n if (!scrollLocked) {\n // Get scroll position\n const scrollPosition = getElementScroll();\n\n // Reset scroll position\n window.scrollTo(scrollPosition.left, 0);\n\n const htmlTag = document.documentElement;\n htmlTag.classList.add(className);\n htmlTag.style.marginTop = `${-scrollPosition.top}px`;\n htmlTag.style.position = 'fixed';\n /*htmlTag.style.overflow = 'hidden';*/\n htmlTag.style.width = '100%';\n document.body.style.overflowY = 'scroll';\n\n // Remember state\n scrollLocked = true;\n scrollTop = scrollPosition.top;\n }\n}\n\n/**\n * @type {function}\n * @ignore\n */\nexport const enable = enableScrollLock;\n\n/**\n * Disable the scroll lock\n */\nexport function disableScrollLock() {\n if (scrollLocked) {\n const scrollPosition = getElementScroll();\n\n const htmlTag = document.documentElement;\n htmlTag.classList.remove(className);\n htmlTag.style.marginTop = '';\n htmlTag.style.position = '';\n htmlTag.style.overflow = '';\n htmlTag.style.width = '';\n document.body.removeAttribute('style');\n // Set the scroll position to what it was before\n window.scrollTo(scrollPosition.left, scrollTop);\n\n // Remember state\n scrollLocked = false;\n }\n}\n\n/**\n * @type {function}\n * @ignore\n */\nexport const disable = disableScrollLock;\n\n/**\n * Toggle the scroll lock between on and off\n */\nexport function toggleScrollLock() {\n if (scrollLocked) {\n disableScrollLock();\n } else {\n enableScrollLock();\n }\n}\n\n/**\n * @type {function}\n * @ignore\n */\nexport const toggle = toggleScrollLock;\n\nexport default {\n enable,\n disable,\n toggle\n};\n","export let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;\n\nlet ticking = false;\nconst scrollFunctions = [];\n\nfunction animate() {\n scrollFunctions.forEach(funcRef => funcRef());\n\n ticking = false;\n}\n\nfunction requestTick() {\n if (!ticking) {\n requestAnimationFrame(animate);\n ticking = true;\n }\n}\n\nfunction scrollHandler() {\n scrollTop = document.documentElement.scrollTop || document.body.scrollTop;\n requestTick();\n}\n/**\n * Adds a function to a function array, executed on a single scroll-event set on window.\n * This avoids the memory load and possible hickups of setting multiple eventlisteners for the same event.\n * Also this optimizes rendering by utilising the requestAnimationFrame for these scroll-events.\n * \n * @param {Function} handler - function to be called on scroll \n * @param {boolean} triggerNow - Should the function be called at once\n */\nexport function onScroll(handler, triggerNow = false) {\n // if first call: setup eventlistener on window\n !scrollFunctions.length ? initScroll() : null;\n\n // Trigger function\n triggerNow ? handler() : null;\n\n scrollFunctions.push(handler); \n}\n\nexport function initScroll() {\n window.addEventListener('scroll', scrollHandler);\n}\n","import { stickyNavOnScroll } from '../utils/stickyNavOnScroll';\r\nimport { enableScrollLock, disableScrollLock } from '../utils/scrollLock';\r\n\r\nexport let nav;\r\n\r\nconst burgerNav = document.querySelector('.nav__burger');\r\nconst burgerNavBackgroundImage = Array.from(document.querySelectorAll('.nav__burger__background-image'));\r\nlet activeLink;\r\nlet hoverLink;\r\nlet activeBackgroundImage;\r\nlet leaveTimer = -1;\r\n\r\nexport function toggleMenuOpen() {\r\n if (nav.classList.contains('nav--open')) {\r\n disableScrollLock();\r\n nav.classList.remove('nav--open');\r\n nav.classList.remove('js-sub-nav-open');\r\n\r\n if (window.pageYOffset > 50) {\r\n setTimeout(() => nav.classList.add('going-up'), 40);\r\n }\r\n\r\n burgerNav.classList.remove('js-sub-nav-open');\r\n\r\n if (activeLink) {\r\n activeLink.classList.remove('js-active');\r\n activeLink = null;\r\n hoverLink = null;\r\n activeBackgroundImage = null;\r\n }\r\n\r\n } else {\r\n enableScrollLock();\r\n nav.classList.add('nav--open');\r\n }\r\n}\r\n\r\nexport function setupNav(selector = '.nav', sticky = true) {\r\n nav = document.body.querySelector(selector);\r\n\r\n if (nav) {\r\n const navBtn = nav.querySelector('.nav__btn');\r\n\r\n navBtn.addEventListener('click', toggleMenuOpen);\r\n\r\n if (sticky) {\r\n stickyNavOnScroll(nav, 'nav--sticky', 30, 'going-up');\r\n }\r\n }\r\n\r\n function changeImage() {\r\n if (hoverLink.hasAttribute('data-background-image')) {\r\n const inactiveBurgerNavBackgroundImage = burgerNavBackgroundImage.filter(x => !x.classList.contains('js-active'))[0];\r\n const activeBurgerNavBackgroundImage = burgerNavBackgroundImage.filter(x => x.classList.contains('js-active'))[0];\r\n\r\n if (hoverLink.getAttribute('data-background-image') != activeBackgroundImage) {\r\n const image = document.createElement('img');\r\n\r\n if (hoverLink.getAttribute('data-background-image') != inactiveBurgerNavBackgroundImage.getAttribute('data-background-image')) {\r\n image.src = hoverLink.getAttribute('data-background-image');\r\n\r\n if (image.complete) {\r\n inactiveBurgerNavBackgroundImage.style.backgroundImage = `url(${image.src})`;\r\n inactiveBurgerNavBackgroundImage.setAttribute('data-background-image', hoverLink.getAttribute('data-background-image'));\r\n inactiveBurgerNavBackgroundImage.classList.add('js-active');\r\n inactiveBurgerNavBackgroundImage.classList.add('js-show');\r\n\r\n activeBurgerNavBackgroundImage.classList.remove('js-active');\r\n activeBurgerNavBackgroundImage.classList.remove('js-show');\r\n //activeBurgerNavBackgroundImage.style.backgroundImage = null;\r\n\r\n activeBackgroundImage = hoverLink.getAttribute('data-background-image');\r\n\r\n burgerNav.classList.remove('js-click');\r\n //burgerNavBackgroundImage.removeEventListener('transitionend', changeImage);\r\n } else {\r\n image.onload = function () {\r\n inactiveBurgerNavBackgroundImage.style.backgroundImage = `url(${image.src})`;\r\n inactiveBurgerNavBackgroundImage.setAttribute('data-background-image', hoverLink.getAttribute('data-background-image'));\r\n inactiveBurgerNavBackgroundImage.classList.add('js-active');\r\n inactiveBurgerNavBackgroundImage.classList.add('js-show');\r\n\r\n activeBurgerNavBackgroundImage.classList.remove('js-active');\r\n activeBurgerNavBackgroundImage.classList.remove('js-show');\r\n //activeBurgerNavBackgroundImage.style.backgroundImage = null;\r\n\r\n activeBackgroundImage = hoverLink.getAttribute('data-background-image');\r\n\r\n burgerNav.classList.remove('js-click');\r\n //burgerNavBackgroundImage.removeEventListener('transitionend', changeImage);\r\n };\r\n }\r\n } else {\r\n inactiveBurgerNavBackgroundImage.classList.add('js-active');\r\n inactiveBurgerNavBackgroundImage.classList.add('js-show');\r\n\r\n activeBurgerNavBackgroundImage.classList.remove('js-active');\r\n activeBurgerNavBackgroundImage.classList.remove('js-show');\r\n\r\n activeBackgroundImage = hoverLink.getAttribute('data-background-image');\r\n\r\n burgerNav.classList.remove('js-click');\r\n\r\n }\r\n }\r\n }\r\n }\r\n\r\n function enterBurgerNavItem(e) {\r\n hoverLink = e.currentTarget;\r\n burgerNav.classList.add('js-hover');\r\n\r\n if (hoverLink.classList.contains('has-children')) {\r\n if (!burgerNav.classList.contains('js-sub-nav-open')) {\r\n if (leaveTimer != -1) {\r\n clearTimeout(leaveTimer);\r\n leaveTimer = -1;\r\n }\r\n\r\n if (hoverLink.hasAttribute('data-background-image')) {\r\n changeImage();\r\n }\r\n }\r\n }\r\n }\r\n\r\n function leaveBurgerNavItem(e) {\r\n const link = e.currentTarget;\r\n burgerNav.classList.remove('js-hover');\r\n\r\n if (leaveTimer != -1) {\r\n clearTimeout(leaveTimer);\r\n leaveTimer = -1;\r\n }\r\n\r\n leaveTimer = setTimeout(function() {\r\n const activeBurgerNavBackgroundImage = burgerNavBackgroundImage.filter(x => x.classList.contains('js-active'))[0];\r\n\r\n if (activeBurgerNavBackgroundImage) {\r\n activeBurgerNavBackgroundImage.classList.remove('js-show');\r\n activeBackgroundImage = null;\r\n leaveTimer = -1;\r\n }\r\n },150);\r\n }\r\n\r\n function clickBurgerNavItem(e) {\r\n const item = e.currentTarget;\r\n\r\n if (burgerNav.classList.contains('js-sub-nav-open') && item.getAttribute('data-background-image') != activeBackgroundImage) {\r\n burgerNav.classList.add('js-click');\r\n changeImage();\r\n }\r\n\r\n if (activeLink) {\r\n if (activeLink != item) {\r\n item.classList.add('js-active');\r\n activeLink.classList.remove('js-active');\r\n burgerNav.classList.add('js-sub-nav-open');\r\n nav.classList.add('js-sub-nav-open');\r\n\r\n activeLink = item;\r\n } else {\r\n activeLink.classList.remove('js-active');\r\n burgerNav.classList.remove('js-sub-nav-open');\r\n nav.classList.remove('js-sub-nav-open');\r\n\r\n activeLink = null;\r\n }\r\n } else {\r\n item.classList.add('js-active');\r\n burgerNav.classList.add('js-sub-nav-open');\r\n nav.classList.add('js-sub-nav-open');\r\n\r\n activeLink = item;\r\n }\r\n }\r\n\r\n function clickBack(e) {\r\n const item = e.currentTarget;\r\n\r\n if (activeLink) {\r\n activeLink.classList.remove('js-active');\r\n activeLink = null;\r\n hoverLink = null;\r\n activeBackgroundImage = null;\r\n }\r\n\r\n burgerNav.classList.remove('js-sub-nav-open');\r\n nav.classList.remove('js-sub-nav-open');\r\n }\r\n\r\n if (burgerNav != undefined) {\r\n const burgerNavItems = burgerNav.querySelectorAll('a.level-1');\r\n const burgerNavSubBacks = burgerNav.querySelectorAll('li.nav__burger__back');\r\n\r\n Array.from(burgerNavItems).forEach(item => {\r\n item.addEventListener('mouseenter', enterBurgerNavItem);\r\n item.addEventListener('mouseleave', leaveBurgerNavItem);\r\n item.addEventListener('click', clickBurgerNavItem);\r\n });\r\n\r\n Array.from(burgerNavSubBacks).forEach(item => {\r\n item.addEventListener('click',clickBack);\r\n });\r\n }\r\n\r\n const navSearchForm = document.querySelector('.nav__search form');\r\n const navSearchIcon = document.querySelector('.nav__search svg');\r\n const navSearchField = document.querySelector('.nav__search input[type=\"text\"]');\r\n\r\n if (navSearchIcon && navSearchField) {\r\n navSearchIcon.addEventListener('click',function() {\r\n if (navSearchForm.classList.contains('js-show')) {\r\n navSearchForm.classList.remove('js-show');\r\n } else {\r\n navSearchForm.classList.add('js-show');\r\n navSearchField.focus();\r\n }\r\n });\r\n }\r\n\r\n if (navSearchField) {\r\n navSearchField.addEventListener('blur',function() {\r\n navSearchForm.classList.remove('js-show');\r\n });\r\n\r\n navSearchField.addEventListener('focus', function () {\r\n navSearchForm.classList.add('js-show');\r\n });\r\n }\r\n\r\n const navBurgerSearchForm = document.querySelector('.nav__burger__search form');\r\n const navBurgerSearchIcon = document.querySelector('.nav__burger__search svg');\r\n const navBurgerSearchField = document.querySelector('.nav__burger__search input[type=\"text\"]');\r\n\r\n if (navBurgerSearchIcon && navBurgerSearchField) {\r\n navBurgerSearchIcon.addEventListener('click', function () {\r\n if (navBurgerSearchForm.classList.contains('js-show')) {\r\n navBurgerSearchForm.classList.remove('js-show');\r\n } else {\r\n navBurgerSearchForm.classList.add('js-show');\r\n navBurgerSearchField.focus();\r\n }\r\n });\r\n }\r\n\r\n if (navBurgerSearchField) {\r\n navBurgerSearchField.addEventListener('blur', function () {\r\n navBurgerSearchForm.classList.remove('js-show');\r\n });\r\n\r\n navBurgerSearchField.addEventListener('focus', function () {\r\n navBurgerSearchForm.classList.add('js-show');\r\n });\r\n }\r\n\r\n const navSupport = document.querySelector('.nav__support');\r\n\r\n if (navSupport) {\r\n const navSupportUl = navSupport.querySelector('ul');\r\n\r\n if (navSupportUl) {\r\n navSupport.addEventListener('click',function() {\r\n if (navSupportUl.classList.contains('js-show')) {\r\n navSupportUl.classList.remove('js-show');\r\n } else {\r\n navSupportUl.classList.add('js-show');\r\n }\r\n });\r\n }\r\n }\r\n}\r\n","import { getElementScroll } from './elementProperties';\nimport { scrollLocked } from './scrollLock';\nimport { onScroll } from './scroll';\n\n/**\n * \n * @param {HTMLElement} element - element to add sticky class to\n * @param {string} className - sticky class name to add on scroll\n * @param {number} scrollInPixels - number of pixels before activating scroll\n * @param {string} goingUpClass - class added when scrolling up\n */\nexport function stickyNavOnScroll(element, className = 'nav--sticky', scrollInPixels = 30, goingUpClass = 'nav--going-up') {\n let scrollTimer;\n let lastScrollPosition;\n\n const scrollHandler = () => {\n\n clearTimeout(scrollTimer);\n\n if (!scrollLocked) {\n scrollTimer = setTimeout(() => {\n const windowScroll = getElementScroll();\n \n if (windowScroll.top > scrollInPixels) {\n element.classList.add(className);\n \n if (lastScrollPosition > windowScroll.top) {\n element.classList.add(goingUpClass);\n } else {\n element.classList.remove(goingUpClass);\n }\n \n lastScrollPosition = windowScroll.top;\n } else {\n element.classList.remove(className);\n element.classList.remove(goingUpClass);\n }\n }, 30);\n }\n\n };\n\n onScroll(scrollHandler, true);\n}\n","import settings from '../../settings.json';\n\nexport const breakpoints = settings.breakpoints;\nexport const breakpointKeys = Object.keys(breakpoints);\nexport let currentWindowWidth = window.innerWidth;\nexport let currentWindowHeight = window.innerHeight;\nexport let currentBreakpoint;\nexport let currentBreakpointIndex = 0;\nlet resizeTimer;\n\nconst resizeFunctions = [];\n\n/**\n * Get various window sizes - width, height etc.\n * This function is fired automatically upon page load. and run each time the window changes size.\n *\n */\nfunction getWindowSizes() {\n currentWindowWidth = window.innerWidth;\n currentWindowHeight = window.innerHeight;\n\n // Calculate which breakpoint is currently active, based on the screen width compared to the breakpoint definitions.\n\n let lastFoundWidth = 0;\n\n breakpointKeys.forEach((key, index) => {\n const width = breakpoints[key];\n if (currentWindowWidth >= width && width > lastFoundWidth) {\n lastFoundWidth = width;\n currentBreakpoint = key;\n currentBreakpointIndex = index;\n }\n });\n}\n\nfunction resizeHandler() {\n clearTimeout(resizeTimer);\n resizeTimer = setTimeout(() => {\n getWindowSizes();\n resizeFunctions.forEach(funcRef => funcRef());\n }, 100);\n}\n\nexport function onWindowResize(handler) {\n if (!currentBreakpoint) {\n initWindowResize();\n }\n\n resizeFunctions.push(handler);\n}\n\nexport function initWindowResize() {\n getWindowSizes();\n window.addEventListener('resize', resizeHandler);\n window.addEventListener('orientationchange', resizeHandler);\n}\n","import { breakpointKeys, currentBreakpointIndex } from '../utils/windowResize';\nimport { onWindowResize } from './windowResize';\nimport { onScroll } from './scroll';\n//import \"objectFitPolyfill\";\n\nexport const isBot = (!('onscroll' in window)) || (typeof navigator !== 'undefined' && /(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent));\n\nlet lastUsedScreenWidth;\nlet lazyArray = [];\n\nlet options = {\n className: 'lazy',\n loadedClass: 'lazy--loaded',\n loadClass: 'lazy--loading',\n decodeImg: true, // This option requires promises support (incl. via polyfill.io)\n oldIe11Fit: false, // This option requires objectFit support\n offset: 0\n};\n\nexport function setupLazyLoading(customOptions = {}) {\n lastUsedScreenWidth = -1;\n options = { ...options, ...customOptions };\n lazyArray = document.body.getElementsByClassName(options.className);\n\n // onWindowsResize set before first lazyLoad, to insure currentBreakPoint is set\n onWindowResize(lazyLoad);\n\n onScroll(lazyLoad, true);\n}\n\nfunction lazyLoad() {\n // If our current screen mode does not match the one we used the last time we made an image lookup,\n // perform a new one now. Otherwise, what would be the point?\n\n if (isBot || lastUsedScreenWidth < currentBreakpointIndex) {\n\n for (let i = 0; i < lazyArray.length; i++) {\n const lazyElem = lazyArray[i];\n\n if (isBot || isInViewport(lazyElem)) {\n lazyElem.classList.add(options.loadClass);\n if (lazyElem.classList.contains('lazy--bg')) {\n loadBgImage(lazyElem);\n } else {\n loadLazyImage(lazyElem);\n }\n }\n }\n\n cleanLazy();\n }\n}\n\nfunction cleanLazy() {\n lazyArray = Array.prototype.filter.call(lazyArray, l => !l.classList.contains(options.loadClass));\n}\n\nfunction isInViewport(el) {\n const rect = el.getBoundingClientRect();\n\n return (\n rect.bottom >= 0 &&\n rect.right >= 0 &&\n rect.top - options.offset <= (window.innerHeight || document.documentElement.clientHeight) &&\n rect.left - options.offset <= (window.innerWidth || document.documentElement.clientWidth)\n );\n}\n\n/**\n * This function gets the image wrapper data attributes src and alt text\n * and creates an new image tag to download the image.\n * It then uses the src as a background-image.\n *\n * @param {HTMLElement} bgContainer - Image wrapper element\n */\nexport function loadBgImage(bgContainer) {\n const src = getImageSrc(bgContainer);\n const handleLoadedBg = () => {\n bgContainer.style.backgroundImage = formattedSrc;\n bgContainer.classList.add(options.loadedClass);\n bgContainer.classList.remove(options.loadClass);\n };\n\n // If no usable source was returned, abort at once.\n if (!src) {\n return;\n }\n\n const formattedSrc = `url(${src})`;\n\n if (bgContainer.style.backgroundImage === formattedSrc) {\n return;\n }\n\n if (options.decodeImg) {\n // Start loading the new image.\n loadImage(src).then(handleLoadedBg);\n } else {\n handleLoadedBg();\n }\n}\n\n/**\n * This function gets the container data attributes src.\n * If the container is an image it sets the src of it.\n * If the container is not an image it creates a new image tag and inserts it into the given container.\n *\n * @param {HTMLElement} container - Image wrapper element\n */\nexport function loadLazyImage(container) {\n const src = getImageSrc(container);\n\n // If no usable source was returned, abort mission.\n if (!src) {\n return;\n }\n\n if (options.decodeImg) {\n // We don't want to start processing if the new URL matches the old one.\n const oldImage = container.querySelector('img');\n if (oldImage && container.classList.contains(options.loadedClass)) {\n if (oldImage.getAttribute('src') === src) {\n if (options.oldIe11Fit) {\n window.objectFitPolyfill(oldImage);\n }\n return;\n } else {\n container.removeChild(oldImage);\n }\n }\n\n // Start loading the new image.\n loadImage(src).then(newImageTag => {\n // Set src and ALT text if defined.\n if (container.tagName === 'IMG') {\n container.src = src;\n } else {\n const altText = container.getAttribute('data-alt') || '';\n newImageTag.setAttribute('alt', altText);\n\n container.appendChild(newImageTag);\n }\n\n container.classList.add(options.loadedClass);\n container.classList.remove(options.loadClass);\n\n // oldIE object-fit polyfill placed here to take resize into account\n if (options.oldIe11Fit) {\n window.objectFitPolyfill(newImageTag);\n }\n });\n } else {\n container.src = src;\n container.classList.add(options.loadedClass);\n container.classList.remove(options.loadClass);\n }\n}\n\n/**\n * Try to decode the image, after it's loaded, and resolve the Promise.\n *\n * @param {Element} newImage\n * @returns {Promise}\n */\nfunction decodeImage(newImage) {\n return 'decode' in newImage ? newImage.decode().then(() => newImage) : Promise.resolve(newImage);\n}\n\n/**\n * Load an image, and return a Promise that resolves once the image is loaded.\n *\n * @param {string} path\n * @returns {Promise} Promise that will resolve with the loaded image once it's ready.\n */\nexport function loadImage(path) {\n const newImage = new Image();\n\n return new Promise(resolve => {\n newImage.addEventListener('load', () => decodeImage(newImage).then(image => resolve(image)), false);\n newImage.src = path;\n });\n}\n\n/**\n * This function gets the data-src from the image wrapper, based on width of the browser window.\n *\n * @param {HTMLElement} container - Image wrapper element\n * @returns {string}\n */\nfunction getImageSrc(container) {\n let src = '';\n let largestBreakpointFound = 0;\n\n if (container.getAttribute('data-src')) {\n src = container.getAttribute('data-src');\n container.removeAttribute('data-src');\n } else {\n breakpointKeys.forEach((breakpointName, index) => {\n if (currentBreakpointIndex >= index) {\n if (index === 0 || index > largestBreakpointFound) {\n const srcAttribute = `data-src-${breakpointName}`;\n src = container.getAttribute(srcAttribute) || src;\n\n container.removeAttribute(srcAttribute);\n\n // Make sure we won't set the size to a smaller breakpoint later, in case they're not properly ordered.\n largestBreakpointFound = index;\n }\n }\n });\n }\n\n return src;\n}\n","export const transitionEndEventName = detectStyleDeclatationName();\nexport const animationEndEventName = detectStyleDeclatationName('animation');\n\n/**\n * Detects which prefixed eventName is in CSSStyleDeclaration\n *\n * @param {string} eventTypeName - choose 'transition' or 'animation'\n * @returns {string}\n */\nexport function detectStyleDeclatationName(eventTypeName = 'transition') {\n const transitions = {\n transition: `${eventTypeName}end`,\n OTransition: `o${eventTypeName}end`,\n MozTransition: `${eventTypeName}end`,\n WebkitTransition: `webkit${eventTypeName}end`\n };\n\n const el = document.createElement('div');\n\n for (const t in transitions) {\n if (el.style[t] !== undefined) {\n return transitions[t];\n }\n }\n return '';\n}\n\n/**\n *\n * @param {HTMLElement} container - container to animate height of\n * @param {HTMLElement} classTarget [default = container] - target element that gets class\n * @param {Boolean} classOnBoth [default = false] - set class on both container and classTarget\n */\nexport function cssAnimateNewHeight(container, classTarget = container, classOnBoth = false) {\n let newHeight;\n const prevHeight = container.offsetHeight;\n\n const delayedClose = () => {\n if (classOnBoth) {\n container.classList.remove('open');\n classTarget.classList.remove('open');\n } else {\n classTarget.classList.remove('open');\n }\n\n container.removeEventListener(transitionEndEventName, delayedClose);\n };\n\n container.removeAttribute('style');\n\n if (classTarget.classList.contains('open')) {\n newHeight = 0;\n container.addEventListener(transitionEndEventName, delayedClose);\n\n if (classOnBoth) {\n classTarget.classList.remove('open');\n }\n } else {\n classTarget.classList.add('open');\n\n if (classOnBoth) {\n container.classList.add('open');\n }\n\n newHeight = container.offsetHeight;\n }\n\n container.style.height = `${prevHeight}px`;\n\n setTimeout(() => {\n container.style.height = `${newHeight}px`;\n }, 10);\n}","import { cssAnimateNewHeight } from '../utils/animation';\r\n\r\n/**\r\n * Attention\r\n * Be aware that this module is dependent on support for Element.prototype.closest\r\n * This is included as default in https://polyfill.io/v3/polyfill.min.js\r\n */\r\n\r\n// Used keycodes\r\nconst keycode = {\r\n space: 32,\r\n arrowUp: 38,\r\n arrowDown: 40,\r\n home: 36,\r\n end: 35\r\n};\r\n\r\nlet activeAccordion;\r\nlet index = 0;\r\n\r\n/**\r\n * The Accordion class uses the cssAnimateNewHeight function to reveal hidden content.\r\n * Default element selector is data-action*=\"accordion\"\r\n * If data-action is set to \"accordion-switch\", active accordions will close when another is opened.\r\n *\r\n * @param {HTMLElement} trigger\r\n * @constructor\r\n */\r\nexport class Accordion {\r\n\r\n /**\r\n * The constructor is fired once the class is instantiated.\r\n *\r\n * @param {HTMLElement} trigger\r\n */\r\n constructor(trigger) {\r\n this.dom = {\r\n trigger,\r\n container: trigger.parentNode.querySelector('.accordion__content') || trigger.nextElementSibling\r\n };\r\n\r\n this.settings = {\r\n type: trigger.getAttribute('data-action')\r\n };\r\n\r\n this.index = index;\r\n\r\n index++;\r\n\r\n this.dom.trigger.addEventListener('click', e => {\r\n if (!(e.ctrlKey || e.metaKey || e.shiftKey)) {\r\n e.preventDefault();\r\n }\r\n if (activeAccordion && this.index !== activeAccordion.index) {\r\n // Dobbelt check added to prevent delayed dobbelt opening\r\n if (activeAccordion.dom.container.classList.contains('open')) {\r\n cssAnimateNewHeight(activeAccordion.dom.container, activeAccordion.dom.trigger, true);\r\n this.dom.container.setAttribute('aria-hidden', true);\r\n activeAccordion.dom.trigger.setAttribute('aria-expanded', 'false');\r\n }\r\n }\r\n\r\n cssAnimateNewHeight(this.dom.container, this.dom.trigger, true);\r\n this.dom.container.setAttribute('aria-hidden', false);\r\n\r\n // Set the inverted value of aria-expanded\r\n const ariaExpanded = this.dom.trigger.getAttribute('aria-expanded') || 'false';\r\n this.dom.trigger.setAttribute('aria-expanded', ariaExpanded === 'false');\r\n\r\n if (this.settings.type === 'accordion-switch') {\r\n activeAccordion = this;\r\n }\r\n });\r\n }\r\n}\r\n\r\nfunction openAccordByHashId() {\r\n if (window.location.hash.indexOf('accordion') > -1) {\r\n const accordionContent = document.getElementById(window.location.hash.replace('#', ''));\r\n if (accordionContent) {\r\n const accord = document.getElementById(accordionContent.getAttribute('aria-labelledby'));\r\n accord.click();\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Initialise Accordions with this function\r\n * Will only run if given selector elements are found in DOM\r\n *\r\n * @param {string} selector - element selector string\r\n */\r\n\r\nexport function setupAccordions(selector = '[data-action*=\"accordion\"]') {\r\n const accordions = document.querySelectorAll(selector);\r\n\r\n if (accordions) {\r\n for (let i = 0; i < accordions.length; i++) {\r\n void new Accordion(accordions[i]);\r\n }\r\n\r\n openAccordByHashId();\r\n }\r\n}\r\n\r\nwindow.addEventListener('keydown', event => {\r\n const focusedElement = document.activeElement;\r\n\r\n if (focusedElement) {\r\n /* This code needs to be fixed!\r\n It makes it imposible to type spaces (ex. in input fields)\r\n\r\n if (event.keyCode === keycode.space) {\r\n // Toggle accordion\r\n event.preventDefault();\r\n focusedElement.click();\r\n\r\n } */\r\n if (focusedElement.closest('.accordion') != undefined) {\r\n if (event.keyCode === keycode.arrowUp) {\r\n // Focus prevoius accordion\r\n if (focusedElement.closest('.accordion').previousElementSibling && focusedElement.closest('.accordion').previousElementSibling.querySelector('.accordion__head')) {\r\n focusedElement.closest('.accordion').previousElementSibling.querySelector('.accordion__head').focus();\r\n }\r\n }\r\n if (event.keyCode === keycode.arrowDown) {\r\n // Focus next accordion\r\n if (focusedElement.closest('.accordion').nextElementSibling && focusedElement.closest('.accordion').nextElementSibling.querySelector('.accordion__head')) {\r\n focusedElement.closest('.accordion').nextElementSibling.querySelector('.accordion__head').focus();\r\n }\r\n }\r\n if (event.keyCode === keycode.home) {\r\n // Focus first accordion\r\n if (focusedElement.closest('.accordion').parentNode.querySelector('.accordion:first-child .accordion__head')) {\r\n event.preventDefault();\r\n focusedElement.closest('.accordion').parentNode.querySelector('.accordion:first-child .accordion__head').focus();\r\n }\r\n }\r\n if (event.keyCode === keycode.end) {\r\n // Focus last accordion\r\n if (focusedElement.closest('.accordion').parentNode.querySelector('.accordion:last-child .accordion__head')) {\r\n event.preventDefault();\r\n focusedElement.closest('.accordion').parentNode.querySelector('.accordion:last-child .accordion__head').focus();\r\n }\r\n }\r\n }\r\n }\r\n});\r\n","export const body = document.body;\nexport const qs = (s, o = body) => o.querySelector(s);\nexport const qsa = (s, o = body) => o.querySelectorAll(s);\n\nexport const allowStatCookies = window.CookieInformation && CookieInformation.getConsentGivenFor('cookie_cat_statistic');\n\n/**\n * Sets a custom CSS variable to ensure precise vh unit mesuarment\n *\n */\n\nexport function setVhProp(e) {\n let vh = window.innerHeight * 0.01;\n\n const setVh = e != undefined ? setTimeout(() => {\n vh = window.innerHeight * 0.01;\n document.documentElement.style.setProperty('--vh', `${vh}px`);\n }, 100) : document.documentElement.style.setProperty('--vh', `${vh}px`);\n}\n\nexport function initVhUnitOverwrite() {\n setVhProp();\n window.addEventListener('orientationchange', setVhProp);\n}\n\nexport function canUseWebP() {\n const elem = document.createElement('canvas');\n\n if (elem.getContext && elem.getContext('2d')) {\n // was able or not to get WebP representation\n return elem.toDataURL('image/webp').indexOf('data:image/webp') === 0;\n }\n\n // very old browser like IE 8, canvas not supported\n return false;\n}\n\n/**\n * Add a to the head\n */\nexport function addPrefetch(kind, url, as) {\n const linkElem = document.createElement('link');\n linkElem.rel = kind;\n linkElem.href = url;\n if (as) {\n linkElem.as = as;\n }\n linkElem.crossorigin = true;\n document.head.append(linkElem);\n}\n\n/**\n * Format number sparated with commas per thousand.\n *\n * @param {Number} num - Number you want to format\n *\n * @returns {string} - Returns the number formatet with commas\n *\n * @example:\n * console.info(formatNumber(2665)) // 2,665\n * console.info(formatNumber(102665)) // 102,665\n * console.info(formatNumber(1240.5)) // 1,240.5\n */\n\nexport function formatNumber(num, seperator = '.') {\n return num.toString().replace(/(\\d)(?=(\\d{3})+(?!\\d))/g, `$1${seperator}`);\n}\n\n/**\n * Prevent function from being executed as long as it is invoked, while given delay hasn't passed.\n *\n * @param {Function} callback Callback\n * @param {String} delay Delay\n * @return {Function} Callback\n */\nexport function debounce(callback, delay) {\n let timer = null;\n\n return function () {\n const context = this,\n args = arguments;\n\n clearTimeout(timer);\n\n timer = setTimeout(function () {\n callback.apply(context, args);\n }, delay);\n };\n}\n\n/*\n* Load JavsScript asynchronously when needed\n* @param {String} source The path to the file\n* @param {Function} callback The callback to excecute upon load\n* @return {Element} Element to attach\n*/\nexport function loadJS (source, callback) {\n const reference = document.getElementsByTagName('script')[0];\n const script = document.createElement('script');\n\n script.src = source;\n script.async = true;\n reference.parentNode.insertBefore(script, reference);\n\n if (callback && typeof(callback) === 'function') {\n script.onload = callback;\n }\n\n return script;\n}\n\n/**\n * Get the thumbnail dimensions to use for a given player size.\n *\n * @param {Object} options\n * @param {number} options.width The width of the player\n * @param {number} options.height The height of the player\n * @return {Object} The width and height\n */\nexport function getRoundedDimensions({ width, height }) {\n let roundedWidth = width;\n let roundedHeight = height;\n\n // If the original width is a multiple of 320 then we should\n // not round up. This is to keep the native image dimensions\n // so that they match up with the actual frames from the video.\n //\n // For example 640x360, 960x540, 1280x720, 1920x1080\n //\n // Round up to nearest 100 px to improve cacheability at the\n // CDN. For example, any width between 601 pixels and 699\n // pixels will render the thumbnail at 700 pixels width.\n if (roundedWidth % 320 !== 0) {\n roundedWidth = Math.ceil(width / 100) * 100;\n roundedHeight = Math.round((roundedWidth / width) * height);\n }\n\n return {\n width: roundedWidth,\n height: roundedHeight\n };\n}\n\n/**\n * Detect if a device as touch support\n *\n * 'ontouchstart' in window - works on most browsers\n * navigator.maxTouchPoints - works on IE10/11 and Surface\n */\nexport function isTouchDevice() {\n return !!('ontouchstart' in window || navigator.maxTouchPoints);\n}\n\nexport const isIE11 = !!window.MSInputMethodContext && !!document.documentMode;\n","import { getElementPosition } from './elementProperties';\n\nconst easeInOutQuad = function(currentTime, start, change, duration) {\n let time = currentTime;\n time /= duration / 2;\n if (time < 1) {\n return (change / 2) * time * time + start;\n }\n time--;\n return (-change / 2) * (time * (time - 2) - 1) + start;\n};\n\nconst easeInOutQuintic = function(currentTime, start, change, duration) {\n let time = currentTime;\n const ts = (time /= duration) * time,\n tc = ts * time;\n return start + change * (6 * tc * ts + -15 * ts * ts + 10 * tc);\n};\n\nexport function scrollTo(to, duration = 750, callback) {\n function move(amount) {\n if (document.scrollingElement) {\n document.scrollingElement.scrollTop = amount;\n } else {\n document.documentElement.scrollTop = amount;\n document.body.parentNode.scrollTop = amount;\n document.body.scrollTop = amount;\n }\n }\n function position() {\n return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop;\n }\n\n const start = position(),\n change = to instanceof Element ? getElementPosition(to).top - start : to - start,\n increment = 20;\n\n\n let currentTime = 0;\n\n const animate = function() {\n // increment the time\n currentTime += increment;\n // find the value with the quadratic in-out easing function\n const val = easeInOutQuintic(currentTime, start, change, duration);\n // move the document.body\n move(val);\n // do the animation unless its over\n if (currentTime < duration) {\n requestAnimationFrame(animate);\n } else {\n if (callback && typeof callback === 'function') {\n // the animation is done so lets callback\n if (typeof callback === 'function') {\n callback();\n }\n }\n }\n };\n animate();\n}\n","import {\n addPrefetch,\n canUseWebP,\n getRoundedDimensions,\n allowStatCookies,\n body\n} from '../utils/helpers';\nimport {\n scrollTo\n} from '../utils/scrollTo';\nimport {\n currentWindowWidth\n} from '../utils/windowResize';\n\n/**\n * Combined lightweight vimeo/youtube embed code.\n *\n * Ported from https://github.com/paulirish/lite-youtube-embed by Paul Irish\n * and https://github.com/luwes/lite-vimeo-embed by Wesley Luyten\n *\n * @param {HTMLElement} container - Element in which you want the video inserted\n */\nclass Video {\n constructor(container) {\n this.container = container;\n this.id = container.getAttribute('data-video-id');\n this.bg = container.getAttribute('data-video-bg') || 0;\n this.byline = container.getAttribute('data-video-byline') || 0;\n this.color = container.getAttribute('data-video-color') || 0;\n this.controls = container.getAttribute('data-video-controls') || 1;\n this.ytUrl = allowStatCookies ? 'https://www.youtube.com' : 'https://www.youtube-nocookie.com';\n this.trigger = container.getAttribute('data-video-trigger');\n\n if (!this.id) {\n this.videoLink = container.getAttribute('data-video-link');\n if (this.videoLink) {\n this.id = extractVideoIdFromUrl(this.videoLink);\n } else {\n console.warn('Video missing video-id / data-video-link');\n return;\n }\n\n if (this.id.indexOf('/') > -1) {\n this.id = this.id.slice(0, this.id.indexOf('/'));\n this.isPrivate = true;\n }\n }\n\n this.isVimeo = container.getAttribute('data-action') === 'video-vimeo' || this.videoLink && this.videoLink.indexOf('vimeo') > -1;\n this.poster = container.getAttribute('data-poster') || container.getAttribute('data-src');\n\n if (!this.poster) {\n if (this.isVimeo) {\n if (this.isPrivate) {\n this.container.classList.add('placeholder');\n } else {\n let {\n width,\n height\n } = getRoundedDimensions(container.getBoundingClientRect());\n const devicePixelRatio = window.devicePixelRatio || 1;\n width *= devicePixelRatio;\n height *= devicePixelRatio;\n /**\n * To get the vimeo poster image, we have to use the Vimeo API.\n */\n this.poster = `https://lite-vimeo-embed.now.sh/thumb/${this.id}`;\n this.poster += `.${canUseWebP() ? 'webp' : 'jpg'}`;\n this.poster += `?mw=${width}&mh=${height}&q=${devicePixelRatio > 1 ? 70 : 85}`;\n }\n\n } else {\n /**\n * Comment about the thumbnail, by original author: Paul Irish\n * Lo, the youtube placeholder image! (aka the thumbnail, poster image, etc)\n * There is much internet debate on the reliability of thumbnail URLs. Weak consensus is that you\n * cannot rely on anything and have to use the YouTube Data API.\n *\n * amp-youtube also eschews using the API, so they just try sddefault with a hqdefault fallback:\n * https://github.com/ampproject/amphtml/blob/6039a6317325a8589586e72e4f98c047dbcbf7ba/extensions/amp-youtube/0.1/amp-youtube.js#L498-L537\n * For now I'm gonna go with this confident (lol) assertion: https://stackoverflow.com/a/20542029, though I'll use `i.ytimg` to optimize for origin reuse.\n *\n * Worth noting that sddefault is _higher_ resolution than hqdefault. Naming is hard. ;)\n * From my own testing, it appears that hqdefault is ALWAYS there sddefault is missing for ~10% of videos*/\n\n this.poster = `https://i.ytimg.com/vi/${this.id}/sddefault.jpg`;\n }\n }\n\n if (this.poster && !this.container.classList.contains('lazy')) {\n this.container.style.backgroundImage = `url(\"${this.poster}\")`;\n }\n\n // On hover (or tap), warm up the TCP connections we're (likely) about to use.\n this.container.addEventListener('pointerover', Video.warmConnections, {\n once: true\n });\n\n // Once the user clicks, add the real iframe and drop our play button\n // TODO: In the future we could be like amp-youtube and silently swap in the iframe during idle time\n // We'd want to only do this for in-viewport or near-viewport ones: https://github.com/ampproject/amphtml/pull/5003\n if (this.bg) {\n this.addIframe();\n } else {\n this.container.addEventListener('click', () => this.openVideo());\n\n if (this.trigger) {\n const trigger = document.getElementById(this.trigger);\n if (trigger) {\n trigger.addEventListener('pointerover', Video.warmConnections, {\n once: true\n });\n trigger.addEventListener('click', () => this.openVideo());\n }\n }\n }\n }\n\n /**\n * Begin pre-connecting to warm up the iframe load\n * Since the embed's network requests load within its iframe,\n * preload/prefetch'ing them outside the iframe will only cause double-downloads.\n * So, the best we can do is warm up a few connections to origins that are in the critical path.\n *\n * Maybe `` would work, but it's unsupported: http://crbug.com/593267\n * But TBH, I don't think it'll happen soon with Site Isolation and split caches adding serious complexity.\n */\n static warmConnections() {\n if (Video.preconnected) return;\n\n if (this.isVimeo) {\n // The iframe document and most of its subresources come right off player.vimeo.com\n addPrefetch('preconnect', 'https://player.vimeo.com');\n // Images\n addPrefetch('preconnect', 'https://i.vimeocdn.com');\n // Files .js, .css\n addPrefetch('preconnect', 'https://f.vimeocdn.com');\n // Metrics\n addPrefetch('preconnect', 'https://fresnel.vimeocdn.com');\n } else {\n // The iframe document and most of its subresources come right off youtube.com\n addPrefetch('preconnect', this.ytUrl);\n // The botguard script is fetched off from google.com\n addPrefetch('preconnect', 'https://www.google.com');\n // Not certain if these ad related domains are in the critical path. Could verify with domain-specific throttling.\n addPrefetch('preconnect', 'https://googleads.g.doubleclick.net');\n addPrefetch('preconnect', 'https://static.doubleclick.net');\n }\n\n Video.preconnected = true;\n }\n\n openVideo() {\n const videoModule = this.container.closest('.video-module');\n\n if (videoModule) {\n videoModule.classList.add('video--expanded');\n const closeBtn = videoModule.querySelector('.btn-close');\n\n setTimeout(this.addIframe.bind(this), 500);\n\n closeBtn.addEventListener('click', () => {\n videoModule.classList.remove('video--expanded');\n const iframe = this.container.querySelector('iframe');\n\n /*iframe ? setTimeout(() => this.container.removeChild(iframe), 500) : null;*/\n iframe ? this.container.removeChild(iframe) : null;\n }, {\n once: true\n });\n }\n }\n\n addIframe() {\n // Only insert iframe if not already inserted (used for .text-video module)\n const videoService = this.isVimeo ? 'https://player.vimeo.com/video' : `${this.ytUrl}/embed`;\n let videoUrl = `${videoService}/${this.id}?autoplay=1&rel=0`;\n\n const iframe = document.createElement('iframe');\n iframe.setAttribute('frameborder', 0);\n iframe.setAttribute('allowtransparency', 'true');\n iframe.setAttribute('playsinline', 'true');\n iframe.setAttribute('tabindex', '-1');\n iframe.setAttribute('allow', 'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; autoplay');\n iframe.addEventListener('load', () => {\n // Timeout is set to prevent paint-lag when iframe is inserted\n setTimeout(() => {\n this.container.classList.remove('loading');\n this.container.classList.add('video--loaded');\n\n if (this.container.getAttribute('data-scroll-to')) {\n scrollTo(this.container, 1000);\n }\n }, 100);\n });\n\n videoUrl += `&controls=${this.controls}&byline=${this.byline}&background=${this.bg}&mute=${this.bg}`;\n if (this.color) videoUrl += `&color=${this.color}`;\n\n iframe.src = videoUrl;\n\n this.container.classList.add('loading');\n this.container.appendChild(iframe);\n\n }\n}\n\n\nfunction extractVideoIdFromUrl(url) {\n const videoIdRegExp = /^.*((youtu.be\\/|vimeo.com\\/)|(v\\/)|(\\/u\\/\\w\\/)|(embed\\/)|(watch\\?))\\??v?=?([^#&?]*).*/;\n const match = url.match(videoIdRegExp);\n\n if (match && match[7]) {\n return match[7];\n } else {\n console.warn(url, 'Invalid Video URL');\n }\n}\n\n/**\n * Initialise video embeds with this function\n * Will only run if given selector elements are found in DOM\n *\n * @param {string} selector - element selector string\n */\n\nexport function setupVideos(selector = '[data-action^=\"video\"]') {\n const videos = document.body.querySelectorAll(selector);\n\n for (let i = 0; i < videos.length; i++) {\n if (videos[i].parentNode.classList.contains('header') && currentWindowWidth < 480) {\n return;\n }\n void new Video(videos[i]);\n }\n}\n","import { scrollTo } from '../utils/scrollTo';\n\n/**\n * This function strips relative site path from hashlink \n * \n * @param {string} hashLink \n * \n * @returns {HTMLElement}\n */\nfunction returnHashElement(hashLink) {\n if (hashLink.indexOf(window.location.pathname) !== -1) {\n return document.getElementById(hashLink.replace(window.location.pathname, '').replace('#', ''));\n } else {\n return document.getElementById(hashLink.replace('#', ''));\n }\n}\n\n/**\n * Scrolls the viewport to an hash-id\n * if found in querystring\n */\nexport function scrollToUrlHash() {\n if (window.location.hash) {\n const element = document.getElementById(window.location.hash.replace('#', ''));\n\n if (element) {\n scrollTo(element);\n }\n }\n}\n\n/**\n * Activate Anchor Link Scroll with this function\n * Will only run if given selector elements are found in DOM\n * \n * @param {string} triggerSelector \n */\n\nexport function setupAnchorLinkScroll(triggerSelector = '[data-action*=\"anchor\"], a[href^=\"#\"]:not([href=\"#\"]):not([role=\"tab\"]):not([data-action*=\"accordion\"])') {\n\n const triggers = document.querySelectorAll(triggerSelector);\n\n for (let i = 0; i < triggers.length; i++) {\n const trigger = triggers[i];\n const hashLink = trigger.getAttribute('href') || trigger.getAttribute('data-target');\n\n if (hashLink) {\n const element = returnHashElement(hashLink);\n\n trigger.addEventListener('click', e => {\n e.preventDefault();\n scrollTo(element);\n });\n }\n }\n}\n","\nconst classNames = {\n activeBtn: 'filter__tab--active',\n hiddenItem: 'hidden'\n};\n\n/**\n *\n * @param {HTMLElement} container\n *\n * @constructor\n */\nexport class Filter {\n\n /**\n * The constructor is fired once the class is instantiated.\n *\n * @param {HTMLElement} container - Element containing filter options (Could be .filter__tabs or .filter__select)\n */\n constructor(container) {\n if (container) {\n this.dom = {\n container,\n module: container.closest('.module'),\n filters: container.querySelectorAll('[data-filter]'),\n allFilter: container.querySelector('[data-filter=\"*\"]'),\n targetContainer: document.body.querySelector(container.getAttribute('data-target-container'))\n };\n\n this.settings = {\n filterType: container.getAttribute('data-action')\n };\n\n if (this.dom.targetContainer) {\n for (let i = 0; i < this.dom.filters.length; i++) {\n\n const filter = this.dom.filters[i];\n const itemCountReplace = filter.getAttribute('data-item-count-replace');\n\n if (filter.tagName === 'BUTTON') {\n filter.addEventListener('click', e => this.filterHandler(e));\n } else {\n filter.addEventListener('change', e => this.filterHandler(e));\n\n if (itemCountReplace) {\n this.replaceWithNumberOfItems(filter, itemCountReplace);\n }\n }\n }\n\n } else {\n window.console.warn('Can\\'t find [data-target-container] on filter container: ', container);\n }\n } else {\n window.console.warn('Filter container missing');\n }\n }\n\n static deselectRadio(e) {\n e.target.checked = !e.target.checked;\n e.target.removeEventListener('click', Filter.deselectRadio);\n\n this.filterHandler(e);\n }\n\n /**\n * Filter function that compares selected filter values with filter-values on filter-item.\n * Added hidden-class to items that hasn't got the selected filter value.\n *\n * @param {HTMLElement} e - event (click or change event\n */\n filterHandler(e) {\n const filter = e.target;\n const filterItems = this.dom.targetContainer.querySelectorAll('[data-filter-value]');\n const isButton = filter.tagName === 'BUTTON';\n const filterValue = isButton ? filter.getAttribute('data-filter') : filter.value;\n\n if (filterValue == '*') {\n if (this.dom.module) {\n this.dom.module.classList.remove('js-filtered');\n }\n } else {\n if (this.dom.module) {\n this.dom.module.classList.add('js-filtered');\n }\n }\n\n if (isButton) {\n if (this.settings.filterType === 'filter-switch') {\n\n for (let i = 0; i < this.dom.filters.length; i++) {\n this.dom.filters[i].classList.remove(classNames.activeBtn);\n }\n\n filter.classList.add(classNames.activeBtn);\n } else {\n if (this.dom.allFilter && filter != this.dom.allFilter) {\n this.dom.allFilter.classList.remove(classNames.activeBtn);\n } else {\n for (let i = 0; i < this.dom.filters.length; i++) {\n if (this.dom.filters[i].tagName === 'SELECT') {\n // This is a small hack to avoid misleeding results if selector is not reset\n // assumes that your selector has a default value of '*'\n this.dom.filters[i].value = '*';\n } else {\n this.dom.filters[i].classList.remove(classNames.activeBtn);\n }\n }\n }\n\n if (!filter.classList.contains(classNames.activeBtn)) {\n filter.classList.add(classNames.activeBtn);\n } else {\n filter.classList.remove(classNames.activeBtn);\n }\n }\n } else if (filter.type === 'radio') {\n const name = filter.name;\n const siblingRadios = this.dom.container.querySelectorAll(`[name=\"${name}\"]`);\n\n for (let r = 0; r < siblingRadios.length; r++) {\n const radio = siblingRadios[r];\n radio.removeEventListener('click', Filter.deselectRadio);\n }\n\n filter.addEventListener('click', Filter.deselectRadio.bind(this));\n }\n\n if (this.settings.filterType === 'filter-switch') {\n for (let i = 0; i < filterItems.length; i++) {\n const item = filterItems[i];\n let itemFilterValues = item.getAttribute('data-filter-value').split(',');\n const cleanFilterValue = filterValue.trim().toLowerCase();\n itemFilterValues = itemFilterValues.map(value => value.trim().toLowerCase());\n\n if (filterValue !== '*' && itemFilterValues.indexOf(cleanFilterValue) === -1) {\n item.classList.add(classNames.hiddenItem);\n } else {\n item.classList.remove(classNames.hiddenItem);\n }\n }\n } else {\n const filterValues = Filter.getSetValues(this.dom.filters);\n const isComboFilter = this.settings.filterType === 'filter-combo';\n\n for (let i = 0; i < filterItems.length; i++) {\n const item = filterItems[i];\n let itemFilterValues = item.getAttribute('data-filter-value').split(',');\n let showItem = !isComboFilter;\n\n itemFilterValues = itemFilterValues.map(value => value.trim().toLowerCase());\n\n if (filter === this.dom.allFilter && this.dom.allFilter.classList.contains(classNames.activeBtn)) {\n showItem = true;\n } else {\n for (let i = 0; i < filterValues.length; i++) {\n const value = filterValues[i];\n const cleanValue = value.trim().toLowerCase();\n\n if (isComboFilter) {\n if (itemFilterValues.indexOf(cleanValue) > -1) {\n showItem = true;\n break;\n }\n } else if (cleanValue != '*' && itemFilterValues.indexOf(cleanValue) === -1) {\n showItem = false;\n }\n }\n }\n\n if (!showItem) {\n item.classList.add(classNames.hiddenItem);\n } else {\n item.classList.remove(classNames.hiddenItem);\n }\n }\n }\n\n // Hide empty Filter sections\n const sections = this.dom.targetContainer.querySelectorAll('[data-filter-section]');\n if (sections.length) {\n for (let s = 0; s < sections.length; s++) {\n const section = sections[s];\n const itemsShownInSection = section.querySelectorAll('[data-filter-value]:not(.hidden)');\n\n if (itemsShownInSection.length < 1) {\n section.classList.add(classNames.hiddenItem);\n } else {\n section.classList.remove(classNames.hiddenItem);\n }\n }\n }\n }\n\n static getSetValues(filters) {\n const valArray = [];\n\n // loop through list of filters\n for (let i = 0, len = filters.length; i < len; i++) {\n const filter = filters[i];\n if (filter.tagName === 'SELECT') {\n if (filter.value !== '*' && filter.value !== '') {\n valArray.push(filter.value);\n }\n } else if (filter.tagName === 'BUTTON') {\n if (filter.classList.contains(classNames.activeBtn)) {\n valArray.push(filter.getAttribute('data-filter'));\n }\n } else {\n if (filter.checked && filter.value !== '*') { // radio checked?\n valArray.push(filter.value); // if so, add its value to array\n }\n }\n }\n return valArray; // return value of checked radio or undefined if none checked\n }\n\n replaceWithNumberOfItems(element, replaceValue) {\n const options = element.children;\n const items = this.dom.targetContainer.querySelectorAll('[data-filter-value]');\n\n if (options) {\n for (let i = 0; i < options.length; i++) {\n const option = options[i];\n\n if (option.value !== '*' && option.value !== '') {\n let count = 0;\n const optionStr = option.innerText;\n\n for (let i = 0; i < items.length; i++) {\n let itemFilterValues = items[i].getAttribute('data-filter-value').split(',');\n\n itemFilterValues = itemFilterValues.map(value => value.trim().toLowerCase());\n\n const cleanValue = option.value.trim().toLowerCase();\n\n if (itemFilterValues.indexOf(cleanValue) > -1) {\n count++;\n }\n }\n\n option.innerText = optionStr.replace(replaceValue, count);\n }\n }\n }\n }\n}\n\nexport function setupFilters(selector = '[data-action*=\"filter\"]') {\n const filterContainers = document.body.querySelectorAll(selector);\n\n for (let i = 0; i < filterContainers.length; i++) {\n void new Filter(filterContainers[i]);\n }\n}\n","import { isVisible } from '../utils/elementProperties';\r\nimport scrollLock, { enableScrollLock, disableScrollLock } from '../utils/scrollLock';\r\n\r\nlet activeOverlay;\r\nlet activeOverlayContent;\r\nlet activeOverlayCloseBtn;\r\n\r\nconst openClass = 'overlay--active';\r\n\r\nfunction outsideClickListener(e) {\r\n if (!activeOverlayContent.contains(e.target) && isVisible(activeOverlayContent)) {\r\n // or use: event.target.closest(selector) === null\r\n overlayClose(e);\r\n activeOverlay.removeEventListener('click', outsideClickListener);\r\n }\r\n}\r\n\r\nfunction overlayOpen(e) {\r\n const targetId = e.currentTarget ? e.currentTarget.getAttribute('data-target') : e;\r\n const lockScroll = e.currentTarget.hasAttribute('data-scroll-lock') ? e.currentTarget.getAttribute('data-scroll-lock') : true;\r\n\r\n activeOverlay = document.getElementById(targetId);\r\n\r\n typeof e.preventDefault == 'function' ? e.preventDefault() : null;\r\n\r\n if (activeOverlay) {\r\n activeOverlay.classList.add(openClass);\r\n activeOverlayContent = activeOverlay.querySelector('.overlay__box');\r\n\r\n activeOverlayCloseBtn = activeOverlay.querySelector('[data-action=\"overlay-close\"]');\r\n activeOverlayCloseBtn.addEventListener('click', overlayClose);\r\n\r\n if (lockScroll === true) {\r\n enableScrollLock();\r\n }\r\n\r\n\r\n if (activeOverlayContent) {\r\n activeOverlay.addEventListener('click', outsideClickListener);\r\n }\r\n } else {\r\n console.warn(`Overlay data-target missing or no element with id: ${targetId} found`);\r\n }\r\n}\r\n\r\nfunction overlayClose(e) {\r\n e.preventDefault();\r\n disableScrollLock();\r\n activeOverlay.classList.remove(openClass);\r\n activeOverlayCloseBtn.removeEventListener('click', overlayClose);\r\n}\r\n\r\nexport function setupOverlay(selector = '[data-action=\"overlay-open\"]') {\r\n const overlayButtonOpen = document.body.querySelectorAll(selector);\r\n\r\n for (let i = 0; i < overlayButtonOpen.length; i++) {\r\n overlayButtonOpen[i].addEventListener('click', overlayOpen);\r\n }\r\n}\r\n","/**\n * Attention\n * Be aware that this module is dependent on support for Element.prototype.closest\n * This is included as default in https://polyfill.io/v3/polyfill.min.js\n */\n\n/**\n * Function that opens new tab\n * and hides the activeTab if found\n *\n * @param {object|HTMLElement} e - click event or tab element\n */\n\n// Used keycodes\nconst keycode = {\n arrowRight: 39,\n arrowLeft: 37,\n home: 36,\n end: 35\n};\n\nfunction openTab(e) {\n const tab = e.target ? e.target : e;\n\n if (!(event.ctrlKey || event.metaKey || event.shiftKey) && e.target) {\n e.preventDefault();\n }\n\n const tabContent = document.getElementById(tab.getAttribute('aria-controls').replace('#', ''));\n\n if (tabContent) {\n const activeTab = tab.parentNode.parentNode.querySelector('.tab--active');\n\n if (activeTab) {\n activeTab.classList.remove('tab--active');\n activeTab.setAttribute('aria-selected', false);\n activeTab.setAttribute('tabindex', -1);\n\n const activeTabContent = document.getElementById(activeTab.getAttribute('aria-controls').replace('#', ''));\n if (activeTabContent) {\n activeTabContent.classList.remove('tab__content--active');\n activeTabContent.setAttribute('aria-hidden', true);\n }\n }\n\n tab.classList.add('tab--active');\n tab.removeAttribute('tabindex');\n tab.setAttribute('aria-selected', true);\n tab.focus();\n tabContent.classList.add('tab__content--active');\n tabContent.setAttribute('aria-hidden', false);\n }\n}\n\nfunction openTabByHashId() {\n if (window.location.hash.indexOf('tab') > -1) {\n const tabContent = document.getElementById(window.location.hash.replace('#', ''));\n if (tabContent) {\n const tab = document.getElementById(tabContent.getAttribute('aria-labelledby'));\n openTab(tab);\n }\n }\n}\n\n/**\n* Initialise Tabs with this function\n* Will only run if given selector elements are found in DOM\n*\n* @param {string} selector - element selector string\n*/\nexport function setupTabs(selector = '[data-action=\"tabs\"]') {\n const tabsContainer = document.body.querySelectorAll(selector);\n\n if (tabsContainer) {\n for (let i = 0; i < tabsContainer.length; i++) {\n const tabs = tabsContainer[i].querySelectorAll('[role=\"tab\"]');\n\n for (let t = 0; t < tabs.length; t++) {\n tabs[t].addEventListener('click', openTab);\n }\n }\n }\n\n openTabByHashId();\n\n window.addEventListener('hashchange', openTabByHashId, false);\n}\n\nwindow.addEventListener('keydown', event => {\n const focusedElement = document.activeElement;\n const tabs = document.activeElement.closest('.tabs__nav');\n\n if (focusedElement && tabs) {\n if (event.keyCode === keycode.arrowLeft) {\n // Open prevoius tab\n if (focusedElement.closest('li').previousElementSibling && focusedElement.closest('li').previousElementSibling.querySelector('.tab')) {\n openTab(focusedElement.closest('li').previousElementSibling.querySelector('.tab'));\n }\n }\n if (event.keyCode === keycode.arrowRight) {\n // Open next tab\n if (focusedElement.closest('li').nextElementSibling && focusedElement.closest('li').nextElementSibling.querySelector('.tab')) {\n openTab(focusedElement.closest('li').nextElementSibling.querySelector('.tab'));\n }\n }\n if (event.keyCode === keycode.home) {\n // Open first tab\n if (tabs.querySelector('li:first-child .tab')) {\n event.preventDefault();\n openTab(tabs.querySelector('li:first-child .tab'));\n }\n }\n if (event.keyCode === keycode.end) {\n // Open last tab\n if (tabs.querySelector('li:last-child .tab')) {\n event.preventDefault();\n openTab(tabs.querySelector('li:last-child .tab'));\n }\n }\n }\n});\n","export function setupSliders(snapToItems = false) {\n const sliders = Array.from(document.querySelectorAll('.slider')).filter(x => x.querySelectorAll('.slider__item').length > 0);\n\n Array.from(sliders).forEach(slider => {\n const maxPxPrSecond = 10000;\n const sliderList = slider.querySelector('.slider__list');\n const sliderItems = slider.querySelectorAll('.slider__item');\n const sliderNavItems = slider.querySelectorAll('.slider__nav__item');\n const sliderNavPrev = slider.querySelector('.slider__button--prev');\n const sliderNavNext = slider.querySelector('.slider__button--next');\n const maxTranslate = 0;\n\n const itemWidth = parseFloat(getComputedStyle(sliderItems[0], null).getPropertyValue('width').replace('px', ''));\n let minTranslate = parseFloat(getComputedStyle(slider, null).getPropertyValue('width').replace('px', '')) - parseFloat(getComputedStyle(sliderList, null).getPropertyValue('width').replace('px', ''));\n\n if (snapToItems) {\n minTranslate = (parseFloat(getComputedStyle(sliderList, null).getPropertyValue('width').replace('px', '')) - itemWidth) * -1;\n }\n\n const itemMargin = parseInt(getComputedStyle(sliderItems[1], null).getPropertyValue('margin-left').replace('px', ''));\n const itemSnapStart = itemWidth / 2;\n let itemIndex = 0;\n let listAnimation = -1;\n\n slider.setAttribute('data-max-translate', maxTranslate);\n slider.setAttribute('data-min-translate', minTranslate);\n\n let move = false;\n let touch = false;\n\n // Start y and start x i s where whe start touching the screen. Only set once at touchstart and mousedown\n let startX = -1;\n let startY = -1;\n\n // Updated as we move the mouse (when button is down) or slide the screen\n let moveX = -1;\n let moveY = -1;\n\n // Used to set the direction - do we need to slide left or right\n let direction = -1;\n\n // Let's save the distance between startX and moveX here so we know how much to move it around\n let distanceX = -1;\n\n // This is used for the current move. This + pxMoved is what we want to translate the slider\n let translateX = -1;\n\n // Lets update this every time we move the slider. We don't want to start from 0 each time\n let pxMoved = 0;\n\n // Did we move at all? Or just click / touch once. If not we don't want to move at all\n let moved = false;\n\n // Let's take a look at how much px. we moved pr. second when moving. Maybe we can use that to calculate if we want to slide a bit mmore - and maybe even bounce if we move more than the slider alows.\n let startTime = -1;\n let endTime = -1;\n let time = -1;\n\n // Let's know if we are currently sliding some extra px\n let animating = false;\n\n // Array to contain the animations steps\n let animationSteps = [];\n\n // Only the last part where we bounce back. The rest is in the \"getAnimationSteps\"\n function getBounceSteps(bouncePx) {\n let lastMove = 0;\n let nextMove = 0;\n let bouncedExtra = 0;\n\n function getNextBounceMove() {\n if (lastMove == 0) {\n nextMove = direction == 'left' ? 5 : -5;\n } else {\n nextMove = lastMove * 1.1;\n }\n\n if (direction == 'left') {\n if ((bouncedExtra + nextMove) > (bouncePx * -1)) {\n nextMove = (bouncePx * -1) - bouncedExtra;\n }\n } else if (direction == 'right') {\n if ((bouncedExtra + nextMove) < (bouncePx * -1)) {\n nextMove = (bouncePx * -1) - bouncedExtra;\n }\n }\n\n lastMove = nextMove;\n\n return nextMove;\n }\n\n if (direction == 'left') {\n while (bouncedExtra < (bouncePx * -1)) {\n nextMove = getNextBounceMove(lastMove);\n bouncedExtra = bouncedExtra + nextMove;\n\n animationSteps.push(nextMove);\n }\n } else if (direction == 'right') {\n while (bouncedExtra > (bouncePx * -1)) {\n nextMove = getNextBounceMove(lastMove);\n bouncedExtra = bouncedExtra + nextMove;\n\n animationSteps.push(nextMove);\n }\n }\n }\n\n function clickSliderItem(e) {\n if (moved) {\n e.preventDefault();\n }\n }\n\n Array.from(sliderItems).forEach(item => {\n if (item.tagName.toLowerCase() == 'a') {\n item.addEventListener('click', clickSliderItem);\n }\n });\n\n function updateNav(index) {\n const activeSliderItems = Array.from(sliderNavItems).filter(x => x.classList.contains('js-active'));\n\n if (activeSliderItems.length == 1) {\n activeSliderItems[0].classList.remove('js-active');\n }\n\n sliderNavItems[index].classList.add('js-active');\n\n if (sliderNavPrev && sliderNavNext) {\n if (itemIndex == 0) {\n sliderNavPrev.classList.add('js-disabled');\n sliderNavNext.classList.remove('js-disabled');\n } else {\n sliderNavPrev.classList.remove('js-disabled');\n\n if (itemIndex + 1 == sliderItems.length) {\n sliderNavNext.classList.add('js-disabled');\n } else {\n sliderNavNext.classList.remove('js-disabled');\n }\n }\n }\n }\n\n // Get the animtionsteps to animate the move we made - including bounce mvoes (above) if we did it really fast ;-)\n function getAnimationSteps(moveExtra) {\n const maxBounce = slider.offsetWidth / 3;\n const maxPrFrame = 100;\n animationSteps = [];\n let lastMove = 0;\n let nextMove = 0;\n let movedTotal = 0;\n let bouncePx = 0;\n let bounce = false;\n\n if (direction == 'left') {\n if (translateX + moveExtra < minTranslate) {\n bounce = true;\n }\n } else if (direction == 'right') {\n if (translateX + moveExtra > 0) {\n bounce = true;\n }\n }\n\n if (bounce) {\n if (direction == 'left') {\n itemIndex = sliderItems.length - 1;\n\n // TODO: When bouncing its the opposite way, so no * -1 here... Remeber in getBounceSteps...\n if ((pxMoved + moveExtra) < (minTranslate - maxBounce)) {\n bouncePx = maxBounce * -1;\n } else {\n bouncePx = (pxMoved + moveExtra) - minTranslate;\n }\n\n if (pxMoved + moveExtra < minTranslate) {\n moveExtra = minTranslate - pxMoved;\n moveExtra = moveExtra + bouncePx;\n }\n } else if (direction == 'right') {\n itemIndex = 0;\n\n if (pxMoved + moveExtra > (maxTranslate + maxBounce)) {\n bouncePx = maxBounce;\n } else {\n bouncePx = (pxMoved + moveExtra);\n }\n\n if (pxMoved + moveExtra > maxTranslate) {\n moveExtra = maxTranslate - pxMoved;\n moveExtra = moveExtra + bouncePx;\n }\n }\n\n updateNav(itemIndex);\n } else {\n if (snapToItems) {\n if (direction == 'left') {\n const newPosition = (moveExtra + pxMoved) * -1;\n const newIndex = Math.round((newPosition + itemSnapStart) / itemWidth);\n\n let moveTotal = 0;\n\n if (newIndex == 0) {\n moveTotal = 0;\n } else {\n if (sliderItems.length - 1 >= newIndex) {\n moveTotal = (sliderItems[newIndex].offsetLeft * -1) - 10;\n }\n }\n\n moveExtra = moveTotal - pxMoved;\n itemIndex = newIndex;\n\n updateNav(itemIndex);\n } else if (direction == 'right') {\n const newPosition = (moveExtra + pxMoved) * -1;\n const newIndex = Math.round((newPosition + itemSnapStart) / itemWidth) - 1;\n\n let moveTotal = 0;\n\n if (newIndex == 0) {\n moveTotal = 10;\n } else {\n if (sliderItems.length - 1 >= newIndex) {\n moveTotal = (sliderItems[newIndex].offsetLeft * -1) + 10;\n }\n }\n\n moveExtra = moveTotal - pxMoved;\n itemIndex = newIndex;\n\n updateNav(itemIndex);\n }\n }\n }\n\n let movedExtra = 0;\n\n function getNextMove() {\n if (lastMove == 0) {\n nextMove = direction == 'left' ? -5 : 5;\n } else {\n nextMove = lastMove * 1.1;\n }\n\n if (direction == 'left') {\n if ((nextMove * -1) > maxPrFrame) {\n nextMove = maxPrFrame * -1;\n }\n\n if ((movedExtra + nextMove) < moveExtra) {\n nextMove = moveExtra - movedExtra;\n }\n } else if (direction == 'right') {\n if (nextMove > maxPrFrame) {\n nextMove = maxPrFrame;\n }\n\n if ((movedExtra + nextMove) > moveExtra) {\n nextMove = moveExtra - movedExtra;\n }\n }\n\n movedExtra = movedExtra + nextMove;\n lastMove = nextMove;\n\n return nextMove;\n }\n\n if (bounce) {\n getBounceSteps(bouncePx);\n }\n\n if (direction == 'left') {\n while (movedTotal > moveExtra) {\n nextMove = getNextMove(lastMove);\n movedTotal = movedTotal + nextMove;\n\n animationSteps.push(nextMove);\n }\n\n animationSteps.push(5);\n } else if (direction == 'right') {\n while (movedTotal < moveExtra) {\n nextMove = getNextMove(lastMove);\n movedTotal = movedTotal + nextMove;\n\n animationSteps.push(nextMove);\n }\n\n animationSteps.push(-5);\n }\n\n animationSteps = animationSteps.reverse();\n\n return animationSteps;\n }\n\n // Start slider (at touch start and mousedown)\n function startSlider(e) {\n move = true;\n startTime = new Date();\n\n if (e.changedTouches) {\n touch = true;\n\n startX = e.changedTouches[0].pageX;\n startY = e.changedTouches[0].pageY;\n } else {\n startX = e.clientX;\n startY = e.clientY;\n\n if (e.target.closest('a')) {\n e.preventDefault();\n }\n\n document.addEventListener('mousemove', documentMouseMove);\n }\n }\n\n // Move slider (when swiping and moving mouse)\n function moveSlider(e) {\n if (e.touches) {\n if (e.touches.length == 1) {\n move = true;\n moved = true;\n\n moveX = e.targetTouches[0].pageX;\n moveY = e.targetTouches[0].pageY;\n }\n } else {\n moved = true;\n\n moveX = e.clientX;\n moveY = e.clientY;\n }\n\n if (move) {\n sliderList.setAttribute('data-barba-prevent', 'all');\n\n distanceX = startX - moveX;\n let distanceY = startY - moveY;\n\n direction = startX > moveX ? 'left' : 'right';\n\n distanceX = distanceX < 0 ? distanceX * -1 : distanceX;\n distanceY = distanceY < 0 ? distanceY * -1 : distanceY;\n\n if (distanceX > (distanceY / 2)) {\n if (e.touches) {\n e.preventDefault();\n }\n\n moveList();\n }\n }\n }\n\n // End slider (touch end and mouse up)\n function endSlider() {\n if (moved) {\n if (!touch) {\n document.removeEventListener('mousemove', documentMouseMove);\n }\n\n pxMoved = translateX;\n\n endTime = new Date();\n\n if (startTime != -1) {\n time = (endTime.getTime() - startTime.getTime()) / 1000;\n\n let pxPrSecond = distanceX / time;\n pxPrSecond = pxPrSecond >= 0 ? pxPrSecond : pxPrSecond * -1;\n\n if (pxPrSecond > maxPxPrSecond) {\n pxPrSecond = maxPxPrSecond;\n }\n\n if (pxPrSecond > 500) {\n moveListExtra(pxPrSecond);\n } else {\n resetSlider();\n }\n } else {\n resetSlider();\n }\n }\n }\n\n // Reset slider variables\n function resetSlider() {\n if (listAnimation != -1) {\n cancelAnimationFrame(listAnimation);\n listAnimation = -1;\n }\n\n move = false;\n\n startX = -1;\n startY = -1;\n\n moveX = -1;\n moveY = -1;\n\n direction = -1;\n\n distanceX = -1;\n\n translateX = -1;\n\n touch = false;\n\n startTime = -1;\n endTime = -1;\n time = -1;\n\n animating = false;\n\n setTimeout(function () {\n moved = false;\n sliderList.removeAttribute('data-barba-prevent');\n }, 50);\n }\n\n // Move list - just when swiping and moving mouse around\n function moveList() {\n translateX = direction == 'left' ? distanceX * -1 : distanceX;\n\n let newTranslateX = translateX + pxMoved;\n newTranslateX = newTranslateX > 0 ? 0 : newTranslateX;\n newTranslateX = newTranslateX < minTranslate ? minTranslate : newTranslateX;\n\n sliderList.style.transform = `translate3d(${newTranslateX}px,0,0)`;\n\n moved = true;\n translateX = newTranslateX;\n }\n\n function sliderTransitionEnd() {\n sliderList.style.transition = null;\n sliderList.removeEventListener('transitionend', sliderTransitionEnd);\n }\n\n function clickNavItem(e) {\n const item = e.target.closest('.slider__nav__item');\n\n if (item) {\n const index = Array.from(sliderNavItems).indexOf(item);\n\n if (index != itemIndex) {\n const newX = ((index * itemWidth) + (index * itemMargin)) * -1;\n\n sliderList.style.transition = 'transform 0.5s ease-in-out';\n sliderList.style.transform = `translate3d(${newX}px,0,0)`;\n\n sliderList.addEventListener('transitionend', sliderTransitionEnd);\n\n moved = true;\n pxMoved = newX;\n\n itemIndex = index;\n\n updateNav(itemIndex);\n }\n }\n }\n\n Array.from(sliderNavItems).forEach(item => {\n item.addEventListener('click', clickNavItem);\n });\n\n if (sliderNavPrev) {\n sliderNavPrev.addEventListener('click', function () {\n if (itemIndex != 0) {\n const index = itemIndex - 1;\n const newX = ((index * itemWidth) + (index * itemMargin)) * -1;\n\n sliderList.style.transition = 'transform 0.5s ease-in-out';\n sliderList.style.transform = `translate3d(${newX}px,0,0)`;\n\n sliderList.addEventListener('transitionend', sliderTransitionEnd);\n\n moved = true;\n pxMoved = newX;\n\n itemIndex = index;\n\n updateNav(itemIndex);\n }\n });\n }\n\n if (sliderNavNext) {\n sliderNavNext.addEventListener('click', function () {\n if (itemIndex + 1 < sliderItems.length) {\n const index = itemIndex + 1;\n const newX = ((index * itemWidth) + (index * itemMargin)) * -1;\n\n sliderList.style.transition = 'transform 0.5s ease-in-out';\n sliderList.style.transform = `translate3d(${newX}px,0,0)`;\n\n sliderList.addEventListener('transitionend', sliderTransitionEnd);\n\n moved = true;\n pxMoved = newX;\n\n itemIndex = index;\n\n updateNav(itemIndex);\n }\n });\n }\n\n // Move list extra if we did it really fast ;-)\n function moveListExtra(pxPrSecond) {\n animating = true;\n\n let moveExtra = (pxPrSecond / 100000000) * (pxPrSecond * pxPrSecond);\n\n if (touch) {\n const _pxPrSecond = pxPrSecond * 2;\n moveExtra = (_pxPrSecond / 100000000) * (_pxPrSecond * _pxPrSecond);\n }\n\n if (direction == 'left') {\n moveExtra = moveExtra * -1;\n }\n\n let newTranslateX = -1;\n let movedExtra = 0;\n let animationStepIndex = 0;\n\n const animationSteps = getAnimationSteps(moveExtra);\n\n function animateList() {\n if (animationStepIndex + 1 >= animationSteps.length) {\n if (newTranslateX != -1) {\n translateX = newTranslateX;\n pxMoved = translateX;\n }\n\n resetSlider();\n } else {\n movedExtra = movedExtra + animationSteps[animationStepIndex];\n animationStepIndex++;\n movedExtra = movedExtra;\n\n newTranslateX = translateX + movedExtra;\n sliderList.style.transform = `translate3d(${newTranslateX}px,0,0)`;\n\n requestAnimationFrame(animateList);\n }\n }\n\n listAnimation = requestAnimationFrame(animateList);\n }\n\n // Events\n function sliderTouchStart(e) {\n if (!animating) {\n resetSlider();\n\n if (e.touches.length == 1) {\n startSlider(e);\n }\n }\n }\n\n function sliderTouchMove(e) {\n if (!animating) {\n moveSlider(e);\n }\n }\n\n function sliderTouchEnd(e) {\n if (!animating) {\n endSlider();\n }\n }\n\n function sliderTouchCancel(e) {\n if (!animating) {\n resetSlider();\n }\n }\n\n function documentMouseUp(e) {\n if (!animating) {\n endSlider();\n }\n }\n\n function documentMouseMove(e) {\n if (!animating) {\n moveSlider(e);\n }\n }\n\n function sliderMouseDown(e) {\n if (!animating) {\n resetSlider();\n startSlider(e);\n }\n }\n\n sliderList.addEventListener('touchstart', sliderTouchStart);\n sliderList.addEventListener('touchmove', sliderTouchMove);\n sliderList.addEventListener('touchend', sliderTouchEnd);\n sliderList.addEventListener('touchcancel', sliderTouchCancel);\n document.addEventListener('mouseup', documentMouseUp);\n sliderList.addEventListener('mousedown', sliderMouseDown);\n });\n}","import { scrollTop } from '../utils/scroll';\nimport { isIE11 } from '../utils/helpers';\n\nexport function setupIntersect() {\n function onChange(changes, observer) {\n changes.forEach(change => {\n if (change.intersectionRatio > 0.5) {\n if (change.target.closest('.product-entrance')) {\n const list = change.target.closest('.product-entrance').querySelector('.product-entrance__list');\n\n if (list) {\n if (list.childNodes[0] == change.target) {\n list.classList.add('js-intersect');\n }\n }\n }\n\n change.target.classList.add('js-intersect');\n change.target.classList.remove('js-scrolled-by');\n } else {\n const elementTop = parseInt(change.target.getAttribute('data-top'));\n\n if (scrollTop > elementTop) {\n change.target.classList.add('js-intersect', 'js-scrolled-by');\n } else {\n change.target.classList.remove('js-scrolled-by');\n }\n }\n });\n }\n\n const intersectElements = document.querySelectorAll('[data-intersect]');\n\n if (!isIE11) {\n const config = {\n root: null,\n rootMargin: '0px',\n threshold: 0.5\n };\n\n const observer = new IntersectionObserver(onChange, config);\n\n Array.from(intersectElements).forEach(element => {\n const elementTop = element.getBoundingClientRect().top + scrollTop;\n\n element.setAttribute('data-top',elementTop);\n observer.observe(element);\n });\n } else {\n Array.from(intersectElements).forEach(element => {\n element.classList.add('js-intersect');\n });\n }\n}\n","import { onReady } from './utils/onReady';\r\nimport { setupNav } from './components/nav';\r\nimport { setupLazyLoading } from './utils/lazyImage';\r\nimport { setupAccordions } from './components/accordion';\r\nimport { setupVideos } from './components/video';\r\nimport { initVhUnitOverwrite, debounce, isTouchDevice, isIE11 } from './utils/helpers';\r\nimport { setupAnchorLinkScroll } from './components/anchors';\r\nimport { setupFilters } from './components/filter';\r\nimport { setupOverlay } from './components/overlay';\r\nimport { setupTabs } from './components/tabs';\r\nimport { setupSliders } from './components/slider';\r\n//import { watchFormFields } from './components/form';\r\nimport { setupProductEntrances } from './components/productentrance';\r\nimport { setupIntersect } from './components/intersect';\r\nimport { setupCollageElements } from './components/collage-element';\r\nimport { setupFormToggleFields } from './components/form';\r\n\r\nfunction init() {\r\n document.body.classList.remove('standby');\r\n\r\n function endAnimation() {\r\n document.body.classList.add('js-animation-done');\r\n }\r\n\r\n if (document.body.getAttribute('data-animate').toLowerCase() == 'true') {\r\n //document.body.classList.add('page-load-animation');\r\n\r\n setTimeout(function() {\r\n const navLogo = document.querySelector('.nav__logo');\r\n\r\n if (navLogo) {\r\n navLogo.addEventListener('transitionend',endAnimation);\r\n }\r\n },1000);\r\n }\r\n\r\n if (isTouchDevice()) {\r\n document.body.classList.add('js-is-touch');\r\n }\r\n\r\n if (isIE11) {\r\n document.body.classList.add('js-ie-11');\r\n }\r\n\r\n setupAnchorLinkScroll();\r\n\r\n setupNav('.nav', false);\r\n\r\n onReady(() => {\r\n initVhUnitOverwrite();\r\n\r\n setupLazyLoading();\r\n\r\n setupAccordions();\r\n\r\n setupFilters();\r\n\r\n setupOverlay();\r\n\r\n setupVideos();\r\n\r\n setupTabs();\r\n\r\n setupSliders(true);\r\n\r\n //watchFormFields();\r\n\r\n setupProductEntrances();\r\n\r\n setupIntersect();\r\n\r\n setupCollageElements();\r\n\r\n setupFormToggleFields();\r\n });\r\n\r\n window.addEventListener('load', () => {\r\n svg4everybody();\r\n });\r\n}\r\n\r\ninit();\r\n","import { isTouchDevice } from '../utils/helpers';\n\nexport function setupProductEntrances() {\n function enterItem(e) {\n const paragraph = e.currentTarget.querySelector('p');\n const height = paragraph.scrollHeight;\n paragraph.style.height = `${height}px`;\n }\n\n function leaveItem(e) {\n const paragraph = e.currentTarget.querySelector('p');\n paragraph.style.height = null;\n }\n\n if (!isTouchDevice()) {\n const productEntranceItems = document.querySelectorAll('.product-entrances li');\n\n Array.from(productEntranceItems).forEach(item => {\n item.addEventListener('mouseenter',enterItem);\n item.addEventListener('mouseleave',leaveItem);\n });\n }\n}","import { onScroll, scrollTop } from '../utils/scroll';\r\nimport { currentWindowHeight } from '../utils/windowResize';\r\n\r\nexport function setupCollageElements() {\r\n const collageHeaderElements = document.querySelectorAll('.header .collage-01__boy,.header .collage-01__line-blue,.header .collage-02__boy,.header .collage-02__line-blue,.header .collage-03__girl,.header .collage-03__line-orange,.header .collage-04__girl,.header .collage-04__line-pink-light');\r\n const collageHeaderDoubleElements = document.querySelectorAll('.header .collage-01__circle-green,.header .collage-01__butterflies,.header .collage-02__circle-blue,.header .collage-02__flamengos,.header .collage-02__flying-flamengo,.header .collage-03__circle-purple,.header .collage-03__leaves,.header .collage-04__circle-yellow,.header .collage-04__umbrellas');\r\n const collageModuleElements = document.querySelectorAll('.module__collage-element');\r\n\r\n const minY = currentWindowHeight * -1;\r\n const maxY = 0;\r\n\r\n Array.from(collageModuleElements).forEach(element => {\r\n const elementTop = element.getBoundingClientRect().top + scrollTop;\r\n element.setAttribute('data-top', elementTop);\r\n });\r\n\r\n onScroll(() => {\r\n Array.from(collageModuleElements).forEach(element => {\r\n const elementTop = parseInt(element.getAttribute('data-top') - (currentWindowHeight / 3));\r\n\r\n if (scrollTop > elementTop) {\r\n let tY = ((scrollTop - elementTop) / 2) * -1;\r\n\r\n if (tY >= minY && tY <= maxY) {\r\n element.style.transform = `translateY(${tY}px)`;\r\n } else {\r\n if (tY < minY) {\r\n tY = minY\r\n } else if (tY > maxY) {\r\n tY = maxY;\r\n }\r\n\r\n element.style.transform = `translateY(${tY}px)`;\r\n }\r\n }\r\n });\r\n\r\n Array.from(collageHeaderElements).forEach(element => {\r\n let tY = (scrollTop / 2) * -1;\r\n\r\n if (tY >= minY && tY <= maxY) {\r\n element.style.transition = 'initial';\r\n element.style.transform = `translateY(${tY}px)`;\r\n } else {\r\n if (tY < minY) {\r\n tY = minY\r\n } else if (tY > maxY) {\r\n tY = maxY;\r\n }\r\n\r\n element.style.transition = 'initial';\r\n element.style.transform = `translateY(${tY}px)`;\r\n }\r\n });\r\n\r\n Array.from(collageHeaderDoubleElements).forEach(element => {\r\n let tY = scrollTop * -1;\r\n\r\n if (tY >= minY && tY <= maxY) {\r\n element.style.transition = 'initial';\r\n element.style.transform = `translateY(${tY}px)`;\r\n } else {\r\n if (tY < minY) {\r\n tY = minY\r\n } else if (tY > maxY) {\r\n tY = maxY;\r\n }\r\n\r\n element.style.transition = 'initial';\r\n element.style.transform = `translateY(${tY}px)`;\r\n }\r\n });\r\n });\r\n}","const invalidClass = 'invalid';\r\n\r\n/**\r\n * Check validation of single form field\r\n * @param {HTMLElement | Object} field - Form field element or event object.\r\n *\r\n * @returns {boolean}\r\n */\r\nfunction checkValidation(input) {\r\n let valid = true;\r\n let val = '';\r\n const field = input.target ? input.target : input;\r\n\r\n field.classList.remove(invalidClass);\r\n\r\n switch (field.nodeName) {\r\n case 'INPUT':\r\n case 'TEXTAREA':\r\n case 'SELECT':\r\n default:\r\n val = field.value;\r\n break;\r\n }\r\n\r\n if (field.type == 'checkbox' && !field.checked || val.trim() == '') {\r\n valid = false;\r\n field.classList.add(invalidClass);\r\n field.focus();\r\n }\r\n\r\n return valid;\r\n}\r\n\r\n/**\r\n * Runs [required] fields within form through validation function\r\n *\r\n * @param {HTMLElement} form - Form element to validate *\r\n * @returns {boolean}\r\n */\r\nexport function validateForm(form) {\r\n const requiredFields = form.querySelectorAll('[required]');\r\n let valid = true;\r\n\r\n for (let i = 0; i < requiredFields.length; i++) {\r\n const field = requiredFields[i];\r\n\r\n valid = checkValidation(field);\r\n if (!valid) {\r\n break;\r\n }\r\n }\r\n\r\n return valid;\r\n}\r\n\r\n/**\r\n * This is ment as an 'input' eventhandler set on textareas,\r\n * to auto increase it's height depending on the users text-input.\r\n */\r\nfunction textAreaAutoHeight() {\r\n this.style.height = ''; // Resets height, in case text is removed\r\n this.style.height = `${this.scrollHeight}px`;\r\n}\r\n\r\n/**\r\n * Simply adds a class to target field if it has a value and removes it if not.\r\n *\r\n * @param {Object || HTMLElement} e - Event or field element\r\n */\r\nfunction checkFieldValue(e) {\r\n const field = e.target || e;\r\n field.value ? field.classList.add('has-text') : field.classList.remove('has-text');\r\n}\r\n\r\n/**\r\n * Sets up 'change'-eventhandler as checkValidation on given fields\r\n *\r\n * @param {HTMLElement} form - Form container with fields to validate\r\n */\r\n\r\nexport function watchFormFields(selector = '[data-action*=\"form\"]') {\r\n const form = document.body.querySelectorAll(selector);\r\n\r\n if (form) {\r\n for (let f = 0; f < form.length; f++) {\r\n const fields = form[f].querySelectorAll('input, select, textarea');\r\n\r\n for (let i = 0; i < fields.length; i++) {\r\n const field = fields[i];\r\n\r\n //Check for prefilled fields\r\n checkFieldValue(field);\r\n field.addEventListener('keyup', checkFieldValue);\r\n\r\n if (field.hasAttribute('required')) {\r\n field.addEventListener('change', checkValidation);\r\n }\r\n\r\n if (field.type == 'textarea') {\r\n field.addEventListener('input', textAreaAutoHeight);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Serializes form fields\r\n *\r\n * @param {HTMLElement} form - Form element to serialize *\r\n * @returns {string} - Returns querystring of fields names and values\r\n */\r\nexport function serialize(form) {\r\n if (!form || form.nodeName !== 'FORM') {\r\n return;\r\n }\r\n let i, j;\r\n const q = [];\r\n for (i = form.elements.length - 1; i >= 0; i = i - 1) {\r\n if (form.elements[i].name === '') {\r\n continue;\r\n }\r\n switch (form.elements[i].nodeName) {\r\n case 'INPUT':\r\n switch (form.elements[i].type) {\r\n case 'text':\r\n case 'tel':\r\n case 'email':\r\n case 'date':\r\n case 'number':\r\n case 'hidden':\r\n case 'password':\r\n case 'button':\r\n case 'reset':\r\n case 'submit':\r\n q.push(`${form.elements[i].name}=${encodeURIComponent(form.elements[i].value)}`);\r\n break;\r\n case 'checkbox':\r\n case 'radio':\r\n if (form.elements[i].checked) {\r\n q.push(`${form.elements[i].name}=${encodeURIComponent(form.elements[i].value)}`);\r\n }\r\n break;\r\n case 'file':\r\n break;\r\n }\r\n break;\r\n case 'TEXTAREA':\r\n q.push(`${form.elements[i].name}=${encodeURIComponent(form.elements[i].value)}`);\r\n break;\r\n case 'SELECT':\r\n switch (form.elements[i].type) {\r\n case 'select-one':\r\n q.push(`${form.elements[i].name}=${encodeURIComponent(form.elements[i].value)}`);\r\n break;\r\n case 'select-multiple':\r\n for (j = form.elements[i].options.length - 1; j >= 0; j = j - 1) {\r\n if (form.elements[i].options[j].selected) {\r\n q.push(\r\n `${form.elements[i].name}=${encodeURIComponent(form.elements[i].options[j].value)}`\r\n );\r\n }\r\n }\r\n break;\r\n }\r\n break;\r\n case 'BUTTON':\r\n switch (form.elements[i].type) {\r\n case 'reset':\r\n case 'submit':\r\n case 'button':\r\n q.push(`${form.elements[i].name}=${encodeURIComponent(form.elements[i].value)}`);\r\n break;\r\n }\r\n break;\r\n }\r\n }\r\n return q.join('&').replace(/%20/g, '+');\r\n}\r\n\r\n/**\r\n * Sets up Form submit eventhandler used when submitting form data through Mandrill\r\n *\r\n * @param {string} selector - querySelector string\r\n */\r\nexport function setupMandrilForms(selector = 'form[data-action*=\"form-mandrill\"]') {\r\n //mandrill forms\r\n const mandrillForms = document.querySelectorAll(selector);\r\n\r\n function mandrillFormSubmit(e) {\r\n e.preventDefault();\r\n\r\n const form = e.target;\r\n if (form !== null) {\r\n if (validateForm(form)) {\r\n form.classList.add('form--working');\r\n\r\n const dealerSelect = form.querySelector('select[name=dealer-mail]');\r\n\r\n if (dealerSelect) {\r\n const dealer = dealerSelect.querySelector(`option[value=\"${dealerSelect.value}\"]`);\r\n\r\n if (dealer && dealer.innerText !== 0) {\r\n form.querySelector('input[name=dealer-name]').value = dealer.innerText;\r\n }\r\n }\r\n\r\n const XHR = new XMLHttpRequest();\r\n const formData = serialize(form);\r\n\r\n // Define what happens\r\n XHR.onreadystatechange = function () {\r\n if (this.readyState === this.DONE) {\r\n if (XHR.onreadystatechange) {\r\n XHR.onreadystatechange = null;\r\n const json = JSON.parse(this.responseText);\r\n\r\n if (json.status !== 'ok') {\r\n const errorText = form.getAttribute('data-error-message');\r\n alert(errorText);\r\n window.console.warn(json);\r\n\r\n form.classList.remove('form--working');\r\n } else {\r\n window.location = form.getAttribute('data-confirmation-url');\r\n }\r\n }\r\n }\r\n };\r\n // Set up our request\r\n XHR.open('POST', '/umbraco/api/mail/sendmultinestedcontent', true);\r\n // Add the required HTTP header for form data POST requests\r\n XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\r\n // Finally, send our data.\r\n XHR.send(formData);\r\n }\r\n }\r\n }\r\n\r\n for (let i = 0; i < mandrillForms.length; i++) {\r\n mandrillForms[i].addEventListener('submit', mandrillFormSubmit);\r\n }\r\n}\r\n\r\nexport function setupFormToggleFields(hiddenFieldClass = 'form__field--hidden') {\r\n const toggleTriggers = document.querySelectorAll('[data-form-field-toggle]');\r\n\r\n function checkToggleFields(e) {\r\n const field = e.currentTarget;\r\n const toggleField = document.querySelector(field.getAttribute('data-form-field-toggle'));\r\n\r\n if (field && toggleField) {\r\n const hasSiblings = toggleField.previousElementSibling != null || toggleField.nextElementSibling != null;\r\n\r\n if (field.options[field.selectedIndex].text.toLowerCase() == toggleField.getAttribute('data-toggle-value-trigger').toLowerCase()) {\r\n toggleField.classList.remove('form__field--hidden');\r\n\r\n if (!hasSiblings) {\r\n const fieldset = toggleField.closest('.form__fieldset');\r\n\r\n if (fieldset) {\r\n fieldset.classList.remove('form__fieldset--hidden');\r\n }\r\n }\r\n } else {\r\n toggleField.classList.add('form__field--hidden');\r\n\r\n if (!hasSiblings) {\r\n const fieldset = toggleField.closest('.form__fieldset');\r\n\r\n if (fieldset) {\r\n fieldset.classList.add('form__fieldset--hidden');\r\n }\r\n }\r\n\r\n const toggleFieldSelect = toggleField.querySelector('select');\r\n\r\n if (toggleFieldSelect) {\r\n toggleFieldSelect.selectedIndex = 0;\r\n }\r\n\r\n const toggleFieldCheckboxes = toggleField.querySelectorAll('input[type=\"checkbox\"]');\r\n\r\n toggleFieldCheckboxes.forEach(checkbox => {\r\n checkbox.checked = false;\r\n });\r\n }\r\n }\r\n }\r\n\r\n toggleTriggers.forEach(toggleTrigger => {\r\n if (toggleTrigger.tagName.toLowerCase() == 'select') {\r\n toggleTrigger.addEventListener('change',checkToggleFields);\r\n }\r\n\r\n const toggleField = document.querySelector(toggleTrigger.getAttribute('data-form-field-toggle'));\r\n\r\n if (toggleField) {\r\n const hasSiblings = toggleField.previousElementSibling != null || toggleField.nextElementSibling != null;\r\n\r\n if (!hasSiblings) {\r\n const fieldset = toggleField.closest('.form__fieldset');\r\n\r\n if (fieldset) {\r\n fieldset.classList.add('form__fieldset--hidden');\r\n }\r\n }\r\n }\r\n });\r\n}"],"names":["functionReferences","readyState","document","readyEventBound","emptyCallbackArrays","length","tempArray","slice","forEach","funcRef","onReady","functionReference","addEventListener","push","getElementScroll","element","window","Element","Document","Window","left","pageXOffset","documentElement","scrollLeft","top","pageYOffset","scrollTop","scrollX","scrollY","console","warn","className","scrollLocked","enableScrollLock","scrollPosition","htmlTag","scrollTo","classList","add","style","marginTop","position","width","body","overflowY","disableScrollLock","remove","overflow","removeAttribute","nav","ticking","scrollFunctions","animate","scrollHandler","requestAnimationFrame","onScroll","handler","triggerNow","activeLink","hoverLink","activeBackgroundImage","burgerNav","querySelector","burgerNavBackgroundImage","Array","from","querySelectorAll","leaveTimer","toggleMenuOpen","contains","setTimeout","setupNav","burgerNavItems","burgerNavSubBacks","selector","sticky","changeImage","inactiveBurgerNavBackgroundImage","activeBurgerNavBackgroundImage","image","hasAttribute","filter","x","getAttribute","createElement","src","complete","backgroundImage","setAttribute","onload","enterBurgerNavItem","e","currentTarget","clearTimeout","leaveBurgerNavItem","clickBurgerNavItem","item","clickBack","scrollTimer","lastScrollPosition","scrollInPixels","goingUpClass","windowScroll","stickyNavOnScroll","undefined","navSearchForm","navSearchIcon","navSearchField","focus","navBurgerSearchForm","navBurgerSearchIcon","navBurgerSearchField","navSupportUl","navSupport","currentBreakpoint","resizeTimer","breakpoints","breakpointKeys","Object","keys","currentWindowWidth","innerWidth","currentWindowHeight","innerHeight","currentBreakpointIndex","resizeFunctions","getWindowSizes","lastFoundWidth","key","index","resizeHandler","onWindowResize","lastUsedScreenWidth","isBot","navigator","test","userAgent","lazyArray","options","loadedClass","loadClass","decodeImg","oldIe11Fit","offset","lazyLoad","i","lazyElem","rect","getBoundingClientRect","bottom","right","clientHeight","clientWidth","bgContainer","handleLoadedBg","formattedSrc","getImageSrc","loadImage","then","container","oldImage","objectFitPolyfill","removeChild","newImageTag","altText","tagName","appendChild","prototype","call","l","path","newImage","Image","Promise","resolve","decode","largestBreakpointFound","breakpointName","srcAttribute","transitionEndEventName","detectStyleDeclatationName","eventTypeName","transitions","transition","OTransition","MozTransition","WebkitTransition","el","t","cssAnimateNewHeight","newHeight","classTarget","classOnBoth","prevHeight","offsetHeight","delayedClose","removeEventListener","height","activeAccordion","keycode","Accordion","trigger","dom","parentNode","nextElementSibling","settings","type","ctrlKey","metaKey","shiftKey","preventDefault","_this","ariaExpanded","setupAccordions","accordionContent","accordions","location","hash","indexOf","getElementById","replace","click","event","focusedElement","activeElement","closest","keyCode","previousElementSibling","allowStatCookies","CookieInformation","getConsentGivenFor","setVhProp","vh","setProperty","addPrefetch","kind","url","as","linkElem","rel","href","crossorigin","head","append","isTouchDevice","maxTouchPoints","isIE11","MSInputMethodContext","documentMode","easeInOutQuintic","currentTime","start","change","duration","time","ts","tc","to","callback","relativeTo","useElement","offsetTop","offsetLeft","getElementPosition","amount","val","scrollingElement","Video","devicePixelRatio","elem","roundedWidth","roundedHeight","id","bg","byline","color","controls","ytUrl","this","videoLink","match","extractVideoIdFromUrl","isPrivate","isVimeo","poster","Math","ceil","round","getContext","toDataURL","warmConnections","once","addIframe","openVideo","closeBtn","videoModule","bind","iframe","_this2","videoService","videoUrl","_this3","preconnected","setupAnchorLinkScroll","triggerSelector","triggers","hashLink","pathname","activeOverlay","activeOverlayContent","activeOverlayCloseBtn","classNames","Filter","module","filters","allFilter","targetContainer","filterType","itemCountReplace","filterHandler","replaceWithNumberOfItems","target","filterItems","isButton","filterValue","value","name","siblingRadios","r","deselectRadio","itemFilterValues","split","cleanFilterValue","trim","toLowerCase","map","filterValues","getSetValues","isComboFilter","showItem","cleanValue","sections","s","section","replaceValue","children","items","option","count","optionStr","innerText","checked","valArray","len","openClass","outsideClickListener","offsetWidth","getClientRects","overlayClose","overlayOpen","targetId","lockScroll","openTab","tab","activeTab","activeTabContent","tabContent","openTabByHashId","setupSliders","snapToItems","sliders","slider","maxPxPrSecond","sliderList","sliderItems","sliderNavItems","sliderNavPrev","sliderNavNext","maxTranslate","itemWidth","parseFloat","getComputedStyle","getPropertyValue","minTranslate","itemMargin","parseInt","itemSnapStart","itemIndex","listAnimation","move","touch","startX","startY","moveX","moveY","direction","distanceX","translateX","pxMoved","moved","startTime","endTime","animating","animationSteps","clickSliderItem","updateNav","activeSliderItems","getAnimationSteps","moveExtra","newPosition","newIndex","moveTotal","maxBounce","maxPrFrame","lastMove","nextMove","movedTotal","bouncePx","bounce","movedExtra","getNextMove","bouncedExtra","getNextBounceMove","getBounceSteps","reverse","startSlider","Date","changedTouches","pageX","pageY","clientX","clientY","documentMouseMove","moveSlider","distanceY","newTranslateX","touches","targetTouches","transform","endSlider","pxPrSecond","getTime","_pxPrSecond","animationStepIndex","animateList","resetSlider","moveListExtra","cancelAnimationFrame","sliderTransitionEnd","clickNavItem","newX","setupIntersect","observer","intersectElements","IntersectionObserver","changes","list","intersectionRatio","childNodes","root","rootMargin","threshold","elementTop","observe","endAnimation","tabs","navLogo","enterItem","paragraph","scrollHeight","leaveItem","productEntranceItems","collageHeaderElements","collageHeaderDoubleElements","collageModuleElements","minY","checkToggleFields","hasSiblings","fieldset","toggleFieldSelect","field","toggleField","selectedIndex","text","checkbox","customOptions","getElementsByClassName","setupLazyLoading","filterContainers","setupFilters","overlayButtonOpen","setupOverlay","videos","setupVideos","tabsContainer","setupTabs","tY","toggleTrigger","svg4everybody"],"mappings":"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"}