<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Preview Layout</title>
    <link media="all" rel="stylesheet" href="../../css/plyr.css">
    <link media="all" rel="stylesheet" href="../../css/swiper-bundle.min.css">
    <link media="all" rel="stylesheet" href="../../css/styles.css">
    <script>
        window.APP = {
            modules: {},
            addModule: function(name, config) {
                this.modules[name] = this.modules[name] || [];
                this.modules[name].push(config);
            },
            DEBUG: 0,
            CONFIG: {},
        };
    </script>

    <style>
        body {
            margin: 25px !important;
        }
    </style>
</head>

<body style="background-color: " class="antialiased text-base font-sans ">
    <script>
        'use strict';
        (function(hyva, undefined) {
            function lifetimeToExpires(options, defaults) {
                const lifetime = options.lifetime || defaults.lifetime;
                if (lifetime) {
                    const date = new Date;
                    date.setTime(date.getTime() + lifetime * 1000);
                    return date;
                }
                return null;
            }

            function generateRandomString() {
                const allowedCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
                    length = 16;
                let formKey = '',
                    charactersLength = allowedCharacters.length;
                for (let i = 0; i < length; i++) {
                    formKey += allowedCharacters[Math.round(Math.random() * (charactersLength - 1))]
                }
                return formKey;
            }
            const sessionCookieMarker = {
                noLifetime: true
            }
            const cookieTempStorage = {};
            const internalCookie = {
                get(name) {
                    const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
                    return v ? v[2] : null;
                },
                set(name, value, days, skipSetDomain) {
                    let expires,
                        path,
                        domain,
                        secure,
                        samesite;
                    const defaultCookieConfig = {
                        expires: null,
                        path: '/',
                        domain: null,
                        secure: false,
                        lifetime: null,
                        samesite: 'lax'
                    };
                    const cookieConfig = window.COOKIE_CONFIG || {};
                    expires = days && days !== sessionCookieMarker ?
                        lifetimeToExpires({
                            lifetime: 24 * 60 * 60 * days,
                            expires: null
                        }, defaultCookieConfig) :
                        lifetimeToExpires(window.COOKIE_CONFIG, defaultCookieConfig) || defaultCookieConfig.expires;
                    path = cookieConfig.path || defaultCookieConfig.path;
                    domain = !skipSetDomain && (cookieConfig.domain || defaultCookieConfig.domain);
                    secure = cookieConfig.secure || defaultCookieConfig.secure;
                    samesite = cookieConfig.samesite || defaultCookieConfig.samesite;
                    document.cookie = name + "=" + encodeURIComponent(value) +
                        (expires && days !== sessionCookieMarker ? '; expires=' + expires.toGMTString() : '') +
                        (path ? '; path=' + path : '') +
                        (domain ? '; domain=' + domain : '') +
                        (secure ? '; secure' : '') +
                        (samesite ? '; samesite=' + samesite : 'lax');
                },
                isWebsiteAllowedToSaveCookie() {
                    const allowedCookies = this.get('user_allowed_save_cookie');
                    if (allowedCookies) {
                        const allowedWebsites = JSON.parse(unescape(allowedCookies));
                        return allowedWebsites[CURRENT_WEBSITE_ID] === 1;
                    }
                    return false;
                },
                getGroupByCookieName(name) {
                    const cookieConsentConfig = window.cookie_consent_config || {};
                    let group = null;
                    for (let prop in cookieConsentConfig) {
                        if (!cookieConsentConfig.hasOwnProperty(prop)) continue;
                        if (cookieConsentConfig[prop].includes(name)) {
                            group = prop;
                            break;
                        }
                    }
                    return group;
                },
                isCookieAllowed(name) {
                    const cookieGroup = this.getGroupByCookieName(name);
                    return cookieGroup ?
                        window.cookie_consent_groups[cookieGroup] :
                        this.isWebsiteAllowedToSaveCookie();
                },
                saveTempStorageCookies() {
                    for (const [name, data] of Object.entries(cookieTempStorage)) {
                        if (this.isCookieAllowed(name)) {
                            this.set(name, data['value'], data['days'], data['skipSetDomain']);
                            delete cookieTempStorage[name];
                        }
                    }
                }
            };
            hyva.getCookie = (name) => {
                const cookieConfig = window.COOKIE_CONFIG || {};
                if (cookieConfig.cookie_restriction_enabled && !internalCookie.isCookieAllowed(name)) {
                    return cookieTempStorage[name] ? cookieTempStorage[name]['value'] : null;
                }
                return internalCookie.get(name);
            }
            hyva.setCookie = (name, value, days, skipSetDomain) => {
                const cookieConfig = window.COOKIE_CONFIG || {};
                if (cookieConfig.cookie_restriction_enabled && !internalCookie.isCookieAllowed(name)) {
                    cookieTempStorage[name] = {
                        value,
                        days,
                        skipSetDomain
                    };
                    return;
                }
                return internalCookie.set(name, value, days, skipSetDomain);
            }
            hyva.setSessionCookie = (name, value, skipSetDomain) => {
                return hyva.setCookie(name, value, sessionCookieMarker, skipSetDomain)
            }
            hyva.getBrowserStorage = () => {
                const browserStorage = window.localStorage || window.sessionStorage;
                if (!browserStorage) {
                    console.warn('Browser Storage is unavailable');
                    return false;
                }
                try {
                    browserStorage.setItem('storage_test', '1');
                    browserStorage.removeItem('storage_test');
                } catch (error) {
                    console.warn('Browser Storage is not accessible', error);
                    return false;
                }
                return browserStorage;
            }
            hyva.postForm = (postParams) => {
                const form = document.createElement("form");
                let data = postParams.data;
                if (!postParams.skipUenc && !data.uenc) {
                    data.uenc = btoa(window.location.href);
                }
                form.method = "POST";
                form.action = postParams.action;
                Object.keys(postParams.data).map(key => {
                    const field = document.createElement("input");
                    field.type = 'hidden'
                    field.value = postParams.data[key];
                    field.name = key;
                    form.appendChild(field);
                });
                const form_key = document.createElement("input");
                form_key.type = 'hidden';
                form_key.value = hyva.getFormKey();
                form_key.name = "form_key";
                form.appendChild(form_key);
                document.body.appendChild(form);
                form.submit();
            }
            hyva.getFormKey = function() {
                let formKey = hyva.getCookie('form_key');
                if (!formKey) {
                    formKey = generateRandomString();
                    hyva.setCookie('form_key', formKey);
                }
                return formKey;
            }
            hyva.formatPrice = (value, showSign, options = {}) => {
                const formatter = new Intl.NumberFormat(
                    'en-US',
                    Object.assign({
                        style: 'currency',
                        currency: 'EUR',
                        signDisplay: showSign ? 'always' : 'auto'
                    }, options)
                );
                return (typeof Intl.NumberFormat.prototype.formatToParts === 'function') ?
                    formatter.formatToParts(value).map(({
                        type,
                        value
                    }) => {
                        switch (type) {
                            case 'currency':
                                return '€' || value;
                            case 'minusSign':
                                return '- ';
                            case 'plusSign':
                                return '+ ';
                            default:
                                return value;
                        }
                    }).reduce((string, part) => string + part) :
                    formatter.format(value);
            }
            /**
             * Internal string replacement function implementation, see hyva.str() for usage details.
             *
             * @param string str Template string with optional placeholders
             * @param int nStart Offset for placeholders, 0 means %0 is replaced with args[0], 1 means %1 is replaced with args[0]
             * @param array ...args Positional replacement arguments. Rest arguments support isn't at 97% yet, so Array.from(arguments).slice() is used instead.
             */
            const formatStr = function(str, nStart) {
                const args = Array.from(arguments).slice(2);
                return str.replace(/(%+)([0-9]+)/g, (m, p, n) => {
                    const idx = parseInt(n) - nStart;
                    if (args[idx] === null || args[idx] === void 0) {
                        return m;
                    }
                    return p.length % 2 ?
                        p.slice(0, -1).replace('%%', '%') + args[idx] :
                        p.replace('%%', '%') + n;
                })
            }
            /**
             * Replace positional parameters like %1 in string with the rest argument in the matching position.
             * The first rest argument replaces %1, the second %2 and so on.
             *
             * Example: hyva.str('%3 %2 %1', 'a', 'b', 'c') => "c b a"
             *
             * To insert a literal % symbol followed by a number, duplicate the %, for example %%2 is returned as %2.
             */
            hyva.str = function(string) {
                const args = Array.from(arguments);
                args.splice(1, 0, 1);
                return formatStr.apply(undefined, args);
            }
            /**
             * Zero based version of hyva.str(): the first rest argument replaces %0, the second %1 and so on.
             *
             * Example: hyva.strf('%2 %1 %0', 'a', 'b', 'c') => "c b a"
             *
             * If in doubt whether to use hyva.str() or hyva.strf(), prefer hyva.str() because it is more similar to __()
             * and it might be possible to reuse existing phrase translations with placeholders.
             */
            hyva.strf = function() {
                const args = Array.from(arguments);
                args.splice(1, 0, 0);
                return formatStr.apply(undefined, args);
            }
            /**
             * Take a html string as `content` parameter and
             * extract an element from the DOM to replace in
             * the current page under the same selector,
             * defined by `targetSelector`
             */
            hyva.replaceDomElement = (targetSelector, content) => {
                // Parse the content and extract the DOM node using the `targetSelector`
                const parser = new DOMParser();
                const doc = parser.parseFromString(content, 'text/html');
                const contentNode = doc.querySelector(targetSelector);
                // Bail if content can't be found
                if (!contentNode) {
                    return;
                }
                hyva.activateScripts(contentNode)
                // Replace the old DOM node with the new content
                document.querySelector(targetSelector).replaceWith(contentNode);
                // Reload customerSectionData and display cookie-messages if present
                window.dispatchEvent(new CustomEvent("reload-customer-section-data"));
                hyva.initMessages();
            }
            hyva.activateScripts = (contentNode) => {
                // Extract all the script tags from the content.
                // Script tags won't execute when inserted into a dom-element directly,
                // therefore we need to inject them to the head of the document.
                const tmpScripts = contentNode.getElementsByTagName('script');
                if (tmpScripts.length > 0) {
                    // Push all script tags into an array
                    // (to prevent dom manipulation while iterating over dom nodes)
                    const scripts = [];
                    for (let i = 0; i < tmpScripts.length; i++) {
                        scripts.push(tmpScripts[i]);
                    }
                    // Iterate over all script tags and duplicate+inject each into the head
                    for (let i = 0; i < scripts.length; i++) {
                        let script = document.createElement('script');
                        script.innerHTML = scripts[i].innerHTML;
                        document.head.appendChild(script);
                        // Remove the original (non-executing) node from the content
                        scripts[i].parentNode.removeChild(scripts[i]);
                    }
                }
                return contentNode;
            }
            /**
             * Return base64 encoded current URL that can be used by Magento to redirect the visitor back to the current page.
             * The func hyva.getUenc handles additional encoding of +, / and = like \Magento\Framework\Url\Encoder::encode().
             */
            const replace = {
                ['+']: '-',
                ['/']: '_',
                ['=']: ','
            };
            hyva.getUenc = () => btoa(window.location.href).replace(/[+/=]/g, match => replace[match]);
            let currentTrap;
            const focusableElements = (rootElement) => {
                const selector = 'button, [href], input, select, textarea, details, [tabindex]:not([tabindex="-1"]';
                return Array.from(rootElement.querySelectorAll(selector))
                    .filter(el => {
                        return el.style.display !== 'none' &&
                            !el.disabled &&
                            el.tabIndex !== -1 &&
                            (el.offsetWidth || el.offsetHeight || el.getClientRects().length)
                    })
            }
            const focusTrap = (e) => {
                const isTabPressed = e.key === 'Tab' || e.keyCode === 9;
                if (!isTabPressed) return;
                const focusable = focusableElements(currentTrap)
                const firstFocusableElement = focusable[0]
                const lastFocusableElement = focusable[focusable.length - 1]
                e.shiftKey ?
                    document.activeElement === firstFocusableElement && (lastFocusableElement.focus(), e.preventDefault()) :
                    document.activeElement === lastFocusableElement && (firstFocusableElement.focus(), e.preventDefault())
            };
            hyva.releaseFocus = (rootElement) => {
                if (currentTrap && (!rootElement || rootElement === currentTrap)) {
                    currentTrap.removeEventListener('keydown', focusTrap)
                    currentTrap = null
                }
            }
            hyva.trapFocus = (rootElement) => {
                if (!rootElement) return;
                hyva.releaseFocus()
                currentTrap = rootElement
                rootElement.addEventListener('keydown', focusTrap)
                const firstElement = focusableElements(rootElement)[0]
                firstElement && firstElement.focus()
            }
            hyva.alpineInitialized = (fn) => window.addEventListener('alpine:initialized', fn, {
                once: true
            })
            window.addEventListener('alpine:initialized', () => {
                console.log('Alpine.js initialized')
            })
            window.addEventListener('user-allowed-save-cookie', () => internalCookie.saveTempStorageCookies())
        }(window.hyva = window.hyva || {}));
    </script>
    <div x-data class="fixed right-0 z-40 inset-y-0 max-w-full">
        <div x-cloak x-transition.opacity x-show="$store.asideBlocs.asides.find(aside => aside.name === 'pdpDeliveryReturn')?.open" class="fixed inset-0 w-full h-full bg-dark-40 backdrop-blur-xl"></div>
        <div x-cloak x-transition:enter="transition ease-out duration-300" x-transition:enter-start="translate-x-full" x-transition:enter-end="translate-x-0" x-transition:leave="transition ease-in duration-300" x-transition:leave-start="translate-x-0" x-transition:leave-end="translate-x-full" x-show="$store.asideBlocs.asides.find(aside => aside.name === 'pdpDeliveryReturn')?.open" class="h-full relative bg-light-white overflow-hidden w-screen md:max-w-screen-sm flex flex-col" @click.outside="$store.asideBlocs.closeAside('pdpDeliveryReturn')">
            <div class="p-4 md:px-10 md:py-6 font-medium text-2xl flex justify-between items-center">
                Livraison et retours
                <button type="button" @click="$store.asideBlocs.closeAside('pdpDeliveryReturn')" class="max-md:btn-size-sm btn btn-dark-ghost  btn-only-icon">
                    <svg class=" shrink-0" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path fill-rule="evenodd" clip-rule="evenodd" d="M8.99469 7.9047C8.70179 7.6118 8.22692 7.6118 7.93403 7.9047C7.64113 8.19759 7.64113 8.67246 7.93403 8.96536L10.9392 11.9706L7.93403 14.9758C7.64114 15.2687 7.64114 15.7435 7.93403 16.0364C8.22693 16.3293 8.7018 16.3293 8.99469 16.0364L11.9999 13.0312L15.0051 16.0364C15.298 16.3293 15.7729 16.3293 16.0658 16.0364C16.3586 15.7435 16.3586 15.2687 16.0658 14.9758L13.0606 11.9706L16.0658 8.96536C16.3587 8.67246 16.3587 8.19759 16.0658 7.9047C15.7729 7.6118 15.298 7.6118 15.0051 7.9047L11.9999 10.9099L8.99469 7.9047Z" fill="currentColor" />
                    </svg>

                </button>
            </div>
            <div class="px-4 md:px-10 overflow-auto flex-1 border-t border-b border-neutral-200">
                <section class="">
                    <div x-data="{ expanded: false }" class="border-b border-neutral-200 md:pb-3 text-neutral-800 text-neutral-800">
                        <h2 class="font-medium py-4 md:pt-6 md:pb-3 text-base md:text-xl">
                            <button type="button" @click="expanded = !expanded " class="flex justify-between items-center w-full ">
                                <span class="flex flex-wrap gap-3">
                                    Retrait en magasin
                                </span>

                                <span :class="expanded ? 'rotate-180' : ''" class="transform transition-transform duration-300">
                                    <svg class=" shrink-0" width="32" height="32" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                        <path fill-rule="evenodd" clip-rule="evenodd" d="M12.5303 14.5303C12.2374 14.8232 11.7626 14.8232 11.4697 14.5303L7.46967 10.5303C7.17678 10.2374 7.17678 9.76256 7.46967 9.46967C7.76256 9.17678 8.23744 9.17678 8.53033 9.46967L12 12.9393L15.4697 9.46967C15.7626 9.17678 16.2374 9.17678 16.5303 9.46967C16.8232 9.76256 16.8232 10.2374 16.5303 10.5303L12.5303 14.5303Z" fill="currentColor" />
                                    </svg>
                                </span>
                            </button>
                        </h2>
                        <div x-cloak x-show="expanded" x-collapse class=" ">
                            Profitez de notre service de retrait gratuit en magasin. Commandez en ligne et récupérez votre produit dans le magasin le plus proche sous 2 heures si le stock est disponible.
                        </div>
                    </div>
                    <div x-data="{ expanded: false }" class="border-b border-neutral-200 md:pb-3 text-neutral-800 text-neutral-800">
                        <h2 class="font-medium py-4 md:pt-6 md:pb-3 text-base md:text-xl">
                            <button type="button" @click="expanded = !expanded " class="flex justify-between items-center w-full ">
                                <span class="flex flex-wrap gap-3">
                                    Livraison offerte
                                </span>

                                <span :class="expanded ? 'rotate-180' : ''" class="transform transition-transform duration-300">
                                    <svg class=" shrink-0" width="32" height="32" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                        <path fill-rule="evenodd" clip-rule="evenodd" d="M12.5303 14.5303C12.2374 14.8232 11.7626 14.8232 11.4697 14.5303L7.46967 10.5303C7.17678 10.2374 7.17678 9.76256 7.46967 9.46967C7.76256 9.17678 8.23744 9.17678 8.53033 9.46967L12 12.9393L15.4697 9.46967C15.7626 9.17678 16.2374 9.17678 16.5303 9.46967C16.8232 9.76256 16.8232 10.2374 16.5303 10.5303L12.5303 14.5303Z" fill="currentColor" />
                                    </svg>
                                </span>
                            </button>
                        </h2>
                        <div x-cloak x-show="expanded" x-collapse class=" ">
                            Nous vous offrons la livraison standard pour toute commande dépassant un certain montant. Livraison rapide et suivie pour garantir votre satisfaction.
                        </div>
                    </div>
                    <div x-data="{ expanded: false }" class="border-b border-neutral-200 md:pb-3 text-neutral-800 text-neutral-800">
                        <h2 class="font-medium py-4 md:pt-6 md:pb-3 text-base md:text-xl">
                            <button type="button" @click="expanded = !expanded " class="flex justify-between items-center w-full ">
                                <span class="flex flex-wrap gap-3">
                                    Retour sans frais
                                </span>

                                <span :class="expanded ? 'rotate-180' : ''" class="transform transition-transform duration-300">
                                    <svg class=" shrink-0" width="32" height="32" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                        <path fill-rule="evenodd" clip-rule="evenodd" d="M12.5303 14.5303C12.2374 14.8232 11.7626 14.8232 11.4697 14.5303L7.46967 10.5303C7.17678 10.2374 7.17678 9.76256 7.46967 9.46967C7.76256 9.17678 8.23744 9.17678 8.53033 9.46967L12 12.9393L15.4697 9.46967C15.7626 9.17678 16.2374 9.17678 16.5303 9.46967C16.8232 9.76256 16.8232 10.2374 16.5303 10.5303L12.5303 14.5303Z" fill="currentColor" />
                                    </svg>
                                </span>
                            </button>
                        </h2>
                        <div x-cloak x-show="expanded" x-collapse class=" ">
                            Retournez vos articles gratuitement sous 30 jours, que ce soit en magasin ou via notre service de retour en ligne. Conditions applicables pour les produits non utilisés.
                        </div>
                    </div>
                    <div x-data="{ expanded: false }" class="border-b border-neutral-200 md:pb-3 text-neutral-800 text-neutral-800">
                        <h2 class="font-medium py-4 md:pt-6 md:pb-3 text-base md:text-xl">
                            <button type="button" @click="expanded = !expanded " class="flex justify-between items-center w-full ">
                                <span class="flex flex-wrap gap-3">
                                    Paiement sécurisé
                                </span>

                                <span :class="expanded ? 'rotate-180' : ''" class="transform transition-transform duration-300">
                                    <svg class=" shrink-0" width="32" height="32" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                        <path fill-rule="evenodd" clip-rule="evenodd" d="M12.5303 14.5303C12.2374 14.8232 11.7626 14.8232 11.4697 14.5303L7.46967 10.5303C7.17678 10.2374 7.17678 9.76256 7.46967 9.46967C7.76256 9.17678 8.23744 9.17678 8.53033 9.46967L12 12.9393L15.4697 9.46967C15.7626 9.17678 16.2374 9.17678 16.5303 9.46967C16.8232 9.76256 16.8232 10.2374 16.5303 10.5303L12.5303 14.5303Z" fill="currentColor" />
                                    </svg>
                                </span>
                            </button>
                        </h2>
                        <div x-cloak x-show="expanded" x-collapse class=" ">
                            Toutes vos transactions sont protégées grâce à notre technologie de cryptage avancée. Achetez en toute sérénité avec nos partenaires de paiement de confiance.
                        </div>
                    </div>
                    <div x-data="{ expanded: false }" class="border-b border-neutral-200 md:pb-3 text-neutral-800 text-neutral-800">
                        <h2 class="font-medium py-4 md:pt-6 md:pb-3 text-base md:text-xl">
                            <button type="button" @click="expanded = !expanded " class="flex justify-between items-center w-full ">
                                <span class="flex flex-wrap gap-3">
                                    Une question ? Un problème ?
                                </span>

                                <span :class="expanded ? 'rotate-180' : ''" class="transform transition-transform duration-300">
                                    <svg class=" shrink-0" width="32" height="32" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                        <path fill-rule="evenodd" clip-rule="evenodd" d="M12.5303 14.5303C12.2374 14.8232 11.7626 14.8232 11.4697 14.5303L7.46967 10.5303C7.17678 10.2374 7.17678 9.76256 7.46967 9.46967C7.76256 9.17678 8.23744 9.17678 8.53033 9.46967L12 12.9393L15.4697 9.46967C15.7626 9.17678 16.2374 9.17678 16.5303 9.46967C16.8232 9.76256 16.8232 10.2374 16.5303 10.5303L12.5303 14.5303Z" fill="currentColor" />
                                    </svg>
                                </span>
                            </button>
                        </h2>
                        <div x-cloak x-show="expanded" x-collapse class=" ">
                            Notre service client est disponible pour répondre à vos questions et résoudre vos problèmes. Contactez-nous via téléphone, e-mail ou chat en ligne.
                        </div>
                    </div>
                </section>

            </div>
        </div>
    </div>
    <div x-data class="fixed right-0 z-40 inset-y-0 max-w-full">
        <div x-cloak x-transition.opacity x-show="$store.asideBlocs.asides.find(aside => aside.name === 'pdpProductInfo')?.open" class="fixed inset-0 w-full h-full bg-dark-40 backdrop-blur-xl"></div>
        <div x-cloak x-transition:enter="transition ease-out duration-300" x-transition:enter-start="translate-x-full" x-transition:enter-end="translate-x-0" x-transition:leave="transition ease-in duration-300" x-transition:leave-start="translate-x-0" x-transition:leave-end="translate-x-full" x-show="$store.asideBlocs.asides.find(aside => aside.name === 'pdpProductInfo')?.open" class="h-full relative bg-light-white overflow-hidden w-screen md:max-w-screen-sm flex flex-col" @click.outside="$store.asideBlocs.closeAside('pdpProductInfo')">
            <div class="p-4 md:px-10 md:py-6 font-medium text-2xl flex justify-between items-center">
                Informations produit
                <button type="button" @click="$store.asideBlocs.closeAside('pdpProductInfo')" class="max-md:btn-size-sm btn btn-dark-ghost  btn-only-icon">
                    <svg class=" shrink-0" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path fill-rule="evenodd" clip-rule="evenodd" d="M8.99469 7.9047C8.70179 7.6118 8.22692 7.6118 7.93403 7.9047C7.64113 8.19759 7.64113 8.67246 7.93403 8.96536L10.9392 11.9706L7.93403 14.9758C7.64114 15.2687 7.64114 15.7435 7.93403 16.0364C8.22693 16.3293 8.7018 16.3293 8.99469 16.0364L11.9999 13.0312L15.0051 16.0364C15.298 16.3293 15.7729 16.3293 16.0658 16.0364C16.3586 15.7435 16.3586 15.2687 16.0658 14.9758L13.0606 11.9706L16.0658 8.96536C16.3587 8.67246 16.3587 8.19759 16.0658 7.9047C15.7729 7.6118 15.298 7.6118 15.0051 7.9047L11.9999 10.9099L8.99469 7.9047Z" fill="currentColor" />
                    </svg>

                </button>
            </div>
            <div class="px-4 md:px-10 overflow-auto flex-1 border-t border-b border-neutral-200">
                <section class="product-details">
                    <!-- Title Section -->
                    <h1 class="text-base md:text-xl font-medium text-neutral-800 mt-5 mb-2">Informations produit</h1>
                    <p class="text-sm md:text-base font-medium text-neutral-800">Précieuse, un modèle conçu en acétate aux lignes épaisses et structurées, associé à une forme carrée oversize pour une allure très mode.</p>

                    <div class="my-6 border-t border-gray-300"></div>

                    <!-- Dimensions Section -->
                    <h2 class="text-base md:text-xl font-medium text-neutral-800 mt-5 mb-2">Dimensions</h2>
                    <div class="grid grid-cols-2 md:grid-cols-4 gap-4 text-center">
                        <div class="text-xs md:text-sm font-medium">
                            <div class="w-12 h-12 mx-auto flex items-center justify-center">
                                <svg class=" shrink-0" width="48" height="24" viewBox="0 0 64 28.8" fill="none" xmlns="http://www.w3.org/2000/svg">
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M14.4 27.3C21.5245 27.3 27.3 21.5245 27.3 14.4C27.3 7.27553 21.5245 1.5 14.4 1.5C7.27553 1.5 1.5 7.27553 1.5 14.4C1.5 21.5245 7.27553 27.3 14.4 27.3ZM14.4 28.8C22.3529 28.8 28.8 22.3529 28.8 14.4C28.8 6.4471 22.3529 0 14.4 0C6.4471 0 0 6.4471 0 14.4C0 22.3529 6.4471 28.8 14.4 28.8Z" fill="currentColor" />
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M49.6 27.3C56.7245 27.3 62.5 21.5245 62.5 14.4C62.5 7.27553 56.7245 1.5 49.6 1.5C42.4755 1.5 36.7 7.27553 36.7 14.4C36.7 21.5245 42.4755 27.3 49.6 27.3ZM49.6 28.8C57.5529 28.8 64 22.3529 64 14.4C64 6.4471 57.5529 7.62939e-07 49.6 7.62939e-07C41.6471 7.62939e-07 35.2 6.4471 35.2 14.4C35.2 22.3529 41.6471 28.8 49.6 28.8Z" fill="currentColor" />
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M35.2 15.15H28.8V13.65H35.2V15.15Z" fill="currentColor" />
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M42.8071 14.9L45.1535 17.2464L44.4464 17.9536L40.8929 14.4L44.4464 10.8464L45.1535 11.5536L42.8071 13.9H56.3929L54.0464 11.5536L54.7536 10.8464L58.3071 14.4L54.7536 17.9536L54.0464 17.2464L56.3929 14.9H42.8071Z" fill="#A3A3A3" />
                                </svg>
                            </div>
                            <p>Largeur du verre</p>
                            <p>57 mm</p>
                        </div>
                        <div class="text-sm font-medium">
                            <div class="w-12 h-12 mx-auto flex items-center justify-center">
                                <svg class=" shrink-0" width="48" height="24" viewBox="0 0 64 28.8" fill="none" xmlns="http://www.w3.org/2000/svg">
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M14.4 27.3C21.5245 27.3 27.3 21.5245 27.3 14.4C27.3 7.27553 21.5245 1.5 14.4 1.5C7.27553 1.5 1.5 7.27553 1.5 14.4C1.5 21.5245 7.27553 27.3 14.4 27.3ZM14.4 28.8C22.3529 28.8 28.8 22.3529 28.8 14.4C28.8 6.4471 22.3529 0 14.4 0C6.4471 0 0 6.4471 0 14.4C0 22.3529 6.4471 28.8 14.4 28.8Z" fill="currentColor" />
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M49.6 27.3C56.7245 27.3 62.5 21.5245 62.5 14.4C62.5 7.27553 56.7245 1.5 49.6 1.5C42.4755 1.5 36.7 7.27553 36.7 14.4C36.7 21.5245 42.4755 27.3 49.6 27.3ZM49.6 28.8C57.5529 28.8 64 22.3529 64 14.4C64 6.4471 57.5529 7.62939e-07 49.6 7.62939e-07C41.6471 7.62939e-07 35.2 6.4471 35.2 14.4C35.2 22.3529 41.6471 28.8 49.6 28.8Z" fill="currentColor" />
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M35.2 15.15H28.8V13.65H35.2V15.15Z" fill="currentColor" />
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M49.1016 7.60712L46.7551 9.95357L46.048 9.24646L49.6016 5.69291L53.1551 9.24646L52.448 9.95357L50.1016 7.60712V21.1929L52.448 18.8465L53.1551 19.5536L49.6016 23.1071L46.048 19.5536L46.7551 18.8465L49.1016 21.1929V7.60712Z" fill="#A3A3A3" />
                                </svg>
                            </div>
                            <p>Hauteur du verre</p>
                            <p>49 mm</p>
                        </div>
                        <div class="text-sm font-medium">
                            <div class="w-12 h-12 mx-auto flex items-center justify-center">
                                <svg class=" shrink-0" width="48" height="24" viewBox="0 0 64 40.34" fill="none" xmlns="http://www.w3.org/2000/svg">
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M0.107107 28.8V0H1.30711V28.8H0.107107Z" fill="currentColor" />
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M51.1071 15.15H1.10711V13.65H51.1071C58.5906 13.65 64.6571 19.7165 64.6571 27.2V28.8H63.1571V27.2C63.1571 20.545 57.7621 15.15 51.1071 15.15Z" fill="currentColor" />
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M1.91421 37.7L4.26066 40.0464L3.55355 40.7536L0 37.2L3.55355 33.6464L4.26066 34.3536L1.91421 36.7H62.7L60.3536 34.3536L61.0607 33.6464L64.6142 37.2L61.0607 40.7536L60.3536 40.0464L62.7 37.7H1.91421Z" fill="#A3A3A3" />
                                </svg>
                            </div>
                            <p>Longueur branche</p>
                            <p>135 mm</p>
                        </div>
                        <div class="text-sm font-medium">
                            <div class="w-12 h-12 mx-auto flex items-center justify-center">
                                <svg class=" shrink-0" width="48" height="24" viewBox="0 0 64 40.34" fill="none" xmlns="http://www.w3.org/2000/svg">
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M15.1071 27.3C22.2316 27.3 28.0071 21.5245 28.0071 14.4C28.0071 7.27553 22.2316 1.5 15.1071 1.5C7.98262 1.5 2.20709 7.27553 2.20709 14.4C2.20709 21.5245 7.98262 27.3 15.1071 27.3ZM15.1071 28.8C23.06 28.8 29.5071 22.3529 29.5071 14.4C29.5071 6.4471 23.06 0 15.1071 0C7.15419 0 0.707092 6.4471 0.707092 14.4C0.707092 22.3529 7.15419 28.8 15.1071 28.8Z" fill="currentColor" />
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M50.3063 27.3C57.4308 27.3 63.2063 21.5245 63.2063 14.4C63.2063 7.27553 57.4308 1.5 50.3063 1.5C43.1818 1.5 37.4063 7.27553 37.4063 14.4C37.4063 21.5245 43.1818 27.3 50.3063 27.3ZM50.3063 28.8C58.2592 28.8 64.7063 22.3529 64.7063 14.4C64.7063 6.4471 58.2592 0 50.3063 0C42.3534 0 35.9063 6.4471 35.9063 14.4C35.9063 22.3529 42.3534 28.8 50.3063 28.8Z" fill="currentColor" />
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M35.9079 15.15H29.5079V13.65H35.9079V15.15Z" fill="currentColor" />
                                    <path fill-rule="evenodd" clip-rule="evenodd" d="M27.5158 37.7L29.8622 40.0464L29.1551 40.7536L25.6015 37.2L29.1551 33.6464L29.8622 34.3536L27.5158 36.7H37.9015L35.5551 34.3536L36.2622 33.6464L39.8158 37.2L36.2622 40.7536L35.5551 40.0464L37.9015 37.7H27.5158Z" fill="#A3A3A3" />
                                </svg>
                            </div>
                            <p>Largeur du pont</p>
                            <p>19 mm</p>
                        </div>
                    </div>

                    <div class="my-6 border-t border-gray-300"></div>

                    <!-- Frame Specs Section -->
                    <h2 class="text-base md:text-xl font-medium text-neutral-800 mt-5 mb-2">Caractéristiques monture</h2>
                    <div class="grid gap-2 text-sm md:text-base text-neutral-800">
                        <div class="flex justify-between">
                            <span>Brand</span>
                            <span>ALAIN AFFLELOU</span>
                        </div>
                        <div class="flex justify-between">
                            <span>Shape</span>
                            <span>Carrée</span>
                        </div>
                        <div class="flex justify-between">
                            <span>Gender</span>
                            <span>Femme</span>
                        </div>
                        <div class="flex justify-between">
                            <span>Material</span>
                            <span>Plastique</span>
                        </div>
                        <div class="flex justify-between">
                            <span>Templematerial</span>
                            <span>Plastique</span>
                        </div>
                        <div class="flex justify-between">
                            <span>Weight</span>
                            <span>46</span>
                        </div>
                        <div class="flex justify-between">
                            <span>Mounting</span>
                            <span>Cerclé</span>
                        </div>
                        <div class="flex justify-between">
                            <span>Color</span>
                            <span>Vert</span>
                        </div>
                        <div class="flex justify-between">
                            <span>Reference</span>
                            <span>Précieuse</span>
                        </div>
                        <div class="flex justify-between">
                            <span>Gtin</span>
                            <span>07630629427815</span>
                        </div>
                    </div>

                    <div class="my-6 border-t border-gray-300"></div>

                    <!-- Lenses Section -->
                    <h2 class="text-base md:text-xl font-medium text-neutral-800 mt-5 mb-2">Caractéristiques verres</h2>
                    <div class="flex justify-between text-sm md:text-base font-medium text-neutral-800 mb-5">
                        <span>Protection</span>
                        <span>Catégorie 2</span>
                    </div>
                </section>

            </div>
        </div>
    </div>
    <div x-data class="fixed right-0 z-40 inset-y-0 max-w-full">
        <div x-cloak x-transition.opacity x-show="$store.asideBlocs.asides.find(aside => aside.name === 'pdpColor')?.open" class="fixed inset-0 w-full h-full bg-dark-40 backdrop-blur-xl"></div>
        <div x-cloak x-transition:enter="transition ease-out duration-300" x-transition:enter-start="translate-x-full" x-transition:enter-end="translate-x-0" x-transition:leave="transition ease-in duration-300" x-transition:leave-start="translate-x-0" x-transition:leave-end="translate-x-full" x-show="$store.asideBlocs.asides.find(aside => aside.name === 'pdpColor')?.open" class="h-full relative bg-light-white overflow-hidden w-screen md:max-w-screen-sm flex flex-col" @click.outside="$store.asideBlocs.closeAside('pdpColor')">
            <div class="p-4 md:px-10 md:py-6 font-medium text-2xl flex justify-between items-center">
                Couleurs
                <button type="button" @click="$store.asideBlocs.closeAside('pdpColor')" class="max-md:btn-size-sm btn btn-dark-ghost  btn-only-icon">
                    <svg class=" shrink-0" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path fill-rule="evenodd" clip-rule="evenodd" d="M8.99469 7.9047C8.70179 7.6118 8.22692 7.6118 7.93403 7.9047C7.64113 8.19759 7.64113 8.67246 7.93403 8.96536L10.9392 11.9706L7.93403 14.9758C7.64114 15.2687 7.64114 15.7435 7.93403 16.0364C8.22693 16.3293 8.7018 16.3293 8.99469 16.0364L11.9999 13.0312L15.0051 16.0364C15.298 16.3293 15.7729 16.3293 16.0658 16.0364C16.3586 15.7435 16.3586 15.2687 16.0658 14.9758L13.0606 11.9706L16.0658 8.96536C16.3587 8.67246 16.3587 8.19759 16.0658 7.9047C15.7729 7.6118 15.298 7.6118 15.0051 7.9047L11.9999 10.9099L8.99469 7.9047Z" fill="currentColor" />
                    </svg>

                </button>
            </div>
            <div class="px-4 md:px-10 overflow-auto flex-1 border-t border-b border-neutral-200">
                <section class="grid grid-cols-2 gap-4 mx-auto p-4">
                    <div class="flex flex-col">
                        <div class="aspect-square">
                            <img src="/img/productSolaire/img_8.png" alt="vert" class="rounded-lg border  !border-neutral-800  hover:border-neutral-600">
                        </div>
                        <span class="mt-2 text-neutral-900 font-semibold capitalize">vert</span>
                    </div>
                    <div class="flex flex-col">
                        <div class="aspect-square">
                            <img src="/img/productSolaire/img_9.png" alt="noir" class="rounded-lg border  border-neutral-300  hover:border-neutral-600">
                        </div>
                        <span class="mt-2 text-neutral-900 font-semibold capitalize">noir</span>
                    </div>
                </section>

            </div>
        </div>
    </div>

    <script src="../../js/gsap.min.js" defer crossorigin></script>
    <script src="../../js/scrollTrigger.min.js" defer crossorigin></script>
    <script src="../../js/swiper-bundle.min.js" defer crossorigin></script>
    <script type="module" src="../../js/anchor.min.js" defer crossorigin></script>
    <script type="module" src="../../js/persist.min.js" defer crossorigin></script>
    <script type="module" src="../../js/intersect.min.js" defer crossorigin></script>
    <script type="module" src="../../js/plyr.min.js" defer crossorigin></script>
    <script type="module" src="../../js/collapse.min.js" defer crossorigin></script>
    <script type="module" src="../../js/alpine3.min.js" defer crossorigin></script>
    <script>
        (g => {
            var h, a, k, p = "The Google Maps JavaScript API",
                c = "google",
                l = "importLibrary",
                q = "__ib__",
                m = document,
                b = window;
            b = b[c] || (b[c] = {});
            var d = b.maps || (b.maps = {}),
                r = new Set,
                e = new URLSearchParams,
                u = () => h || (h = new Promise(async (f, n) => {
                    await (a = m.createElement("script"));
                    e.set("libraries", [...r] + "");
                    for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]);
                    e.set("callback", c + ".maps." + q);
                    a.src = `https://maps.${c}apis.com/maps/api/js?` + e;
                    d[q] = f;
                    a.onerror = () => h = n(Error(p + " could not load."));
                    a.nonce = m.querySelector("script[nonce]")?.nonce || "";
                    m.head.append(a)
                }));
            d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n))
        })({
            key: "AIzaSyAmlBHNWuFlAL7elylRqvhRn4MD7ko0sWs",
            v: "weekly",
            // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
            // Add other bootstrap parameters as needed, using camel case.
        });
    </script>
    <script src="../../js/markerclusterer.min.js" defer crossorigin></script>

    <script>
        window.addEventListener('alpine:init', () => {
            console.log('Alpine.js has been initialized');
            Alpine.store('screen', {
                isMobile: window.matchMedia('(max-width: 768px)').matches,
                isTablet: window.matchMedia('(max-width: 1024px)').matches,
                // Méthode d'initialisation pour mettre à jour `isMobile` en fonction de la taille de l'écran
                init() {
                    const mobileMedia = window.matchMedia('(max-width: 768px)');
                    const tabletMedia = window.matchMedia('(max-width: 1024px)');
                    this.isMobile = mobileMedia.matches;
                    this.isTablet = tabletMedia.matches;
                    const updateScreen = (event, type) => {
                        if (type === 'mobile') this.isMobile = event.matches;
                        if (type === 'tablet') this.isTablet = event.matches;
                    };
                    [{
                            media: mobileMedia,
                            type: 'mobile'
                        },
                        {
                            media: tabletMedia,
                            type: 'tablet'
                        }
                    ].forEach(({
                        media,
                        type
                    }) => {
                        if (typeof media.onchange !== 'object') {
                            media.addListener((e) => updateScreen(e, type));
                        } else {
                            media.addEventListener('change', (e) => updateScreen(e, type));
                        }
                    });
                }
            });
            Alpine.store('filter', {
                filters: [],
                getFilter(type, value) {
                    return this.filters.some((filter) => filter.type === type && filter.value === value);
                },
                toggleFilter(type, value) {
                    const filterArray = this.filters.selected[type];
                    const index = filterArray.indexOf(value);
                    if (index === -1) {
                        filterArray.push(value);
                    } else {
                        filterArray.splice(index, 1);
                    }
                    this.applyFilters();
                },
                clearFilters() {
                    this.filters = [];
                }
            });
            Alpine.store('asideBlocs', {
                asides: [],
                // Ajouter un nouvel aside au tableau
                addAside(name, customProperties = {}) {
                    if (!this.asides.find(aside => aside.name === name)) {
                        this.asides.push({
                            name,
                            open: false,
                            ...customProperties, // Ajoute des propriétés spécifiques
                        });
                    }
                },
                // Supprimer un aside par son nom
                removeAside(name) {
                    this.asides = this.asides.filter(aside => aside.name !== name);
                },
                // Basculer l'état d'ouverture d'un aside
                toggleAside(name) {
                    const aside = this.asides.find(aside => aside.name === name);
                    if (aside) {
                        aside.open = !aside.open;
                        document.body.classList.toggle('overflow-hidden', aside.open);
                    }
                },
                // Fermer un aside spécifique
                closeAside(name) {
                    const aside = this.asides.find(aside => aside.name === name);
                    if (aside) {
                        aside.open = false;
                        document.body.classList.remove('overflow-hidden');
                    }
                },
                // Ouvrir un aside spécifique
                openAside(name) {
                    const aside = this.asides.find(aside => aside.name === name);
                    if (aside) {
                        aside.open = true;
                        document.body.classList.add('overflow-hidden');
                    }
                }
            });
            Alpine.store('locator', {
                allStores: [], // Liste complète des magasins
                countStore: "",
                filteredStores: [], // Liste des magasins filtrés
                filteredDistanceStores: null, //Liste des magasins trié par distance
                selectedStore: null, // Magasin sélectionné
                isAudio: false, // Type de magasin affiché (true = audio, false = optique)
                loading: true, // État de chargement
                mapCenter: null, // Centre lat et lng de la google map
                mapInstance: null, // Instance de la google map. ( /!\ Toutes les fonctions ne sont pas disponible )
                // Listes des filtres disponibles (extraites des données)
                filterLists: {
                    audio: {
                        mutuals: [], // Liste des mutuelles optique disponibles
                        brands: [], // Liste des marques optique disponibles
                        types: [] // Contiendra ['optic', 'teleophtalmologie'] selon disponibilité
                    },
                    optic: {
                        mutuals: [], // Liste des mutuelles optique disponibles
                        brands: [], // Liste des marques optique disponibles
                        types: [] // Contiendra ['audio', 'teleophtalmologie'] selon disponibilité
                    }
                },
                // Modification des selectedFilters pour inclure les types
                selectedFilters: {
                    audio: {
                        mutuals: [], // Mutuelles audio sélectionnées
                        brands: [], // Marques audio sélectionnées
                        types: [] // Les types sélectionnés
                    },
                    optic: {
                        mutuals: [], // Mutuelles audio sélectionnées
                        brands: [], // Marques audio sélectionnées
                        types: [] // Les types sélectionnés
                    },
                    search: ''
                },
                // Défault donnée des prises de rdv
                defaultStepperState: {
                    steps: [{
                            id: 1,
                            title: 'Où',
                            completed: true
                        },
                        {
                            id: 2,
                            title: 'Quoi',
                            completed: false
                        },
                        {
                            id: 3,
                            title: 'Quand',
                            completed: false
                        },
                        {
                            id: 4,
                            title: 'Qui',
                            completed: false
                        }
                    ],
                    completed: false,
                    currentStep: 2,
                    code_mur: null,
                    type: null,
                    data: []
                },
                // Initialisation avec persist
                stepperData: Alpine.$persist(function() {
                    return {
                        ...this.defaultStepperState
                    }
                }).as('stepperData'),
                // Getters
                get currentFilterList() {
                    return this.filterLists[this.currentType];
                },
                get currentType() {
                    return this.isAudio ? 'audio' : 'optic';
                },
                get currentSelectedFilters() {
                    return this.selectedFilters[this.currentType];
                },
                async init() {
                    try {
                        // Détection du type depuis l'URL
                        try {
                            const pathname = window.location.pathname;
                            this.isAudio = pathname.includes('/acousticien');
                        } catch (error) {
                            console.error('Erreur lors de la détection du type depuis l\'URL:', error);
                            this.isAudio = false; // Défault value
                        }
                        await this.loadLibraries();
                        await this.loadStores();
                        this.extractFiltersFromStores();
                        this.applyFilters();
                    } finally {
                        this.loading = false;
                    }
                },
                async loadLibraries() {
                    const [geometry] = await Promise.all([
                        google.maps.importLibrary("geometry"),
                    ]);
                },
                async loadStores() {
                    try {
                        const response = await fetch(`${window.location.origin}/js/json/getListv2.json`);
                        const data = await response.json();
                        if (data.success) {
                            this.countStore = data.data.totalCount ?? data.data.items.length;
                            this.allStores = data.data.items;
                        }
                    } catch (error) {
                        console.error('Erreur lors du chargement des magasins:', error);
                        this.allStores = [];
                    }
                },
                extractFiltersFromStores() {
                    const storesArray = Object.values(this.allStores);
                    // Pour les magasins Audio
                    const audioStores = storesArray.filter(store =>
                        store.locations.some(location => location.is_audio)
                    );
                    // Comptage pour les mutuelles audio
                    const audioMutualCounts = new Map();
                    audioStores.forEach(store => {
                        store.locations
                            .filter(location => location.is_audio)
                            .forEach(location => {
                                (location.mutuelles || []).forEach(mutual => {
                                    audioMutualCounts.set(mutual, (audioMutualCounts.get(mutual) || 0) + 1);
                                });
                            });
                    });
                    // Comptage pour les marques audio
                    const audioBrandCounts = new Map();
                    audioStores.forEach(store => {
                        store.locations
                            .filter(location => location.is_audio)
                            .forEach(location => {
                                (location.brands || []).forEach(brand => {
                                    audioBrandCounts.set(brand, (audioBrandCounts.get(brand) || 0) + 1);
                                });
                            });
                    });
                    // Pour les magasins Optique
                    const opticStores = storesArray.filter(store =>
                        store.locations.some(location => !location.is_audio)
                    );
                    // Comptage pour les mutuelles optique
                    const opticMutualCounts = new Map();
                    opticStores.forEach(store => {
                        store.locations
                            .filter(location => !location.is_audio)
                            .forEach(location => {
                                (location.mutuelles || []).forEach(mutual => {
                                    opticMutualCounts.set(mutual, (opticMutualCounts.get(mutual) || 0) + 1);
                                });
                            });
                    });
                    // Comptage pour les marques optique
                    const opticBrandCounts = new Map();
                    opticStores.forEach(store => {
                        store.locations
                            .filter(location => !location.is_audio)
                            .forEach(location => {
                                (location.brands || []).forEach(brand => {
                                    opticBrandCounts.set(brand, (opticBrandCounts.get(brand) || 0) + 1);
                                });
                            });
                    });
                    this.filterLists.audio = {
                        mutuals: Array.from(audioMutualCounts.entries())
                            .map(([id, count]) => ({
                                id,
                                label: id,
                                count
                            }))
                            .sort((a, b) => a.label.localeCompare(b.label)),
                        brands: Array.from(audioBrandCounts.entries())
                            .map(([id, count]) => ({
                                id,
                                label: id,
                                count
                            }))
                            .sort((a, b) => a.label.localeCompare(b.label)),
                        types: this.extractAvailableTypes(audioStores, true)
                    };
                    this.filterLists.optic = {
                        mutuals: Array.from(opticMutualCounts.entries())
                            .map(([id, count]) => ({
                                id,
                                label: id,
                                count
                            }))
                            .sort((a, b) => a.label.localeCompare(b.label)),
                        brands: Array.from(opticBrandCounts.entries())
                            .map(([id, count]) => ({
                                id,
                                label: id,
                                count
                            }))
                            .sort((a, b) => a.label.localeCompare(b.label)),
                        types: this.extractAvailableTypes(opticStores, false)
                    };
                },
                // Méthode pour extraire les types disponibles
                extractAvailableTypes(stores, isAudio) {
                    const types = new Set();
                    const counts = {
                        [isAudio ? 'optic' : 'audio']: 0,
                        teleophtalmologie: 0
                    };
                    stores.forEach(store => {
                        // Vérifie si le magasin a l'autre type de service
                        const hasOtherService = store.locations.some(location =>
                            isAudio ? !location.is_audio : location.is_audio
                        );
                        if (hasOtherService) {
                            types.add(isAudio ? 'optic' : 'audio');
                            counts[isAudio ? 'optic' : 'audio']++;
                        }
                        // Vérifie si le magasin a la téléophtalmologie
                        const hasTelephtalmology = store.locations.some(location =>
                            location.attributes.teleophtalmologie?.value === "1"
                        );
                        if (hasTelephtalmology) {
                            types.add('teleophtalmologie');
                            counts.teleophtalmologie++;
                        }
                    });
                    // Retourne un tableau d'objets avec le type et son count
                    return Array.from(types).sort().map(type => ({
                        id: type,
                        label: type,
                        count: counts[type]
                    }));
                },
                // Dans toggleStoreType du store locator
                toggleStoreType(isAudio) {
                    if (isAudio !== undefined) {
                        this.isAudio = isAudio;
                    } else {
                        this.isAudio = !this.isAudio;
                    }
                    // Mise à jour de l'URL
                    try {
                        const currentUrl = new URL(window.location.href);
                        const params = new URLSearchParams(currentUrl.search);
                        // Changer le pathname en gardant la même base
                        const newPathname = currentUrl.pathname.replace(
                            /(\/opticien|\/acousticien)/,
                            this.isAudio ? '/acousticien' : '/opticien'
                        );
                        // Construire la nouvelle URL avec les paramètres existants
                        const newUrl = `${currentUrl.origin}${newPathname}${params.toString() ? '?' + params.toString() : ''}`;
                        // Mettre à jour l'URL sans recharger la page
                        window.history.pushState({}, '', newUrl);
                    } catch (error) {
                        console.error('Erreur lors de la mise à jour de l\'URL:', error);
                    }
                    this.selectedStore = null;
                    this.clearFilters();
                    this.applyFilters();
                },
                updateFilter(category, value) {
                    const filters = this.selectedFilters[this.currentType][category];
                    const index = filters.indexOf(value.id || value);
                    if (index === -1) {
                        filters.push(value.id || value);
                    } else {
                        filters.splice(index, 1);
                    }
                },
                updateSearchTerm(term) {
                    this.filters.selected.search = term;
                    this.applyFilters();
                },
                clearFilters() {
                    this.selectedFilters[this.currentType].mutuals = [];
                    this.selectedFilters[this.currentType].brands = [];
                    this.selectedFilters[this.currentType].types = [];
                    this.selectedFilters.search = '';
                    this.applyFilters();
                },
                // Application des filtres modifiée
                applyFilters() {
                    const searchTerm = this.selectedFilters.search?.toLowerCase() || '';
                    const selectedMutuals = this.selectedFilters[this.currentType].mutuals || [];
                    const selectedBrands = this.selectedFilters[this.currentType].brands || [];
                    const selectedTypes = this.selectedFilters[this.currentType].types || [];
                    const filteredStores = Object.values(this.allStores).filter(store => {
                        // 1. Vérification du service principal (toujours requis)
                        const hasMainService = store.locations.some(location =>
                            this.isAudio ? location.is_audio : !location.is_audio
                        );
                        if (!hasMainService) return false;
                        // 2. Vérification des types additionnels si sélectionnés
                        if (selectedTypes.length > 0) {
                            // Vérifie l'autre service si sélectionné
                            const otherServiceType = this.isAudio ? 'optic' : 'audio';
                            if (selectedTypes.includes(otherServiceType)) {
                                const hasOtherService = store.locations.some(location =>
                                    this.isAudio ? !location.is_audio : location.is_audio
                                );
                                if (!hasOtherService) return false;
                            }
                            // Vérifie la téléophtalmologie si sélectionnée
                            if (selectedTypes.includes('teleophtalmologie')) {
                                const hasTelephtalmology = store.locations.some(location =>
                                    location.attributes.teleophtalmologie?.value === "1"
                                );
                                if (!hasTelephtalmology) return false;
                            }
                        }
                        // Filtres existants inchangés
                        if (searchTerm && !this.matchesSearch(store, searchTerm)) return false;
                        // Filtre par mutuelles
                        if (selectedMutuals.length > 0) {
                            const storeMutuals = store.locations
                                .filter(location => this.isAudio ? location.is_audio : !location.is_audio)
                                .flatMap(location => location.mutuelles || []);
                            if (!selectedMutuals.some(mutualId => storeMutuals.includes(mutualId))) {
                                return false;
                            }
                        }
                        if (selectedBrands.length > 0) {
                            const storeBrands = store.locations
                                .filter(location => this.isAudio ? location.is_audio : !location.is_audio)
                                .flatMap(location => location.brands || []);
                            if (!selectedBrands.some(brandId => storeBrands.includes(brandId))) {
                                return false;
                            }
                        }
                        return true;
                    });
                    this.filteredStores = filteredStores;
                    this.updateDistances(filteredStores);
                },
                // Mise à jour de la méthode matchesSearch également si nécessaire
                matchesSearch(store, searchTerm) {
                    return store.locations.some(location =>
                        location.name?.toLowerCase().includes(searchTerm) ||
                        store.city?.toLowerCase().includes(searchTerm) ||
                        store.zip?.toLowerCase().includes(searchTerm)
                    );
                },
                selectStore(store) {
                    this.selectedStore = store;
                },
                isFilterSelected(category, value) {
                    return this.selectedFilters[category].includes(value);
                },
                updateDistances(filteredStores) {
                    if (!this.mapInstance) return;
                    const center = this.mapInstance.getCenter();
                    const stores = Object.values(filteredStores || {});
                    // Créer de nouveaux objets avec les distances au lieu de modifier les existants
                    this.filteredDistanceStores = stores.map(store => {
                        const distance = google.maps.geometry.spherical.computeDistanceBetween(
                            center, {
                                lat: parseFloat(store.lat),
                                lng: parseFloat(store.lng)
                            }
                        );
                        // Retourner un nouvel objet au lieu de modifier l'original
                        return {
                            ...store,
                            distance: (distance / 1000).toFixed(1) + ' km'
                        };
                    }).sort((a, b) => {
                        const distA = parseFloat(a.distance);
                        const distB = parseFloat(b.distance);
                        return distA - distB;
                    });
                },
                setMapCenter(lat, lng, zoom) {
                    if (!isNaN(lat) && !isNaN(lng)) {
                        this.mapInstance.panTo({
                            lat,
                            lng
                        })
                    }
                    if (zoom) {
                        this.mapInstance.setZoom(zoom)
                    }
                },
                goToStore(store) {
                    if (!this.mapInstance || !store) return;
                    const lat = parseFloat(store.lat);
                    const lng = parseFloat(store.lng);
                    if (isNaN(lat) || isNaN(lng)) return;
                    this.setMapCenter(lat, lng, 15)
                    this.selectStore(store);
                },
                // PARTIE: PRISE DE RENDEZ-VOUS
                initStepper(store) {
                    this.stepperData = {
                        ...this.defaultStepperState,
                        code_mur: store.mur_code,
                        type: this.isAudio,
                        data: [{
                            title: 'MAGASIN',
                            value: `${store.address}, ${store.zip} ${store.city}`
                        }]
                    };
                },
                updateStepperData(title, value, targetStep) {
                    if (!this.stepperData) return;
                    // Trouver l'index de la donnée existante
                    const currentIndex = this.stepperData.data.findIndex(item => item.title === title);
                    // Mise à jour ou ajout des données
                    if (currentIndex === -1) {
                        // Ajout d'une nouvelle entrée
                        this.stepperData.data.push({
                            title,
                            value
                        });
                    } else if (this.stepperData.data[currentIndex].value !== value) {
                        // Si la valeur change, on supprime les données suivantes
                        this.stepperData.data = this.stepperData.data.slice(0, currentIndex + 1);
                        this.stepperData.data[currentIndex] = {
                            title,
                            value
                        };
                    }
                    // Mise à jour du step et des états des étapes si nécessaire
                    if (targetStep) {
                        this.stepperData.currentStep = targetStep;
                        this.stepperData.steps = this.stepperData.steps.map(step => ({
                            ...step,
                            completed: step.id < targetStep
                        }));
                    }
                    // Alpine.persist se charge automatiquement de la persistance
                    return this.stepperData;
                },
                completeStepperData(appointmentId) {
                    if (!this.stepperData) return;
                    // Marquer toutes les étapes comme complétées
                    this.stepperData.steps = this.stepperData.steps.map(step => ({
                        ...step,
                        completed: true
                    }));
                    // Marquer le stepper comme complété et ajouter l'ID du rendez-vous
                    this.stepperData.completed = true;
                    this.stepperData.appointmentId = appointmentId;
                },
                goToStepperStep(targetStep) {
                    // Vérifier que l'étape cible est valide
                    if (!this.stepperData || targetStep < 1 || targetStep > 4) return;
                    // Si on retourne à l'étape 1, réinitialiser complètement
                    if (targetStep === 1) {
                        this.resetStepperData();
                        this.$store.asideBlocs.closeAside('storeLocatorAppointment');
                        return;
                    }
                    // Mettre à jour l'étape courante et l'état des étapes
                    this.stepperData.currentStep = targetStep;
                    this.stepperData.steps = this.stepperData.steps.map(step => ({
                        ...step,
                        completed: step.id < targetStep
                    }));
                },
                resetStepperData() {
                    // Réinitialiser avec les valeurs par défaut
                    this.stepperData = Alpine.persist({
                        ...this.defaultStepperState
                    }, 'stepperData');
                }
            });
        });
    </script>

</body>

</html>
{% extends '@layout' %}

{% block yield %}
    {% render "@pdp-deliveryreturn" %}
    {% render "@pdp-productinfo" %}
    {% render "@pdp-color" %}
    {{ yield }}
{% endblock %}
/* No context defined. */

No notes defined.