{"version":3,"file":"header-section-xxxxxxxxxxxxxxxxxxxx.min.js","mappings":"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","sources":["webpack://lange/webpack/runtime/load script","webpack://lange/./scripts/sections/header/sticky-header.ts","webpack://lange/webpack/bootstrap","webpack://lange/webpack/runtime/define property getters","webpack://lange/webpack/runtime/ensure chunk","webpack://lange/webpack/runtime/get javascript chunk filename","webpack://lange/webpack/runtime/get mini-css chunk filename","webpack://lange/webpack/runtime/hasOwnProperty shorthand","webpack://lange/webpack/runtime/publicPath","webpack://lange/webpack/runtime/jsonp chunk loading","webpack://lange/./scripts/sections/header/search-panel-manager/index.ts","webpack://lange/./scripts/lib/debounce.ts","webpack://lange/./scripts/sections/header/search-input/index.ts","webpack://lange/./scripts/sections/header/search-input/index.scss","webpack://lange/./scripts/sections/header/search-input/index.html","webpack://lange/./scripts/sections/header/search-panel/index.ts","webpack://lange/./scripts/sections/header/search-panel/index.scss","webpack://lange/./scripts/sections/header/search-panel/index.html","webpack://lange/./scripts/sections/header/search-panel/get-search-results.ts","webpack://lange/./scripts/sections/header/main-menu-manager/index.ts","webpack://lange/./scripts/lib/splide-slidebar-extension.ts","webpack://lange/./scripts/lib/webpack-path.ts","webpack://lange/./scripts/sections/header/mobile-menu-manager/index.ts","webpack://lange/./scripts/sections/header/top-banner-carousel.ts","webpack://lange/./scripts/sections/header/countdown-timer.ts","webpack://lange/./scripts/sections/header/top-banner/index.ts","webpack://lange/./scripts/sections/header/top-banner/index.scss","webpack://lange/./scripts/sections/header/top-banner/index.html"],"sourcesContent":["var inProgress = {};\nvar dataWebpackPrefix = \"lange:\";\n// loadScript function to load a script via script tag\n__webpack_require__.l = function(url, done, key, chunkId) {\n\tif(inProgress[url]) { inProgress[url].push(done); return; }\n\tvar script, needAttach;\n\tif(key !== undefined) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tfor(var i = 0; i < scripts.length; i++) {\n\t\t\tvar s = scripts[i];\n\t\t\tif(s.getAttribute(\"src\") == url || s.getAttribute(\"data-webpack\") == dataWebpackPrefix + key) { script = s; break; }\n\t\t}\n\t}\n\tif(!script) {\n\t\tneedAttach = true;\n\t\tscript = document.createElement('script');\n\n\t\tscript.charset = 'utf-8';\n\t\tscript.timeout = 120;\n\t\tif (__webpack_require__.nc) {\n\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n\t\t}\n\t\tscript.setAttribute(\"data-webpack\", dataWebpackPrefix + key);\n\n\t\tscript.src = url;\n\t}\n\tinProgress[url] = [done];\n\tvar onScriptComplete = function(prev, event) {\n\t\t// avoid mem leaks in IE.\n\t\tscript.onerror = script.onload = null;\n\t\tclearTimeout(timeout);\n\t\tvar doneFns = inProgress[url];\n\t\tdelete inProgress[url];\n\t\tscript.parentNode && script.parentNode.removeChild(script);\n\t\tdoneFns && doneFns.forEach(function(fn) { return fn(event); });\n\t\tif(prev) return prev(event);\n\t}\n\tvar timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);\n\tscript.onerror = onScriptComplete.bind(null, script.onerror);\n\tscript.onload = onScriptComplete.bind(null, script.onload);\n\tneedAttach && document.head.appendChild(script);\n};","let header: HTMLElement;\nlet mainMenu: HTMLElement;\nlet container: HTMLElement;\n\nfunction onDOMContentLoaded() {\n  header = document.querySelector<HTMLElement>('#shopify-section-header');\n  mainMenu = document.querySelector<HTMLElement>('#main-menu');\n  container = document.querySelector<HTMLElement>('#shopify-section-header .header-container');\n  if (!header || !mainMenu || !container) {\n    console.warn('sticky header: header, main menu or container not found');\n    return;\n  }\n\n  // intersection observer is used to detect when the header becomes sticky or unstuck, it's\n  // necessary to apply different styles in each state on desktop.\n  const intersectionObserver = new IntersectionObserver((entries) => {\n    for (const entry of entries) {\n      if (entry.intersectionRatio < 1) {\n        header.classList.remove('unstuck');\n        header.classList.add('stuck');\n      } else {\n        if (header.classList.contains('stuck')) {\n          header.classList.remove('stuck');\n          header.classList.add('unstuck');\n        }\n      }\n    }\n  }, {\n    rootMargin: '-1px 0px 0px 0px', // Trigger when header moves up by 1px\n    threshold: 1 // Trigger when less than 100% visible\n  });\n\n  // Resize observer is used to update the top offset CSS variable when the header size changes\n  const resizeObserver = new ResizeObserver((_entries) => {\n    const newOffsetTop = calculateTopOffset();\n    header.style.setProperty('--sticky-offset-top', `${newOffsetTop}px`);\n\n    // on mobile, the main menu is hidden, so we don't need to observe it\n    if (mainMenu.offsetParent === null) {\n      intersectionObserver.disconnect();\n      mainMenu.classList.remove('stuck');\n      mainMenu.classList.remove('unstuck');\n    } else {\n      intersectionObserver.observe(mainMenu);\n    }\n  });\n  resizeObserver.observe(header);\n}\n\n/**\n * Calculates the top offset for the sticky header.\n */\nfunction calculateTopOffset() {\n  if (mainMenu.offsetParent === null) {\n    // the main menu is hidden on mobile, so we use the container height instead\n    return container.offsetHeight - header.offsetHeight + 1;\n  }\n\n  // The offset is the distance from the top of the page to the top of the main menu\n  return mainMenu.offsetHeight - header.offsetHeight + 1;\n}\n\ndocument.addEventListener('DOMContentLoaded', onDOMContentLoaded);\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = function(chunkId) {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce(function(promises, key) {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks\n__webpack_require__.u = function(chunkId) {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \"-\" + \"4c2b34155a625ff7db66\" + \".min.js\";\n};","// This function allow to reference async chunks\n__webpack_require__.miniCssF = function(chunkId) {\n\t// return url for filenames based on template\n\treturn undefined;\n};","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","__webpack_require__.p = \"\";","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t\"header-section\": 0\n};\n\n__webpack_require__.f.j = function(chunkId, promises) {\n\t\t// JSONP chunk loading for javascript\n\t\tvar installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;\n\t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n\t\t\t// a Promise means \"currently loading\".\n\t\t\tif(installedChunkData) {\n\t\t\t\tpromises.push(installedChunkData[2]);\n\t\t\t} else {\n\t\t\t\tif(true) { // all chunks have JS\n\t\t\t\t\t// setup Promise in chunk cache\n\t\t\t\t\tvar promise = new Promise(function(resolve, reject) { installedChunkData = installedChunks[chunkId] = [resolve, reject]; });\n\t\t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n\t\t\t\t\t// start chunk loading\n\t\t\t\t\tvar url = __webpack_require__.p + __webpack_require__.u(chunkId);\n\t\t\t\t\t// create error before stack unwound to get useful stacktrace later\n\t\t\t\t\tvar error = new Error();\n\t\t\t\t\tvar loadingEnded = function(event) {\n\t\t\t\t\t\tif(__webpack_require__.o(installedChunks, chunkId)) {\n\t\t\t\t\t\t\tinstalledChunkData = installedChunks[chunkId];\n\t\t\t\t\t\t\tif(installedChunkData !== 0) installedChunks[chunkId] = undefined;\n\t\t\t\t\t\t\tif(installedChunkData) {\n\t\t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n\t\t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n\t\t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n\t\t\t\t\t\t\t\terror.type = errorType;\n\t\t\t\t\t\t\t\terror.request = realSrc;\n\t\t\t\t\t\t\t\tinstalledChunkData[1](error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\t__webpack_require__.l(url, loadingEnded, \"chunk-\" + chunkId, chunkId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n};\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n// no on chunks loaded\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunklange\"] = self[\"webpackChunklange\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","import { CustomElement } from '@integrabeauty/custom-elements';\n\n/**\n * Manages the search panel behavior. Listens for show and close requests and handles the panel\n * visibility and positioning. Also interacts with a modal system to display the panel as a modal.\n */\nclass SearchPanelManager extends HTMLElement implements CustomElement {\n  public shadowRoot!: ShadowRoot;\n\n  /**\n   * Stores the element to return focus to when the search panel is closed.\n   */\n  private returnFocusTo: HTMLElement;\n\n  private onSearchPanelShowRequestedBound = this.onSearchPanelShowRequested.bind(this);\n  private onSearchPanelCloseRequestedBound = this.onSearchPanelCloseRequested.bind(this);\n  private onShroudClickedBound = this.onShroudClicked.bind(this);\n  private onAddToCardBound = this.onAddToCard.bind(this);\n\n  public constructor() {\n    super();\n  }\n\n  public connectedCallback() {\n    addEventListener('search-panel-show-requested', this.onSearchPanelShowRequestedBound);\n    addEventListener('search-panel-close-requested', this.onSearchPanelCloseRequestedBound);\n    addEventListener('shroud-clicked', this.onShroudClickedBound);\n    addEventListener('ofir-add-to-cart', this.onAddToCardBound);\n  }\n\n  public disconnectedCallback() {\n    removeEventListener('search-panel-show-requested', this.onSearchPanelShowRequestedBound);\n    removeEventListener('search-panel-close-requested', this.onSearchPanelCloseRequestedBound);\n    removeEventListener('shroud-clicked', this.onShroudClickedBound);\n    removeEventListener('ofir-add-to-cart', this.onAddToCardBound);\n  }\n\n  private onSearchPanelShowRequested(event: WindowEventMap['search-panel-show-requested']) {\n    if (event.detail.returnFocusTo) {\n      this.returnFocusTo = event.detail.returnFocusTo;\n    }\n\n    this.showPanel();\n  }\n\n  private onSearchPanelCloseRequested(_event: WindowEventMap['search-panel-close-requested']) {\n    this.closePanel();\n  }\n\n  private onShroudClicked(event: WindowEventMap['shroud-clicked']) {\n    const searchPanel = this.querySelector('search-panel');\n    if (event.detail.element === searchPanel) {\n      this.closePanel();\n    }\n  }\n\n  /**\n   * Handles the event when an item is added to the cart.\n   * If a user adds an item to the cart while the search panel is active, the panel should be\n   * closed so the search panel does not obstruct the view of the cart modal.\n   */\n  private onAddToCard(_event: Event) {\n    const searchPanel = this.querySelector<HTMLElement>('search-panel');\n    const isActive = searchPanel.dataset.active === 'true';\n    if (isActive) {\n      this.closePanel();\n    }\n  }\n\n  private showPanel() {\n    type Element = HTMLElementTagNameMap['search-panel'];\n    const searchPanel = this.querySelector<Element>('search-panel');\n    searchPanel.dataset.active = 'true';\n\n    const headerOffsetBottom = getHeaderOffsetBottom();\n    searchPanel.style.top = `${headerOffsetBottom}px`;\n    searchPanel.focus();\n\n    type Detail = WindowEventMap['modal-show-requested']['detail'];\n    const modalShowEvent = new CustomEvent<Detail>('modal-show-requested', {\n      detail: { element: searchPanel }\n    });\n    dispatchEvent(modalShowEvent);\n  }\n\n  private closePanel() {\n    type Element = HTMLElementTagNameMap['search-panel'];\n    const searchPanel = this.querySelector<Element>('search-panel');\n    searchPanel.dataset.active = 'false';\n\n    if (this.returnFocusTo) {\n      // return focus to the element that requested the panel. Delay to ensure inert attributes are\n      // removed. The inert attribute are controlled by the modal manager, this functionality should\n      // be moved to the modal manager in the future.\n      setTimeout(() => {\n        this.returnFocusTo.focus();\n        this.returnFocusTo = null;\n      }, 100);\n    }\n\n    type Detail = WindowEventMap['modal-close-requested']['detail'];\n    const modalCloseEvent = new CustomEvent<Detail>('modal-close-requested', {\n      detail: { element: searchPanel }\n    });\n    dispatchEvent(modalCloseEvent);\n  }\n}\n\nfunction getHeaderOffsetBottom() {\n  const header = document.querySelector<HTMLElement>('#shopify-section-header');\n  const headerRect = header.getBoundingClientRect();\n  return headerRect.height + headerRect.top;\n}\n\n// TODO move return focus functionality to the modal-manager like on Lange to be default behavior\n// for all modals\ntype SearchPanelShowRequestedEvent = CustomEvent<{\n  returnFocusTo?: HTMLElement;\n}>;\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'search-panel-manager': SearchPanelManager;\n  }\n\n  interface WindowEventMap {\n    'search-panel-close-requested': CustomEvent;\n    'search-panel-show-requested': SearchPanelShowRequestedEvent;\n  }\n}\n\nif (!customElements.get('search-panel-manager')) {\n  customElements.define('search-panel-manager', SearchPanelManager);\n}\n","export default function debounce<F extends (...params: any[])=> unknown>(func: F, timeout = 300) {\n  let timer: ReturnType<typeof setTimeout> = null;\n  return (...args: unknown[]) => {\n    clearTimeout(timer);\n    timer = setTimeout(() => func(...args), timeout);\n  };\n}\n","import type { CustomElement } from '@integrabeauty/custom-elements';\nimport debounce from '../../../lib/debounce';\nimport html from './index.html';\nimport styles from './index.scss';\n\n/**\n * Search input component with an input field, a submit button, and a clear button.\n * Dispatches 'search-input-changed' events when the input value changes so the parent component\n * can handle the search logic.\n */\nclass SearchInput extends HTMLElement implements CustomElement {\n  public shadowRoot!: ShadowRoot;\n  private onInputBound = this.onInput.bind(this);\n  private onSubmitBound = this.onSubmit.bind(this);\n  private onResetBound = this.onReset.bind(this);\n  private onCloseClickedBound = this.onCloseClicked.bind(this);\n  private onShroudClickedBound = this.onShroudClicked.bind(this);\n  private sendSearchInputChangedEventBound = this.sendSearchInputChangedEvent.bind(this);\n  private sendSearchInputChangedEventDebounced =\n    debounce(this.sendSearchInputChangedEventBound, 250);\n\n  public constructor() {\n    super();\n    // delegatesFocus allows the shadow DOM to forward focus to the input element when the search\n    // modal is opened.\n    this.attachShadow({ mode: 'open', delegatesFocus: true });\n    this.shadowRoot.innerHTML = `<style>${styles}</style>${html}`;\n  }\n\n  public connectedCallback() {\n    this.render();\n  }\n\n  public disconnectedCallback() {\n    const input = this.shadowRoot.querySelector('input');\n    input.removeEventListener('input', this.onInputBound);\n\n    const form = this.shadowRoot.querySelector('form');\n    form.removeEventListener('submit', this.onSubmitBound);\n    form.removeEventListener('reset', this.onResetBound);\n\n    const closeButton = this.shadowRoot.querySelector<HTMLElement>('.close');\n    closeButton.removeEventListener('click', this.onCloseClickedBound);\n\n    removeEventListener('shroud-clicked', this.onShroudClickedBound);\n  }\n\n  private render() {\n    const input = this.shadowRoot.querySelector('input');\n    input.addEventListener('input', this.onInputBound);\n\n    const form = this.shadowRoot.querySelector('form');\n    form.addEventListener('submit', this.onSubmitBound);\n    form.addEventListener('reset', this.onResetBound);\n\n    const closeButton = this.shadowRoot.querySelector<HTMLElement>('.close');\n    closeButton.addEventListener('click', this.onCloseClickedBound);\n\n    addEventListener('shroud-clicked', this.onShroudClickedBound);\n  }\n\n  /**\n   * Handles the search input field input event.\n   */\n  private onInput(event: Event) {\n    const input = <HTMLInputElement>event.target;\n    const clearButton = this.shadowRoot.querySelector<HTMLButtonElement>('button[type=\"reset\"]');\n    const query = input.value.trim();\n    clearButton.disabled = query === '';\n    this.sendSearchInputChangedEventDebounced(query);\n  }\n\n  /**\n   * Handles the form submit event.\n   */\n  private onSubmit(event: Event) {\n    event.preventDefault();\n    const input = this.shadowRoot.querySelector<HTMLInputElement>('input');\n    const query = input.value.trim();\n    if (query === '') {\n      return;\n    }\n\n    this.sendSearchInputChangedEvent(query);\n  }\n\n  /**\n   * Handles the form reset event.\n   */\n  private onReset(_event: Event) {\n    // disable the clear button. oninput listener controls its state based on input value but input\n    // event is not called on reset as well as change event.\n    const clearButton = this.shadowRoot.querySelector<HTMLButtonElement>('button[type=\"reset\"]');\n    clearButton.disabled = true;\n\n    // Reset focus on the input field. Because of delegatesFocus, focusing the root will focus the\n    // input.\n    this.focus();\n\n    this.sendSearchInputChangedEvent('');\n  }\n\n  /**\n   * Handles the close button click event.\n   * Resets the form, disables the clear button, and dispatches a 'search-panel-close-requested'\n   * event.\n   */\n  private onCloseClicked(_event: Event) {\n    const form = this.shadowRoot.querySelector('form');\n    form.reset();\n\n    const clearButton = this.shadowRoot.querySelector<HTMLButtonElement>('button[type=\"reset\"]');\n    clearButton.disabled = true;\n\n    const event = new Event('search-panel-close-requested');\n    dispatchEvent(event);\n  }\n\n  /**\n   * Handles the shroud clicked event.\n   * Resets the form and disables the clear button. We don't need to dispatch any event here\n   * because the parent component is already listening to the 'shroud-clicked' event.\n   */\n  private onShroudClicked(event: WindowEventMap['shroud-clicked']) {\n    if (!event.detail || !event.detail.element) {\n      return;\n    }\n\n    // Only reset the form if the search panel shroud was clicked, not any other shroud (e.g. cart\n    // drawer shroud).\n    if (event.detail.element.tagName !== 'SEARCH-PANEL') {\n      return;\n    }\n\n    const form = this.shadowRoot.querySelector('form');\n    form.reset();\n\n    const clearButton = this.shadowRoot.querySelector<HTMLButtonElement>('button[type=\"reset\"]');\n    clearButton.disabled = true;\n  }\n\n  /**\n   * Dispatches a 'search-input-changed' event with the given query.\n   * It should be debounced because it's called on every input event.\n   */\n  private sendSearchInputChangedEvent(query: string) {\n    type Detail = HTMLElementEventMap['search-input-changed']['detail'];\n    const customEvent = new CustomEvent<Detail>('search-input-changed', {\n      detail: {\n        query\n      }\n    });\n    this.dispatchEvent(customEvent);\n  }\n}\n\ntype SearchInputChangedEvent = CustomEvent<{\n  query: string;\n}>;\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'search-input': SearchInput;\n  }\n\n  interface HTMLElementEventMap {\n    'search-input-changed': SearchInputChangedEvent;\n  }\n}\n\nif (!customElements.get('search-input')) {\n  customElements.define('search-input', SearchInput);\n}\n","export default \":host{position:relative}button{appearance:none;background:#0000;border:0;cursor:pointer;font:inherit;outline:inherit;padding:0}button:focus{outline:none}button:focus-visible{outline:2px solid #000;outline-offset:1px}form{align-items:center;border-bottom:1px solid;column-gap:16px;display:flex;justify-content:space-between}input{appearance:none;border:none;flex-grow:1;font-family:inherit;font-size:inherit;line-height:1;padding-bottom:20px;padding-top:20px;width:50%}input:focus{outline:none}input:focus-visible{outline:2px solid #000;outline-offset:-1px}button[type=reset]:disabled{display:none}.close svg{display:block;height:14px;width:14px}.visually-hidden{height:1px;overflow:hidden;position:absolute;width:1px;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);white-space:nowrap}\";","// Module\nvar code = \"<form action=\\\"/search\\\"><svg width=\\\"24\\\" height=\\\"24\\\" viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M22 21.1627L16.6245 15.9453C19.4071 12.5959 19.2806 7.57184 16.1818 4.41567C13.083 1.25951 7.64427 1.13069 4.41897 4.41567C1.19368 7.70066 1.19368 13.1112 4.41897 16.3962C6.06324 18.0709 8.1502 18.8438 10.3004 18.8438C12.4506 18.8438 14.1581 18.1353 15.7391 16.7827L21.1146 22L22 21.0982V21.1627ZM5.30434 15.4944C2.52174 12.6603 2.52174 8.15153 5.30434 5.31743C6.69565 3.90038 8.4664 3.19184 10.3004 3.19184C12.1344 3.19184 13.9051 3.90038 15.2964 5.31743C18.079 8.15153 18.079 12.6603 15.2964 15.4944C12.5138 18.3285 8.08695 18.3285 5.30434 15.4944Z\\\" fill=\\\"black\\\"></path></svg><label for=\\\"search\\\" class=\\\"visually-hidden\\\">Search</label><input id=\\\"search\\\" type=\\\"text\\\" name=\\\"q\\\" value=\\\"\\\" placeholder=\\\"Search\\\" autocomplete=\\\"off\\\"><button type=\\\"reset\\\" disabled=\\\"disabled\\\">Clear</button><button class=\\\"close\\\" type=\\\"button\\\" aria-label=\\\"Close search\\\"><svg viewBox=\\\"0 0 17 17\\\" fill=\\\"none\\\" stroke=\\\"#000\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" id=\\\"icon-close\\\"><path d=\\\"M1 1L16 16\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\"/><path d=\\\"M16 1L1 16\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\"/></svg></button></form>\";\n// Exports\nexport default code;","import { CustomElement } from '@integrabeauty/custom-elements';\nimport getSearchResults from './get-search-results';\nimport html from './index.html';\nimport styles from './index.scss';\n\n/**\n * Search panel with an input and search results triggered by the search button in the header\n */\nclass SearchPanel extends HTMLElement implements CustomElement {\n  readonly dataset!: {\n    /**\n     * Indicates whether the search panel is active (open) or not.\n     */\n    active: 'false' | 'true';\n  };\n\n  public shadowRoot!: ShadowRoot;\n  private onSearchInputChangedBound = this.onSearchInputChanged.bind(this);\n  private onSearchPanelCloseRequestedBound = this.onSearchPanelCloseRequested.bind(this);\n\n  public constructor() {\n    super();\n    this.attachShadow({ mode: 'open', delegatesFocus: true });\n    this.shadowRoot.innerHTML = `<style>${styles}</style>${html}`;\n  }\n\n  public connectedCallback() {\n    this.render();\n  }\n\n  public disconnectedCallback() {\n    type SearchInput = HTMLElementTagNameMap['search-input'];\n    const searchInput = this.shadowRoot.querySelector<SearchInput>('search-input');\n    searchInput.removeEventListener('search-input-changed', this.onSearchInputChangedBound);\n\n    removeEventListener('search-panel-close-requested', this.onSearchPanelCloseRequestedBound);\n  }\n\n  private render() {\n    type SearchInput = HTMLElementTagNameMap['search-input'];\n    const searchInput = this.shadowRoot.querySelector<SearchInput>('search-input');\n    searchInput.addEventListener('search-input-changed', this.onSearchInputChangedBound);\n\n    addEventListener('search-panel-close-requested', this.onSearchPanelCloseRequestedBound);\n  }\n\n  private async onSearchInputChanged(event: HTMLElementEventMap['search-input-changed']) {\n    this.renderSearchResults('');\n\n    if (!event.detail.query) {\n      return;\n    }\n\n    this.showLoader();\n\n    try {\n      const response = await getSearchResults(event.detail.query);\n\n      if (!response.ok) {\n        const error = new Error(response.statusText);\n        console.error(error);\n        // this.hideDropdown();\n        throw error;\n      }\n\n      const html = await response.text();\n      this.renderSearchResults(html);\n    } catch (e) {\n      console.log(e);\n      this.renderSearchResults('');\n    }\n  }\n\n  private onSearchPanelCloseRequested(_event: WindowEventMap['search-panel-close-requested']) {\n    this.renderSearchResults('');\n  }\n\n  private showLoader() {\n    const loader = this.shadowRoot.querySelector<HTMLElement>('.loader');\n    loader.classList.remove('hidden');\n  }\n\n  private hideLoader() {\n    const loader = this.shadowRoot.querySelector<HTMLElement>('.loader');\n    loader.classList.add('hidden');\n  }\n\n  private renderSearchResults(html: string) {\n    this.innerHTML = html;\n    this.hideLoader();\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'search-panel': SearchPanel;\n  }\n}\n\nif (!customElements.get('search-panel')) {\n  customElements.define('search-panel', SearchPanel);\n}\n","export default \":host{background-color:#fff;bottom:0;left:0;overflow-y:auto;position:fixed;right:0;top:152px;z-index:510}:host([data-active=false]){display:none}.header{background-color:#fff;padding:16px 16px 32px;position:sticky;top:0;z-index:1}.container{box-sizing:initial;margin-left:auto;margin-right:auto;max-width:1600px;padding-bottom:64px}.results{padding-left:16px;padding-right:16px}.loader{align-items:center;animation:loader 1s linear infinite;border:5px solid #cdcfd1;border-bottom-color:#0000;border-radius:50%;box-sizing:border-box;display:flex;height:48px;justify-content:center;margin-left:auto;margin-right:auto;width:48px}@keyframes loader{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.visually-hidden{height:1px;overflow:hidden;position:absolute;width:1px;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);white-space:nowrap}.hidden{display:none}\";","// Module\nvar code = \"<div class=\\\"container\\\"><h2 class=\\\"visually-hidden\\\">Search Modal</h2><div class=\\\"header\\\"><search-input></search-input></div><div class=\\\"results\\\"><slot></slot></div><div class=\\\"loader hidden\\\"></div></div>\";\n// Exports\nexport default code;","/**\n * Fetch search results for the given query.\n *\n * This is a request to the search suggestions endpoint with the additional section_id parameter.\n * It says to Shopify that we want the rendered search-results.liquid section HTML to be returned in\n * the response.\n *\n * @see https://shopify.dev/docs/api/ajax/reference/predictive-search#get--locale-search-suggest\n */\nexport default function getSearchResults(query: string) {\n  const params = new URLSearchParams();\n\n  // The search query.\n  params.set('q', query);\n\n  // Searching only for products.\n  params.set('resources[type]', 'product');\n\n  // Section name. Shopify will render `search-results.liquid` and return its HTML.\n  params.set('section_id', 'search-results');\n\n  const url = `/search/suggest?${params}`;\n  return fetch(url);\n}\n","import { CustomElement } from '@integrabeauty/custom-elements';\n\n/**\n * Manages the main menu panels behavior.\n */\nclass MainMenuManager extends HTMLElement implements CustomElement {\n  public shadowRoot!: ShadowRoot;\n  private activePanel: string;\n\n  private onDOMContentLoadedBound = this.onDOMContentLoaded.bind(this);\n  private onButtonClickedBound = this.onButtonClicked.bind(this);\n  private onHamburgerButtonClickedBound = this.onHamburgerButtonClicked.bind(this);\n  private onPointerEnterBound = this.onPointerEnter.bind(this);\n  private onMainMenuMouseLeaveBound = this.onMainMenuMouseLeave.bind(this);\n  private onPanelMouseLeaveBound = this.onPanelMouseLeave.bind(this);\n\n  public constructor() {\n    super();\n  }\n\n  public connectedCallback() {\n    addEventListener('DOMContentLoaded', this.onDOMContentLoadedBound);\n  }\n\n  public disconnectedCallback() {\n    removeEventListener('DOMContentLoaded', this.onDOMContentLoadedBound);\n\n    const panelButtons = this.querySelectorAll<HTMLButtonElement>('.menu-panel-button');\n    for (const button of panelButtons) {\n      button.removeEventListener('click', this.onButtonClickedBound);\n      button.removeEventListener('pointerdown', onPointerDown);\n      button.removeEventListener('pointerenter', this.onPointerEnterBound);\n    }\n\n    const hamburgerButton = this.querySelector('#main-menu-hamburger');\n    if (hamburgerButton) {\n      hamburgerButton.removeEventListener('click', this.onHamburgerButtonClickedBound);\n    }\n\n    const panels = this.querySelectorAll<HTMLElement>('.menu-panel:not(#menu-panel-main-mobile)');\n    for (const panel of panels) {\n      panel.removeEventListener('mouseleave', this.onPanelMouseLeaveBound);\n    }\n\n    const searchButton = this.querySelector('.search-button');\n    if (searchButton) {\n      searchButton.removeEventListener('click', onSearchClicked);\n    }\n\n    const cartButton = this.querySelector('#cart-link');\n    if (cartButton) {\n      searchButton.removeEventListener('click', onCartClicked);\n    }\n\n    const mainMenu = this.querySelector<HTMLElement>('#main-menu');\n    mainMenu.removeEventListener('mouseleave', this.onMainMenuMouseLeaveBound);\n  }\n\n  private onDOMContentLoaded() {\n    const panelButtons = this.querySelectorAll<HTMLElement>('.menu-panel-button');\n    for (const button of panelButtons) {\n      button.addEventListener('click', this.onButtonClickedBound);\n      button.addEventListener('pointerdown', onPointerDown);\n      button.addEventListener('pointerenter', this.onPointerEnterBound);\n    }\n\n    const hamburgerButton = this.querySelector('#main-menu-hamburger');\n    if (hamburgerButton) {\n      hamburgerButton.addEventListener('click', this.onHamburgerButtonClickedBound);\n    }\n\n    const panels = this.querySelectorAll<HTMLElement>('.menu-panel:not(#menu-panel-main-mobile)');\n    for (const panel of panels) {\n      panel.addEventListener('mouseleave', this.onPanelMouseLeaveBound);\n    }\n\n    const searchButton = this.querySelector('.search-button');\n    if (searchButton) {\n      searchButton.addEventListener('click', onSearchClicked);\n    }\n\n    const cartButton = this.querySelector('#cart-link');\n    if (cartButton) {\n      cartButton.addEventListener('click', onCartClicked);\n    }\n\n    const mainMenu = this.querySelector<HTMLElement>('#main-menu');\n    mainMenu.addEventListener('mouseleave', this.onMainMenuMouseLeaveBound);\n  }\n\n  /**\n   * Handles click events on menu panel buttons to open or close panels.\n   */\n  private onButtonClicked(event: Event) {\n    const button = <HTMLButtonElement>event.currentTarget;\n    if (button.classList.contains('active')) {\n      this.clearActiveState();\n      return;\n    }\n\n    this.clearActiveState();\n    this.setActiveState(button);\n  }\n\n  private onHamburgerButtonClicked(event: Event) {\n    const button = <HTMLButtonElement>event.currentTarget;\n    if (button.classList.contains('active')) {\n      button.classList.remove('active');\n      button.setAttribute('aria-expanded', 'false');\n\n      this.clearActiveState();\n      type MainMenuHamburgerClickedEventDetail =\n        WindowEventMap['main-menu-hamburger-clicked']['detail'];\n      const hamburgerClickedEvent =\n        new CustomEvent<MainMenuHamburgerClickedEventDetail>('main-menu-hamburger-clicked', {\n          detail: { isActive: false }\n        });\n      dispatchEvent(hamburgerClickedEvent);\n      return;\n    }\n\n    this.clearActiveState();\n    this.setActiveState(button);\n\n    type MainMenuHamburgerClickedEventDetail =\n      WindowEventMap['main-menu-hamburger-clicked']['detail'];\n    const hamburgerClickedEvent =\n      new CustomEvent<MainMenuHamburgerClickedEventDetail>('main-menu-hamburger-clicked', {\n        detail: { isActive: true }\n      });\n    dispatchEvent(hamburgerClickedEvent);\n  }\n\n  private setActiveState(button: HTMLElement) {\n    const panelId = button.getAttribute('aria-controls');\n    const panel = this.querySelector(`#${panelId}`);\n    if (!panel) {\n      console.warn(`Main menu: panel with ID ${panelId} not found`);\n      return;\n    }\n\n    const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\n    if (Number.isInteger(scrollbarWidth)) {\n      document.documentElement.style.setProperty('--scrollbar-width', scrollbarWidth + 'px');\n    }\n\n    document.documentElement.classList.add('js-no-scroll');\n\n    this.activePanel = panelId;\n\n    panel.removeAttribute('inert');\n    panel.classList.remove('hidden');\n    button.classList.add('active');\n    button.setAttribute('aria-expanded', 'true');\n  }\n\n  private clearActiveState() {\n    document.documentElement.classList.remove('js-no-scroll');\n\n    // check all active buttons for safety, in fact there should be only one\n    const activeButtons = this.querySelectorAll('.menu-panel-button.active');\n    for (const button of activeButtons) {\n      button.classList.remove('active');\n      button.setAttribute('aria-expanded', 'false');\n    }\n\n    if (this.activePanel) {\n      const panel = this.querySelector<HTMLElement>(`#${this.activePanel}`);\n      if (panel) {\n        panel.setAttribute('inert', '');\n        panel.classList.add('hidden');\n      }\n\n      this.activePanel = '';\n    }\n  }\n\n  /**\n   * Handles pointer enter events on menu panel buttons to open panels on mouse hover.\n   */\n  private onPointerEnter(event: PointerEvent) {\n    if (event.pointerType !== 'mouse') {\n      return;\n    }\n\n    const button = <HTMLElement>event.currentTarget;\n    this.clearActiveState();\n    this.setActiveState(button);\n  }\n\n  /**\n   * Closes the active panel when the mouse leaves the main menu area,\n   * unless the mouse is moving into the active panel itself.\n   */\n  private onMainMenuMouseLeave(event: MouseEvent) {\n    const relatedTarget = <HTMLElement>event.relatedTarget;\n\n    // If there's no related target, it means the mouse left the window, so we should close the\n    // active panel.\n    if (!relatedTarget) {\n      this.clearActiveState();\n      return false;\n    }\n\n    const closestPanel = relatedTarget.closest('.menu-panel');\n    if (closestPanel && closestPanel.id === this.activePanel) {\n      return false;\n    } else {\n      this.clearActiveState();\n    }\n  }\n\n  /**\n   * Closes the active panel when the mouse leaves the panel area,\n   * unless the mouse is moving back to the main menu area.\n   */\n  private onPanelMouseLeave(event: MouseEvent) {\n    const relatedTarget = <HTMLElement>event.relatedTarget;\n\n    // If there's no related target, it means the mouse left the window, so we should close the\n    // active panel.\n    if (!relatedTarget) {\n      this.clearActiveState();\n      return false;\n    }\n\n    const closestPanel = relatedTarget.closest('#main-menu');\n    if (closestPanel) {\n      return false;\n    } else {\n      this.clearActiveState();\n    }\n  }\n}\n\n/**\n * Go to provided URL if it's a mouse click.\n *\n * This is our businness requirement to navigate on mouse clicks. For accessibility reasons,\n * we need to keep the menu button element as a button, so we handle navigation manually here.\n */\nfunction onPointerDown(event: PointerEvent) {\n  if (event.pointerType !== 'mouse') {\n    return;\n  }\n\n  const button = <HTMLElement>event.currentTarget;\n  const url = button.dataset.href;\n  if (url) {\n    window.location.href = url;\n  }\n}\n\nfunction onSearchClicked(event: Event) {\n  const searchPanelShowRequstedEvent = new CustomEvent('search-panel-show-requested', {\n    detail: {\n      returnFocusTo: <HTMLElement>event.currentTarget\n    }\n  });\n  dispatchEvent(searchPanelShowRequstedEvent);\n}\n\nfunction onCartClicked(_event: Event) {\n  const modalShowEvent = new Event('cart-modal-show-requested');\n  dispatchEvent(modalShowEvent);\n}\n\ntype MainMenuHamburgerClickedEvent = CustomEvent<{\n  isActive: boolean;\n}>;\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'main-menu-manager': MainMenuManager;\n  }\n\n  interface WindowEventMap {\n    'main-menu-hamburger-clicked': MainMenuHamburgerClickedEvent;\n  }\n}\n\nif (!customElements.get('main-menu-manager')) {\n  customElements.define('main-menu-manager', MainMenuManager);\n}\n","import type { Splide, Components, Options } from '@splidejs/splide';\n\n/**\n * Extension to add a custom slidebar to the Splide slider for visualizing and controlling the\n * slide position.\n *\n * If you want to render a sidebar in a specific place in the HTML, add the sidebar's markup\n * directly to your template. If no markup is provided, the sidebar will be automatically created\n * and inserted right before the closing tag of the Splide root element.\n *\n * This library was copy-paged from Lange.\n *\n * @param splide The main Splide instance\n * @param components Splide components\n * @param options Splide options object, containing customization options\n *\n * @see https://splidejs.com/components/\n * @see https://splidejs.com/guides/options/\n * @see https://splidejs.com/guides/extension/\n */\nexport function splideSlidebarExtension(splide: Splide, components: Components, options: Options) {\n  /**\n   * Root slidebar element\n   */\n  let slidebar: HTMLElement;\n\n  /**\n   * Indicates whether the sidebar markup is already present in the HTML or not.\n   */\n  let hasSlidebarMarkup = false;\n\n  /**\n   * Slide bar handle element\n   */\n  let handle: HTMLElement;\n\n  /**\n   * Slidebar current position\n   */\n  let position = 0;\n\n  /**\n   * Maximum allowable position value for the slidebar handle\n   */\n  let maxPosition: number;\n\n  /**\n   * Maximum allowable position value for the Splide's track. Store the value to not calculate all\n   * the time when the slider is dragged.\n   */\n  let maxTrackPosition: number;\n\n  /**\n   * Previous x-coordinate of the touch, needed to calculate the touch movement distance.\n   */\n  let previousTouchX = 0;\n\n  /**\n   * Mounts the extension, setting up the slidebar and initializing event listeners. Splide call\n   * this method automatically when the slider is ready.\n   *\n   * @see https://splidejs.com/guides/extension/\n   */\n  function mount() {\n    slidebar = components.Elements.root.querySelector('.splide__slider');\n    handle = components.Elements.root.querySelector('.splide__slider-handle');\n\n    if (slidebar && handle) {\n      hasSlidebarMarkup = true;\n    } else {\n      renderSlidebar();\n    }\n\n    splide.on('ready', onSplideReady);\n    splide.on('updated', onSplideOptionsUpdated);\n    splide.on('overflow', onSplideOverflowed);\n  }\n\n  /**\n   * Enables the slidebar functionality, adding the necessary event listeners.\n   */\n  function enable() {\n    if (!hasSlidebarMarkup) {\n      components.Elements.root.appendChild(slidebar);\n    }\n\n    slidebar.classList.remove('hidden');\n\n    // Without this delay, the first page of the carousel is not clickable. There’s an issue with\n    // calling the components.Controller.go() method immediately when the extension is mounted.\n    setTimeout(onSplideResized);\n\n    if (!splide.is('fade')) {\n      splide.on('dragging.slidebar', onSplideDragging);\n    }\n\n    splide.on('move.slidebar', onSplideMoveStarted);\n    splide.on('resized.slidebar', onSplideResized);\n    handle.addEventListener('mousedown', onMousedown);\n    handle.addEventListener('touchstart', onTouchstart, { passive: true });\n    handle.addEventListener('transitionend', onTransitionend);\n    slidebar.addEventListener('click', onSlidebarClicked);\n  }\n\n  /**\n   * Disables the slidebar functionality, removing the event listeners and slidebar element.\n   */\n  function disable() {\n    slidebar.classList.add('hidden');\n\n    splide.off('move.slidebar');\n    splide.off('resized.slidebar');\n    splide.off('dragging.slidebar');\n    handle.removeEventListener('mousedown', onMousedown);\n    handle.removeEventListener('touchstart', onTouchstart);\n    handle.removeEventListener('transitionend', onTransitionend);\n    slidebar.removeEventListener('click', onSlidebarClicked);\n  }\n\n  /**\n   * Creates elements, calculates, and sets the handle width based on the number of slides, but does\n   * not append the element to the DOM.\n   */\n  function renderSlidebar() {\n    slidebar = document.createElement('div');\n    slidebar.classList.add('splide__slider');\n\n    handle = document.createElement('div');\n    handle.classList.add('splide__slider-handle');\n\n    handle.style.width = calculateHandleWidth();\n\n    slidebar.appendChild(handle);\n  }\n\n  /**\n   * Calculates the width of the handle.\n   *\n   * The function works depending upon the 'mode' the Splide is in. If it's in 'fade' mode, the\n   * width is calculated based on the proportion of 'perPage' option to the total number of slides,\n   * scaled to fit a percentage scale (0-100).\n   *\n   * For other modes, the handle width is determined by the ratio of list size\n   * to slider size, also expressed as a percentage.\n   *\n   * @returns The calculated width of the handle.\n   */\n  function calculateHandleWidth() {\n    let handleWidth;\n    if (splide.is('fade')) {\n      handleWidth = (options.perPage / components.Slides.getLength()) * 100;\n    } else {\n      handleWidth = (components.Layout.listSize() / components.Layout.sliderSize()) * 100;\n    }\n\n    return `${handleWidth}%`;\n  }\n\n  /**\n   * Calculates maximum values for the slidebar and track, ensuring they stay in sync.\n   */\n  function recalculateSlidebarAndTrackPosition() {\n    maxPosition = slidebar.offsetWidth - handle.offsetWidth;\n    maxTrackPosition = components.Layout.sliderSize() - components.Layout.listSize();\n\n    components.Controller.go(splide.index, true);\n  }\n\n  /**\n   * Processes and restricts handle movement within the slidebar bounds.\n   *\n   * @param toPosition Desired new position of the handle.\n   */\n  function processHandleMove(toPosition: number) {\n    const newPosition = getHandlePositionWithinBounds(toPosition);\n\n    // avoid position update if handle position hasn't changed.\n    if (position === newPosition) {\n      return;\n    }\n\n    position = getHandlePositionWithinBounds(toPosition);\n\n    if (!splide.is('fade')) {\n      const newSplidePosition = getCalculatedTrackPosition(position);\n      components.Move.translate(newSplidePosition);\n    }\n\n    // it ensures the DOM updates are synchronized with the browser's refresh rate, avoiding\n    // unnecessary reflows and keeping animations smooth\n    requestAnimationFrame(() => {\n      handle.style.transform = `translateX(${position}px)`;\n    });\n  }\n\n  /**\n   * Adjusts and returns the intended position of the handle within the boundaries of a slider.\n   * Checks whether the new position is within the range [0, maxPosition]. If the intended position\n   * is less than 0, it will be set to 0. If it's larger than maxPosition, it will be set\n   * to maxPosition. If it's the same as the current position, it will return this value without\n   * changes.\n   *\n   * @param toPosition - The intended new position.\n   * @returns newPosition - The adjusted position within the range [0, maxPosition].\n   */\n  function getHandlePositionWithinBounds(toPosition: number) {\n    let newPosition = toPosition;\n    if (newPosition <= 0) {\n      newPosition = 0;\n    } else if (newPosition >= maxPosition) {\n      newPosition = maxPosition;\n    }\n\n    return newPosition;\n  }\n\n  /**\n   * Aligns the track position based on the current position of the handle.\n   */\n  function alignTrackPosition() {\n    let index: number;\n\n    if (splide.is('fade')) {\n      index = Math.round(position / (maxPosition / components.Slides.getLength()));\n    } else {\n      const currentSplidePosition = components.Move.getPosition();\n      index = components.Move.toIndex(currentSplidePosition);\n    }\n\n    components.Controller.go(index, true);\n  }\n\n  function onSplideOptionsUpdated(_options: Options) {\n    toggleSlidebar();\n  }\n\n  function onSplideReady() {\n    toggleSlidebar();\n  }\n\n  function toggleSlidebar() {\n    // We need to both check isEnough() and isOverflow(). Depending on the Splide options or due\n    // to some Splide bugs, solely relying on one of these methods has led to issues.\n    if (options.slidebar && components.Slides.isEnough() && components.Layout.isOverflow()) {\n      enable();\n    } else {\n      disable();\n    }\n  }\n\n  function onMousedown() {\n    addEventListener('mousemove', onMousemove);\n    addEventListener('mouseup', onMouseup);\n  }\n\n  function onMouseup() {\n    // TODO: \"mouseup\" event is fired on touch devices right after \"touchend\". Need to investigate,\n    // if we can replace mouse and touch events with \"pointerdown\" and \"pointerup\" events.\n\n    alignTrackPosition();\n\n    removeEventListener('mousemove', onMousemove);\n    removeEventListener('mouseup', onMouseup);\n  }\n\n  function onMousemove(event: MouseEvent) {\n    const newPosition = position + event.movementX;\n    processHandleMove(newPosition);\n  }\n\n  function onTouchstart(event: TouchEvent) {\n    const touch = event.touches[0];\n    previousTouchX = touch.clientX;\n\n    addEventListener('touchmove', onTouchmove);\n    addEventListener('touchend', onTouchend);\n  }\n\n  function onTouchend(_event: TouchEvent) {\n    previousTouchX = 0;\n\n    alignTrackPosition();\n\n    removeEventListener('touchmove', onTouchmove);\n    removeEventListener('touchend', onTouchend);\n  }\n\n  function onTouchmove(event: TouchEvent) {\n    const touch = event.touches[0];\n    const movementX = touch.clientX - previousTouchX;\n    const newPosition = position + movementX;\n    previousTouchX = touch.clientX;\n\n    processHandleMove(newPosition);\n  }\n\n  /**\n   * Resets handle transition style once transition ends\n   */\n  function onTransitionend() {\n    handle.style.transition = '';\n  }\n\n  function onSlidebarClicked(event: MouseEvent) {\n    if (event.target !== event.currentTarget) {\n      return;\n    }\n\n    const newSlidebarPosition = event.offsetX - handle.offsetWidth / 2;\n    let index: number;\n\n    if (splide.is('fade')) {\n      index = Math.round(newSlidebarPosition / (maxPosition / components.Slides.getLength()));\n    } else {\n      const newTrackPosition = getCalculatedTrackPosition(newSlidebarPosition);\n      index = components.Move.toIndex(newTrackPosition);\n    }\n\n    components.Controller.go(index, true);\n  }\n\n  function onSplideResized() {\n    handle.style.width = calculateHandleWidth();\n\n    recalculateSlidebarAndTrackPosition();\n  }\n\n  function onSplideOverflowed(isOverflow: boolean) {\n    if (isOverflow) {\n      enable();\n    } else {\n      disable();\n    }\n  }\n\n  /**\n   * Sets the handle position based on the active slide's position.\n   *\n   * @param index Active Slide index.\n   */\n  function onSplideMoveStarted(index: number) {\n    let newSlidebarPosition;\n    if (splide.is('fade')) {\n      newSlidebarPosition = (options.perPage / (components.Slides.getLength() - 1)) * maxPosition *\n        index;\n    } else {\n      const newTrackPosition = components.Move.toPosition(index);\n      newSlidebarPosition = getCalculatedSlidebarPosition(newTrackPosition);\n    }\n\n    position = getHandlePositionWithinBounds(newSlidebarPosition);\n    handle.style.transform = `translateX(${position}px)`;\n    handle.style.transition = 'transform 400ms cubic-bezier(0.25, 1, 0.5, 1)';\n  }\n\n  function onSplideDragging() {\n    const newPosition = getCalculatedSlidebarPosition();\n    position = getHandlePositionWithinBounds(newPosition);\n    handle.style.transform = `translateX(${position}px)`;\n  }\n\n  /**\n   * Calculates the handle's position based on the current track position.\n   *\n   * @param trackPosition Optional track position for calculation. If not provided the value from\n   *   the Move component is taken. We don't need to pass a new track position if this function used\n   *   to get the slidebar position when the slider is dragged, but it's necessary if used when\n   *   the slider is moved to a certain slide because the position at the end of moving should be\n   *   taken instead of the current Splide's track position.\n   */\n  function getCalculatedSlidebarPosition(trackPosition?: number) {\n    // Use the max track position for the last reachable slide index rather than computing from\n    // layout dimensions. The arithmetic below doesn't work if the last slide is reached. It's good\n    // enough for the slide position in the middle of the slider but causes the slidebar handle to\n    // never fully reach the end.\n    const endIndex = components.Controller.getEnd();\n    const currentIndex = components.Controller.getIndex();\n    if (endIndex === currentIndex) {\n      return maxPosition;\n    }\n\n    const currentTrackPosition = -1 * (trackPosition ?? components.Move.getPosition());\n    const ratio = currentTrackPosition / maxTrackPosition;\n    const newSlideBarPosition = ratio * maxPosition;\n    return newSlideBarPosition;\n  }\n\n  /**\n   * Calculates the track's position based on the handle's position.\n   *\n   * @param slidebarPosition Position of the slidebar handle.\n   */\n  function getCalculatedTrackPosition(slidebarPosition: number) {\n    const ratio = slidebarPosition / maxPosition;\n    const newTrackPosition = -1 * ratio * maxTrackPosition;\n    return newTrackPosition;\n  }\n\n  return {\n    mount\n  };\n}\n","export {};\n\n// See webpack.md for help. This MUST be included in any module that performs dynamic imports.\n\ndeclare global {\n  /**\n   * This is a global that is defined in a liquid snippet to point to the Shopify asset path.\n   * Webpack compilation is transpiled to point the variable to the global. Because Webpack\n   * compilation involves raw string replacement, this variable has to actually exist. Because we\n   * do not know the public path at compile time this is basically a hack that allows to define the\n   * public path at runtime. This public path is needed for webpack to perform its dynamic module\n   * loading, e.g. to support dynamic imports.\n   */\n  // eslint-disable-next-line @typescript-eslint/naming-convention\n  var __webpack_public_path__: string;\n}\n\n__webpack_public_path__ = window.__webpack_public_path__;\n","import '../../../lib/webpack-path';\nimport { CustomElement } from '@integrabeauty/custom-elements';\nimport type { Options, Splide } from '@splidejs/splide';\nimport { splideSlidebarExtension } from '../../../lib/splide-slidebar-extension';\n\nclass MobileMenuManager extends HTMLElement implements CustomElement {\n  public shadowRoot!: ShadowRoot;\n  private carousels = new Map<string, Splide>();\n  private panelsHistory = ['mobile-menu-panel-main'];\n\n  private onDOMContentLoadedBound = this.onDOMContentLoaded.bind(this);\n  private onButtonClickedBound = this.onButtonClicked.bind(this);\n  private onMainMenuHamburgerClickedBound = this.onMainMenuHamburgerClicked.bind(this);\n  private onBackButtonClickedBound = this.onBackButtonClicked.bind(this);\n\n  public constructor() {\n    super();\n  }\n\n  public connectedCallback() {\n    addEventListener('DOMContentLoaded', this.onDOMContentLoadedBound);\n    addEventListener('main-menu-hamburger-clicked', this.onMainMenuHamburgerClickedBound);\n  }\n\n  public disconnectedCallback() {\n    removeEventListener('DOMContentLoaded', this.onDOMContentLoadedBound);\n    removeEventListener('main-menu-hamburger-clicked', this.onMainMenuHamburgerClickedBound);\n\n    const panelButtons = this.querySelectorAll('button.mobile-menu-button');\n    for (const button of panelButtons) {\n      button.removeEventListener('click', this.onButtonClickedBound);\n    }\n\n    const backButtons = this.querySelectorAll('.menu-back-button');\n    for (const backButton of backButtons) {\n      backButton.addEventListener('click', this.onBackButtonClickedBound);\n    }\n  }\n\n  private onDOMContentLoaded() {\n    const panelButtons = this.querySelectorAll('button.mobile-menu-button');\n    for (const button of panelButtons) {\n      button.addEventListener('click', this.onButtonClickedBound);\n    }\n\n    const backButtons = this.querySelectorAll('.menu-back-button');\n    for (const backButton of backButtons) {\n      backButton.addEventListener('click', this.onBackButtonClickedBound);\n    }\n\n    this.initCarousel().catch(console.warn);\n  }\n\n  private onButtonClicked(event: Event) {\n    const button = <HTMLButtonElement>event.currentTarget;\n    const panelId = button.getAttribute('aria-controls');\n    this.clearActiveState();\n    this.setActiveState(panelId);\n    this.panelsHistory.push(panelId);\n  }\n\n  private onMainMenuHamburgerClicked(event: WindowEventMap['main-menu-hamburger-clicked']) {\n    // hide all open panels, omitting the main panel\n    const activePanels = this.querySelectorAll('.mobile-menu-panel:not(.hidden)');\n    for (const activePanel of activePanels) {\n      activePanel.classList.add('hidden');\n    }\n\n    // hide all expanded buttons\n    const activeButtons = this.querySelectorAll('button.mobile-menu-button[aria-expanded=\"true\"]');\n    for (const activeButton of activeButtons) {\n      activeButton.setAttribute('aria-expanded', 'false');\n    }\n\n    // set the initial panel history state\n    this.panelsHistory = ['mobile-menu-panel-main'];\n\n    // the main panel should be visible by default\n    const mainPanel = this.querySelector<HTMLElement>('#mobile-menu-panel-main');\n    mainPanel.classList.remove('hidden');\n\n    // set focus to a first interactive element if the menu is opened\n    if (event.detail.isActive) {\n      const firstInteractiveElement = mainPanel.querySelector<HTMLElement>('.mobile-menu-button');\n      firstInteractiveElement.focus();\n    }\n  }\n\n  private onBackButtonClicked(_event: Event) {\n    this.clearActiveState();\n    this.panelsHistory.pop();\n    const newActivePanelId = this.panelsHistory[this.panelsHistory.length - 1];\n    this.setActiveState(newActivePanelId);\n  }\n\n  private setActiveState(panelId: string) {\n    const panel = this.querySelector(`#${panelId}`);\n    panel.classList.remove('hidden');\n\n    // set focus to a first interactive element in the panel\n    const firstButton = panel.querySelector<HTMLElement>('.mobile-menu-button, .menu-back-button');\n    if (firstButton) {\n      firstButton.focus();\n    }\n\n    const button = this.querySelector(`button[aria-controls=\"${panelId}\"]`);\n    if (button) {\n      button.setAttribute('aria-expanded', 'true');\n    }\n\n    // Refresh carousel if exists. It should fix issues with the missing slidebar\n    const splide = this.carousels.get(panelId);\n    if (splide) {\n      splide.refresh();\n    }\n  }\n\n  private clearActiveState() {\n    const activePanelId = this.panelsHistory[this.panelsHistory.length - 1];\n    const activePanel = this.querySelector(`#${activePanelId}`);\n    if (activePanel) {\n      activePanel.classList.add('hidden');\n    }\n\n    const activeButton = this.querySelector(`button[aria-controls=\"${activePanelId}\"]`);\n    if (activeButton) {\n      activeButton.classList.remove('active');\n      activeButton.setAttribute('aria-expanded', 'false');\n    }\n  }\n\n  /**\n   * Initialize special offers carousels inside mobile menu panels\n   */\n  private async initCarousel() {\n    const { Splide } = await import('@splidejs/splide');\n\n    const options: Options = {\n      type: 'slide',\n      fixedWidth: 180,\n      arrows: false,\n      pagination: false,\n      gap: '20px',\n      perPage: 1,\n      perMove: 1,\n      keyboard: true,\n      slidebar: true,\n      mediaQuery: 'min',\n      breakpoints: {\n        992: {\n          destroy: true\n        }\n      }\n    };\n\n    // this.querySelectorAll() doesn't work with Splide, only document.querySelectorAll()!\n    const carouselElements =\n      document.querySelectorAll<HTMLElement>('mobile-menu-manager .splide--menu-special-offers');\n    for (const carouselElement of carouselElements) {\n      const parentPanel = carouselElement.closest('.mobile-menu-panel');\n      const parentPanelId = parentPanel.getAttribute('id');\n      const splide = new Splide(carouselElement, options);\n      this.carousels.set(parentPanelId, splide);\n      splide.mount({\n        splideSlidebarExtension\n      });\n    }\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'mobile-menu-manager': MobileMenuManager;\n  }\n}\n\nif (!customElements.get('mobile-menu-manager')) {\n  customElements.define('mobile-menu-manager', MobileMenuManager);\n}\n","/**\n * Full-width promo banner carousel at the top of the page.\n *\n * Displays multiple banners that automatically rotate based on a customizable interval. The\n * top-banner custom element can hide himself based on counter calculation or if the user clicked\n * the close button. When that happens the \"top-banner-updated\" event is fired, and we need to\n * refresh the Splide carousel.\n */\n\nimport '../../lib/webpack-path';\nimport type { Options, Splide } from '@splidejs/splide';\n\nlet splide: Splide;\n\nasync function onDOMContentLoaded() {\n  const carousel = document.querySelector<HTMLElement>('.top-banner-carousel');\n  if (!carousel) {\n    return;\n  }\n\n  const { Splide } = await import('@splidejs/splide');\n  const options: Options = {\n    type: 'fade',\n    pagination: false,\n    rewind: true\n  };\n\n  options.arrows = carousel.dataset.showArrows === 'true';\n\n  // We need to enable autoplay only if the interval is a valid positive number, otherwise we\n  // don't need to enable it.\n  const interval = parseInt(carousel.dataset.interval, 10);\n  if (interval > 0) {\n    options.autoplay = true;\n    options.interval = interval;\n  }\n\n  splide = new Splide(carousel, options);\n  splide.mount();\n\n  splide.on('mounted', (_event: Event) => {\n    const event = new Event('top-banner-carousel-updated');\n    dispatchEvent(event);\n  });\n\n  splide.on('refresh', (_event: Event) => {\n    const event = new Event('top-banner-carousel-updated');\n    dispatchEvent(event);\n  });\n\n  for (const event of top_banner_carousel_event_queue) {\n    if (isTopBannerUpdatedEvent(event)) {\n      try {\n        onTopBannerUpdated(event);\n      } catch (error) {\n        console.warn(error);\n      }\n    }\n  }\n}\n\nfunction onTopBannerUpdated(_event: Event) {\n  if (!splide) {\n    return;\n  }\n\n  splide.refresh();\n}\n\nfunction isTopBannerUpdatedEvent(value: any): value is WindowEventMap['top-banner-updated'] {\n  return value?.type === 'top-banner-updated';\n}\n\naddEventListener('DOMContentLoaded', onDOMContentLoaded);\naddEventListener('top-banner-updated', onTopBannerUpdated);\n\ndeclare global {\n  // eslint-disable-next-line @typescript-eslint/naming-convention\n  var top_banner_carousel_event_queue: Event[];\n  // eslint-disable-next-line @typescript-eslint/naming-convention\n  var top_banner_carousel_event_listener: (event: Event)=> void;\n\n  interface WindowEventMap {\n    'top-banner-carousel-updated': Event;\n  }\n}\n","// This library was copied from Lange to support top banner component. So some documentation can be\n// related to lange only, but I'd like to keep it as it is to have fewer differences between\n// Ofir and Lange because that should help to move this library/component to a shared app.\n//\n// We have now more than one element that displays a countdown clock on the page. When the elements\n// use separate `setInterval()` calls to display their time the effect of them not being\n// synchronized can be seen even if the interval is low (50-100ms).\n//\n// This module provides a very simple synchronization method and some shared utilities for timestamp\n// calculations.\n//\n// Clock synchronization is based on a single `setInterval()` call. This starts a timer which emits\n// `timer-tick` events. Each page element can listen to the events to update the displayed time at\n// the very same moment other elements do.\n//\n// The timer has to be initialized with the `startTimer()` function. There is no possibility to stop\n// the timer, as we would have to implement a reference counter which would be prone to problems,\n// i.e. a bug in a simple component could stop all timers on the page. Instead of stopping the timer\n// the components should stop listening to the events.\n\nlet intervalId: ReturnType<typeof setInterval> | null = null;\n\n/**\n * Calculate the remaining time between currentTimestamp and endTimestamp and express it as an\n * object with number of days, hours, minutes, seconds as integers and a human readable `text`\n */\nexport function timeLeft(currentTimestamp: number, endTimestamp: number) {\n  if (currentTimestamp > endTimestamp || !endTimestamp) {\n    return null;\n  }\n\n  const secondsLeft = Math.round((endTimestamp - currentTimestamp) / 1000);\n  const seconds = secondsLeft % 60;\n\n  const minutesLeft = (secondsLeft - seconds) / 60;\n  const minutes = minutesLeft % 60;\n\n  const hoursLeft = (minutesLeft - minutes) / 60;\n  const hours = hoursLeft % 24;\n\n  const days = (hoursLeft - hours) / 24;\n\n  const text = [\n    days.toString(),\n    days === 1 ? 'day' : 'days',\n    hours.toString(),\n    hours === 1 ? 'hour' : 'hours',\n    minutes.toString(),\n    minutes === 1 ? 'minute' : 'minutes',\n    seconds.toString(),\n    seconds === 1 ? 'second' : 'seconds'\n  ].join(' ');\n\n  return {\n    text, days, hours, minutes, seconds\n  };\n}\n\n/**\n * Start emitting `timer-tick` events\n *\n * This function may be called multiple times. It will only start a single timer.\n */\nexport function startTimer() {\n  if (intervalId) {\n    return;\n  }\n\n  // dispatch the first event immediately\n  setTimeout(tick, 0);\n\n  intervalId = setInterval(tick, 1000);\n}\n\nfunction tick() {\n  type Detail = TimerTickEvent['detail'];\n  const event = new CustomEvent<Detail>('timer-tick', {\n    detail: { timestamp: Date.now() }\n  });\n  dispatchEvent(event);\n}\n\ntype TimerTickEvent = CustomEvent<{\n  timestamp: number;\n}>;\n\ndeclare global {\n  interface WindowEventMap {\n    'timer-tick': TimerTickEvent;\n  }\n}\n","import type { CustomElement } from '@integrabeauty/custom-elements';\nimport debounce from '../../../lib/debounce';\nimport { startTimer, timeLeft } from '../countdown-timer';\nimport html from './index.html';\nimport styles from './index.scss';\n\n/**\n * Custom HTML element representing a top banner with features like a clock, badge, and close\n * button. All of these features are optional and configurable via data-attributes. The\n * component store the hash of the messages closed by user to prevent showing it again. In case\n * of a horizontal overflow the message will be auto scrolled to ensure the entire message is\n * visible.\n */\nclass TopBanner extends HTMLElement implements CustomElement {\n  readonly dataset!: {\n    /**\n     * Should the badge be displayed\n     */\n    badgeShow: 'false' | 'true';\n\n    /**\n     * The text of the clock badge.\n     *\n     * @default \"Limited Time\"\n     */\n    badgeText: string;\n\n    /**\n     * Stop time as unix epoch time.\n     *\n     * @see https://www.epochconverter.com\n     */\n    clockEndTime: string;\n\n    /**\n     * If false the entire clock and the \"Limited time\" badge will disappear\n     */\n    clockShow: 'false' | 'true';\n\n    /**\n     * Start time as unix epoch time.\n     *\n     * @see https://www.epochconverter.com\n     */\n    clockStartTime: string;\n\n    /**\n     * If false the close button will disappear\n     */\n    closeButtonShow: 'false' | 'true';\n\n    /**\n     * Represents a URL link as a string\n     */\n    link: string;\n\n    /**\n     * Message to be shown. Slot can't be used because of the auto scrolling feature that\n     * requires the message to be cloned and duplicated in the DOM in case of overflow to ensure\n     * smooth scrolling.\n     */\n    message: string;\n\n    /**\n     * Scrolling animation speed in pixels per second. The default value is 80px/s. A number\n     * value represented as a string, for example \"80\".\n     */\n    scrollingSpeed: string;\n  };\n\n  public shadowRoot!: ShadowRoot;\n  private endTimestamp: number | null = null;\n\n  private onCloseClickedBound = this.onCloseClicked.bind(this);\n  private onTimerTickBound = this.onTimerTick.bind(this);\n  private onWindowResizedBound = this.onWindowResized.bind(this);\n  private onWindowResizedDebounced = debounce(this.onWindowResizedBound, 300);\n  private onTopBannerCarouselUpdatedBound = this.onTopBannerCarouselUpdated.bind(this);\n\n  constructor() {\n    super();\n    this.attachShadow({ mode: 'open' });\n    this.shadowRoot.innerHTML = `<style>${styles}</style>${html}`;\n  }\n\n  public connectedCallback() {\n    this.render();\n\n    window.addEventListener('resize', this.onWindowResizedDebounced);\n\n    // If there's multiple banners in the carousel, we need to listen for the carousel update event\n    // triggered after the Splide carousel initialization. In the case of a single banner,\n    // there's no such event, so we can just check the overflow on the initial render without\n    // waiting for any events.\n    if (this.classList.contains('splide__slide')) {\n      addEventListener('top-banner-carousel-updated', this.onTopBannerCarouselUpdatedBound);\n    } else {\n      this.handleOverflow();\n    }\n  }\n\n  public disconnectedCallback() {\n    window.removeEventListener('resize', this.onWindowResizedDebounced);\n    removeEventListener('top-banner-carousel-updated', this.onTopBannerCarouselUpdatedBound);\n    removeEventListener('timer-tick', this.onTimerTickBound);\n    const closeButton = this.shadowRoot.querySelector('button.close');\n    closeButton?.removeEventListener('click', this.onCloseClickedBound);\n  }\n\n  private render() {\n    if (this.dataset.clockEndTime) {\n      this.endTimestamp = parseInt(this.dataset.clockEndTime, 10) * 1000;\n    }\n\n    const closeButton = this.shadowRoot.querySelector('button.close');\n    closeButton.addEventListener('click', this.onCloseClickedBound);\n\n    // Check if the user dismissed the current message. We use an extremely simple,\n    // non-cryptographic hash as we just want to detect if the message has changed since the last\n    // time the user clicked close. We accept the extremely rare possibility of collision and\n    // storage failing as the consequence is that the user will (not) see a promo message. The\n    // message length is not bound, so we cannot just save the message itself into storage.\n    const current = this.getCurrentMessageHash();\n    const dismissed = readDismissed();\n    if (current !== dismissed) {\n      // start everything only if the message has not been dismissed\n      startTimer();\n      addEventListener('timer-tick', this.onTimerTickBound);\n      this.showBanner();\n\n      // render message\n      const message = this.shadowRoot.querySelector('.message');\n      message.innerHTML = this.dataset.message;\n\n      // render timer clock\n      const timer = this.shadowRoot.querySelector('.timer');\n      if (this.dataset.clockShow === 'true') {\n        if (this.shouldShowClock()) {\n          // the clock should be displayed - it is active\n          timer.classList.remove('hidden');\n        } else {\n          // the clock was set to be displayed but the message expired already\n          // hide the entire banner\n          this.hideBanner();\n        }\n      } else {\n        // the clock was disabled but we still have a message to show - hide the timer\n        timer.classList.add('hidden');\n      }\n\n      // render badge\n      const badge = this.shadowRoot.querySelector('.badge');\n      if (badge) {\n        badge.textContent = this.dataset.badgeText || 'Limited Time';\n        if (this.dataset.badgeShow === 'true') {\n          badge.classList.remove('hidden');\n        }\n      }\n\n      const closeButton = this.shadowRoot.querySelector('.close');\n      if (this.dataset.closeButtonShow === 'true') {\n        closeButton.classList.remove('hidden');\n      } else {\n        closeButton.classList.add('hidden');\n      }\n\n      // render link\n      const link = this.shadowRoot.querySelector<HTMLAnchorElement>('.link');\n      if (this.dataset.link) {\n        link.href = this.dataset.link;\n      } else {\n        link.removeAttribute('href');\n      }\n\n      this.renderClock(Date.now());\n\n      updatePagePositioning();\n    }\n  }\n\n  /**\n   * We have a few requirements to show the countdown clock. Calculate the decision\n   */\n  private shouldShowClock() {\n    const currentTimestamp = Date.now();\n\n    let startTimestamp = Number.MAX_SAFE_INTEGER;\n    if (this.dataset.clockStartTime) {\n      startTimestamp = parseInt(this.dataset.clockStartTime, 10) * 1000;\n    }\n\n    let endTimestamp = 0;\n    if (this.dataset.clockEndTime) {\n      endTimestamp = parseInt(this.dataset.clockEndTime, 10) * 1000;\n    }\n\n    return this.dataset.clockShow === 'true' &&\n      startTimestamp <= currentTimestamp &&\n      endTimestamp >= currentTimestamp;\n  }\n\n  private onTimerTick(event: WindowEventMap['timer-tick']) {\n    this.renderClock(event.detail.timestamp);\n  }\n\n  private renderClock(timestamp: number) {\n    const timer = this.shadowRoot.querySelector<HTMLElement>('.timer');\n    if (!this.shouldShowClock()) {\n      if (timer && !timer.classList.contains('hidden')) {\n        timer.classList.add('hidden');\n        updatePagePositioning();\n      }\n\n      return;\n    }\n\n    const remaining = timeLeft(timestamp, this.endTimestamp);\n\n    this.setClockSegmentValue('.days', remaining.days);\n    this.setClockSegmentValue('.hours', remaining.hours);\n    this.setClockSegmentValue('.minutes', remaining.minutes);\n    this.setClockSegmentValue('.seconds', remaining.seconds);\n\n    timer?.setAttribute('aria-label', remaining.text);\n  }\n\n  private setClockSegmentValue(selector: string, value: number) {\n    const stringValue = value < 10 ? '0' + value : value.toString();\n    const element = this.shadowRoot.querySelector(selector);\n    if (element && element.textContent !== stringValue) {\n      element.textContent = stringValue;\n    }\n  }\n\n  private hideBanner() {\n    this.parentElement.removeChild(this);\n\n    // ensure the whole page is repositioned\n    updatePagePositioning();\n  }\n\n  private showBanner() {\n    // TODO fix eslint error\n    // eslint-disable-next-line wc/no-self-class\n    this.classList.remove('hidden');\n\n    // ensure the whole page is repositioned\n    updatePagePositioning();\n  }\n\n  private onCloseClicked(_event: Event) {\n    this.hideBanner();\n    const hash = this.getCurrentMessageHash();\n    writeDismissed(hash);\n  }\n\n  private onWindowResized(_event: Event) {\n    this.handleOverflow();\n  }\n\n  /**\n   * Update the overflow state if the banner is a part of a carousel and the carousel was updated.\n   * We need to do that because the Splide carousel is hidden until it's fully initialized and\n   * it cause incorrect overflow state calculation on the initial render of the banner.\n   */\n  private onTopBannerCarouselUpdated(_event: Event) {\n    this.handleOverflow();\n  }\n\n  /**\n   * Check if the message is overflowing horizontally and if so enable auto scrolling animation or\n   * disable it if the window was resized to be bigger. We should check it on every window resize.\n   */\n  private handleOverflow() {\n    const wrapper = this.shadowRoot.querySelector('.wrapper');\n    const overflowed = wrapper.classList.contains('overflowed');\n    const link = this.shadowRoot.querySelector<HTMLElement>('.link');\n\n    // We should always check the actual content width not the link width as the link might contain\n    // a cloned content for the scrolling animation if it's overflowed.\n    const originalContent = this.shadowRoot.querySelector('.link-content:not(.clone)');\n    const contentWidth = originalContent.scrollWidth;\n    const wrapperWidth = wrapper.getBoundingClientRect().width;\n\n    // Calculating the animation duration so the scrolling speed is consistent regardless of the\n    // message length. We need to duplicate the content width because the cloned content. This\n    // calculation might be not 100% precise but still gives a good approximation and ensures the\n    // scrolling speed is consistent across different message lengths.\n    const overflow = contentWidth * 2 - wrapperWidth;\n    const scrollingSpeed = parseInt(this.dataset.scrollingSpeed, 10) || 80;\n    const duration = overflow / scrollingSpeed;\n\n    if (overflowed) {\n      // If it's already overflowed we should disable the scrolling animation in the case there's no\n      // more overflow for the current frame size.\n      if (contentWidth <= wrapperWidth) {\n        const linkContentClone = this.shadowRoot.querySelector('.link-content.clone');\n        if (linkContentClone) {\n          linkContentClone.remove();\n        }\n\n        wrapper.classList.remove('overflowed');\n      } else {\n        // if overflowed and it shouldn't be disabled, we should update the animation duration\n        // because the message window size might be changed\n        link.style.animationDuration = `${duration}s`;\n      }\n    } else {\n      // If it's not overflowed we should enable the scrolling animation in the case there's an\n      // overflow for the current frame size.\n      if (contentWidth > wrapperWidth) {\n        wrapper.classList.add('overflowed');\n        link.style.animationDuration = `${duration}s`;\n\n        // duplicate the link content to imitate infinite scrolling effect with pure CSS animation.\n        const linkContent = this.shadowRoot.querySelector('.link-content');\n        const linkContentClone = <HTMLElement>linkContent.cloneNode(true);\n        linkContentClone.classList.add('clone');\n        link.appendChild(linkContentClone);\n      }\n    }\n  }\n\n  private getCurrentMessageHash() {\n    return jenkinsHash(this.dataset.message);\n  }\n}\n\nfunction readDismissed() {\n  try {\n    return sessionStorage.getItem('top_banner_dismissed');\n  } catch (error) {\n    console.log(error);\n  }\n\n  return '';\n}\n\n/**\n * This writes into session storage so that there is a natural expiration. Previously this was\n * setting a cookie that expired after four hours. This is roughly the same.\n *\n * Errors are logged instead of thrown. This logs at a level not monitored by error instrumentation\n * just to help with development.\n */\nfunction writeDismissed(hash: string) {\n  try {\n    sessionStorage.setItem('top_banner_dismissed', hash);\n  } catch (error) {\n    console.warn(error);\n  }\n}\n\n/**\n * Very simple and fast non-cryptographic string hashing function. Return b)\n a 32-bit\n * unsigned number (as a hex string)\n *\n * See https://en.wikipedia.org/wiki/Jenkins_hash_function#one_at_a_time for details\n * Based on https://www.burtleburtle.net/bob/hash/doobs.html the original C source is Public Domain\n *\n * Modified to work with empty and undefined inputs\n */\nfunction jenkinsHash(key: string | undefined) {\n  let hash = 0;\n  const inputLength = key?.length || 0;\n  for (let i = 0; i < inputLength; i++) {\n    hash += key.charCodeAt(i);\n    hash += hash << 10;\n    // JS has no 32 bit unsigned int values, so we use the trick in the next line to\n    // truncate the value to 32 bits and remove the sign\n    hash = (hash & 0xFFFFFFFF) >>> 0;\n    hash ^= hash >>> 6;\n  }\n\n  hash += hash << 3;\n  // truncate again\n  hash = (hash & 0xFFFFFFFF) >>> 0;\n  hash ^= hash >>> 11;\n  hash += hash << 15;\n\n  // truncate before returning\n  hash = (hash & 0xFFFFFFFF) >>> 0;\n  return hash.toString(16);\n}\n\nfunction updatePagePositioning() {\n  dispatchEvent(new Event('top-banner-updated'));\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'top-banner': TopBanner;\n  }\n\n  interface WindowEventMap {\n    'top-banner-updated': Event;\n  }\n}\n\nif (!customElements.get('top-banner')) {\n  customElements.define('top-banner', TopBanner);\n}\n","export default \":host{align-items:center;background-color:#f4826d;color:#000;display:flex;flex-wrap:wrap;font-size:.875rem;justify-content:center;line-height:1.5;min-height:42px;padding:8px 16px;position:relative;text-align:center;white-space:nowrap}:host([data-close-button-show=true]){padding-left:30px;padding-right:30px}:host(.splide__slide){padding-left:42px;padding-right:42px}.wrapper{max-width:100%;overflow:hidden;width:100%}@keyframes auto-scroll{0%{transform:translateX(0)}to{transform:translateX(calc(-50% - .5em))}}.wrapper.overflowed a{animation:auto-scroll 10s linear infinite}a{color:inherit;display:inline-block;text-decoration:none}.link-content{align-items:center;display:inline-flex;flex-wrap:wrap;justify-content:center}.link-content:nth-child(2){margin-left:1em}b{font-weight:600}.close{background:#0000;border:none;color:inherit;cursor:pointer;height:18px;padding:0;position:absolute;right:7px;top:50%;transform:translateY(-50%);width:18px}.close svg{fill:currentcolor}.timer{font-size:.75rem;font-weight:600;margin:4px 6px;white-space:nowrap}.days,.hours,.minutes,.seconds{background-color:#fff;border-radius:3px;display:inline-block;height:22px;line-height:22px;width:22px}.separator{margin:0 6px}.badge{background-color:#fff;border-radius:100px;display:inline-block;font-size:.75rem;font-weight:600;height:22px;line-height:22px;margin:4px 6px;padding:0 10px;text-transform:uppercase;white-space:nowrap}.hidden{display:none}\";","// Module\nvar code = \"<button class=\\\"close hidden\\\"><svg width=\\\"18\\\" height=\\\"18\\\" viewBox=\\\"0 0 18 18\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><title>Close the top banner</title><path fill-rule=\\\"evenodd\\\" clip-rule=\\\"evenodd\\\" d=\\\"M13.8977 4.89775C14.1174 4.67808 14.1174 4.32192 13.8977 4.10225C13.6781 3.88258 13.3219 3.88258 13.1023 4.10225L9 8.2045L4.89775 4.10225C4.67808 3.88258 4.32192 3.88258 4.10225 4.10225C3.88258 4.32192 3.88258 4.67808 4.10225 4.89775L8.2045 9L4.10225 13.1023C3.88258 13.3219 3.88258 13.6781 4.10225 13.8977C4.32192 14.1174 4.67808 14.1174 4.89775 13.8977L9 9.7955L13.1023 13.8977C13.3219 14.1174 13.6781 14.1174 13.8977 13.8977C14.1174 13.6781 14.1174 13.3219 13.8977 13.1023L9.7955 9L13.8977 4.89775Z\\\"/></svg></button><div class=\\\"wrapper\\\"><a class=\\\"link\\\"><div class=\\\"link-content\\\"><div role=\\\"timer\\\" aria-live=\\\"off\\\" aria-atomic=\\\"true\\\" class=\\\"timer hidden\\\"><span class=\\\"days\\\">00</span><span class=\\\"separator\\\">:</span><span class=\\\"hours\\\">00</span><span class=\\\"separator\\\">:</span><span class=\\\"minutes\\\">00</span><span class=\\\"separator\\\">:</span><span class=\\\"seconds\\\">00</span></div><div class=\\\"badge hidden\\\">Limited time</div><div class=\\\"message\\\"></div></div></a></div>\";\n// Exports\nexport default code;"],"names":["inProgress","dataWebpackPrefix","header","mainMenu","container","document","addEventListener","querySelector","console","warn","intersectionObserver","IntersectionObserver","entries","entry","intersectionRatio","classList","remove","add","contains","rootMargin","threshold","ResizeObserver","_entries","newOffsetTop","offsetParent","offsetHeight","calculateTopOffset","style","setProperty","concat","disconnect","observe","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","m","d","definition","key","o","Object","defineProperty","enumerable","get","f","e","chunkId","Promise","all","keys","reduce","promises","u","miniCssF","obj","prop","prototype","hasOwnProperty","call","l","url","done","push","script","needAttach","scripts","getElementsByTagName","i","length","s","getAttribute","createElement","charset","timeout","nc","setAttribute","src","onScriptComplete","prev","event","onerror","onload","clearTimeout","doneFns","parentNode","removeChild","forEach","fn","setTimeout","bind","type","target","head","appendChild","p","installedChunks","j","installedChunkData","promise","resolve","reject","error","Error","errorType","realSrc","message","name","request","webpackJsonpCallback","parentChunkLoadingFunction","data","chunkIds","moreModules","runtime","some","id","chunkLoadingGlobal","self","SearchPanelManager","HTMLElement","constructor","super","onSearchPanelShowRequestedBound","this","onSearchPanelShowRequested","onSearchPanelCloseRequestedBound","onSearchPanelCloseRequested","onShroudClickedBound","onShroudClicked","onAddToCardBound","onAddToCard","connectedCallback","disconnectedCallback","removeEventListener","detail","returnFocusTo","showPanel","_event","closePanel","searchPanel","element","dataset","active","headerOffsetBottom","headerRect","getBoundingClientRect","height","top","getHeaderOffsetBottom","focus","modalShowEvent","CustomEvent","dispatchEvent","modalCloseEvent","debounce","func","timer","_len","arguments","args","Array","_key","apply","customElements","define","SearchInput","onInputBound","onInput","onSubmitBound","onSubmit","onResetBound","onReset","onCloseClickedBound","onCloseClicked","sendSearchInputChangedEventBound","sendSearchInputChangedEvent","sendSearchInputChangedEventDebounced","attachShadow","mode","delegatesFocus","shadowRoot","innerHTML","render","form","input","clearButton","query","value","trim","disabled","preventDefault","reset","Event","tagName","customEvent","SearchPanel","onSearchInputChangedBound","onSearchInputChanged","renderSearchResults","showLoader","response","params","URLSearchParams","set","fetch","getSearchResults","ok","statusText","html","text","log","hideLoader","MainMenuManager","onDOMContentLoadedBound","onDOMContentLoaded","onButtonClickedBound","onButtonClicked","onHamburgerButtonClickedBound","onHamburgerButtonClicked","onPointerEnterBound","onPointerEnter","onMainMenuMouseLeaveBound","onMainMenuMouseLeave","onPanelMouseLeaveBound","onPanelMouseLeave","panelButtons","querySelectorAll","button","onPointerDown","hamburgerButton","panels","panel","searchButton","onSearchClicked","onCartClicked","cartButton","currentTarget","clearActiveState","setActiveState","hamburgerClickedEvent","isActive","panelId","scrollbarWidth","window","innerWidth","documentElement","clientWidth","Number","isInteger","activePanel","removeAttribute","activeButtons","pointerType","relatedTarget","closestPanel","closest","href","location","searchPanelShowRequstedEvent","splideSlidebarExtension","splide","components","options","slidebar","handle","maxPosition","maxTrackPosition","hasSlidebarMarkup","position","previousTouchX","enable","Elements","root","onSplideResized","is","on","onSplideDragging","onSplideMoveStarted","onMousedown","onTouchstart","passive","onTransitionend","onSlidebarClicked","disable","off","calculateHandleWidth","handleWidth","perPage","Slides","getLength","Layout","listSize","sliderSize","processHandleMove","toPosition","newPosition","getHandlePositionWithinBounds","newSplidePosition","getCalculatedTrackPosition","Move","translate","requestAnimationFrame","transform","alignTrackPosition","index","Math","round","currentSplidePosition","getPosition","toIndex","Controller","go","onSplideOptionsUpdated","_options","toggleSlidebar","onSplideReady","isEnough","isOverflow","onMousemove","onMouseup","movementX","touch","touches","clientX","onTouchmove","onTouchend","transition","newSlidebarPosition","offsetX","offsetWidth","newTrackPosition","width","onSplideOverflowed","getCalculatedSlidebarPosition","trackPosition","getEnd","getIndex","slidebarPosition","mount","__webpack_public_path__","MobileMenuManager","carousels","Map","panelsHistory","onMainMenuHamburgerClickedBound","onMainMenuHamburgerClicked","onBackButtonClickedBound","onBackButtonClicked","backButtons","backButton","initCarousel","catch","activePanels","activeButton","mainPanel","pop","newActivePanelId","firstButton","refresh","activePanelId","Splide","fixedWidth","arrows","pagination","gap","perMove","keyboard","mediaQuery","breakpoints","destroy","carouselElements","carouselElement","parentPanelId","onTopBannerUpdated","isTopBannerUpdatedEvent","async","carousel","rewind","showArrows","interval","parseInt","autoplay","top_banner_carousel_event_queue","intervalId","tick","timestamp","Date","now","TopBanner","endTimestamp","onTimerTickBound","onTimerTick","onWindowResizedBound","onWindowResized","onWindowResizedDebounced","onTopBannerCarouselUpdatedBound","onTopBannerCarouselUpdated","handleOverflow","closeButton","clockEndTime","getCurrentMessageHash","sessionStorage","getItem","readDismissed","setInterval","showBanner","clockShow","shouldShowClock","hideBanner","badge","textContent","badgeText","badgeShow","closeButtonShow","link","renderClock","updatePagePositioning","currentTimestamp","startTimestamp","MAX_SAFE_INTEGER","clockStartTime","remaining","secondsLeft","seconds","minutesLeft","minutes","hoursLeft","hours","days","toString","join","timeLeft","setClockSegmentValue","selector","stringValue","parentElement","hash","setItem","writeDismissed","wrapper","overflowed","contentWidth","scrollWidth","wrapperWidth","duration","scrollingSpeed","linkContentClone","animationDuration","cloneNode","inputLength","charCodeAt","jenkinsHash"],"sourceRoot":""}