{"version":3,"file":"index-CSlZD6q3.js","sources":["../../../Nybergs.Frontend/scripts/utils/accordion.mjs","../../../Nybergs.Frontend/scripts/utils/overlay.mjs","../../../Nybergs.Frontend/scripts/utils/lock-focus.js","../../../Nybergs.Frontend/scripts/utils/scroll.mjs","../../../Nybergs.Frontend/scripts/main-menu.mjs","../../../Nybergs.Frontend/scripts/utils/animation-utils.mjs","../../../Nybergs.Frontend/scripts/setup-animations.mjs","../../../Nybergs.Frontend/scripts/konamiCode.js","../../../Nybergs.Frontend/scripts/slideshow.js","../../../Nybergs.Frontend/scripts/utils/lock-scroll.mjs","../../../Nybergs.Frontend/scripts/utils/mobile-gesture.mjs","../../../Nybergs.Frontend/scripts/media-gallery.mjs","../../../Nybergs.Frontend/scripts/utils/dom-utils.mjs","../../../Nybergs.Frontend/scripts/clickable-containers.mjs","../../../Nybergs.Frontend/scripts/menu-background.mjs","../../../Nybergs.Frontend/scripts/pagination.mjs","../../../Nybergs.Frontend/scripts/index.mjs"],"sourcesContent":["/**\n * Creates an accordion functionality for a details element.\n * @param {string} detailsSelector - The details element to create the accordion for.\n * @param {string} contentSelector - The accordion object with `shrink`, `open`, and `expand` methods.\n */\nexport default function accordionAnimation(detailsSelector, contentSelector) {\n document.querySelectorAll(detailsSelector).forEach((el) => {\n const summary = el.querySelector('summary');\n const content = el.querySelector(contentSelector);\n\n let animation = null;\n let isClosing = false;\n let isExpanding = false;\n\n summary.addEventListener('click', (e) => {\n e.preventDefault();\n el.style.overflow = 'hidden';\n\n if(isClosing || !el.open) {\n openAccordion();\n } else if(isExpanding || el.open) {\n shrinkAccordion();\n }\n });\n\n /**\n * Shrinks the accordion.\n */\n function shrinkAccordion() {\n isClosing = true;\n const startHeight = `${el.offsetHeight}px`;\n const endHeight = `${summary.offsetHeight}px`;\n\n if(animation) {\n animation.cancel();\n }\n\n animation = el.animate({\n height: [startHeight, endHeight],\n }, {\n duration: 200,\n easing: 'ease-out',\n });\n\n animation.onfinish = () => onAnimationFinish(false);\n animation.oncancel = () => isClosing = false;\n }\n\n /**\n * Opens the accordion.\n */\n function openAccordion() {\n el.style.height = `${el.offsetHeight}px`;\n el.open = true;\n\n requestAnimationFrame(() => expandAccordion());\n }\n\n /**\n * Expands the accordion.\n */\n function expandAccordion() {\n isExpanding = true;\n const startHeight = `${el.offsetHeight}px`;\n const endHeight = `${summary.offsetHeight + content.offsetHeight}px`;\n\n if(animation) {\n animation.cancel();\n }\n\n animation = el.animate({\n height: [startHeight, endHeight],\n }, {\n duration: 200,\n easing: 'ease-out',\n });\n\n animation.onfinish = () => onAnimationFinish(true);\n animation.oncancel = () => isExpanding = false;\n }\n\n /**\n *\n * @param {boolean} open - Indicates whether the accordion is open or not.\n */\n function onAnimationFinish(open) {\n el.open = open;\n animation = null;\n isClosing = false;\n isExpanding = false;\n el.style.height = el.style.overflow = '';\n }\n });\n}\n","/**\n * Toggles overlay for the given element.\n * @param {HTMLElement | Element | null | undefined} element - The target element for which the overlay will be toggled.\n */\nexport function toggleOverlay(element) {\n if(element === null || element === undefined) {\n return;\n }\n\n element.classList.toggle('show-overlay');\n toggleNoScroll();\n}\n\n/**\n * Toggles the 'no-scroll' class on the body based on the presence of any overlay.\n */\nfunction toggleNoScroll() {\n const anyOverlayOpen = document.querySelectorAll('.show-overlay').length > 0;\n\n if(anyOverlayOpen) {\n document.body.classList.add('no-scroll');\n } else {\n document.body.classList.remove('no-scroll');\n }\n}\n","let focusStack = [];\n\n/**\n * @param { HTMLElement } element Element to lock focus inside.\n */\nexport function lockFocus(element) {\n if(focusStack.length > 0) {\n const { handler } = focusStack[focusStack.length - 1];\n document.removeEventListener('focus', handler, true);\n }\n\n const handler = createFocusHandler(element);\n focusStack.push({ element, handler });\n\n if(element.getAttribute('tabindex') === null) {\n element.setAttribute('tabindex', '-1');\n }\n\n document.addEventListener('focus', handler, true);\n toggleIframeTabindex(true);\n}\n\n/**\n * Unlock focus from the current element and re-lock it to the previous one if any.\n */\nexport function unlockFocus() {\n if(focusStack.length === 0) {\n return;\n }\n\n const { handler: unlockedHandler } = focusStack.pop();\n document.removeEventListener('focus', unlockedHandler, true);\n\n if(focusStack.length > 0) {\n const { element: topElement, handler: topHandler } = focusStack[focusStack.length - 1];\n document.addEventListener('focus', topHandler, true);\n topElement.focus();\n }\n\n if(focusStack.length === 0) {\n toggleIframeTabindex(false);\n }\n}\n\n/**\n * @param { HTMLElement } element Element to lock focus inside.\n * @returns { (event: Event) => void } Focus handler.\n */\nfunction createFocusHandler(element) {\n return function focusHandler(event) {\n if(!element.contains(event.target)) {\n element.focus();\n }\n };\n}\n\n/**\n * This is bugfix that I added becuase the iframe is not a part of the tab order by default which\n * enables tabbig to it despite the focus being locked on the menu.\n * Toggles the tabindex attribute of an iframe in the document.\n * When `disable` is true, sets the tabindex to '-1' to remove the iframe from the tab order.\n * When `disable` is false, removes the tabindex attribute to restore the iframe to the tab order.\n * @param {boolean} disable - A flag indicating whether to disable or enable the iframe's tabindex.\n */\nfunction toggleIframeTabindex(disable) {\n const iFrame = document.querySelector('iframe');\n if(iFrame) {\n if(disable) {\n iFrame.setAttribute('tabindex', '-1');\n } else {\n iFrame.removeAttribute('tabindex');\n }\n }\n}\n","/**\n * @typedef {object} ScrollInfo Information about the scroll event.\n * @property {boolean} isScrollingDown Whether the user is scrolling down.\n * @property {boolean} isBeyondThreshold Whether the user has scrolled beyond the threshold.\n */\n\n/**\n * @param {(scrollInfo: ScrollInfo) => void} handleScroll Function to handle scroll event.\n * @param {number} threshold Threshold for more granular control over handleScroll\n * @param {HTMLElement | Window} element Element to attach the scroll event listener to.\n * @returns {() => void} Abort function for the scroll event listener.\n */\nexport function onScroll(handleScroll, threshold = 0, element = window){\n let lastScrollTop = 0;\n const abortSignal = new AbortController();\n\n element.addEventListener(\n 'scroll',\n function() {\n let scrollTop = window.scrollY || document.documentElement.scrollTop;\n const scrollThreshold = threshold;\n const isScrollingDown = scrollTop > lastScrollTop;\n const isBeyondThreshold = scrollTop > scrollThreshold;\n\n handleScroll({isScrollingDown, isBeyondThreshold});\n\n lastScrollTop = scrollTop <= 0 ? 0 : scrollTop;\n },\n { signal: abortSignal.signal }\n );\n\n return () => abortSignal.abort();\n}\n","import { toggleOverlay } from './utils/overlay.mjs';\nimport { lockFocus, unlockFocus } from './utils/lock-focus.js';\nimport { onScroll } from './utils/scroll.mjs';\n\n/**\n * Export the menu toggle functionality.\n */\nexport default function init() {\n initMenuToggle();\n}\n\n/**\n * Initializes the menu toggle functionality.\n */\nfunction initMenuToggle() {\n /**\n * Click event handler for the open menu button.\n * Toggles the overlay for the mobile menu container.\n */\n function handleMenuButtonClick() {\n toggleOverlay(menuContainer);\n toggleOverlay(overlay);\n toggleIsActive();\n\n const isMenuActive = mobileMenu.classList.contains('is-active');\n\n\n if(isMenuActive) {\n lockFocus(mobileMenu);\n } else {\n unlockFocus();\n }\n }\n\n const openMenuButton = document.querySelector('.open-menu-button');\n const menuContainer = document.querySelector('.menu');\n const overlay = document.querySelector('.overlay');\n const mobileMenu = document.querySelector('.top-row');\n\n openMenuButton?.addEventListener('click', handleMenuButtonClick);\n}\n\n/**\n * Show/hide desktop menu on scroll.\n */\nonScroll(({isScrollingDown, isBeyondThreshold}) => {\n if(isBeyondThreshold) {\n setMenuCollapse(isScrollingDown);\n } else {\n setMenuCollapse(false);\n }\n}, 150);\n\n/**\n * @param {boolean} collapse Whether to collapse menu\n */\nfunction setMenuCollapse(collapse) {\n const menuContainers = document.querySelectorAll('.menu-container, .mobile-menu-container');\n menuContainers.forEach(menu => menu.classList.toggle('collapsed', collapse));\n}\n\n/**\n * Toggles the 'is-active' class on the '.open-menu-button' element.\n */\nfunction toggleIsActive() {\n const button = document.querySelector('.open-menu-button');\n const topRow = document.querySelector('.top-row');\n if(button) {\n button.classList.toggle('is-active');\n topRow.classList.toggle('is-active');\n }\n}\n","/**\n * Animates an element with a specified animation class and optional delay.\n * @param {HTMLElement} element - The DOM element to animate.\n * @param {string} animation - The animation class to add to the element.\n * @param {number} [delay] - Optional delay (in milliseconds) before the animation starts.\n */\nfunction animate(element, animation, delay = 0) {\n if(element === null) {\n return;\n }\n\n if(delay === 0) {\n element.classList.add(animation);\n return;\n }\n\n element.style.visibility = 'hidden';\n setTimeout(() => {\n element.style.visibility = 'visible';\n element.classList.add(animation);\n }, delay);\n}\n\n/**\n * Sets up animations for elements that should animate when they enter the screen.\n * @param {string[]} selectors - An array of CSS selectors for elements to animate on screen entry.\n */\nfunction setupEnterScreenAnimations(selectors) {\n const elementsToFadeUpOnEnterScreen = document.querySelectorAll(selectors.join(', '));\n\n elementsToFadeUpOnEnterScreen.forEach((element) => {\n element.style.visibility = 'hidden';\n });\n\n triggerOnEnterScreen((element) => {\n element.style.visibility = 'visible';\n animate(element, 'fade-up');\n }, elementsToFadeUpOnEnterScreen);\n}\n\n/**\n * Observes elements and triggers a callback when they enter the screen.\n * @param {Function} enterScreenCallback - The callback function to execute when an element enters the screen.\n * @param {NodeList} elements - A NodeList of DOM elements to observe.\n */\nfunction triggerOnEnterScreen(enterScreenCallback, elements) {\n const enterScreenObserver = new IntersectionObserver((entries) => {\n entries.forEach((entry) => {\n if(entry.isIntersecting) {\n const element = entry.target;\n enterScreenCallback(element);\n enterScreenObserver.unobserve(element);\n }\n });\n });\n\n elements.forEach((element) => {\n enterScreenObserver.observe(element);\n });\n}\n\nexport {\n animate,\n setupEnterScreenAnimations,\n triggerOnEnterScreen\n};\n","import { animate, setupEnterScreenAnimations } from './utils/animation-utils.mjs';\n\n/**\n * Initializes all animations on the page if the user does not prefer reduced motion.\n * It sets up animations for elements that should animate when entering the screen and\n * initializes header animations.\n */\nfunction initAnimations() {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if(prefersReducedMotion) {\n return;\n }\n\n initEnterScreenAnimations();\n initHeaderAnimations();\n}\n\n/**\n * Initializes header animations by selecting the header element and applying animations to its child elements.\n * It selects the `h1` element within the header and applies a 'clip-right' animation with a delay of 100ms.\n * It also selects the `p` element within the header and applies the same 'clip-right' animation with a delay of 550ms.\n * If the header or any of its child elements are not found, the function exits without applying animations.\n */\nfunction initEnterScreenAnimations() {\n setupEnterScreenAnimations([\n '.page-listing-block > *',\n '.mixed-listing-block > *'\n ]);\n}\n\n/**\n * Initializes animations for various blocks on the page that should animate upon entering the viewport.\n * It uses the `setupEnterScreenAnimations` utility function to set up the animations for a predefined\n * list of CSS selectors. Each selector corresponds to a block or component on the page that will have\n * the 'fade-up' animation applied as it comes into view.\n */\nfunction initHeaderAnimations() {\n const header = document.querySelector('.header');\n if(header === null) {\n return;\n }\n\n const heading = header.querySelector('h1');\n const ingress = header.querySelector('p');\n\n animate(heading, 'clip-right', 100);\n animate(ingress, 'clip-right', 100);\n}\n\nexport default initAnimations;\n","(function() {\n const konamiCode = [\n 'ArrowUp',\n 'ArrowUp',\n 'ArrowDown',\n 'ArrowDown',\n 'ArrowLeft',\n 'ArrowRight',\n 'ArrowLeft',\n 'ArrowRight',\n 'KeyB',\n 'KeyA',\n ];\n let konamiIndex = 0;\n\n /**\n * Checks if the sequence of keydown events matches the Konami Code.\n * If the full sequence is entered correctly, it activates an easter egg.\n * @param {KeyboardEvent} event - The keyboard event to check.\n */\n function checkKonamiCode(event) {\n if(event.code === konamiCode[konamiIndex]) {\n konamiIndex++;\n if(konamiIndex === konamiCode.length) {\n activateEasterEgg();\n konamiIndex = 0; // Reset the index\n }\n } else {\n konamiIndex = 0; // Reset the index if the wrong key is pressed\n }\n }\n\n /**\n * Activates the easter egg when the Konami Code is entered correctly.\n */\n function activateEasterEgg() {\n const bulbasaurAsciiArt = `\n ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠉⢳⠴⢲⠂⠀⠀⠀⠀⠀\n ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⠤⠤⠤⠤⠤⠤⠤⠤⠤⠖⠊⠀⣠⠎⠀⡞⢹⠏⠀⠀⠀⠀\n ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡴⠊⠁⠀⠀⠀⠀⠀⢀⡠⠤⠄⠀⠀⠀⠁⠀⠀⢀⠀⢸⠀⠀⠀⠀⠀\n ⠀⠀⠀⠀⠀⣠⠤⠤⠄⣀⠀⠀⠀⠀⢀⣌⠀⠀⠀⠀⠀⢀⣠⣆⡁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠘⡄⠀⠀⠀⠀\n ⠀⠀⠀⠀⡴⠁⠀⠀⠐⠛⠉⠁⠀⠀⣉⠉⠉⠉⠑⠒⠉⠁⠀⠀⢸⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢧⠀⠱⡀⠀⠀⠀\n ⠀⠀⠀⢰⣥⠆⠀⠀⠀⣠⣴⣶⣿⣿⣿⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⢇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡆⠀⠑⡄⠀⠀\n ⠀⠀⢀⡜⠁⠀⠀⢀⠀⠻⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠀⠀⠸⡀⠀\n ⠀⢀⣮⢖⣧⢠⠀⣿⠇⠀⠀⠁⠀⠀⠀⠠⠀⢀⣠⣴⣤⡀⠀⠀⠀⠈⡗⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⢱⠀\n ⠀⣼⠃⣼⣿⠘⠀⠀⠀⢠⣶⣿⡆⠀⠀⠁⣠⠊⣸⣿⣿⣿⡄⠀⠀⠀⡇⠀⢑⣄⠀⠀⠀⠀⠀⠀⢠⠃⠀⠀⠸⡆\n ⠀⣿⢰⣿⣿⠀⠀⠀⠀⠙⠻⠿⠁⠀⠀⠠⠁⠀⣿⣿⣿⣿⡇⠀⠀⠀⠇⠀⢻⣿⣷⣦⣀⡀⣀⠠⠋⠀⠀⠀⢀⡇\n ⠈⠉⠺⠿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⢿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠈⢿⣿⣿⣿⣿⢦⡀⠀⠀⠀⠀⡸⠀\n ⠘⣟⠦⢀⠀⠀⢠⠀⠀⡠⠀⠀⠀⠀⠀⠀⠉⠉⠉⠉⠁⣀⠔⠀⠀⠀⠀⠀⠀⠀⠛⠻⠟⠋⠀⠙⢦⠀⣠⠜⠀⠀\n ⠀⠈⠑⠤⡙⠳⣶⣦⣤⣤⣤⣤⣤⣤⣤⣤⣴⣶⡶⠞⠁⠀⠀⣠⠖⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠈⢯⠁⠀⠀⠀\n ⠀⠀⠀⠀⠈⢳⠤⣙⡻⠿⣿⣿⣿⣿⡿⠿⠛⠉⠀⢀⣀⡤⡚⠁⠀⠀⠀⠀⠀⠀⣧⠖⣁⣤⣦⠀⠀⠈⢇⠀⠀⠀\n ⠀⠀⠀⠀⠀⢸⠀⢀⣩⣍⠓⠒⣒⠒⠒⠒⠒⠊⠉⠁⢀⡟⠀⠀⣾⣷⠀⠀⠀⠀⠏⢴⣿⣿⣿⠀⠀⠀⢸⠀⠀⠀\n ⠀⠀⠀⠀⠀⠘⣶⣿⣿⣿⠀⠀⠈⠒⢄⣀⡀⠀⠀⠀⣼⣶⣿⡇⠈⠋⠀⠀⠀⡼⠀⠈⠻⣿⡿⠀⠀⠀⢸⠀⠀⠀\n ⠀⠀⠀⠀⠀⠀⠹⡿⠿⠋⠀⠀⠀⠀⡜⠁⠈⢯⡀⢺⣿⣿⣿⠃⠀⠀⠀⢀⣼⣇⠀⠀⠀⠀⠀⠀⠀⠀⡞⠀⠀⠀\n ⠀⠀⠀⠀⠀⠀⠀⣿⣦⣄⣠⣀⣠⠞⠀⠀⠀⠈⠛⣿⡛⠛⠁⠀⠀⠀⣠⠊⠀⠈⢦⣄⣀⣀⣀⣀⢀⡼⠁⠀⠀⠀\n ⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠛⠉⠀⠀⠀⠀⠀⠀⠘⠛⠿⣿⠷⡾⠗⠊⠁⠀⠀⠀⠈⠉⠙⠛⠛⠛⠉⠀⠀⠀⠀⠀\n `;\n console.log(bulbasaurAsciiArt);\n alert('Konami Code activated, check your console!');\n }\n\n document.addEventListener('keydown', checkKonamiCode);\n})();\n","/**\n * Initializes the slideshow functionality on the page.\n */\nfunction initSlideshow() {\n const slideshowBlocks = document.querySelectorAll('.slideshow-block');\n\n slideshowBlocks.forEach((block) => {\n const slideshow = block.querySelector('.slideshow');\n if(!slideshow) return;\n\n const slides = slideshow.getElementsByClassName('slide');\n if(slides.length <= 1) return;\n\n const arrowLeft = slideshow.querySelector('.arrow-left');\n const arrowRight = slideshow.querySelector('.arrow-right');\n const dots = slideshow.querySelectorAll('.indicator');\n\n let slideIndex = 1;\n let startX = 0;\n let startY = 0;\n let isSwiping = false;\n\n showSlide(slideIndex);\n\n arrowLeft.addEventListener('click', () => {\n showSlide((slideIndex -= 1));\n });\n\n arrowRight.addEventListener('click', () => {\n showSlide((slideIndex += 1));\n });\n\n dots.forEach((dot, index) => {\n dot.addEventListener('click', () => {\n showSlide((slideIndex = index + 1));\n });\n });\n\n slideshow.addEventListener('touchstart', handleTouchStart);\n slideshow.addEventListener('touchmove', handleTouchMove);\n slideshow.addEventListener('touchend', handleTouchEnd);\n\n /**\n * Handles the start of a touch event on the slideshow.\n * @param {TouchEvent} event - The touch start event object.\n */\n function handleTouchStart(event) {\n startX = event.touches[0].clientX;\n startY = event.touches[0].clientY;\n isSwiping = true;\n }\n\n /**\n * Handles the movement during a touch event on the slideshow.\n * @param {TouchEvent} event - The touch move event object.\n */\n function handleTouchMove(event) {\n if(!isSwiping) return;\n\n const currentX = event.touches[0].clientX;\n const currentY = event.touches[0].clientY;\n const diffX = startX - currentX;\n const diffY = startY - currentY;\n\n if(Math.abs(diffX) > Math.abs(diffY)) {\n event.preventDefault();\n }\n }\n\n /**\n * Handles the end of a touch event on the slideshow.\n * @param {TouchEvent} event - The touch end event object.\n */\n function handleTouchEnd(event) {\n if(!isSwiping) return;\n\n const currentX = event.changedTouches[0].clientX;\n const diffX = startX - currentX;\n\n if(Math.abs(diffX) > 50) {\n if(diffX > 0) {\n showSlide((slideIndex += 1));\n } else {\n showSlide((slideIndex -= 1));\n }\n }\n\n isSwiping = false;\n }\n\n /**\n * Displays the slide corresponding to the index provided, wrapping around if the index is out of bounds.\n * @param {number} n - The index of the slide to show (1-based).\n */\n function showSlide(n) {\n if(n > slides.length) {\n slideIndex = 1;\n }\n if(n < 1) {\n slideIndex = slides.length;\n }\n for(let i = 0; i < slides.length; i++) {\n slides[i].style.display = 'none';\n }\n for(let i = 0; i < dots.length; i++) {\n dots[i].className = dots[i].className.replace(' current', '');\n }\n slides[slideIndex - 1].style.display = 'block';\n dots[slideIndex - 1].className += ' current';\n }\n });\n}\n\nexport default initSlideshow;\n","/**\n * @param { HTMLElement } element Element to lock the scroll on.\n */\nexport function lockScroll(element) {\n element.style.overflow = 'hidden';\n}\n\n/**\n * @param { HTMLElement } element Element to unlock the scroll on.\n */\nexport function unlockScroll(element) {\n element.style.overflow = 'auto';\n}\n","/**\n * Applies a swipe handler to an element.\n * @param {HTMLElement} element Element to apply the swipe handler to.\n * @param {'right' | 'left'} direction Direction to swipe.\n * @param {() => void} func Function to call on swipe.\n */\nexport function applySwipeHandler(element, direction, func) {\n element.addEventListener('touchstart', handleTouchStart);\n element.addEventListener('touchmove', handleTouchMove);\n element.addEventListener('touchend', () => handleTouchEnd(func));\n\n let touchStartX = 0;\n let touchEndX = 0;\n\n /**\n * Measures the starting touch position.\n * @param {TouchEvent} event Touch event.\n */\n function handleTouchStart(event) {\n touchStartX = event.touches[0].clientX;\n }\n\n /**\n * Measures the starting touch position.\n * @param {TouchEvent} event Touch event.\n */\n function handleTouchMove(event) {\n touchEndX = event.touches[0].clientX;\n }\n\n /**\n * Triggers the swipe function based on the touch start and end positions.\n */\n function handleTouchEnd() {\n if(direction === 'left' && touchEndX < touchStartX || direction === 'right' && touchEndX > touchStartX) {\n func();\n }\n\n touchStartX = 0;\n touchEndX = 0;\n }\n}\n","import { lockFocus, unlockFocus } from './utils/lock-focus';\nimport { lockScroll, unlockScroll } from './utils/lock-scroll.mjs';\nimport { applySwipeHandler } from './utils/mobile-gesture.mjs';\n\nconst GALLERY_MEDIA_SELECTOR = '.caption-media-block';\n\n/**\n * Sets up the gallery modal functionality.\n */\nexport default function setupGalleryModal() {\n const galleries = document.querySelectorAll('.media-gallery-block');\n galleries.forEach(gallery => {\n const modal = gallery.querySelector('.media-gallery-modal');\n\n initOpenModalListeners(gallery);\n initCloseModalListeners(modal);\n initSwitchImageListeners(modal);\n });\n}\n\n/**\n * Initializes the event listeners for opening the modal.\n * @param {HTMLElement} gallery - The gallery element.\n */\nfunction initOpenModalListeners(gallery) {\n const galleryMedia = gallery.querySelectorAll('.gallery .media');\n const seeMoreButton = gallery.querySelector('.overlay-text');\n const modal = gallery.querySelector('.media-gallery-modal');\n\n galleryMedia.forEach(media => {\n const index = media.getAttribute('data-index');\n const correspondingModalMedia = modal.querySelector(`${GALLERY_MEDIA_SELECTOR}[data-index=\"${index}\"]`);\n media.addEventListener('click', () => {\n openModal(modal, correspondingModalMedia);\n });\n\n if(seeMoreButton !== null && index === '2') {\n seeMoreButton.addEventListener('click', () => {\n openModal(modal, correspondingModalMedia);\n });\n }\n });\n}\n\n/**\n * Initializes the event listeners for switching between images in the modal.\n * @param {HTMLElement} modal - The modal element.\n */\nfunction initSwitchImageListeners(modal) {\n const prevButton = modal.querySelector('.prev-button');\n const nextButton = modal.querySelector('.next-button');\n\n prevButton?.addEventListener('click', () => navigateMedia('prev', modal));\n nextButton?.addEventListener('click', () => navigateMedia('next', modal));\n applySwipeHandler(modal, 'left', () => navigateMedia('next', modal));\n applySwipeHandler(modal, 'right', () => navigateMedia('prev', modal));\n}\n\n/**\n * Initializes the event listeners for closing the modal.\n * @param {HTMLElement} modal - The modal element.\n */\nfunction initCloseModalListeners(modal) {\n const modalCloseButton = modal.querySelector('.close-button');\n modalCloseButton.addEventListener('click', () => {\n closeModal(modal);\n });\n\n modal.addEventListener('click', (event) => {\n if(event.target === modal) {\n closeModal(modal);\n }\n });\n}\n\n/**\n * Opens the modal and displays the corresponding media.\n * @param {HTMLElement} modal - The modal element.\n * @param {HTMLElement} correspondingModalMedia - The corresponding media element to display.\n */\nfunction openModal(modal, correspondingModalMedia) {\n modal.classList.add('show');\n //TODO: fix this so that it works please\n lockFocus(modal);\n lockScroll(document.body);\n correspondingModalMedia.classList.add('show');\n\n // Check if the corresponding modal media is the first or last and update button states\n const mediaList = Array.from(modal.querySelectorAll(GALLERY_MEDIA_SELECTOR));\n const index = mediaList.indexOf(correspondingModalMedia);\n toggleButtonState(modal, index, mediaList.length);\n}\n\n/**\n * Toggles the disabled attribute of prev and next buttons based on current index.\n * @param {HTMLElement} modal - The modal element.\n * @param {number} currentIndex - The index of the currently displayed media.\n * @param {number} mediaCount - The total count of media items.\n */\nfunction toggleButtonState(modal, currentIndex, mediaCount) {\n const prevButton = modal.querySelector('.prev-button');\n const nextButton = modal.querySelector('.next-button');\n\n if(prevButton) {\n if(currentIndex === 0) {\n prevButton.setAttribute('disabled', true);\n } else {\n prevButton.removeAttribute('disabled');\n }\n }\n\n if(nextButton) {\n if(currentIndex === mediaCount - 1) {\n nextButton.setAttribute('disabled', true);\n } else {\n nextButton.removeAttribute('disabled');\n }\n }\n}\n\n/**\n * Closes the modal and hides all media elements.\n * @param {HTMLElement} modal - The modal element to close.\n */\nfunction closeModal(modal) {\n modal.classList.remove('show');\n unlockFocus(modal);\n unlockScroll(document.body);\n modal.querySelectorAll(GALLERY_MEDIA_SELECTOR).forEach(media => {\n media.classList.remove('show');\n });\n}\n\n/**\n * Navigates to the previous or next media item within the modal.\n * @param {'next' | 'prev'} direction - The direction to navigate ('next' or 'prev').\n * @param {HTMLElement} modal - The modal element containing media items.\n */\nfunction navigateMedia(direction, modal) {\n const currentMedia = modal.querySelector(`${GALLERY_MEDIA_SELECTOR}.show`);\n const currentIndex = parseInt(currentMedia.getAttribute('data-index'));\n const newIndex = direction === 'prev' ? currentIndex - 1 : currentIndex + 1;\n\n const mediaCount = modal.querySelectorAll(GALLERY_MEDIA_SELECTOR).length;\n const newMedia = modal.querySelector(`${GALLERY_MEDIA_SELECTOR}[data-index=\"${newIndex}\"]`);\n if(newMedia) {\n currentMedia.classList.remove('show');\n newMedia.classList.add('show');\n toggleButtonState(modal, newIndex, mediaCount);\n }\n}\n","/**\n * @callback HTMLElementCallback\n * @param {Element} element\n * @returns {boolean}\n */\n\n/**\n * @param {Element} element\n * @param {HTMLElementCallback} predicate\n * @param {boolean} includeSelf Include the starting element in the search\n * @returns {Element|null} The first ancestor that matches the predicate, or null if no match was found\n */\nexport let firstAnscestorOrDefault = (element, predicate, includeSelf = false) => {\n let parent = includeSelf ? element : element.parentElement;\n\n while(parent) {\n if(predicate(parent)) {\n return parent;\n }\n\n parent = parent.parentElement;\n }\n\n return null;\n};\n","import { firstAnscestorOrDefault } from './utils/dom-utils.mjs';\n\nconst ME_SECONDARY_BUTTON = 2;\n\n/**\n * @param {Element} rootElement\n */\nexport default function apply(rootElement = document.body) {\n const handleClick = (/** @type {MouseEvent} */ event) => {\n if(event.button === ME_SECONDARY_BUTTON) {\n // Ignore right clicks\n return;\n }\n\n /**\n * @type {HTMLElement}\n */\n // @ts-ignore\n const clickedElement = event.target;\n\n const clickTargetAncestor = firstAnscestorOrDefault(clickedElement, element => element.matches('[data-click-target]'));\n if(!clickedElement.matches('[data-click-target]') && !clickTargetAncestor) {\n // No click target found\n return;\n }\n\n const clickIgnoreAncestor = firstAnscestorOrDefault(clickedElement, element => element.matches('[data-click-ignore]'));\n if(clickedElement.matches('[data-click-ignore]') || !!clickIgnoreAncestor) {\n // Click should be ignored\n return;\n }\n\n const ownerElement = clickTargetAncestor ?? clickedElement;\n const clickTarget = ownerElement.getAttribute('data-click-target');\n if(!clickTarget) {\n return;\n }\n\n const targetElement = ownerElement.querySelector(clickTarget);\n if(!targetElement || targetElement === event.target) {\n return;\n }\n\n const newEvent = new window.MouseEvent('click', {\n view: event.view,\n bubbles: true,\n cancelable: true,\n button: event.button,\n buttons: event.buttons\n });\n\n targetElement.dispatchEvent(newEvent);\n\n event.preventDefault();\n event.stopPropagation();\n };\n\n rootElement.addEventListener('click', handleClick);\n rootElement.addEventListener('mouseup', handleClick);\n}\n","import { onScroll } from './utils/scroll.mjs';\n\nconst NOT_TRANSPARENT_CLASS = 'not-transparent';\n\n/**\n * This function applies the background to the menu-container\n * if the header has the no-background class.\n * @param {Element} rootElement - The root element to search within, defaults to document.body.\n */\nexport default function applyBackgroundChange(rootElement = document.body) {\n const header = rootElement.querySelector('.header');\n const menuContainer = rootElement.querySelector('.menu-container');\n\n let removeScrollHandler;\n\n const updateMenuBackground = () => {\n if(header.classList.contains('no-background')) {\n menuContainer.classList.add(NOT_TRANSPARENT_CLASS);\n removeScrollHandler?.();\n } else {\n menuContainer.classList.remove(NOT_TRANSPARENT_CLASS);\n removeScrollHandler = setOnScroll(menuContainer);\n }\n };\n\n updateMenuBackground();\n\n const observer = new MutationObserver(updateMenuBackground);\n observer.observe(header, { attributes: true, attributeFilter: ['class'] });\n}\n\n/**\n * @param {Element} menuContainer Menu container\n * @returns {Function} Abort function for the scroll event listener.\n */\nfunction setOnScroll(menuContainer) {\n return onScroll(({isBeyondThreshold}) => {\n if(isBeyondThreshold) {\n menuContainer.classList.add(NOT_TRANSPARENT_CLASS);\n } else {\n menuContainer.classList.remove(NOT_TRANSPARENT_CLASS);\n }\n }, 150);\n}\n","/**\n * Initializes the pagination functionality.\n */\nexport default function initPagination() {\n const paginationForm = getPaginationForm();\n const currentPage = document.querySelector('#page');\n\n const pageButtons = document.querySelectorAll('.pagination .page-button');\n\n if(paginationForm) {\n paginationForm.addEventListener('submit', function() {\n currentPage.value = '1';\n });\n }\n\n const next = document.querySelector('#next');\n const previous = document.querySelector('#previous');\n\n pageButtons.forEach(function(pageButton) {\n pageButton.addEventListener('click', function() {\n currentPage.value = pageButton.value;\n submitPaginationForm();\n });\n });\n\n if(next) {\n next.addEventListener('click', function() {\n const value = currentPage.value;\n currentPage.value = (parseInt(value) + 1).toString();\n submitPaginationForm();\n });\n }\n\n if(previous) {\n previous.addEventListener('click', function() {\n const value = currentPage.value;\n currentPage.value = (parseInt(value) - 1).toString();\n submitPaginationForm();\n });\n }\n\n /**\n * Submits the pagination form.\n */\n function submitPaginationForm() {\n const selectedInput = document.querySelector('#selected-input');\n const selectedCategory = document.querySelector('.category-button.selected');\n\n if(selectedInput && (selectedInput.value === undefined || selectedInput.value === null || selectedInput.value === 'Alla')) {\n if(selectedCategory) {\n selectedInput.value = selectedCategory.value;\n }\n }\n\n if(paginationForm) {\n paginationForm.submit();\n }\n }\n\n /**\n * Retrieves the pagination form.\n * @returns {HTMLFormElement|null} The pagination form or null if not found.\n */\n function getPaginationForm() {\n const forms = document.querySelectorAll('form');\n\n for(let i = 0; i < forms.length; i++) {\n const form = forms[i];\n const pageInput = form.querySelector('#page');\n\n if(pageInput !== null) {\n return form;\n }\n }\n\n return null;\n }\n}\n","import '../styles/fonts.scss';\nimport '../styles/main.scss';\nimport accordionAnimation from './utils/accordion.mjs';\nimport initMainMenu from './main-menu';\nimport initAnimations from './setup-animations.mjs';\nimport './konamiCode';\nimport initSlideshow from './slideshow.js';\nimport setupGalleryModal from './media-gallery';\nimport applyClickableContainers from './clickable-containers.mjs';\nimport applyBackgroundChange from './menu-background.mjs';\nimport initPagination from './pagination.mjs';\n\ninitMainMenu();\naccordionAnimation('.faq-item details', '.faq-answer');\ninitAnimations();\ninitSlideshow();\nsetupGalleryModal();\napplyClickableContainers();\napplyBackgroundChange();\ninitPagination();\n\n"],"names":["accordionAnimation","detailsSelector","contentSelector","el","summary","content","animation","isClosing","isExpanding","e","openAccordion","shrinkAccordion","startHeight","endHeight","onAnimationFinish","expandAccordion","open","toggleOverlay","element","toggleNoScroll","focusStack","lockFocus","handler","createFocusHandler","toggleIframeTabindex","unlockFocus","unlockedHandler","topElement","topHandler","event","disable","iFrame","onScroll","handleScroll","threshold","lastScrollTop","abortSignal","scrollTop","scrollThreshold","isScrollingDown","isBeyondThreshold","init","initMenuToggle","handleMenuButtonClick","menuContainer","overlay","toggleIsActive","mobileMenu","openMenuButton","setMenuCollapse","collapse","menu","button","topRow","animate","delay","setupEnterScreenAnimations","selectors","elementsToFadeUpOnEnterScreen","triggerOnEnterScreen","enterScreenCallback","elements","enterScreenObserver","entries","entry","initAnimations","initEnterScreenAnimations","initHeaderAnimations","header","heading","ingress","konamiCode","konamiIndex","checkKonamiCode","activateEasterEgg","initSlideshow","block","slideshow","slides","arrowLeft","arrowRight","dots","slideIndex","startX","startY","isSwiping","showSlide","dot","index","handleTouchStart","handleTouchMove","handleTouchEnd","currentX","currentY","diffX","diffY","n","i","lockScroll","unlockScroll","applySwipeHandler","direction","func","touchStartX","touchEndX","GALLERY_MEDIA_SELECTOR","setupGalleryModal","gallery","modal","initOpenModalListeners","initCloseModalListeners","initSwitchImageListeners","galleryMedia","seeMoreButton","media","correspondingModalMedia","openModal","prevButton","nextButton","navigateMedia","closeModal","mediaList","toggleButtonState","currentIndex","mediaCount","currentMedia","newIndex","newMedia","firstAnscestorOrDefault","predicate","includeSelf","parent","ME_SECONDARY_BUTTON","apply","rootElement","handleClick","clickedElement","clickTargetAncestor","clickIgnoreAncestor","ownerElement","clickTarget","targetElement","newEvent","NOT_TRANSPARENT_CLASS","applyBackgroundChange","removeScrollHandler","updateMenuBackground","setOnScroll","initPagination","paginationForm","getPaginationForm","currentPage","pageButtons","next","previous","pageButton","submitPaginationForm","value","selectedInput","selectedCategory","forms","form","initMainMenu","applyClickableContainers"],"mappings":"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"}