{
  "version": 3,
  "sources": ["/cdn/shop/t/20/assets/collection.js?mdsv=20261022a"],
  "sourcesContent": ["\n\nconst loadCollection = async () => {\n  const collectionProducts = document.querySelector('.collection-products')\n  const productList = collectionProducts.querySelector('.product-list')\n  const filters = document.querySelector('#offcanvas-collection-filters .collection-filters')\n\n  // Panneaux d'accord\u00E9on de filtres actuellement OUVERTS (sidebar desktop +\n  // tiroir mobile). Le rechargement AJAX remplace tout le balisage des filtres \u2192\n  // sans \u00E7a, chaque panneau revient \u00E0 son \u00E9tat par d\u00E9faut (ferm\u00E9) et le filtre\n  // qu'on vient de cocher se referme. On m\u00E9morise les id ouverts pour les\n  // rouvrir \u00E0 l'identique apr\u00E8s remplacement. Les id (filters-collapse-N /\n  // offcanvas-filters-collapse-N) sont stables : m\u00EAme collection = m\u00EAmes filtres\n  // dans le m\u00EAme ordre, quel que soit le filtre actif.\n  const openFilterPanels = new Set(\n    [...document.querySelectorAll('.collection-filters .collapse.show')].map(el => el.id)\n  )\n\n  if (productList) {\n    productList.style.opacity = '.2'\n  }\n\n  const response = await fetch(window.location.href)\n  // Sans ces gardes, une r\u00E9ponse d'erreur (5xx, page de maintenance) faisait\n  // remplacer la grille produits par le texte \u00AB null \u00BB.\n  if (!response.ok) {\n    if (productList) productList.style.opacity = ''\n    return\n  }\n\n  const data = await response.text()\n  const parser = new DOMParser()\n  const newDocument = parser.parseFromString(data, 'text/html')\n\n  const nextProducts = newDocument.querySelector('.collection-products')\n  const nextFilters = newDocument.querySelector('#offcanvas-collection-filters .collection-filters')\n\n  if (!nextProducts) {\n    if (productList) productList.style.opacity = ''\n    return\n  }\n\n  collectionProducts?.replaceWith(nextProducts)\n  if (nextFilters) filters?.replaceWith(nextFilters)\n\n  // Rouvrir les panneaux qui l'\u00E9taient avant le rechargement (cf. capture plus\n  // haut) : .show sur le panneau + \u00E9tat \u00AB ouvert \u00BB sur son bouton. Les boutons\n  // du tiroir mobile sont rendus ferm\u00E9s (aria-expanded=\"false\" + .collapsed,\n  // fl\u00E8che vers le bas) ; ceux de la sidebar desktop portent d\u00E9j\u00E0 \"true\".\n  // Bootstrap relira cet \u00E9tat au prochain clic.\n  openFilterPanels.forEach(id => {\n    const panel = document.getElementById(id)\n    if (!panel) return\n    panel.classList.add('show')\n    document.querySelectorAll(`[data-bs-target=\"#${id}\"]`).forEach(btn => {\n      btn.classList.remove('collapsed')\n      btn.setAttribute('aria-expanded', 'true')\n    })\n  })\n\n  window.dispatchEvent(new CustomEvent('kt.collection.loaded'))\n\n  const newCollectionProducts = document.querySelector('.collection-products')\n  // D\u00E9calage = hauteur r\u00E9ellement \u00E9pingl\u00E9e du header collant en haut :\n  // ~la hauteur du header quand il est sticky (desktop), ~0 quand il d\u00E9file\n  // (mobile < 768px, #header-group passe en position:static).\n  const stickyHeader = document.querySelector('#header-group')\n  const headerOffset = stickyHeader ? Math.max(0, Math.round(stickyHeader.getBoundingClientRect().bottom)) : 0\n  // Ancrage JUSTE SOUS le fil d'Ariane : on vise la rang\u00E9e filtres/produits\n  // (pas le haut de la section) \u2192 le fil d'Ariane reste au ras du header et les\n  // r\u00E9sultats commencent juste dessous. Repli sur la section si vide.\n  // + petit espace (anchorGap) pour ne pas coller les r\u00E9sultats au header.\n  const anchorGap = 28\n  const scrollAnchor = newCollectionProducts.querySelector('.custom-row-breakpoint-collection') || newCollectionProducts\n  scrollAnchor.style.scrollMarginTop = `${headerOffset + anchorGap}px`\n  scrollAnchor.scrollIntoView()\n}\n\nclass CollectionFilters extends HTMLElement {\n  constructor () {\n    super()\n\n    this.form = this.querySelector('form')\n\n    if (!this.form) return\n\n    this.form.querySelectorAll('input').forEach(input => {\n      input.addEventListener('change', () => {\n        const params = new URLSearchParams(new FormData(this.form))\n        const url = `${window.location.pathname}?${params.toString()}`\n        window.history.replaceState({}, '', url)\n\n        loadCollection()\n      })\n    })\n\n    this.querySelectorAll('.btn-filters-clear-all').forEach(btn => {\n      const params = new URLSearchParams(window.location.search)\n\n      for (const key of params.keys()) {\n        if (key.includes('filter.')) {\n          btn.removeAttribute('hidden')\n        }\n      }\n\n      btn.addEventListener('click', () => {\n        for (const key of [...params.keys()]) {\n          if (key.includes('filter.')) {\n            params.delete(key)\n          }\n        }\n\n        const url = `${window.location.pathname}?${params.toString()}`\n        window.history.replaceState({}, '', url)\n        loadCollection()\n      })\n    })\n  }\n}\ncustomElements.define('collection-filters', CollectionFilters)\n\nclass SortBy extends HTMLElement {\n  constructor () {\n    super()\n\n    this.querySelectorAll('input, select').forEach(control => {\n      control.addEventListener('change', () => {\n        this.setUrl(control.value)\n        loadCollection()\n      })\n    })\n  }\n\n  setUrl (value) {\n    const params = new URLSearchParams(window.location.search)\n    params.set('sort_by', value)\n    params.delete('page')\n    const url = `${window.location.pathname}?${params.toString()}`\n    window.history.replaceState({}, '', url)\n  }\n}\ncustomElements.define('sort-by', SortBy)\n\nclass Pagination extends HTMLElement {\n  constructor () {\n    super()\n\n    this.querySelectorAll('a').forEach(elem => {\n      elem.addEventListener('click', (event) => {\n        event.preventDefault()\n\n        this.setUrl(elem.dataset.newPage)\n        loadCollection()\n      })\n    })\n  }\n\n  setUrl (value) {\n    const params = new URLSearchParams(window.location.search)\n    params.set('page', value)\n    const url = `${window.location.pathname}?${params.toString()}`\n    window.history.replaceState({}, '', url)\n  }\n}\ncustomElements.define('collection-pagination', Pagination)\n\n/*\n  Load more (maquette 1b) \u2014 utilis\u00E9 sur mobile \u00E0 la place des num\u00E9ros de page.\n  R\u00E9cup\u00E8re la page suivante, ajoute ses cartes \u00E0 la liste courante (append, sans\n  recharger), met \u00E0 jour le compteur \u00AB vu X sur Y \u00BB et l'URL de la page suivante.\n  Les cartes ajout\u00E9es restent fonctionnelles : ATC et points forts sont g\u00E9r\u00E9s par\n  d\u00E9l\u00E9gation d'\u00E9v\u00E9nements sur document (assets/custom.js).\n*/\nclass LoadMore extends HTMLElement {\n  constructor () {\n    super()\n\n    this.button = this.querySelector('[data-load-more-btn]')\n    this.shownEl = this.querySelector('[data-load-more-shown]')\n    this.loading = false\n\n    this.button?.addEventListener('click', () => this.loadMore())\n\n    // Option \u00AB Produits \u00E9puis\u00E9s \u00E0 la fin \u00BB (pages marques) : chargement auto de\n    // toute la collection, cf. autoLoadAll() plus bas.\n    if ('autoAll' in this.dataset) this.autoLoadAll()\n  }\n\n  // Renvoie true si la page suivante a bien \u00E9t\u00E9 ajout\u00E9e (utilis\u00E9 par autoLoadAll)\n  async loadMore () {\n    const nextUrl = this.dataset.nextUrl\n\n    if (!nextUrl || this.loading) return false\n\n    this.loading = true\n    if (this.button) {\n      this.button.disabled = true\n      this.button.classList.add('is-loading')\n    }\n\n    try {\n      const response = await fetch(nextUrl)\n      // Sans ce test, une erreur HTTP vidait `nextUrl` et retirait \u00AB Voir\n      // plus \u00BB alors que la pagination est masqu\u00E9e : collection tronqu\u00E9e\n      // sans recours. Le catch existant restaure bouton et pagination.\n      if (!response.ok) throw new Error(`HTTP ${response.status}`)\n      const data = await response.text()\n      const newDocument = new DOMParser().parseFromString(data, 'text/html')\n\n      const currentList = document.querySelector('.collection-products .product-list')\n      const newList = newDocument.querySelector('.collection-products .product-list')\n\n      if (currentList && newList) {\n        const fragment = document.createDocumentFragment()\n        Array.from(newList.children).forEach(item => fragment.appendChild(item))\n        currentList.appendChild(fragment)\n\n        if (this.shownEl) {\n          // On compte les CARTES, pas tous les enfants : la grille peut aussi\n          // contenir la banni\u00E8re image (snippets/collection-grid-banner.liquid).\n          this.shownEl.textContent = currentList.querySelectorAll(':scope > .product-result-list-item').length\n        }\n      }\n\n      window.dispatchEvent(new CustomEvent('kt.collection.loaded'))\n\n      // URL \u00AB page suivante \u00BB de la page fra\u00EEchement charg\u00E9e (vide si c'\u00E9tait la derni\u00E8re)\n      const newLoadMore = newDocument.querySelector('.collection-products load-more')\n      const newNextUrl = newLoadMore?.dataset.nextUrl\n\n      if (newNextUrl) {\n        this.dataset.nextUrl = newNextUrl\n        if (this.button) {\n          this.button.disabled = false\n          this.button.classList.remove('is-loading')\n        }\n      } else {\n        // Plus de pages : on retire le bouton, le compteur reste affich\u00E9.\n        // nextUrl vid\u00E9 pour que la boucle d'autoLoadAll s'arr\u00EAte proprement.\n        this.dataset.nextUrl = ''\n        this.button?.remove()\n      }\n      return true\n    } catch (error) {\n      if (this.button) {\n        this.button.disabled = false\n        this.button.classList.remove('is-loading')\n      }\n      return false\n    } finally {\n      this.loading = false\n    }\n  }\n\n  /*\n    Pages marques (option \u00AB Produits \u00E9puis\u00E9s \u00E0 la fin \u00BB) : le classement global\n    exige de voir TOUTE la collection, or Liquid ne rend que `limit` produits par\n    page (max 50, et des marques comme DMEGC en ont ~90). On charge donc\n    automatiquement les pages suivantes, et apr\u00E8s chaque ajout on d\u00E9place les\n    cartes \u00E9puis\u00E9es (data-soldout, pos\u00E9 par collection-products.liquid) tout en\n    bas de la liste \u2014 l'ordre relatif de chaque groupe est conserv\u00E9. Num\u00E9ros de\n    page et bouton \u00AB Voir plus \u00BB sont masqu\u00E9s (tout tient sur une seule page) ;\n    en cas d'\u00E9chec r\u00E9seau ils r\u00E9apparaissent (repli en pagination classique).\n    Relanc\u00E9 apr\u00E8s chaque rechargement AJAX (filtres / tri), puisque la section\n    enti\u00E8re \u2014 donc cet \u00E9l\u00E9ment \u2014 est remplac\u00E9e par loadCollection().\n  */\n  async autoLoadAll () {\n    // Lien profond ?page=N : pagination classique, pour ne pas cacher les pages pr\u00E9c\u00E9dentes\n    const pageParam = new URLSearchParams(window.location.search).get('page')\n    if (pageParam && pageParam !== '1') return\n\n    const pagination = document.querySelector('.collection-products collection-pagination')\n    if (pagination) pagination.style.display = 'none'\n    this.style.display = 'none'\n\n    while (this.dataset.nextUrl) {\n      const ok = await this.loadMore()\n      if (!ok) {\n        if (pagination) pagination.style.display = ''\n        this.style.display = ''\n        return\n      }\n      this.partitionSoldOut()\n    }\n  }\n\n  // D\u00E9place les cartes \u00E9puis\u00E9es \u00E0 la fin de la liste (append = retrait + r\u00E9insertion)\n  partitionSoldOut () {\n    const list = document.querySelector('.collection-products .product-list')\n    if (!list) return\n    list.append(...list.querySelectorAll(':scope > [data-soldout]'))\n  }\n}\ncustomElements.define('load-more', LoadMore)\n\n/*\n  Bouton \u00AB retour en haut \u00BB (mobile) \u2014 appara\u00EEt apr\u00E8s avoir scroll\u00E9, remonte\n  en haut de la page au clic. Rendu hors de .collection-products, il persiste\n  aux rechargements AJAX : le listener n'est attach\u00E9 qu'une fois.\n*/\nclass CollectionToTop extends HTMLElement {\n  constructor () {\n    super()\n\n    this.threshold = 600\n    this.button = this.querySelector('button')\n    this.update = this.update.bind(this)\n\n    this.button?.addEventListener('click', () => {\n      window.scrollTo({ top: 0, behavior: 'smooth' })\n    })\n\n    window.addEventListener('scroll', this.update, { passive: true })\n    this.update()\n  }\n\n  update () {\n    this.classList.toggle('is-visible', window.scrollY > this.threshold)\n  }\n}\ncustomElements.define('collection-to-top', CollectionToTop)\n\n/*\n  Slider de puissance (maquette) \u2014 remplace les cases \u00E0 cocher du filtre\n  m\u00E9tachamp custom.puissance par un slider min/max \u00E0 deux poign\u00E9es. Il glisse sur\n  les bornes r\u00E9ellement disponibles (nombres pars\u00E9s depuis le libell\u00E9, ex. \u00AB 200 W \u00BB\n  \u2192 200, \u00AB 5-15 kWh \u00BB \u2192 min 5 / max 15 pour un produit \u00E0 variantes) et coche EN\n  COULISSE les valeurs qui CHEVAUCHENT la plage choisie \u2192 le filtrage AJAX existant\n  (CollectionFilters \u00E9coute le change des cases) s'en charge. Ainsi une batterie\n  \u00AB 5-15 kWh \u00BB ressort m\u00EAme quand le client filtre \u00E0 min 10 (car 15 \u2265 10).\n  L'unit\u00E9 (W/kW/kWh) vient de Liquid selon la collection. Les contr\u00F4les du slider\n  portent [data-power-control] et n'ont pas de name \u2192 exclus du FormData.\n  Au-dessus de la barre : une pastille par valeur du filtre pour choisir une\n  puissance EXACTE \u2014 clic = (d\u00E9)cocher cette seule case, SANS chevauchement\n  (contrairement au slider), les poign\u00E9es se r\u00E9alignent en visuel (deriveIndices).\n  Progressive enhancement : sans JS, les cases \u00E0 cocher restent utilisables ;\n  moins de 2 valeurs distinctes \u2192 pas de slider.\n*/\nclass PowerRangeFilter extends HTMLElement {\n  connectedCallback () {\n    if (this.dataset.ready) return\n\n    this.unit = this.dataset.unit || ''\n    this.checkboxes = [...this.querySelectorAll('input[type=\"checkbox\"]')]\n    // Chaque case peut porter une valeur ponctuelle (\u00AB 10 kWh \u00BB) ou une plage\n    // (\u00AB 5-15 kWh \u00BB, pour un produit \u00E0 variantes) : on retient min ET max.\n    this.items = this.checkboxes\n      .map(cb => { const r = this.parseRange(cb.value); return r ? { cb, min: r.min, max: r.max } : null })\n      .filter(Boolean)\n    // Arr\u00EAts du slider = toutes les bornes distinctes (les min ET les max) : le max\n    // d'une plage (15) devient une but\u00E9e atteignable m\u00EAme sans produit ponctuel \u00E0 15.\n    this.nums = [...new Set(this.items.flatMap(it => [it.min, it.max]))].sort((a, b) => a - b)\n\n    if (this.nums.length < 2) return // pas assez de valeurs distinctes pour un slider\n    this.dataset.ready = '1'\n    this.N = this.nums.length\n\n    // \u00C9tat initial d'apr\u00E8s les cases d\u00E9j\u00E0 coch\u00E9es (filtre actif dans l'URL)\n    this.loIdx = 0\n    this.hiIdx = this.N - 1\n    const checked = this.items.filter(it => it.cb.checked)\n    if (checked.length) {\n      const idx = this.deriveIndices(checked)\n      this.loIdx = idx.lo\n      this.hiIdx = idx.hi\n    }\n\n    this.build()\n    this.refresh()\n    this.refreshChips()\n  }\n\n  parseNum (str) {\n    const m = String(str).replace(',', '.').match(/\\d+(?:\\.\\d+)?/)\n    return m ? parseFloat(m[0]) : null\n  }\n\n  // Extrait la plage num\u00E9rique d'un libell\u00E9 : \u00AB 5-15 kWh \u00BB \u2192 {min:5, max:15},\n  // \u00AB 200 W \u00BB \u2192 {min:200, max:200}. Tol\u00E8re \u00AB - \u00BB, \u00AB \u00E0 \u00BB, espaces et d\u00E9cimales.\n  parseRange (str) {\n    const matches = String(str).replace(/,/g, '.').match(/\\d+(?:\\.\\d+)?/g)\n    if (!matches) return null\n    const nums = matches.map(Number)\n    return { min: Math.min(...nums), max: Math.max(...nums) }\n  }\n\n  // Retrouve les index [lo,hi] du slider \u00E0 partir des cases coch\u00E9es (retour depuis\n  // l'URL). Avec le chevauchement, min(coch\u00E9s) peut sous-estimer lo (une plage\n  // \u00AB 5-15 \u00BB coch\u00E9e \u00E0 partir de 10 a min=5) : on cherche donc un couple d'arr\u00EAts qui\n  // reproduit EXACTEMENT l'ensemble coch\u00E9 (N petit \u2192 force brute). Plusieurs couples\n  // peuvent donner le m\u00EAme r\u00E9sultat quand un arr\u00EAt n'existe que comme max de plage\n  // (ex. 15) ; on retient alors le plus LARGE, pour garder la poign\u00E9e max ouverte \u2014\n  // \u00E7a colle au raisonnement \u00AB minimum X, max ouvert \u00BB du client. Repli si aucun ne\n  // colle (URL forg\u00E9e \u00E0 la main) : borne large min/max des coch\u00E9s.\n  deriveIndices (checked) {\n    const checkedSet = new Set(checked.map(it => it.cb))\n    const reproduces = (lo, hi) =>\n      this.items.every(it =>\n        (it.max >= this.nums[lo] && it.min <= this.nums[hi]) === checkedSet.has(it.cb))\n    let best = null\n    for (let lo = 0; lo < this.N; lo++) {\n      for (let hi = lo; hi < this.N; hi++) {\n        if (reproduces(lo, hi) && (!best || hi - lo > best.hi - best.lo)) best = { lo, hi }\n      }\n    }\n    if (best) return best\n    return {\n      lo: this.nums.indexOf(Math.min(...checked.map(it => it.min))),\n      hi: this.nums.indexOf(Math.max(...checked.map(it => it.max)))\n    }\n  }\n\n  build () {\n    const ul = this.querySelector('ul')\n    if (ul) ul.hidden = true\n\n    const wrap = document.createElement('div')\n    wrap.className = 'power-range'\n    wrap.innerHTML =\n      '<div class=\"power-range__inputs\">' +\n        '<label class=\"power-range__field\">' +\n          '<span class=\"power-range__field-label\">Min.</span>' +\n          '<input type=\"number\" class=\"power-range__num power-range__num--min\" data-power-control step=\"any\" aria-label=\"Puissance minimale\">' +\n        '</label>' +\n        '<span class=\"power-range__sep\">\u00E0</span>' +\n        '<label class=\"power-range__field\">' +\n          '<span class=\"power-range__field-label\">Max.</span>' +\n          '<input type=\"number\" class=\"power-range__num power-range__num--max\" data-power-control step=\"any\" aria-label=\"Puissance maximale\">' +\n        '</label>' +\n        '<span class=\"power-range__unit\">' + this.unit + '</span>' +\n      '</div>' +\n      '<div class=\"power-range__slider\">' +\n        '<div class=\"power-range__track\"></div>' +\n        '<div class=\"power-range__fill\"></div>' +\n        '<input type=\"range\" class=\"power-range__handle power-range__handle--min\" data-power-control min=\"0\" max=\"' + (this.N - 1) + '\" step=\"1\" value=\"' + this.loIdx + '\" aria-label=\"Curseur minimum\">' +\n        '<input type=\"range\" class=\"power-range__handle power-range__handle--max\" data-power-control min=\"0\" max=\"' + (this.N - 1) + '\" step=\"1\" value=\"' + this.hiIdx + '\" aria-label=\"Curseur maximum\">' +\n      '</div>'\n\n    // Pastilles \u00AB puissance exacte \u00BB au-dessus de la barre : une par valeur du\n    // filtre, tri\u00E9es num\u00E9riquement (l'ordre Shopify des cases est alphab\u00E9tique :\n    // \u00AB 10 kWh \u00BB passerait avant \u00AB 5 kWh \u00BB). Libell\u00E9 repris de la case masqu\u00E9e.\n    const chips = document.createElement('div')\n    chips.className = 'power-range__chips'\n    const sorted = [...this.items].sort((a, b) => a.min - b.min || a.max - b.max)\n    for (const it of sorted) {\n      const btn = document.createElement('button')\n      btn.type = 'button'\n      btn.className = 'power-range__chip'\n      btn.setAttribute('data-power-control', '')\n      const labelEl = it.cb.closest('.form-check')?.querySelector('.form-check-label span')\n      btn.textContent = labelEl ? labelEl.textContent.trim() : it.cb.value\n      btn.disabled = it.cb.disabled\n      btn.addEventListener('click', () => this.onChip(it))\n      it.chip = btn\n      chips.appendChild(btn)\n    }\n    wrap.insertBefore(chips, wrap.firstChild)\n\n    this.appendChild(wrap)\n\n    this.numMin = wrap.querySelector('.power-range__num--min')\n    this.numMax = wrap.querySelector('.power-range__num--max')\n    this.hMin = wrap.querySelector('.power-range__handle--min')\n    this.hMax = wrap.querySelector('.power-range__handle--max')\n    this.fill = wrap.querySelector('.power-range__fill')\n    this.sliderEl = wrap.querySelector('.power-range__slider')\n\n    for (const el of [this.numMin, this.numMax]) {\n      el.min = this.nums[0]\n      el.max = this.nums[this.N - 1]\n    }\n\n    this.hMin.addEventListener('input', () => this.onHandle('min'))\n    this.hMax.addEventListener('input', () => this.onHandle('max'))\n    this.hMin.addEventListener('change', () => this.commit())\n    this.hMax.addEventListener('change', () => this.commit())\n    this.numMin.addEventListener('change', () => this.onNum('min'))\n    this.numMax.addEventListener('change', () => this.onNum('max'))\n  }\n\n  onHandle (which) {\n    let lo = parseInt(this.hMin.value, 10)\n    let hi = parseInt(this.hMax.value, 10)\n    if (lo > hi) {\n      if (which === 'min') { lo = hi } else { hi = lo }\n    }\n    this.loIdx = lo\n    this.hiIdx = hi\n    this.refresh()\n  }\n\n  onNum (which) {\n    const val = this.parseNum(which === 'min' ? this.numMin.value : this.numMax.value)\n    if (val !== null) {\n      const idx = this.nearestIdx(val)\n      if (which === 'min') {\n        this.loIdx = Math.min(idx, this.hiIdx)\n      } else {\n        this.hiIdx = Math.max(idx, this.loIdx)\n      }\n    }\n    this.refresh()\n    this.commit()\n  }\n\n  // Choix EXACT : (d\u00E9)coche uniquement cette valeur \u2014 pas de logique de\n  // chevauchement, contrairement au slider. Les poign\u00E9es se r\u00E9alignent en visuel\n  // seulement (deriveIndices) : surtout ne pas repasser par syncCheckboxes, qui\n  // r\u00E9-\u00E9largirait la s\u00E9lection \u00E0 tout ce qui chevauche.\n  onChip (it) {\n    it.cb.checked = !it.cb.checked\n    const checked = this.items.filter(x => x.cb.checked)\n    if (checked.length) {\n      const idx = this.deriveIndices(checked)\n      this.loIdx = idx.lo\n      this.hiIdx = idx.hi\n    } else {\n      this.loIdx = 0\n      this.hiIdx = this.N - 1\n    }\n    this.refresh()\n    this.refreshChips()\n    it.cb.dispatchEvent(new Event('change', { bubbles: true }))\n  }\n\n  refreshChips () {\n    this.items.forEach(it => {\n      if (!it.chip) return\n      it.chip.classList.toggle('is-active', it.cb.checked)\n      it.chip.setAttribute('aria-pressed', it.cb.checked ? 'true' : 'false')\n    })\n  }\n\n  nearestIdx (val) {\n    let best = 0\n    let bestDist = Infinity\n    this.nums.forEach((n, i) => {\n      const d = Math.abs(n - val)\n      if (d < bestDist) { bestDist = d; best = i }\n    })\n    return best\n  }\n\n  refresh () {\n    this.hMin.value = this.loIdx\n    this.hMax.value = this.hiIdx\n    this.numMin.value = this.nums[this.loIdx]\n    this.numMax.value = this.nums[this.hiIdx]\n    const span = this.N - 1\n    this.fill.style.left = ((this.loIdx / span) * 100) + '%'\n    this.fill.style.right = (100 - (this.hiIdx / span) * 100) + '%'\n    // La poign\u00E9e min passe au-dessus quand les deux sont au maximum (sinon inatteignable)\n    this.hMin.style.zIndex = this.loIdx >= span ? 6 : 3\n    // M\u00EAme valeur min == max : d\u00E9caler les 2 poign\u00E9es c\u00F4te \u00E0 c\u00F4te (pas superpos\u00E9es)\n    this.sliderEl.classList.toggle('power-range__slider--point', this.loIdx === this.hiIdx)\n  }\n\n  syncCheckboxes () {\n    const lo = this.nums[this.loIdx]\n    const hi = this.nums[this.hiIdx]\n    const full = this.loIdx === 0 && this.hiIdx === this.N - 1\n    this.items.forEach(it => {\n      // Chevauchement : la case est coch\u00E9e d\u00E8s que la plage du produit [min,max]\n      // recoupe la plage choisie [lo,hi]. Un produit \u00AB 5-15 kWh \u00BB ressort donc\n      // aussi quand le client filtre \u00E0 un minimum de 10 (car 15 \u2265 10), pas seulement \u00E0 5.\n      it.cb.checked = full ? false : (it.max >= lo && it.min <= hi)\n    })\n  }\n\n  commit () {\n    this.syncCheckboxes()\n    this.refreshChips()\n    const trigger = this.checkboxes.find(cb => !cb.disabled) || this.checkboxes[0]\n    if (trigger) trigger.dispatchEvent(new Event('change', { bubbles: true }))\n  }\n}\ncustomElements.define('power-range-filter', PowerRangeFilter)\n\n/*\n  Tiroir Filtres ouvert (mobile/tablette) : certains widgets flottants d'apps\n  (position:fixed, ajout\u00E9s au <body>) chevauchent le panneau \u2014 R\u00E9compenses\n  (Smile.io) et Inbox (Shopify Inbox). On pose une classe sur <body> \u00E0 l'ouverture\n  et on la retire \u00E0 la fermeture ; le masquage r\u00E9el, PAR BREAKPOINT (tablette vs\n  mobile), est g\u00E9r\u00E9 en CSS (assets/collection.css). M\u00EAme approche que le panier\n  (body.cart-offcanvas-open, cf. assets/cart.js). Le conteneur du tiroir\n  (#offcanvas-collection-filters) n'est PAS remplac\u00E9 par l'AJAX de filtrage\n  (seul son contenu .collection-filters l'est) \u2192 les \u00E9couteurs restent valides.\n*/\n;(function () {\n  const drawer = document.getElementById('offcanvas-collection-filters')\n  if (!drawer) return\n  drawer.addEventListener('show.bs.offcanvas', () => {\n    document.body.classList.add('mds-filter-offcanvas-open')\n  })\n  drawer.addEventListener('hidden.bs.offcanvas', () => {\n    document.body.classList.remove('mds-filter-offcanvas-open')\n  })\n})()\n\n/*\n  Banni\u00E8re VID\u00C9O de la grille (snippets/collection-grid-banner.liquid).\n  La banni\u00E8re est rendue une fois par palier d'\u00E9cran (mobile / tablette /\n  desktop) et les exemplaires hors palier sont en display:none. Pour une image\n  \u00E7a suffit (loading=\"lazy\" ne t\u00E9l\u00E9charge rien de masqu\u00E9), mais un <video>\n  t\u00E9l\u00E9chargerait sa source m\u00EAme masqu\u00E9 : l'URL du MP4 est donc pos\u00E9e sur\n  `data-src` c\u00F4t\u00E9 Liquid et n'est activ\u00E9e QUE pour l'exemplaire r\u00E9ellement\n  visible et proche du viewport \u2192 un seul t\u00E9l\u00E9chargement, au bon format.\n  L'observateur sert aussi de lecteur : lecture \u00E0 l'entr\u00E9e dans l'\u00E9cran, pause\n  \u00E0 la sortie (une banni\u00E8re hors-champ ne consomme pas de CPU).\n  Rejou\u00E9 apr\u00E8s chaque rechargement AJAX (filtres, tri, \u00AB Voir plus \u00BB), qui\n  remplace la grille : les nouveaux \u00E9l\u00E9ments doivent \u00EAtre observ\u00E9s \u00E0 leur tour.\n*/\n;(function () {\n  // Respecte \u00AB r\u00E9duire les animations \u00BB : on laisse l'affiche (poster) fixe.\n  if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return\n\n  const hydrate = (video) => {\n    if (video.dataset.bannerVideoLoaded) return\n    video.dataset.bannerVideoLoaded = 'true'\n    video.querySelectorAll('source[data-src]').forEach(source => {\n      source.src = source.dataset.src\n      source.removeAttribute('data-src')\n    })\n    video.load()\n  }\n\n  const observer = 'IntersectionObserver' in window\n    ? new IntersectionObserver(entries => {\n        entries.forEach(entry => {\n          const video = entry.target\n          if (entry.isIntersecting) {\n            hydrate(video)\n            // Muette : la lecture auto est autoris\u00E9e. Le .catch absorbe les\n            // refus \u00E9ventuels (mode \u00E9conomie d'\u00E9nergie) sans casser la page.\n            video.play().catch(() => {})\n          } else if (!video.paused) {\n            video.pause()\n          }\n        })\n      }, { rootMargin: '200px' })\n    : null\n\n  const scan = () => {\n    document.querySelectorAll('video[data-banner-video]').forEach(video => {\n      if (video.dataset.bannerVideoBound) return\n      video.dataset.bannerVideoBound = 'true'\n      // Sans IntersectionObserver (tr\u00E8s anciens navigateurs) : on charge\n      // seulement si l'exemplaire est visible (offsetParent null = display:none).\n      if (observer) {\n        observer.observe(video)\n      } else if (video.offsetParent !== null) {\n        hydrate(video)\n        video.play().catch(() => {})\n      }\n    })\n  }\n\n  scan()\n  window.addEventListener('kt.collection.loaded', scan)\n})()\n\n/*\n  Bascule d'affichage \u00AB Voir \u00BB grille / liste (snippets/collection-utilities.liquid).\n  L'\u00E9tat vit dans la classe html.mds-view-list (pos\u00E9e avant le rendu des cartes\n  par le script inline du snippet) : <html> n'est jamais remplac\u00E9 par les\n  rechargements AJAX de loadCollection(), la vue choisie survit donc aux filtres,\n  au tri et \u00E0 la pagination. M\u00E9moris\u00E9 dans localStorage (pr\u00E9f\u00E9rence du visiteur,\n  toutes collections confondues). Styles de la vue liste : assets/collection.css.\n*/\nconst COLLECTION_VIEW_KEY = 'mds-collection-view'\n\nclass CollectionViewToggle extends HTMLElement {\n  connectedCallback () {\n    if (this.dataset.ready) return\n    this.dataset.ready = '1'\n\n    this.buttons = [...this.querySelectorAll('[data-view]')]\n    this.buttons.forEach(btn =>\n      btn.addEventListener('click', () => this.setView(btn.dataset.view)))\n    this.sync()\n  }\n\n  sync () {\n    const isList = document.documentElement.classList.contains('mds-view-list')\n    this.buttons.forEach(btn =>\n      btn.setAttribute('aria-pressed', String((btn.dataset.view === 'list') === isList)))\n  }\n\n  setView (view) {\n    document.documentElement.classList.toggle('mds-view-list', view === 'list')\n    try {\n      localStorage.setItem(COLLECTION_VIEW_KEY, view)\n    } catch (error) {\n      // Navigation priv\u00E9e / stockage bloqu\u00E9 : la vue reste valable pour la page\n    }\n    this.sync()\n  }\n}\ncustomElements.define('collection-view-toggle', CollectionViewToggle)\n\n/*\n  \u00AB Aper\u00E7u rapide \u00BB (vue liste, desktop + tablette) : bouton\n  .product-card-quick-view des cartes (snippets/product-card.liquid).\n  Un seul popup Bootstrap #mds-quick-view, cr\u00E9\u00E9 au premier clic et rattach\u00E9 \u00E0\n  <body> (hors de la section remplac\u00E9e par l'AJAX des filtres). Son contenu est\n  la section AJAX sections/product-quick-view.liquid, rendue dans le contexte du\n  produit (?section_id=product-quick-view) et gard\u00E9e en cache par URL ; elle est\n  pr\u00E9charg\u00E9e au survol du bouton. D\u00E9l\u00E9gation sur document : les cartes ajout\u00E9es\n  par \u00AB Voir plus \u00BB ou les filtres n'ont rien \u00E0 r\u00E9initialiser.\n  Ajout au panier : requ\u00EAte /cart/add.js faite ici (erreurs affich\u00E9es DANS le\n  popup), puis fermeture du popup et SEULEMENT ENSUITE kt.cart.added \u2192 le popup\n  \u00AB Ajout\u00E9 au panier \u00BB s'ouvre sur une page sans autre modal (deux modals\n  Bootstrap superpos\u00E9s se disputent le verrou de scroll du <body>).\n*/\n;(function () {\n  const SECTION_ID = 'product-quick-view'\n  const sectionCache = new Map()\n  const canHoverZoom = window.matchMedia('(hover: hover) and (pointer: fine)')\n\n  let modalEl = null\n  let bodyEl = null\n  let modal = null\n  let trigger = null\n  let openToken = 0\n  let addedCart = null\n\n  const loadingHTML =\n    '<div class=\"qv-modal__loading\" role=\"status\">' +\n      '<span class=\"qv-modal__spinner\" aria-hidden=\"true\"></span>' +\n      '<span class=\"visually-hidden\">Chargement de l\u2019aper\u00E7u\u2026</span>' +\n    '</div>'\n\n  const fetchSection = (productUrl) => {\n    if (!sectionCache.has(productUrl)) {\n      const request = (async () => {\n        const url = new URL(productUrl, window.location.origin)\n        url.search = ''\n        url.searchParams.set('section_id', SECTION_ID)\n        // Le rendu de section renvoie des 503 passagers sur cette boutique\n        // (cf. cart-added-popup.js) : quelques nouveaux essais espac\u00E9s.\n        for (const delay of [0, 600, 1500, 3000]) {\n          if (delay) await new Promise(resolve => setTimeout(resolve, delay))\n          try {\n            const response = await fetch(url.toString())\n            if (response.ok) return await response.text()\n          } catch (error) {\n            // r\u00E9seau : nouvel essai\n          }\n        }\n        throw new Error('section indisponible')\n      })()\n      sectionCache.set(productUrl, request)\n      request.catch(() => sectionCache.delete(productUrl))\n    }\n    return sectionCache.get(productUrl)\n  }\n\n  const stopMedia = (scope) => {\n    if (!scope) return\n    scope.querySelectorAll('video').forEach(video => video.pause())\n    scope.querySelectorAll('[data-qv-embed]').forEach(embed => { embed.innerHTML = '' })\n  }\n\n  // M\u00EAme suite que Cart.add (assets/cart.js) une fois la requ\u00EAte r\u00E9ussie\n  const announceCartAdd = (data) => {\n    window.dispatchEvent(new CustomEvent('kt.cart.added', { detail: data }))\n    const cart = document.querySelector('cart-container')\n    if (cart && data.sections && typeof cart.reloadCartElements === 'function') {\n      cart.reloadCartElements(data.sections)\n    }\n    if (!document.querySelector('cart-added-popup')) {\n      const drawer = document.getElementById('offcanvas-cart')\n      if (drawer) window.bootstrap.Offcanvas.getOrCreateInstance(drawer).show()\n    }\n  }\n\n  const ensureModal = () => {\n    if (modalEl) return\n    modalEl = document.createElement('div')\n    modalEl.id = 'mds-quick-view'\n    modalEl.className = 'modal fade qv-modal'\n    modalEl.tabIndex = -1\n    modalEl.setAttribute('aria-labelledby', 'mds-quick-view-title')\n    modalEl.setAttribute('aria-hidden', 'true')\n    modalEl.innerHTML =\n      '<div class=\"modal-dialog modal-dialog-centered modal-dialog-scrollable qv-modal__dialog\">' +\n        '<div class=\"modal-content qv-modal__content\">' +\n          '<button type=\"button\" class=\"qv-modal__close\" data-bs-dismiss=\"modal\" aria-label=\"Fermer\">' +\n            '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M18 6 6 18M6 6l12 12\"/></svg>' +\n          '</button>' +\n          '<div class=\"modal-body qv-modal__body\" data-qv-body></div>' +\n        '</div>' +\n      '</div>'\n    document.body.appendChild(modalEl)\n    bodyEl = modalEl.querySelector('[data-qv-body]')\n    modal = window.bootstrap.Modal.getOrCreateInstance(modalEl)\n\n    // Fermeture : couper vid\u00E9os / iframes encore en lecture\n    modalEl.addEventListener('hide.bs.modal', () => stopMedia(bodyEl))\n    modalEl.addEventListener('hidden.bs.modal', () => {\n      if (addedCart) {\n        const data = addedCart\n        addedCart = null\n        announceCartAdd(data)\n        return\n      }\n      if (trigger && trigger.isConnected) trigger.focus()\n    })\n  }\n\n  const initQuickView = (root) => {\n    const slides = [...root.querySelectorAll('[data-qv-slide]')]\n    const thumbs = [...root.querySelectorAll('[data-qv-thumb]')]\n\n    const showSlide = (index) => {\n      slides.forEach((slide, i) => {\n        const active = i === index\n        if (!active) stopMedia(slide)\n        slide.hidden = !active\n        const embed = active ? slide.querySelector('[data-qv-embed]') : null\n        if (embed && !embed.firstChild) {\n          const iframe = document.createElement('iframe')\n          iframe.src = embed.dataset.qvEmbed\n          iframe.title = embed.dataset.qvEmbedTitle || ''\n          iframe.allow = 'autoplay; encrypted-media; fullscreen; picture-in-picture'\n          iframe.allowFullscreen = true\n          embed.appendChild(iframe)\n        }\n      })\n      thumbs.forEach((thumb, i) => {\n        thumb.classList.toggle('is-active', i === index)\n        thumb.setAttribute('aria-pressed', String(i === index))\n      })\n    }\n\n    thumbs.forEach(thumb =>\n      thumb.addEventListener('click', () => showSlide(Number(thumb.dataset.qvThumb))))\n\n    // Zoom au survol (souris uniquement) : loupe = image HD en fond agrandi,\n    // positionn\u00E9e d'apr\u00E8s le pointeur, dans une bo\u00EEte qui \u00E9pouse l'image.\n    if (canHoverZoom.matches) {\n      root.querySelectorAll('[data-qv-zoom]').forEach(zoom => {\n        const lens = zoom.querySelector('.qv__zoom-lens')\n        if (!lens) return\n        const move = (event) => {\n          const rect = zoom.getBoundingClientRect()\n          const x = Math.min(100, Math.max(0, (event.clientX - rect.left) / rect.width * 100))\n          const y = Math.min(100, Math.max(0, (event.clientY - rect.top) / rect.height * 100))\n          lens.style.backgroundPosition = `${x}% ${y}%`\n        }\n        zoom.addEventListener('mouseenter', (event) => {\n          if (!lens.style.backgroundImage) lens.style.backgroundImage = `url(\"${zoom.dataset.zoomSrc}\")`\n          move(event)\n          zoom.classList.add('is-zooming')\n        })\n        zoom.addEventListener('mousemove', move)\n        zoom.addEventListener('mouseleave', () => zoom.classList.remove('is-zooming'))\n      })\n    } else {\n      root.classList.add('qv--no-zoom')\n    }\n\n    const form = root.querySelector('[data-qv-form]')\n    if (!form) return\n\n    // Quantit\u00E9 : minimum d'achat = le plus restrictif entre le th\u00E8me\n    // (data-min-quantity) et la r\u00E8gle Pareto (cf. ajout rapide, custom.js)\n    let minQty = Math.max(1, parseInt(root.dataset.minQuantity, 10) || 1)\n    if (typeof window.mdsParetoMinQuantity === 'function') {\n      minQty = Math.max(minQty, window.mdsParetoMinQuantity(root.dataset.productId, root.dataset.collectionIds))\n    }\n    const qtyInput = form.querySelector('[data-qv-qty-input]')\n    const qtyMinus = form.querySelector('[data-qv-qty=\"-1\"]')\n    const clampQty = () => {\n      if (!qtyInput) return\n      const value = Math.max(minQty, parseInt(qtyInput.value, 10) || minQty)\n      qtyInput.value = value\n      if (qtyMinus) qtyMinus.disabled = value <= minQty\n    }\n    if (qtyInput) {\n      qtyInput.min = minQty\n      clampQty()\n      qtyInput.addEventListener('change', clampQty)\n      form.querySelectorAll('[data-qv-qty]').forEach(btn => btn.addEventListener('click', () => {\n        qtyInput.value = (parseInt(qtyInput.value, 10) || minQty) + Number(btn.dataset.qvQty)\n        clampQty()\n      }))\n    }\n\n    // Variantes (produits \u00E0 options) : selects \u2192 variante, prix et disponibilit\u00E9\n    const atcBtn = form.querySelector('[data-qv-atc]')\n    const buyBtn = form.querySelector('[data-qv-buy]')\n    const idInput = form.querySelector('[name=\"id\"]')\n    const optionSelects = [...form.querySelectorAll('[data-qv-option]')]\n    const variantsJson = root.querySelector('[data-qv-variants]')\n    if (optionSelects.length && variantsJson) {\n      let variants = []\n      try { variants = JSON.parse(variantsJson.textContent) } catch (error) { variants = [] }\n      const locales = (window.theme && window.theme.locales && window.theme.locales.product) || {}\n      const money = (cents) => window.Shopify.formatMoney(cents)\n\n      optionSelects.forEach(select => select.addEventListener('change', () => {\n        const selected = optionSelects.map(s => s.value)\n        const variant = variants.find(v => JSON.stringify(v.options) === JSON.stringify(selected)) || null\n        const available = !!(variant && variant.available)\n\n        if (variant) {\n          idInput.value = variant.id\n          const onSale = variant.compare_at_price > variant.price\n          const priceEl = root.querySelector('[data-qv-price]')\n          const compareEl = root.querySelector('[data-qv-compare]')\n          const badgeEl = root.querySelector('[data-qv-badge]')\n          priceEl.textContent = money(variant.price)\n          priceEl.classList.toggle('is-sale', onSale)\n          compareEl.textContent = onSale ? money(variant.compare_at_price) : ''\n          compareEl.hidden = !onSale\n          badgeEl.hidden = !onSale\n          if (onSale) badgeEl.querySelector('[data-qv-savings]').textContent = money(variant.compare_at_price - variant.price)\n\n          const mediaId = variant.featured_media && variant.featured_media.id\n          const slideIndex = mediaId ? slides.findIndex(s => s.dataset.mediaId === String(mediaId)) : -1\n          if (slideIndex >= 0) showSlide(slideIndex)\n        }\n\n        if (atcBtn) {\n          atcBtn.disabled = !available\n          atcBtn.textContent = available\n            ? (locales.add_to_cart || 'Ajouter au panier')\n            : (variant ? (locales.sold_out || '\u00C9puis\u00E9') : (locales.unavailable || 'Indisponible'))\n        }\n        if (buyBtn) buyBtn.disabled = !available\n        const qtyRow = form.querySelector('[data-qv-qty-row]')\n        if (qtyRow) qtyRow.hidden = !available\n      }))\n    }\n\n    const errorEl = form.querySelector('[data-qv-error]')\n\n    const addToCart = async (withSections) => {\n      clampQty()\n      const formData = new FormData(form)\n      const cart = document.querySelector('cart-container')\n      if (withSections && cart && typeof cart.sectionsToRender === 'function') {\n        formData.append('sections', cart.sectionsToRender())\n        formData.append('sections_url', window.location.pathname)\n      }\n      const routes = window.Shopify.routes || {}\n      const response = await fetch(`${routes.cart_add_url || '/cart/add'}.js`, {\n        method: 'POST',\n        headers: { Accept: 'application/json' },\n        body: formData\n      })\n      let data = {}\n      try { data = await response.json() } catch (error) { data = {} }\n      if (!response.ok) throw new Error(data.description || data.message || '')\n      return data\n    }\n\n    const run = async (button, action) => {\n      if (!button || button.classList.contains('loading')) return\n      if (errorEl) errorEl.hidden = true\n      button.classList.add('loading')\n      button.disabled = true\n      try {\n        await action()\n      } catch (error) {\n        console.error('MDS aper\u00E7u rapide \u2014 ajout au panier :', error)\n        if (errorEl) {\n          errorEl.textContent = error.message || 'Une erreur est survenue, merci de r\u00E9essayer.'\n          errorEl.hidden = false\n        }\n        button.classList.remove('loading')\n        button.disabled = false\n      }\n    }\n\n    form.addEventListener('submit', (event) => {\n      event.preventDefault()\n      run(atcBtn, async () => {\n        const data = await addToCart(true)\n        // La suite (popup \u00AB Ajout\u00E9 au panier \u00BB) part du hidden.bs.modal\n        addedCart = data\n        modal.hide()\n      })\n    })\n\n    // \u00AB Achetez-le maintenant \u00BB : comme la fiche produit (buyNowToCart,\n    // assets/product.js) \u2014 ajout puis page panier. Le bouton reste en\n    // chargement pendant la navigation.\n    buyBtn?.addEventListener('click', () => run(buyBtn, async () => {\n      await addToCart(false)\n      window.location.href = (window.Shopify.routes && window.Shopify.routes.cart_url) || '/cart'\n    }))\n\n    // Bouton \u00AB copier le lien \u00BB du partage (product-share-buttons)\n    const copyBtn = root.querySelector('[data-share-copy]')\n    copyBtn?.addEventListener('click', async () => {\n      const feedback = copyBtn.parentElement?.querySelector('.pdp-share__copied')\n      try {\n        await navigator.clipboard.writeText(copyBtn.dataset.shareUrl || window.location.href)\n        if (feedback) {\n          feedback.hidden = false\n          setTimeout(() => { feedback.hidden = true }, 2000)\n        }\n      } catch (error) {\n        // Presse-papiers indisponible : pas de confirmation affich\u00E9e\n      }\n    })\n  }\n\n  const open = async (productUrl, button) => {\n    ensureModal()\n    trigger = button\n    addedCart = null\n    const token = ++openToken\n    bodyEl.innerHTML = loadingHTML\n    modal.show()\n\n    try {\n      const html = await fetchSection(productUrl)\n      if (token !== openToken) return\n      const doc = new DOMParser().parseFromString(html, 'text/html')\n      const root = doc.querySelector('[data-qv]')\n      if (!root) throw new Error('aper\u00E7u absent de la section')\n      bodyEl.replaceChildren(root)\n      initQuickView(root)\n    } catch (error) {\n      if (token !== openToken) return\n      console.error('MDS aper\u00E7u rapide :', error)\n      bodyEl.innerHTML =\n        '<div class=\"qv-modal__fail\">' +\n          '<p>L\u2019aper\u00E7u de ce produit n\u2019a pas pu \u00EAtre charg\u00E9.</p>' +\n          '<a class=\"btn btn-primary\" href=\"' + productUrl + '\">Voir la fiche produit</a>' +\n        '</div>'\n    }\n  }\n\n  document.addEventListener('click', (event) => {\n    const button = event.target instanceof Element ? event.target.closest('[data-quick-view-url]') : null\n    if (!button) return\n    event.preventDefault()\n    open(button.dataset.quickViewUrl, button)\n  })\n\n  // Pr\u00E9chargement au survol / focus du bouton : l'aper\u00E7u s'ouvre sans attente\n  const prefetch = (event) => {\n    const button = event.target instanceof Element ? event.target.closest('[data-quick-view-url]') : null\n    if (button) fetchSection(button.dataset.quickViewUrl).catch(() => {})\n  }\n  document.addEventListener('pointerover', prefetch, { passive: true })\n  document.addEventListener('focusin', prefetch)\n})()\n"],
  "mappings": "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",
  "names": []
}
