{"version":3,"file":"client.mjs","sources":["../app/components/hardware-option.ts","../app/components/hardware-overlay.ts","../app/components/short-filter.ts","../app/configs/requests.ts","../app/configs/environment.ts","../app/client.ts","../app/components/navigation.ts"],"sourcesContent":["import {HardwareFilterOption} from '../types/types.ts';\n\nexport const HardwareOption = ({\n    label,\n    value,\n    isSelected,\n    isDisabled,\n}: HardwareFilterOption & {isSelected: boolean; isDisabled: boolean}) => `\n    <label class=\"hardware-option\">\n        <input \n            name=\"${value}\"\n            type=\"checkbox\" \n            class=\"checkbox ${isSelected ? 'checked' : ''}\" \n            ${isDisabled && !isSelected ? 'disabled' : ''}\n            data-value=\"${value}\">\n        <span>${label}</span>\n    </label>\n`;\n\nexport const setupHardwareOption = ({\n    shadowRoot,\n    changeHardwareSelection,\n}: {\n    shadowRoot: ShadowRoot;\n    changeHardwareSelection: (value: string) => void;\n}) => {\n    shadowRoot.querySelectorAll('.checkbox').forEach(checkbox => {\n        checkbox.addEventListener('change', event => {\n            const value = (event.target as HTMLElement).dataset.value;\n            if (!value) return;\n            changeHardwareSelection(value);\n        });\n    });\n};\n","import {EnvironmentUrls} from '../configs/environment.ts';\nimport {HardwareFilterCategory} from '../types/types.ts';\nimport {HardwareOption, setupHardwareOption} from './hardware-option.ts';\n\nconst MAX_SELECTION_COUNT = 3;\n\ninterface OverlayHandlers {\n    documentHandler: EventListener;\n    shadowHandler: EventListener;\n    shadowRootRef: ShadowRoot;\n}\n\nconst overlayHandlers = new WeakMap<ShadowRoot, OverlayHandlers>();\n\nexport const cleanupHardwareOverlay = (shadowRoot: ShadowRoot): void => {\n    const handlers = overlayHandlers.get(shadowRoot);\n    if (handlers) {\n        document.removeEventListener('mousedown', handlers.documentHandler);\n        handlers.shadowRootRef.removeEventListener('mousedown', handlers.shadowHandler, true);\n        overlayHandlers.delete(shadowRoot);\n    }\n};\n\nconst getSelectionCount = (selectedHardware: Array<string>) => {\n    if (selectedHardware.length === 1 && selectedHardware[0] === 'all') return 0;\n    return selectedHardware.length;\n};\n\nconst getHintText = (selectedHardware: Array<string>) => {\n    const selectionCount = getSelectionCount(selectedHardware);\n\n    if (selectionCount === 0) return `Sie können bis zu ${MAX_SELECTION_COUNT} Handys wählen`;\n\n    const remainingSelectableCount = MAX_SELECTION_COUNT - selectionCount;\n\n    switch (remainingSelectableCount) {\n        case 0:\n            return `Sie haben ${selectionCount} Handys zur Auswahl hinzugefügt`;\n        case 1:\n            return 'Sie können noch ein weiteres Handy wählen';\n        default:\n            return `Sie können noch ${remainingSelectableCount} weitere Handys wählen`;\n    }\n};\n\nexport const HardwareOverlay = ({\n    hardwareOptions,\n    selectedHardware,\n    isHardwareOverlayVisible,\n    environment,\n}: {\n    hardwareOptions: Array<HardwareFilterCategory>;\n    selectedHardware: Array<string>;\n    isHardwareOverlayVisible: boolean;\n    environment: EnvironmentUrls;\n}) => `\n<div \n    class=\"hardware-overlay\"\n    id=\"hardware-overlay\"\n    tabindex=\"0\" \n    style=\"${isHardwareOverlayVisible ? '' : 'display: none'}\"\n>\n    <header class=\"header\" id=\"overlay-header\">Ihre Handyauswahl</header>\n    <div class=\"sub-header\">\n        <img\n           \n            alt=\"\"\n            src=\"${environment.assetsExternal}/${getSelectionCount(selectedHardware) >= MAX_SELECTION_COUNT ? 'holding-slider/check-blue.svg' : 'holding-slider/light-bulb.svg'}\"\n            class=\"hint-icon\"\n            width=\"18\"\n            height=\"18\"\n            loading=\"lazy\"\n        />\n        <div>\n            ${getHintText(selectedHardware)}\n        </div>        \n    </div>\n    <div class=\"hardware-options\">\n         ${HardwareOption({\n             label: 'Alle Handys',\n             value: 0,\n             isSelected: selectedHardware.length === 0,\n             isDisabled: selectedHardware.length >= MAX_SELECTION_COUNT,\n         })}\n        ${hardwareOptions\n            .map(\n                section => `\n                    <div class=\"category\">${section.label}</div>\n                    ${section.options\n                        .map(option =>\n                            HardwareOption({\n                                ...option,\n                                isSelected: selectedHardware.includes(`${option.value}`),\n                                isDisabled: selectedHardware.length >= MAX_SELECTION_COUNT,\n                            }),\n                        )\n                        .join('')}\n                `,\n            )\n            .join('')}\n    </div>\n    <button\n        id=\"hardware-button\"\n        class=\"button\"\n    >\n        Auswahl übernehmen\n    </button>\n</div>   \n`;\n\n// Attach dismiss-on-outside-click listeners. Called independently from the\n// rest of the setup so the host can toggle overlay visibility without\n// rebinding button/checkbox listeners (which would cause duplicate handlers).\nexport const attachHardwareOverlayDismissListeners = (\n    shadowRoot: ShadowRoot,\n    closeHardwareOverlay: () => void,\n): void => {\n    cleanupHardwareOverlay(shadowRoot);\n\n    // Clicks outside the closed shadow host: composedPath reveals only the\n    // host (shadow internals are hidden), so anything not including it is\n    // clearly outside and should dismiss the overlay.\n    const documentHandler: EventListener = event => {\n        if (event.composedPath().includes(shadowRoot.host)) return;\n        cleanupHardwareOverlay(shadowRoot);\n        closeHardwareOverlay();\n    };\n\n    // Clicks inside the shadow: use a capture-phase listener on the\n    // shadowRoot so we can see the real target (composedPath inside the\n    // shadow exposes internal nodes). Dismiss unless the click landed on\n    // the overlay itself or its trigger (the trigger has its own toggle).\n    const shadowHandler: EventListener = event => {\n        const path = event.composedPath();\n        const overlay = shadowRoot.getElementById('hardware-overlay');\n        const trigger = shadowRoot.getElementById('hardware-selection');\n        if (overlay && path.includes(overlay)) return;\n        if (trigger && path.includes(trigger)) return;\n        cleanupHardwareOverlay(shadowRoot);\n        closeHardwareOverlay();\n    };\n\n    overlayHandlers.set(shadowRoot, {documentHandler, shadowHandler, shadowRootRef: shadowRoot});\n    document.addEventListener('mousedown', documentHandler);\n    shadowRoot.addEventListener('mousedown', shadowHandler, true);\n};\n\nexport const setupHardwareOverlay = ({\n    shadowRoot,\n    closeHardwareOverlay,\n    changeHardwareSelection,\n    isHardwareOverlayVisible,\n}: {\n    shadowRoot: ShadowRoot;\n    closeHardwareOverlay: () => void;\n    isHardwareOverlayVisible: boolean;\n} & Parameters<typeof setupHardwareOption>[0]) => {\n    cleanupHardwareOverlay(shadowRoot);\n\n    if (isHardwareOverlayVisible) {\n        attachHardwareOverlayDismissListeners(shadowRoot, closeHardwareOverlay);\n    }\n\n    shadowRoot.getElementById('hardware-button')?.addEventListener('click', () => {\n        cleanupHardwareOverlay(shadowRoot);\n        closeHardwareOverlay();\n    });\n    shadowRoot.getElementById('overlay-header')?.addEventListener('click', () => {\n        cleanupHardwareOverlay(shadowRoot);\n        closeHardwareOverlay();\n    });\n\n    setupHardwareOption({shadowRoot, changeHardwareSelection});\n};\n","import {HardwareFilterCategory, DataIncludedFilterOption, HardwareFilterOption} from '../types/types.ts';\nimport {FilterIcon} from './filter-icon.ts';\nimport {EnvironmentUrls} from '../configs/environment.ts';\nimport {HardwareOverlay, setupHardwareOverlay} from './hardware-overlay.ts';\n\nconst getHardwarePath = (hardwareSelection: Array<string>) => {\n    if (hardwareSelection.length === 0 || hardwareSelection.includes('all')) return 'handy-uebersicht';\n    if (hardwareSelection.length === 1) return `vergleich/${hardwareSelection[0]}`;\n    return `vergleiche/${hardwareSelection.join('-mit-')}`;\n};\n\nconst getLink = (\n    selectedDataIncluded: number,\n    hardwareOptions: Array<HardwareFilterCategory>,\n    hardwareSelection: Array<string>,\n    environment: EnvironmentUrls,\n) => {\n    const allOptions = hardwareOptions.flatMap(category => category.options);\n    const hardwareKeys = hardwareSelection.map(id => {\n        const option = allOptions.find(opt => `${opt.value}` === id);\n        return option?.key ?? id;\n    });\n    \n    const queryParams = new URLSearchParams({data_included: `${selectedDataIncluded}`}).toString();\n    return `${environment.host}/${getHardwarePath(hardwareKeys)}?${queryParams}`;\n};\n\nconst getHardwareLabel = (hardwareOptions: Array<HardwareFilterCategory>, selectedHardware: Array<string>) => {\n    if (selectedHardware.length === 0 || selectedHardware.includes('all')) return 'Alle Handys';\n\n    if (selectedHardware.length === 1) {\n        return hardwareOptions.reduce((acc, section) => {\n            const options = section.options.filter(option => selectedHardware.includes(`${option.value}`));\n            return [...acc, ...options];\n        }, [] as Array<HardwareFilterOption>)[0].label;\n    }\n\n    return `${selectedHardware.length} Handys gewählt`;\n};\n\nexport const ShortFilter = ({\n    dataIncluded,\n    selectedDataIncluded,\n    hardwareOptions,\n    selectedHardware,\n    isHardwareOverlayVisible,\n    environment,\n}: {\n    dataIncluded: Array<DataIncludedFilterOption>;\n    selectedDataIncluded: number;\n    hardwareOptions: Array<HardwareFilterCategory>;\n    selectedHardware: Array<string>;\n    isHardwareOverlayVisible: boolean;\n    environment: EnvironmentUrls;\n}): string => `\n<div class=\"short-filter\">\n    <div class=\"container\">\n        <div class=\"filter remove-appearance\" id=\"hardware-selection\">\n            <div class=\"filter-text\">\n                <label for=\"hardware-selection\" class=\"filter-title\">Ihre Handyauswahl</label>\n                <div class=\"select\">${getHardwareLabel(hardwareOptions, selectedHardware)}</div>\n            </div>\n            ${FilterIcon()}\n        </div>\n        ${HardwareOverlay({\n            hardwareOptions,\n            selectedHardware,\n            isHardwareOverlayVisible,\n            environment,\n        })}\n    </div>\n    <div class=\"divider\"></div>\n    <div class=\"container\">\n        <div class=\"filter\">\n            <div class=\"filter-text\">\n                <label for=\"data-included\" class=\"filter-title\">\n                    Datenvolumen \n                </label>\n                <select id=\"data-included\" class=\"select remove-appearance\">\n                    ${dataIncluded\n                        .map(\n                            ({value, label}) =>\n                                `<option value=\"${value}\" ${value.toString(10) === selectedDataIncluded.toString(10) ? 'selected' : ''}>${label}</option>`,\n                        )\n                        .join('')}\n                   \n                </select>\n            </div>\n            ${FilterIcon()}\n        </div>\n    </div>\n    <a\n        id=\"filter-submit\"\n        class=\"button\"\n        href=\"${getLink(selectedDataIncluded, hardwareOptions, selectedHardware, environment)}\"\n    >\n        Vergleichen\n    </a>\n    <link \n        href=\"${getLink(selectedDataIncluded, hardwareOptions, selectedHardware, environment)}\" \n        rel=\"prefetch\" \n    />\n</div>    \n`;\n\nexport const setupShortFilter = ({\n    shadowRoot,\n    clickFilterCta,\n    dataIncludedChange,\n    openHardwareOverlay,\n    closeHardwareOverlay,\n    changeHardwareSelection,\n    isHardwareOverlayVisible,\n}: {\n    shadowRoot: ShadowRoot;\n    clickFilterCta: () => void;\n    dataIncludedChange: (selectedValue: number) => void;\n    openHardwareOverlay: () => void;\n} & Parameters<typeof setupHardwareOverlay>[0]): void => {\n    shadowRoot.getElementById('filter-submit')?.addEventListener('click', () => clickFilterCta());\n    shadowRoot.getElementById('data-included')?.addEventListener('change', event => {\n        const selectedValue = (event.target as HTMLSelectElement).value;\n        dataIncludedChange(parseInt(selectedValue));\n    });\n    shadowRoot.getElementById('hardware-selection')?.addEventListener('click', () => openHardwareOverlay());\n\n    setupHardwareOverlay({\n        shadowRoot,\n        closeHardwareOverlay,\n        changeHardwareSelection,\n        isHardwareOverlayVisible,\n    });\n};\n","import {EnvironmentUrls} from './environment.ts';\nimport {HardwareFilterCategory, DataIncludedFilterOption, DeviceOutput} from '../types/types.ts';\n\nconst getPubApiDefaultHeaders = (deviceOutput: DeviceOutput) =>\n    ({\n        'Accept': 'application/json',\n        'X-App-Version': '1.0.0',\n        'X-App-Platform': deviceOutput,\n        'X-Requested-With': 'XMLHttpRequest',\n        'Content-Type': 'application/json',\n    }) as const;\n\nexport const getFilter = async (\n    deviceOutput: DeviceOutput,\n    environment: EnvironmentUrls,\n    signal?: AbortSignal,\n): Promise<{\n    dataIncluded: Array<DataIncludedFilterOption>;\n    hardware: Array<HardwareFilterCategory>;\n}> => {\n    try {\n        const response = await fetch(`${environment.publicApi}/v1/filter/holding-slider`, {\n            method: 'GET',\n            headers: getPubApiDefaultHeaders(deviceOutput),\n            signal,\n        });\n\n        if (!response.ok) {\n            return {dataIncluded: [], hardware: []};\n        }\n\n        const json = await response.json();\n\n        return {\n            dataIncluded: json.data_included || [],\n            hardware: json.hw_prop_model_multiselect || [],\n        };\n    } catch {\n        return {dataIncluded: [], hardware: []};\n    }\n};\n\nexport const getPrefilling = async (\n    deviceOutput: DeviceOutput,\n    environment: EnvironmentUrls,\n    signal?: AbortSignal,\n): Promise<Partial<{data_included: number}>> => {\n    try {\n        const response = await fetch(`${environment.publicApi}/filter/prefilling`, {\n            method: 'GET',\n            headers: getPubApiDefaultHeaders(deviceOutput),\n            credentials: 'include',\n            signal,\n        });\n        if (!response.ok) {\n            return {};\n        }\n        return response.json();\n    } catch {\n        return {};\n    }\n};\n\nexport const setPrefilling = async (\n    deviceOutput: DeviceOutput,\n    environment: EnvironmentUrls,\n    selectedDataIncluded: number,\n    signal?: AbortSignal,\n): Promise<void> => {\n    try {\n        await fetch(`${environment.publicApi}/filter/prefilling`, {\n            method: 'PUT',\n            headers: getPubApiDefaultHeaders(deviceOutput),\n            body: JSON.stringify({data_included: selectedDataIncluded}),\n            credentials: 'include',\n            signal,\n        });\n    } catch {}\n};\n","export type HostEnv = 'live' | 'test' | 'int' | 'local';\n\nexport interface EnvironmentUrls {\n    publicApi: string;\n    host: string;\n    assetsExternal: string;\n}\n\nconst local = (): EnvironmentUrls => {\n    const n = import.meta.env.VITE_LOCAL_TESTING_NUMBER ?? '1';\n    const name = import.meta.env.VITE_LOCAL_NAME ?? 'local';\n    return {\n        publicApi: `https://pub-api${n}.${name}.handyvertrag.check24-test.de`,\n        host: `https://handyvertrag${n}.${name}.handyvertrag.check24-test.de`,\n        assetsExternal: `https://assets-handyvertrag${n}.${name}.handyvertrag.check24-test.de`,\n    };\n};\n\nconst test: EnvironmentUrls = {\n    publicApi: 'https://pub-api.handyvertrag.check24-test.de',\n    host: 'https://handyvertrag.check24-test.de',\n    assetsExternal: 'https://assets.handyvertrag.check24-test.de',\n};\n\nconst int: EnvironmentUrls = {\n    publicApi: 'https://pub-api.handyvertrag.check24-test.de',\n    host: 'https://handyvertrag.check24.de',\n    assetsExternal: 'https://assets.handyvertrag.check24-test.de',\n};\n\nconst live: EnvironmentUrls = {\n    publicApi: 'https://pub-api.handyvertrag.check24.de',\n    host: 'https://handyvertrag.check24.de',\n    assetsExternal: 'https://assets.handyvertrag.check24.de',\n};\n\nexport const resolveEnvironment = (env: HostEnv | null | undefined): EnvironmentUrls => {\n    switch (env) {\n        case 'local':\n            return local();\n        case 'test':\n            return test;\n        case 'int':\n            return int;\n        case 'live':\n        default:\n            return live;\n    }\n};\n\n// Prefers the explicit `env` attribute value from the host; falls back to hostname\n// detection so the component behaves correctly during local development without needing\n// the hub to inject attributes.\nexport const normalizeEnv = (raw: string | null): HostEnv => {\n    if (raw === 'test' || raw === 'int' || raw === 'live' || raw === 'local') return raw;\n    if (typeof window !== 'undefined') {\n        const host = window.location.hostname;\n        if (host.endsWith('.check24-test.de')) return 'test';\n        if (host.endsWith('.check24.de')) return 'live';\n    }\n    return 'live';\n};\n","/// <reference types=\"../.check24-home/types/client\" />\n\nimport styles from './client.scss?inline';\nimport {HomeClientComponentElement, HomeClientComponentProps, UserInfo} from '../.check24-home/types/client';\nimport {Language} from '../.check24-home/types/check24';\nimport {Navigation, setupNavigation} from './components/navigation.ts';\nimport {ShortFilter, setupShortFilter} from './components/short-filter.ts';\nimport {getPrefilling, getFilter, setPrefilling} from './configs/requests.ts';\nimport {HardwareFilterCategory, DataIncludedFilterOption, DeviceOutput} from './types/types.ts';\nimport {resolveEnvironment, normalizeEnv, EnvironmentUrls, HostEnv} from './configs/environment.ts';\nimport {cleanupHardwareOverlay, attachHardwareOverlayDismissListeners} from './components/hardware-overlay.ts';\n\ndeclare const __PHONES_DATA_URL__: string;\nconst phonesImageUrl: string = __PHONES_DATA_URL__;\n\n// Anchors the skeleton's CSS animation to the document timeline instead of the\n// moment this element is inserted, so a skeleton mounted after page load still\n// pulses in the same phase it would have if it had been there since navigation start.\nconst anchorToDocumentTimeline = (element: Element): void => {\n    for (const animation of element.getAnimations()) {\n        animation.startTime = 0;\n    }\n};\n\ndeclare global {\n    interface Window {\n        dataLayer?: Array<Record<string, unknown>>;\n    }\n}\n\ntype MobilfunkBundleProps = HomeClientComponentProps;\ntype RenderPhase = 'awaiting-hub-skeleton' | 'own-skeleton' | 'ready';\n\nexport default class MobilfunkBundleDefaultClient extends HTMLElement implements HomeClientComponentElement {\n    deviceOutput: DeviceOutput = 'desktop';\n    language: Language = 'de-DE';\n    user?: UserInfo | undefined;\n    platform: 'app' | 'web' = 'web';\n\n    #shadow: ShadowRoot | null = null;\n    #dataIncludedFilter: Array<DataIncludedFilterOption> = [];\n    #hardwareFilter: Array<HardwareFilterCategory> = [];\n\n    #selectedDataIncluded = 0;\n    #selectedHardware: Array<string> = [];\n    #isHardwareOverlayVisible = false;\n    #phase: RenderPhase = 'awaiting-hub-skeleton';\n    #shellRendered = false;\n    #didNotifyRender = false;\n    #controller = new AbortController();\n\n    #env: HostEnv = 'live';\n    #environment: EnvironmentUrls = resolveEnvironment('live');\n\n    // Spec host attributes: product-slug, deviceoutput, language, platform, env, sso-env.\n    // Also observe device-output (hyphenated) for reference/legacy host compatibility.\n    // `user` is not a host attribute; it surfaces as a prop via C24Home.validateAttributes.\n    static get observedAttributes(): string[] {\n        return ['product-slug', 'device-output', 'deviceoutput', 'language', 'platform', 'env', 'sso-env'];\n    }\n\n    attributeChangedCallback(name: string, oldValue: string, newValue: string): void {\n        if (oldValue === newValue) return;\n\n        this.#applyAttributes();\n\n        if (this.#shadow) {\n            if (name === 'device-output' || name === 'deviceoutput' || name === 'env') {\n                void this.#loadData();\n            } else {\n                this.#render();\n            }\n        }\n    }\n\n    async connectedCallback() {\n        this.#controller = new AbortController();\n\n        await this.#ensureFont();\n\n        this.#applyAttributes();\n        this.#phase = this.#hasHubSkeleton() ? 'awaiting-hub-skeleton' : 'own-skeleton';\n\n        if (this.#phase === 'own-skeleton') {\n            this.#attachShadow();\n            this.#render();\n        }\n\n        await this.#loadData();\n    }\n\n    // Inter font must be loaded at document level — @import inside shadow DOM is not reliable.\n    // The first render waits for the font so the headline does not flash in the fallback font.\n    async #ensureFont(): Promise<void> {\n        const timeout = new Promise<void>(resolve => setTimeout(resolve, 1500));\n\n        let link = document.getElementById('mobileservice-inter-font') as HTMLLinkElement | null;\n        if (!link) {\n            link = document.createElement('link');\n            link.id = 'mobileservice-inter-font';\n            link.rel = 'stylesheet';\n            link.href = 'https://wireframe-static.cdn.check24.com/inter.css?slug=check24_lp';\n            const loaded = new Promise<void>(resolve => {\n                link!.addEventListener('load', () => resolve(), {once: true});\n                link!.addEventListener('error', () => resolve(), {once: true});\n            });\n            document.head.appendChild(link);\n            await Promise.race([loaded, timeout]);\n        }\n\n        if (!('fonts' in document)) return;\n        try {\n            await Promise.race([\n                Promise.all([document.fonts.load('bold 30px Inter'), document.fonts.load('16px Inter')]),\n                timeout,\n            ]);\n        } catch {\n            // fall back to the system font\n        }\n    }\n\n    disconnectedCallback(): void {\n        this.#controller.abort();\n        if (this.#shadow) {\n            cleanupHardwareOverlay(this.#shadow);\n        }\n    }\n\n    #applyAttributes(): void {\n        if (typeof C24Home !== 'undefined' && typeof C24Home.validateAttributes === 'function') {\n            try {\n                const validated = C24Home.validateAttributes<MobilfunkBundleProps>(this.attributes);\n                const deviceOutput = this.#asString(validated.deviceOutput);\n                if (\n                    deviceOutput === 'desktop' ||\n                    deviceOutput === 'mobile' ||\n                    deviceOutput === 'tabletapp' ||\n                    deviceOutput === 'app'\n                ) {\n                    this.deviceOutput = deviceOutput;\n                }\n                const language = this.#asString(validated.language);\n                if (language) this.language = language as Language;\n                if (validated.user && typeof validated.user === 'object' && 'id' in validated.user) {\n                    this.user = validated.user;\n                }\n                const platform = this.#asString(validated.platform);\n                if (platform === 'app' || platform === 'web') this.platform = platform;\n            } catch {\n                this.#applyRawAttributes();\n            }\n        } else {\n            this.#applyRawAttributes();\n        }\n\n        this.#env = normalizeEnv(this.getAttribute('env'));\n        this.#environment = resolveEnvironment(this.#env);\n    }\n\n    #asString(value: unknown): string | undefined {\n        if (typeof value === 'string') return value;\n        if (value && typeof value === 'object' && 'value' in value) {\n            return (value as Attr).value;\n        }\n        return undefined;\n    }\n\n    #applyRawAttributes(): void {\n        const deviceOutput = this.getAttribute('deviceoutput') ?? this.getAttribute('device-output');\n        if (\n            deviceOutput === 'desktop' ||\n            deviceOutput === 'mobile' ||\n            deviceOutput === 'tabletapp' ||\n            deviceOutput === 'app'\n        ) {\n            this.deviceOutput = deviceOutput;\n        }\n        const language = this.getAttribute('language');\n        if (language) this.language = language as Language;\n        const platform = this.getAttribute('platform');\n        if (platform === 'app' || platform === 'web') this.platform = platform;\n        const userAttr = this.getAttribute('user');\n        if (userAttr) {\n            try {\n                const parsed: unknown = JSON.parse(userAttr);\n                if (\n                    parsed !== null &&\n                    typeof parsed === 'object' &&\n                    'id' in parsed &&\n                    typeof (parsed as {id: unknown}).id === 'string'\n                ) {\n                    this.user = parsed as UserInfo;\n                }\n            } catch {\n                // ignore malformed user attribute\n            }\n        }\n    }\n\n    #attachShadow(): void {\n        if (!this.#shadow) {\n            this.#shadow = this.attachShadow({mode: 'closed'});\n        }\n    }\n\n    #hasHubSkeleton(): boolean {\n        if (this.querySelector('.c24-mb-skeleton')) return true;\n        const parent = this.parentElement;\n        if (!parent) return false;\n        for (const child of Array.from(parent.children)) {\n            if (child !== this && child.classList.contains('c24-mb-skeleton')) return true;\n        }\n        return false;\n    }\n\n    #render(): void {\n        if (this.#phase === 'awaiting-hub-skeleton') return;\n        if (!this.#shadow) return;\n\n        if (this.#phase === 'own-skeleton') {\n            this.#renderSkeleton();\n            return;\n        }\n\n        this.#renderReady();\n    }\n\n    #ensureShell(): void {\n        if (!this.#shadow || this.#shellRendered) return;\n\n        this.#shadow.innerHTML = `\n            <style>${styles}</style>\n            <div class=\"teaser-root\">\n                <a href=\"${this.#environment.host}\" class=\"teaser-overlay-link\" aria-label=\"Zum Mobilfunk Bundle Vergleich\"></a>\n                <div class=\"phones-layer\" aria-hidden=\"true\">\n                    <img class=\"phones-image\" src=\"${phonesImageUrl}\" alt=\"\" loading=\"eager\" decoding=\"async\" />\n                </div>\n                <div class=\"headline\">\n                    <div class=\"mainline\">Handy mit Vertrag</div>\n                    <div class=\"subline\">Top Smartphones zum Top-Preis</div>\n                </div>\n                <section class=\"search-bar\" id=\"search-bar\">\n                    ${Navigation()}\n                    <div id=\"filter-slot\"></div>\n                </section>\n            </div>\n        `;\n        setupNavigation({\n            shadowRoot: this.#shadow,\n            onSimOnlyClick: () => this.#track('teaser_click'),\n        });\n        this.#shellRendered = true;\n    }\n\n    #renderSkeleton(): void {\n        if (!this.#shadow || this.#shadow.querySelector('.short-filter--skeleton')) return;\n\n        this.#ensureShell();\n        const filterSlot = this.#shadow.getElementById('filter-slot');\n        if (!filterSlot) return;\n\n        filterSlot.innerHTML = `<div class=\"short-filter short-filter--skeleton skeleton\" aria-hidden=\"true\"></div>`;\n        const skeleton = filterSlot.querySelector('.skeleton');\n        if (skeleton) anchorToDocumentTimeline(skeleton);\n    }\n\n    #renderReady(): void {\n        if (!this.#shadow) return;\n\n        this.#ensureShell();\n        const filterSlot = this.#shadow.getElementById('filter-slot');\n        if (!filterSlot) return;\n\n        filterSlot.innerHTML = ShortFilter({\n            dataIncluded: this.#dataIncludedFilter,\n            selectedDataIncluded: this.#selectedDataIncluded,\n            hardwareOptions: this.#hardwareFilter,\n            selectedHardware: this.#selectedHardware,\n            isHardwareOverlayVisible: this.#isHardwareOverlayVisible,\n            environment: this.#environment,\n        });\n        this.#setupEventListeners();\n\n        if (!this.#didNotifyRender) {\n            this.#didNotifyRender = true;\n            (this as HomeClientComponentElement).onRender?.();\n        }\n    }\n\n    async #loadData() {\n        const {signal} = this.#controller;\n\n        const prefilling = await getPrefilling(this.deviceOutput, this.#environment, signal);\n        if (signal.aborted) return;\n        this.#selectedDataIncluded = prefilling?.data_included ?? 0;\n\n        const filter = await getFilter(this.deviceOutput, this.#environment, signal);\n        if (signal.aborted) return;\n        this.#dataIncludedFilter = filter.dataIncluded;\n        this.#hardwareFilter = filter.hardware;\n\n        this.#phase = 'ready';\n        this.#attachShadow();\n        this.#render();\n    }\n\n    #setupEventListeners(): void {\n        if (!this.#shadow) return;\n        setupShortFilter({\n            shadowRoot: this.#shadow,\n            clickFilterCta: () => this.#track('teaser_click'),\n            dataIncludedChange: selectedValue => {\n                this.#selectedDataIncluded = selectedValue;\n                void setPrefilling(this.deviceOutput, this.#environment, selectedValue, this.#controller.signal);\n                this.#render();\n            },\n            changeHardwareSelection: selectedHardware => {\n                if (selectedHardware === '0') {\n                    this.#selectedHardware = [];\n                } else if (this.#selectedHardware.includes(selectedHardware)) {\n                    this.#selectedHardware = this.#selectedHardware.filter(value => value !== selectedHardware);\n                } else {\n                    this.#selectedHardware.push(selectedHardware);\n                }\n\n                this.#render();\n            },\n            openHardwareOverlay: () => {\n                this.#setHardwareOverlayVisible(true);\n            },\n            closeHardwareOverlay: () => {\n                this.#setHardwareOverlayVisible(false);\n            },\n            isHardwareOverlayVisible: this.#isHardwareOverlayVisible,\n        });\n    }\n\n    // Toggle the overlay's visibility without rebuilding the search-bar DOM.\n    // This matters because a full re-render would destroy the native <select>\n    // mid-click, breaking the \"close dropdown A, open dropdown B\" interaction.\n    #setHardwareOverlayVisible(visible: boolean): void {\n        this.#isHardwareOverlayVisible = visible;\n        if (!this.#shadow) return;\n\n        const overlay = this.#shadow.getElementById('hardware-overlay');\n        if (overlay) {\n            overlay.style.display = visible ? '' : 'none';\n        }\n\n        if (visible) {\n            overlay?.focus({preventScroll: true});\n            attachHardwareOverlayDismissListeners(this.#shadow, () => this.#setHardwareOverlayVisible(false));\n        } else {\n            cleanupHardwareOverlay(this.#shadow);\n        }\n    }\n\n    #track(event: 'teaser_click') {\n        window.dataLayer = window.dataLayer ?? [];\n        window.dataLayer.push({event, product: 'mobilfunk:bundle'});\n    }\n}\n\nif (typeof customElements !== 'undefined' && !customElements.get('mobileservice-default')) {\n    customElements.define('mobileservice-default', MobilfunkBundleDefaultClient);\n}\n","export const Navigation = (): string => `\n<nav class=\"navigation\">\n    <a\n        href=\"https://handytarife.check24.de\"\n        class=\"nav-link\"\n        id=\"simonly-link\"\n    >\n        Handytarife (SIM-Karte)\n    </a>\n    <span class=\"nav-link active\">Handy mit Vertrag</span>\n</nav>\n`;\n\nexport const setupNavigation = ({\n    shadowRoot,\n    onSimOnlyClick,\n}: {\n    shadowRoot: ShadowRoot;\n    onSimOnlyClick: () => void;\n}): void => {\n    shadowRoot.getElementById('simonly-link')?.addEventListener('click', () => onSimOnlyClick());\n};\n"],"names":["HardwareOption","label","value","isSelected","isDisabled","overlayHandlers","WeakMap","cleanupHardwareOverlay","shadowRoot","handlers","get","document","removeEventListener","documentHandler","shadowRootRef","shadowHandler","delete","getSelectionCount","selectedHardware","length","attachHardwareOverlayDismissListeners","closeHardwareOverlay","event","composedPath","includes","host","path","overlay","getElementById","trigger","set","addEventListener","getLink","selectedDataIncluded","hardwareOptions","hardwareSelection","environment","allOptions","flatMap","category","options","hardwareKeys","map","id","option","find","opt","key","queryParams","URLSearchParams","data_included","toString","join","getHardwarePath","getPubApiDefaultHeaders","deviceOutput","Accept","test","publicApi","assetsExternal","int","live","resolveEnvironment","env","name","local","MobilfunkBundleDefaultClient","HTMLElement","constructor","super","arguments","__privateAdd","this","_MobilfunkBundleDefaultClient_instances","__publicField","_shadow","_dataIncludedFilter","_hardwareFilter","_selectedDataIncluded","_selectedHardware","_isHardwareOverlayVisible","_phase","_shellRendered","_didNotifyRender","_controller","AbortController","_env","_environment","observedAttributes","attributeChangedCallback","oldValue","newValue","__privateMethod","applyAttributes_fn","call","__privateGet","loadData_fn","render_fn","connectedCallback","__privateSet","ensureFont_fn","hasHubSkeleton_fn","attachShadow_fn","disconnectedCallback","abort","WeakSet","async","timeout","Promise","setTimeout","resolve","link","createElement","rel","href","loaded","once","head","appendChild","race","all","fonts","load","C24Home","validateAttributes","validated","attributes","asString_fn","language","user","platform","applyRawAttributes_fn","raw","window","location","hostname","endsWith","normalizeEnv","getAttribute","userAttr","parsed","JSON","parse","attachShadow","mode","querySelector","parent","parentElement","child","Array","from","children","classList","contains","renderReady_fn","renderSkeleton_fn","ensureShell_fn","innerHTML","onSimOnlyClick","setupNavigation","track_fn","filterSlot","skeleton","element","animation","getAnimations","startTime","dataIncluded","isHardwareOverlayVisible","reduce","acc","section","filter","getHardwareLabel","selectionCount","remainingSelectableCount","getHintText","HardwareOverlay","ShortFilter","setupEventListeners_fn","onRender","signal","prefilling","response","fetch","method","headers","credentials","ok","json","getPrefilling","aborted","hardware","hw_prop_model_multiselect","getFilter","clickFilterCta","dataIncludedChange","openHardwareOverlay","changeHardwareSelection","selectedValue","target","parseInt","querySelectorAll","forEach","checkbox","dataset","setupHardwareOption","setupHardwareOverlay","setupShortFilter","body","stringify","setPrefilling","push","setHardwareOverlayVisible_fn","visible","style","display","focus","preventScroll","dataLayer","product","customElements","define"],"mappings":"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"}