{"version":3,"file":"client.mjs","sources":["../app/configs/environment.ts","../app/configs/links.ts","../app/configs/tariff-filter-defaults.ts","../app/types/types.ts","../app/configs/requests.ts","../app/render.ts","../app/client.ts","../app/configs/layout.ts"],"sourcesContent":["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    if (\n        import.meta.env.DEV &&\n        typeof window !== 'undefined' &&\n        (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1')\n    ) {\n        return {\n            publicApi: `${window.location.origin}/pub-api`,\n            host: live.host,\n            assetsExternal: live.assetsExternal,\n        };\n    }\n\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\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        // Production layout checks run on loopback hosts; Vite's dev proxy is handled above.\n        if (host.endsWith('.check24-test.de')) return 'test';\n        if (host.endsWith('.check24.de')) return 'live';\n    }\n    return 'live';\n};\n","export const HOME_SOURCE = 'home';\n\nexport const TID2 = {\n    topLeft: 'home_teaser_top_left_web',\n    topRight: 'home_teaser_top_right_web',\n    bottomLeft: 'home_teaser_bottom_left_web',\n    bottomRight: 'home_teaser_bottom_right_web',\n    headline: 'home_teaser_grid_headline_web',\n} as const;\n\nexport const CELL_TID2 = [TID2.topLeft, TID2.topRight, TID2.bottomLeft, TID2.bottomRight] as const;\n\nexport const OVERVIEW_PATH = 'handy-uebersicht';\n\nexport function formatMonthlyPrice(amountInCents: number): string {\n    const [whole, fraction] = (amountInCents / 100).toFixed(2).split('.');\n    const grouped = whole.replace(/\\B(?=(\\d{3})+(?!\\d))/g, '.');\n    return `${grouped},${fraction} € mtl.`;\n}\n\nexport function trackedUrl(host: string, path: string, tid2: string): string {\n    const url = new URL(`${host.replace(/\\/$/, '')}/${path.replace(/^\\//, '')}`);\n    url.searchParams.set('tid2', tid2);\n    url.searchParams.set('source', HOME_SOURCE);\n    return url.toString();\n}\n\nexport function devicePath(hardwareKey: string): string {\n    return `vergleich/${encodeURIComponent(hardwareKey)}`;\n}\n","const tariffFilterDefaults = {\n    '5g': 'all',\n    black_deals: 'no',\n    christmas_delivery: 'no',\n    combinationBenefitProvider: '0',\n    contract_time: '24',\n    data_included: '0',\n    data_speed: '0',\n    deliverable_within_a_week: 'no',\n    device_price: '999999',\n    easy_rnp: 'no',\n    esim_only: 'no',\n    flexible_contract_start: 'no',\n    refurbished: 'egal',\n    with_high_acceptance_rate: 'all',\n    smily_benefit: 'all',\n    young_tariff: 'no',\n    orderby: 'popularity',\n    paypal_payment: 'all',\n    rnp: 'egal',\n    hwprop_color_group: 'egal',\n    hwprop_memorysize: 'egal',\n} as const;\n\nexport const tariffFilterDefaultsQueryString = new URLSearchParams(tariffFilterDefaults).toString();\n","export type Brand<K, T> = K & {__brand: T};\n\nexport type HardwareKey = Brand<string, 'HardwareKey'>;\n\nexport type HardwareImage = Readonly<{\n    big?: string;\n    giant?: string;\n    medium?: string;\n    small?: string;\n    zoom?: string;\n}>;\n\nexport type Hardware = Readonly<{\n    hardwareKey: HardwareKey;\n    displayName: string;\n    cheapestHardwarePrice: Readonly<{\n        amount: number;\n        currency: string;\n    }>;\n    images: Readonly<{\n        front?: HardwareImage;\n        back?: HardwareImage;\n    }>;\n}>;\n\nexport interface ResultListDataItem {\n    readonly sorting: Record<string, {direction: 'asc' | 'desc'; priority: number}>;\n    readonly tariffselection: {version: number; variation: string; subvariation: string};\n}\n\nexport const POPULARITY_SORT = 'popularity';\n","import {formatMonthlyPrice} from './links.ts';\nimport {tariffFilterDefaultsQueryString} from './tariff-filter-defaults.ts';\nimport {EnvironmentUrls} from './environment.ts';\nimport {Hardware, HardwareImage, HardwareKey, POPULARITY_SORT, ResultListDataItem} from '../types/types.ts';\n\nconst pubApiDefaultHeaders = {\n    Accept: 'application/json',\n    'X-App-Version': '1.0.0',\n    'X-App-Platform': 'app',\n    'X-Requested-With': 'XMLHttpRequest',\n    'Content-Type': 'application/json',\n} as const;\n\nexport type TeaserDeviceImage = Readonly<{\n    big?: string;\n    medium?: string;\n}>;\n\nexport type TeaserDevice = Readonly<{\n    hardwareKey: HardwareKey;\n    displayName: string;\n    priceLabel: string;\n    front: TeaserDeviceImage;\n    back: TeaserDeviceImage;\n}>;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n    typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst asHardwareKey = (value: unknown): HardwareKey | undefined => {\n    if (typeof value !== 'string' || value.length === 0) return undefined;\n    return value as HardwareKey;\n};\n\nconst asFiniteNumber = (value: unknown): number | undefined =>\n    typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n\nconst readImage = (value: unknown): HardwareImage | undefined => {\n    if (!isRecord(value)) return undefined;\n    const image: {big?: string; giant?: string; medium?: string; small?: string; zoom?: string} = {};\n    for (const key of ['big', 'giant', 'medium', 'small', 'zoom'] as const) {\n        const url = value[key];\n        if (typeof url === 'string' && url.length > 0) image[key] = url;\n    }\n    return image;\n};\n\nconst readHardware = (value: unknown): Hardware | undefined => {\n    if (!isRecord(value)) return undefined;\n    const hardwareKey = asHardwareKey(value.hardwareKey);\n    if (!hardwareKey || typeof value.displayName !== 'string') return undefined;\n    if (!isRecord(value.cheapestHardwarePrice)) return undefined;\n    const amount = asFiniteNumber(value.cheapestHardwarePrice.amount);\n    if (amount === undefined) return undefined;\n    const currency =\n        typeof value.cheapestHardwarePrice.currency === 'string' ? value.cheapestHardwarePrice.currency : '';\n    const images = isRecord(value.images) ? value.images : {};\n    return {\n        hardwareKey,\n        displayName: value.displayName,\n        cheapestHardwarePrice: {amount, currency},\n        images: {\n            front: readImage(images.front),\n            back: readImage(images.back),\n        },\n    };\n};\n\nconst readTariff = (value: unknown): ResultListDataItem | undefined => {\n    if (!isRecord(value) || !isRecord(value.sorting) || !isRecord(value.tariffselection)) return undefined;\n    const version = asFiniteNumber(value.tariffselection.version);\n    const variation = value.tariffselection.variation;\n    const subvariation = value.tariffselection.subvariation;\n    if (version === undefined || typeof variation !== 'string' || typeof subvariation !== 'string') return undefined;\n    if (variation.length === 0 || subvariation.length === 0) return undefined;\n\n    const sorting: ResultListDataItem['sorting'] = {};\n    for (const [key, item] of Object.entries(value.sorting)) {\n        if (!isRecord(item)) continue;\n        const priority = asFiniteNumber(item.priority);\n        const direction = item.direction === 'asc' || item.direction === 'desc' ? item.direction : undefined;\n        if (priority === undefined || !direction) continue;\n        sorting[key] = {direction, priority};\n    }\n\n    return {sorting, tariffselection: {version, variation, subvariation}};\n};\n\nconst readTopsellerKeys = (value: unknown): HardwareKey[] => {\n    if (!Array.isArray(value)) return [];\n    return value.flatMap(item => {\n        if (!isRecord(item)) return [];\n        const key = asHardwareKey(item.hardwareIdentifier);\n        return key ? [key] : [];\n    });\n};\n\nexport const imageSrc = (image: HardwareImage | undefined, size: 'big' | 'medium'): string | undefined => {\n    if (!image) return undefined;\n    const url =\n        size === 'big' ? image.big || image.medium || image.small : image.medium || image.small || image.big;\n    return url ? url : undefined;\n};\n\nexport const getTopsellerKeys = async (environment: EnvironmentUrls, signal?: AbortSignal): Promise<HardwareKey[]> => {\n    try {\n        const response = await fetch(`${environment.publicApi}/v1/top-seller/by-os`, {\n            method: 'GET',\n            headers: pubApiDefaultHeaders,\n            signal,\n        });\n        if (!response.ok) return [];\n\n        const json: unknown = await response.json();\n        if (!isRecord(json)) return [];\n\n        return [\n            ...readTopsellerKeys(json.iosTopsellers).slice(0, 2),\n            ...readTopsellerKeys(json.androidTopsellers).slice(0, 2),\n        ];\n    } catch {\n        return [];\n    }\n};\n\nexport const getActiveHardwareList = async (\n    environment: EnvironmentUrls,\n    signal?: AbortSignal,\n): Promise<Record<string, Hardware> | undefined> => {\n    try {\n        const response = await fetch(`${environment.publicApi}/v2/hardware/active-hardware-list`, {\n            method: 'GET',\n            headers: pubApiDefaultHeaders,\n            signal,\n        });\n        if (!response.ok) return undefined;\n\n        const json: unknown = await response.json();\n        if (!isRecord(json) || !Array.isArray(json.hardwareList)) return undefined;\n\n        return Object.fromEntries(\n            json.hardwareList.flatMap(item => {\n                const hardware = readHardware(item);\n                return hardware ? [[hardware.hardwareKey, hardware] as const] : [];\n            }),\n        );\n    } catch {\n        return undefined;\n    }\n};\n\nconst monthlyAmount = async (environment: EnvironmentUrls, key: HardwareKey, signal?: AbortSignal): Promise<number> => {\n    const resultResponse = await fetch(\n        `${environment.publicApi}/v2/result/collection/for-client/mobile/by-hardware-key/${key}?${tariffFilterDefaultsQueryString}`,\n        {\n            method: 'GET',\n            headers: pubApiDefaultHeaders,\n            signal,\n        },\n    );\n    if (!resultResponse.ok) return 0;\n\n    const resultJson: unknown = await resultResponse.json();\n    const rawTariffs = isRecord(resultJson) && Array.isArray(resultJson.tariffs) ? resultJson.tariffs : [];\n    const tariffs = rawTariffs.flatMap(item => {\n        const tariff = readTariff(item);\n        return tariff ? [tariff] : [];\n    });\n    if (tariffs.length === 0) return 0;\n\n    const direction = tariffs[0]?.sorting?.[POPULARITY_SORT]?.direction ?? 'asc';\n    const sorted = [...tariffs].sort((a, b) => {\n        const delta = (a.sorting?.[POPULARITY_SORT]?.priority ?? 0) - (b.sorting?.[POPULARITY_SORT]?.priority ?? 0);\n        return direction === 'desc' ? -delta : delta;\n    });\n    const selection = sorted[0]?.tariffselection;\n    if (!selection) return 0;\n\n    const priceResponse = await fetch(\n        `${environment.publicApi}/v1/price-layer/by-tariff-selection/${selection.version}/${selection.variation}/${selection.subvariation}`,\n        {\n            method: 'GET',\n            headers: pubApiDefaultHeaders,\n            signal,\n        },\n    );\n    if (!priceResponse.ok) return 0;\n\n    const priceJson: unknown = await priceResponse.json();\n    if (!isRecord(priceJson) || !isRecord(priceJson.prices) || !isRecord(priceJson.prices.monthlyBasicfee)) return 0;\n    return asFiniteNumber(priceJson.prices.monthlyBasicfee.amount) ?? 0;\n};\n\nexport const getMonthlyPrices = async (\n    environment: EnvironmentUrls,\n    keys: HardwareKey[],\n    signal?: AbortSignal,\n): Promise<Record<string, number>> => {\n    const entries = await Promise.all(\n        keys.map(async key => {\n            try {\n                return [key, await monthlyAmount(environment, key, signal)] as const;\n            } catch {\n                return [key, 0] as const;\n            }\n        }),\n    );\n    return Object.fromEntries(entries);\n};\n\nconst loads = new Map<string, Promise<TeaserDevice[]>>();\n\nexport const loadTopSmartphones = (environment: EnvironmentUrls): Promise<TeaserDevice[]> => {\n    const cached = loads.get(environment.publicApi);\n    if (cached) return cached;\n\n    const load = (async () => {\n        const topSellerKeys = await getTopsellerKeys(environment);\n        const [activeHardwares, monthlyPrices] = await Promise.all([\n            getActiveHardwareList(environment),\n            getMonthlyPrices(environment, topSellerKeys),\n        ]);\n        return topSellerKeys\n            .map(key => activeHardwares?.[key])\n            .filter((value): value is Hardware => value !== undefined)\n            .flatMap(hardware => {\n                const front = {\n                    big: imageSrc(hardware.images.front, 'big'),\n                    medium: imageSrc(hardware.images.front, 'medium'),\n                };\n                const back = {\n                    big: imageSrc(hardware.images.back, 'big'),\n                    medium: imageSrc(hardware.images.back, 'medium'),\n                };\n                if ((!front.big && !front.medium) || (!back.big && !back.medium)) return [];\n                const monthly = monthlyPrices[hardware.hardwareKey] ?? 0;\n                const amount = monthly > 0 ? monthly : hardware.cheapestHardwarePrice.amount;\n                if (!Number.isFinite(amount)) return [];\n                return [\n                    {\n                        hardwareKey: hardware.hardwareKey,\n                        displayName: hardware.displayName,\n                        priceLabel: formatMonthlyPrice(amount),\n                        front,\n                        back,\n                    },\n                ];\n            });\n    })()\n        .then(devices => {\n            if (devices.length === 0) loads.delete(environment.publicApi);\n            return devices;\n        })\n        .catch(error => {\n            loads.delete(environment.publicApi);\n            throw error;\n        });\n\n    loads.set(environment.publicApi, load);\n    return load;\n};\n","import {CELL_TID2, OVERVIEW_PATH, TID2, devicePath, trackedUrl} from './configs/links.ts';\nimport type {TeaserDevice} from './configs/requests.ts';\n\nconst escapeHtml = (value: string): string =>\n    value.replace(/[&<>\"']/g, char => {\n        switch (char) {\n            case '&':\n                return '&amp;';\n            case '<':\n                return '&lt;';\n            case '>':\n                return '&gt;';\n            case '\"':\n                return '&quot;';\n            default:\n                return '&#39;';\n        }\n    });\n\nconst HEADLINE = ['Top Smartphones -', 'günstig mit Vertrag'] as const;\n\nexport const skeletonHtml = (): string => `\n<section class=\"c24-hv-skeleton\" aria-hidden=\"true\">\n    <div class=\"headline\" aria-hidden=\"true\">\n        <span class=\"line skeleton\"></span>\n        <span class=\"line skeleton\"></span>\n    </div>\n    <div class=\"grid\">\n        ${[0, 1, 2, 3].map(() => `<div class=\"cell skeleton\"></div>`).join('')}\n    </div>\n</section>`;\n\nconst deviceImage = (image: TeaserDevice['front'], large: boolean): string =>\n    (large ? image.big || image.medium : image.medium || image.big) ?? '';\n\nconst cellHtml = (device: TeaserDevice, host: string, tid2: string, large: boolean): string => {\n    const href = escapeHtml(trackedUrl(host, devicePath(device.hardwareKey), tid2));\n    const name = escapeHtml(device.displayName);\n    const price = escapeHtml(device.priceLabel);\n    return `<a class=\"cell\" href=\"${href}\" data-tid2=\"${tid2}\">\n        <span class=\"name\">${name}</span>\n        <span class=\"devices\">\n            <img class=\"back\" src=\"${escapeHtml(deviceImage(device.back, large))}\" alt=\"\" decoding=\"async\" />\n            <img class=\"front\" src=\"${escapeHtml(deviceImage(device.front, large))}\" alt=\"\" decoding=\"async\" />\n        </span>\n        <span class=\"price\">${price}</span>\n    </a>`;\n};\n\nexport const teaserHtml = (devices: TeaserDevice[], host: string, large = false): string => {\n    const overview = escapeHtml(trackedUrl(host, OVERVIEW_PATH, TID2.headline));\n    const cells = devices\n        .slice(0, 4)\n        .map((device, index) => cellHtml(device, host, CELL_TID2[index] ?? TID2.topLeft, large))\n        .join('');\n    const placeholders = Array.from(\n        {length: Math.max(0, 4 - devices.length)},\n        () => `<a class=\"cell\" href=\"${overview}\" data-tid2=\"${TID2.headline}\"></a>`,\n    ).join('');\n\n    return `<div class=\"teaser\">\n        <a class=\"rest\" href=\"${overview}\" data-tid2=\"${TID2.headline}\" aria-label=\"${escapeHtml(HEADLINE.join(' '))}\"></a>\n        <a class=\"headline\" href=\"${overview}\" data-tid2=\"${TID2.headline}\">\n            <span>${HEADLINE[0]}</span>\n            <span>${HEADLINE[1]}</span>\n        </a>\n        <div class=\"grid\">${cells}${placeholders}</div>\n    </div>`;\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 {normalizeEnv, resolveEnvironment, EnvironmentUrls} from './configs/environment.ts';\nimport {isHeroLayout, isInactive} from './configs/layout.ts';\nimport {loadTopSmartphones, TeaserDevice} from './configs/requests.ts';\nimport {skeletonHtml, teaserHtml} from './render.ts';\n\ndeclare global {\n    interface Window {\n        dataLayer?: Array<Record<string, unknown>>;\n    }\n}\n\nconst isLanguage = (value: string): value is Language =>\n    value === 'de-DE' || value === 'en-GB' || value === 'en-US' || value === 'de-AT' || value === 'es-ES';\n\nconst anchorToDocumentTimeline = (element: Element): void => {\n    for (const animation of element.getAnimations()) {\n        animation.startTime = 0;\n    }\n};\n\nexport default class HandyvertragTopSmartphonesClient extends HTMLElement implements HomeClientComponentElement {\n    deviceOutput: HomeClientComponentProps['deviceOutput'] = 'desktop';\n    language: Language = 'de-DE';\n    user?: UserInfo;\n    platform: 'app' | 'web' = 'web';\n    onRender?: () => void;\n\n    #shadow: ShadowRoot | null = null;\n    #devices: TeaserDevice[] = [];\n    #phase: 'loading' | 'ready' = 'loading';\n    #controller = new AbortController();\n    #environment: EnvironmentUrls = resolveEnvironment('live');\n    #observer: ResizeObserver | null = null;\n    #heroMedia: MediaQueryList | null = null;\n    #tileMedia: MediaQueryList | null = null;\n    #measuring = false;\n    #didNotifyRender = false;\n\n    static get observedAttributes(): string[] {\n        return [\n            'product-slug',\n            'device-output',\n            'deviceoutput',\n            'language',\n            'platform',\n            'env',\n            'sso-env',\n            'data-teaser-active',\n        ];\n    }\n\n    attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n        if (oldValue === newValue) return;\n        this.#applyAttributes();\n        if (!this.#shadow) return;\n        if (name === 'env') {\n            this.#controller.abort();\n            this.#controller = new AbortController();\n            this.#phase = 'loading';\n            this.dataset.state = 'loading';\n            void this.#load();\n        }\n    }\n\n    async connectedCallback(): Promise<void> {\n        this.#controller = new AbortController();\n        this.#applyAttributes();\n        this.#bindLayout();\n        this.#syncLayout();\n        this.dataset.state = 'loading';\n        if (!this.#hasHubSkeleton()) {\n            this.#attachShadow();\n            this.#render();\n        }\n        await this.#ensureFont();\n        await this.#load();\n    }\n\n    disconnectedCallback(): void {\n        this.#controller.abort();\n        this.#observer?.disconnect();\n        this.#observer = null;\n        window.removeEventListener('resize', this.#syncLayout);\n        this.#heroMedia?.removeEventListener('change', this.#syncLayout);\n        this.#tileMedia?.removeEventListener('change', this.#syncLayout);\n        this.removeEventListener('pointerdown', this.#onPointerDown);\n    }\n\n    #attachShadow(): void {\n        if (this.#shadow) return;\n        this.#shadow = this.attachShadow({mode: 'closed'});\n        this.#shadow.addEventListener('click', this.#onShadowClick);\n        this.addEventListener('pointerdown', this.#onPointerDown);\n    }\n\n    #bindLayout(): void {\n        this.#observer?.disconnect();\n        window.removeEventListener('resize', this.#syncLayout);\n        this.#heroMedia?.removeEventListener('change', this.#syncLayout);\n        this.#tileMedia?.removeEventListener('change', this.#syncLayout);\n\n        this.#heroMedia = window.matchMedia('(min-width: 769px)');\n        this.#tileMedia = window.matchMedia('(max-width: 768px)');\n        this.#heroMedia.addEventListener('change', this.#syncLayout);\n        this.#tileMedia.addEventListener('change', this.#syncLayout);\n        window.addEventListener('resize', this.#syncLayout);\n        this.#observer = new ResizeObserver(() => this.#syncLayout());\n        if (this.parentElement) this.#observer.observe(this.parentElement);\n    }\n\n    #syncLayout = (): void => {\n        if (this.#measuring) return;\n        this.#measuring = true;\n        const slotWidth = this.#measureSlotWidth();\n        this.#measuring = false;\n        const hero = slotWidth > 0 && isHeroLayout(window.innerWidth, slotWidth);\n        const layout = hero ? 'hero' : 'tile';\n        const changed = this.dataset.layout !== layout;\n        if (hero) this.dataset.promotion = 'top';\n        else delete this.dataset.promotion;\n        this.dataset.layout = layout;\n        if (changed && this.#phase === 'ready') this.#render();\n    };\n\n    #measureSlotWidth(): number {\n        const slot = this.assignedSlot?.parentElement ?? this.parentElement;\n        if (slot) {\n            const width = slot.getBoundingClientRect().width;\n            if (width > 0) return width;\n        }\n        return this.clientWidth;\n    }\n\n    #hasHubSkeleton(): boolean {\n        if (this.querySelector('.c24-hv-skeleton')) return true;\n        const parent = this.parentElement;\n        if (!parent) return false;\n        for (const child of parent.children) {\n            if (child !== this && child.classList.contains('c24-hv-skeleton')) return true;\n        }\n        return false;\n    }\n\n    #render(): void {\n        if (!this.#shadow) return;\n        this.#shadow.innerHTML =\n            this.#phase === 'ready'\n                ? `<style>${styles}</style>${teaserHtml(this.#devices, this.#environment.host, this.dataset.layout === 'hero')}`\n                : `<style>${styles}</style>${skeletonHtml()}`;\n        const rect = this.getBoundingClientRect();\n        const size = `${Math.round(rect.width)}x${Math.round(rect.height)}`;\n        if (this.#phase !== 'ready') {\n            this.dataset.skeletonSize = size;\n            for (const skeleton of this.#shadow.querySelectorAll('.skeleton')) {\n                anchorToDocumentTimeline(skeleton);\n            }\n            return;\n        }\n        this.dataset.shift = this.dataset.skeletonSize === size ? '0' : `${this.dataset.skeletonSize ?? ''}->${size}`;\n        if (!this.#didNotifyRender) {\n            this.#didNotifyRender = true;\n            this.onRender?.();\n        }\n    }\n\n    async #load(): Promise<void> {\n        const {signal} = this.#controller;\n        try {\n            const devices = await loadTopSmartphones(this.#environment);\n            if (signal.aborted || !this.isConnected) return;\n            this.#devices = devices;\n            this.#showReady();\n        } catch {\n            if (signal.aborted || !this.isConnected) return;\n            this.#devices = [];\n            this.#showReady();\n        }\n    }\n\n    #showReady(): void {\n        this.#phase = 'ready';\n        this.dataset.state = 'ready';\n        this.#attachShadow();\n        this.#syncLayout();\n        this.#render();\n    }\n\n    async #ensureFont(): Promise<void> {\n        const timeout = new Promise<void>(resolve => setTimeout(resolve, 1500));\n        let link = document.getElementById('handyvertrag-inter-font') as HTMLLinkElement | null;\n        if (!link) {\n            link = document.createElement('link');\n            link.id = 'handyvertrag-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        if (!('fonts' in document)) return;\n        try {\n            await Promise.race([\n                Promise.all([\n                    document.fonts.load('800 34px Inter'),\n                    document.fonts.load('800 22px Inter'),\n                    document.fonts.load('400 16px Inter'),\n                    document.fonts.load('400 11px Inter'),\n                ]),\n                timeout,\n            ]);\n        } catch {\n            return;\n        }\n    }\n\n    #applyAttributes(): void {\n        if (typeof C24Home !== 'undefined' && typeof C24Home.validateAttributes === 'function') {\n            try {\n                const validated = C24Home.validateAttributes<HomeClientComponentProps>(this.attributes);\n                this.#assignProps(validated);\n            } catch {\n                this.#applyRawAttributes();\n            }\n        } else {\n            this.#applyRawAttributes();\n        }\n        this.#environment = resolveEnvironment(normalizeEnv(this.getAttribute('env')));\n    }\n\n    #assignProps(validated: HomeClientComponentProps): void {\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 && isLanguage(language)) this.language = language;\n        if (validated.user && typeof validated.user.id === 'string' && validated.user.id.length > 0)\n            this.user = validated.user;\n        const platform = this.#asString(validated.platform);\n        if (platform === 'app' || platform === 'web') this.platform = platform;\n    }\n\n    #asString(value: unknown): string | undefined {\n        if (typeof value === 'string') return value;\n        if (value && typeof value === 'object' && 'value' in value && typeof value.value === 'string') return value.value;\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 && isLanguage(language)) this.language = language;\n        const platform = this.getAttribute('platform');\n        if (platform === 'app' || platform === 'web') this.platform = platform;\n    }\n\n    #inactive(): boolean {\n        return isInactive(this.getAttribute('data-teaser-active'));\n    }\n\n    #track(tid2: string): void {\n        window.dataLayer = window.dataLayer ?? [];\n        window.dataLayer.push({\n            event: 'teaser_click',\n            product: 'mobilfunk:bundle',\n            tid2,\n        });\n    }\n\n    #onPointerDown = (event: Event): void => {\n        if (this.#inactive()) event.stopPropagation();\n    };\n\n    #onShadowClick = (event: Event): void => {\n        if (!(event instanceof MouseEvent)) return;\n        const link = event\n            .composedPath()\n            .find((node): node is HTMLAnchorElement => node instanceof HTMLAnchorElement && Boolean(node.href));\n        if (!link) return;\n        const tid2 = link.dataset.tid2;\n        if (!tid2) return;\n\n        const modified = event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;\n        if (!modified) event.preventDefault();\n        this.#track(tid2);\n        if (this.#inactive()) event.stopPropagation();\n        if (!modified) window.location.assign(link.href);\n    };\n}\n\nif (typeof customElements !== 'undefined' && !customElements.get('mobileservice-top-smartphones-without-form')) {\n    customElements.define('mobileservice-top-smartphones-without-form', HandyvertragTopSmartphonesClient);\n}\n","const MOBILE_MAX_VIEWPORT = 768;\nconst HERO_SLOT_MIN = 400;\nconst HERO_SLOT_MAX = 559;\n\nexport function isHeroLayout(viewportWidth: number, slotWidth: number): boolean {\n    if (viewportWidth <= MOBILE_MAX_VIEWPORT) return false;\n    return slotWidth >= HERO_SLOT_MIN && slotWidth <= HERO_SLOT_MAX;\n}\n\nexport function isInactive(teaserActive: string | null): boolean {\n    return teaserActive === 'false';\n}\n"],"names":["test","publicApi","host","assetsExternal","int","live","resolveEnvironment","env","name","local","TID2","CELL_TID2","formatMonthlyPrice","amountInCents","whole","fraction","toFixed","split","replace","trackedUrl","path","tid2","url","URL","searchParams","set","toString","tariffFilterDefaultsQueryString","URLSearchParams","black_deals","christmas_delivery","combinationBenefitProvider","contract_time","data_included","data_speed","deliverable_within_a_week","device_price","easy_rnp","esim_only","flexible_contract_start","refurbished","with_high_acceptance_rate","smily_benefit","young_tariff","orderby","paypal_payment","rnp","hwprop_color_group","hwprop_memorysize","POPULARITY_SORT","pubApiDefaultHeaders","Accept","isRecord","value","Array","isArray","asHardwareKey","length","asFiniteNumber","Number","isFinite","readImage","image","key","readTopsellerKeys","flatMap","item","hardwareIdentifier","imageSrc","size","big","medium","small","getActiveHardwareList","async","environment","signal","response","fetch","method","headers","ok","json","hardwareList","Object","fromEntries","hardware","hardwareKey","displayName","cheapestHardwarePrice","amount","currency","images","front","back","readHardware","monthlyAmount","resultResponse","resultJson","tariffs","tariff","sorting","tariffselection","version","variation","subvariation","entries","priority","direction","readTariff","sorted","sort","a","b","delta","selection","priceResponse","priceJson","prices","monthlyBasicfee","getMonthlyPrices","keys","Promise","all","map","loads","Map","escapeHtml","char","HEADLINE","deviceImage","large","isLanguage","anchorToDocumentTimeline","element","animation","getAnimations","startTime","HandyvertragTopSmartphonesClient","HTMLElement","constructor","super","arguments","__privateAdd","this","_HandyvertragTopSmartphonesClient_instances","__publicField","_shadow","_devices","_phase","_controller","AbortController","_environment","_observer","_heroMedia","_tileMedia","_measuring","_didNotifyRender","_syncLayout","__privateGet","__privateSet","slotWidth","__privateMethod","measureSlotWidth_fn","call","hero","viewportWidth","isHeroLayout","window","innerWidth","layout","changed","dataset","promotion","render_fn","_onPointerDown","event","inactive_fn","stopPropagation","_onShadowClick","MouseEvent","link","composedPath","find","node","HTMLAnchorElement","Boolean","href","modified","button","metaKey","ctrlKey","shiftKey","altKey","preventDefault","location","assign","observedAttributes","attributeChangedCallback","oldValue","newValue","applyAttributes_fn","abort","state","load_fn","connectedCallback","bindLayout_fn","hasHubSkeleton_fn","attachShadow_fn","ensureFont_fn","disconnectedCallback","disconnect","removeEventListener","WeakMap","WeakSet","attachShadow","mode","addEventListener","matchMedia","ResizeObserver","parentElement","observe","slot","assignedSlot","width","getBoundingClientRect","clientWidth","querySelector","parent","child","children","classList","contains","innerHTML","styles","devices","overview","cells","slice","device","index","encodeURIComponent","price","priceLabel","cellHtml","join","placeholders","from","Math","max","teaserHtml","rect","round","height","shift","skeletonSize","onRender","skeleton","querySelectorAll","cached","get","load","topSellerKeys","getTopsellerKeys","iosTopsellers","androidTopsellers","activeHardwares","monthlyPrices","filter","monthly","then","delete","catch","error","loadTopSmartphones","aborted","isConnected","showReady_fn","timeout","setTimeout","resolve","document","getElementById","createElement","id","rel","loaded","once","head","appendChild","race","fonts","C24Home","validateAttributes","validated","attributes","applyRawAttributes_fn","raw","hostname","endsWith","normalizeEnv","getAttribute","assignProps_fn","deviceOutput","asString_fn","language","user","platform","track_fn","dataLayer","push","product","customElements","define"],"mappings":"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"}