{"version":3,"file":"client.mjs","sources":["../app/constants.ts","../app/utils.ts","../app/teaser_internet.client.ts"],"sourcesContent":["const PSS_URL_PROD = 'https://internet.check24.de/';\nconst PSS_URL_TEST = 'https://internet.check24-test.de/';\n\nfunction hostname(): string {\n    return globalThis.location?.hostname ?? '';\n}\n\n/**\n * Product start page origin. The widget is hosted on www.check24.de, so tile\n * links must go to the PSS — never the holding host or the local preview origin.\n */\nexport function getPssUrl(): string {\n    const host = hostname();\n    // check24-test.de must be checked before returning PROD (test hostnames also end with check24.de).\n    if (host.endsWith('check24-test.de')) {\n        return PSS_URL_TEST;\n    }\n    return PSS_URL_PROD;\n}\n\nexport function getAssetBaseUrl(): string {\n    const host = hostname();\n    if (host === 'localhost' || host === '127.0.0.1') {\n        return `${globalThis.location?.origin ?? ''}/`;\n    }\n    return getPssUrl();\n}\n\nexport function getTeaserZipApiUrl(): string {\n    const host = hostname();\n    if (host === 'localhost' || host === '127.0.0.1') {\n        return `${globalThis.location?.origin ?? ''}/api/teaser-zip`;\n    }\n    return `${getPssUrl()}api/teaser-zip`;\n}\n\nexport const TID3_VALUE = 'webteaser_grid';\n\nconst TILE_KEYS = ['internet', 'router', 'fiber', 'tv'] as const;\nexport type TileKey = (typeof TILE_KEYS)[number];\n\nexport type TileIcon = 'wifi' | 'router' | 'fiber' | 'tv' | 'tv_v2';\n\nexport type TileDefinition = {\n    readonly key: TileKey;\n    readonly label: string;\n    readonly icon: TileIcon;\n    readonly params: Readonly<Record<string, string>>;\n};\n\n/**\n * Tile definitions matching the app teaser configuration.\n * - Internet (Top Left): tid4=teaser_tl\n * - Internet with Router (Top Right): tid4=teaser_tr, router=true\n * - Fiberglass (Bottom Left): tid4=teaser_bl, context=teaser_fiber, keyword=glasfaser\n * - Internet + TV (Bottom Right): tid4=teaser_br, tariffType=tv\n */\nexport const TILES: readonly TileDefinition[] = [\n    {\n        key: 'internet',\n        label: 'Internet',\n        icon: 'wifi',\n        params: { tid4: 'teaser_tl' },\n    },\n    {\n        key: 'router',\n        label: 'Inkl. Router',\n        icon: 'router',\n        params: { tid4: 'teaser_tr', router: 'true' },\n    },\n    {\n        key: 'fiber',\n        label: 'Glasfaser',\n        icon: 'fiber',\n        params: {\n            tid4: 'teaser_bl',\n            context: 'teaser_fiber',\n            keyword: 'glasfaser',\n        },\n    },\n    {\n        key: 'tv',\n        label: 'Internet + TV',\n        icon: 'tv_v2',\n        params: { tid4: 'teaser_br', tariffType: 'tv' },\n    },\n];\n\nexport type TeaserPrices = {\n    readonly internet: number;\n    readonly router: number;\n    readonly fiber: number;\n    readonly tv: number;\n};\n\n/** Starting prices shown on the tile chips (euros / month). */\nexport const TEASER_PRICES: TeaserPrices = {\n    internet: 17.07,\n    router: 21,\n    fiber: 17.07,\n    tv: 18.95,\n};\n\nexport const DEFAULT_TITLE = 'Günstiges Internet für Ihr Zuhause';\nexport const PERSONALISED_TITLE_PREFIX = 'Internet für Ihr Zuhause in ';\n\nexport type Labels = {\n    readonly defaultTitle: string;\n    readonly pricePrefix: string;\n    readonly priceSuffix: string;\n};\n\nexport const labels: Labels = {\n    defaultTitle: DEFAULT_TITLE,\n    pricePrefix: 'ab',\n    priceSuffix: '€ mtl.',\n};\n","import {\n    DEFAULT_TITLE,\n    getAssetBaseUrl,\n    getPssUrl,\n    PERSONALISED_TITLE_PREFIX,\n    TID3_VALUE,\n    type TileDefinition,\n} from './constants';\n\nconst DESKTOP_MIN_VIEWPORT_PX = 1024;\nconst HERO_SLOT_MIN_WIDTH_PX = 400;\nconst HERO_SLOT_MAX_WIDTH_PX = 559;\n\n/**\n * Hero layout only when viewport >= 1024 px AND the available slot is 400–559 px.\n * Below 1024 px, layout is always Tile regardless of slot width.\n */\nexport function isHeroSlot(slotWidth: number, viewportWidth: number = globalThis.innerWidth ?? 0): boolean {\n    if (viewportWidth < DESKTOP_MIN_VIEWPORT_PX) return false;\n    return slotWidth >= HERO_SLOT_MIN_WIDTH_PX && slotWidth <= HERO_SLOT_MAX_WIDTH_PX;\n}\n\nexport function formatPrice(value: number): string {\n    return new Intl.NumberFormat('de-DE', {\n        minimumFractionDigits: 2,\n        maximumFractionDigits: 2,\n    }).format(value);\n}\n\nexport function formatPriceChip(prefix: string, value: number, suffix: string): string {\n    return `${prefix} ${formatPrice(value)} ${suffix}`;\n}\n\nexport function getTileIconUrl(icon: TileDefinition['icon']): string {\n    return `${getAssetBaseUrl()}img/teaser/teaser_${icon}.png`;\n}\n\nexport function buildTileUrl(tile: TileDefinition): string {\n    const url = new URL(getPssUrl());\n\n    new URLSearchParams(globalThis.location?.search ?? '').forEach((value, key) => {\n        if (key !== 'tid3' && key !== 'customerType') {\n            url.searchParams.set(key, value);\n        }\n    });\n\n    url.searchParams.set('tid3', TID3_VALUE);\n\n    for (const [key, value] of Object.entries(tile.params)) {\n        url.searchParams.set(key, value);\n    }\n\n    return url.toString();\n}\nexport function isValidZip(zip: unknown): zip is string {\n    return typeof zip === 'string' && /^\\d{5}$/.test(zip);\n}\n\nexport function formatTitle(zip?: string | null): string {\n    if (isValidZip(zip)) {\n        return `${PERSONALISED_TITLE_PREFIX}${zip}`;\n    }\n    return DEFAULT_TITLE;\n}\n\nconst FETCH_TIMEOUT_MS = 3_000;\n\nexport async function fetchTeaserZip(apiUrl: string, signal?: AbortSignal): Promise<string | null> {\n    // Always enforce the timeout, even with a caller signal — the headline shimmer waits on this.\n    const controller = new AbortController();\n    const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n    const abortFromCaller = (): void => controller.abort();\n    signal?.addEventListener('abort', abortFromCaller, { once: true });\n    if (signal?.aborted) controller.abort();\n\n    try {\n        const response = await fetch(apiUrl, {\n            credentials: 'include',\n            signal: controller.signal,\n        });\n        if (!response.ok) return null;\n        const data = (await response.json()) as { zip?: unknown };\n        return isValidZip(data?.zip) ? data.zip : null;\n    } catch {\n        return null;\n    } finally {\n        clearTimeout(timeoutId);\n        signal?.removeEventListener('abort', abortFromCaller);\n    }\n}\n","/// <reference types=\"../.check24-home/types/client\" />\n\nimport type { Language } from '../.check24-home/types/check24';\nimport type { HomeClientComponentElement, HomeClientComponentProps } from '../.check24-home/types/client';\nimport { getTeaserZipApiUrl, labels, TEASER_PRICES, TILES } from './constants';\nimport { buildTileUrl, fetchTeaserZip, formatPriceChip, formatTitle, getTileIconUrl, isHeroSlot } from './utils';\nimport clientStyles from './assets/tile_teaser_client.css?raw';\n\nexport default class InternetTileTeaserClient extends HTMLElement implements HomeClientComponentElement {\n    deviceOutput: 'desktop' | 'mobile' | 'tabletapp' | 'app' = 'desktop';\n    language: Language = 'de-DE';\n    platform: 'app' | 'web' = 'web';\n\n    private shadow: ShadowRoot | null = null;\n    private resizeObserver: ResizeObserver | null = null;\n    private breakpointMedia: MediaQueryList | null = null;\n    private layoutListenersBound = false;\n    private abortController: AbortController | null = null;\n\n    static get observedAttributes(): string[] {\n        return ['data-teaser-active', 'deviceoutput', 'platform'];\n    }\n\n    attributeChangedCallback(_name: string, oldValue: string, newValue: string): void {\n        if (oldValue === newValue) return;\n        this.applyAttributes();\n        this.updatePromotionAttribute();\n    }\n\n    connectedCallback(): void {\n        if (!this.shadow) {\n            this.shadow = this.attachShadow({ mode: 'closed' });\n        }\n\n        this.applyAttributes();\n        this.updatePromotionAttribute();\n        this.render();\n        this.bindLayoutListeners();\n        void this.loadPersonalisedHeadline();\n    }\n\n    disconnectedCallback(): void {\n        this.abortController?.abort();\n        this.abortController = null;\n        window.removeEventListener('resize', this.boundUpdatePromotionAttribute);\n        this.breakpointMedia?.removeEventListener('change', this.boundUpdatePromotionAttribute);\n        this.breakpointMedia = null;\n        this.resizeObserver?.disconnect();\n        this.resizeObserver = null;\n        this.layoutListenersBound = false;\n    }\n\n    private boundUpdatePromotionAttribute = (): void => {\n        this.updatePromotionAttribute();\n    };\n\n    private bindLayoutListeners(): void {\n        if (this.layoutListenersBound) return;\n        this.layoutListenersBound = true;\n\n        window.addEventListener('resize', this.boundUpdatePromotionAttribute);\n        this.breakpointMedia = window.matchMedia('(min-width: 1024px)');\n        this.breakpointMedia.addEventListener('change', this.boundUpdatePromotionAttribute);\n        if (typeof ResizeObserver !== 'undefined') {\n            this.resizeObserver = new ResizeObserver(this.boundUpdatePromotionAttribute);\n            const slotTarget = this.assignedSlot?.parentElement ?? this.parentElement ?? this;\n            this.resizeObserver.observe(slotTarget);\n        }\n    }\n\n    private applyAttributes(): void {\n        const validator = (globalThis as Record<string, unknown>).C24Home as typeof C24Home | undefined;\n\n        if (typeof validator?.validateAttributes === 'function') {\n            const validated = validator.validateAttributes<HomeClientComponentProps>(this.attributes);\n            this.deviceOutput = validated.deviceOutput ?? this.deviceOutput;\n            this.platform = validated.platform ?? this.platform;\n            this.language = validated.language ?? this.language;\n            return;\n        }\n\n        this.deviceOutput =\n            (this.getAttribute('deviceoutput') as InternetTileTeaserClient['deviceOutput']) ||\n            (this.getAttribute('device-output') as InternetTileTeaserClient['deviceOutput']) ||\n            'desktop';\n        this.platform = (this.getAttribute('platform') as InternetTileTeaserClient['platform']) || 'web';\n        this.language = (this.getAttribute('language') as Language) || 'de-DE';\n    }\n\n    private getAvailableSlotWidth(): number {\n        const slotParent = this.assignedSlot?.parentElement;\n        if (slotParent) return slotParent.clientWidth;\n        if (this.parentElement) return this.parentElement.clientWidth;\n        return this.clientWidth;\n    }\n\n    private updatePromotionAttribute(): void {\n        const isHero = isHeroSlot(this.getAvailableSlotWidth(), window.innerWidth);\n        if (isHero) {\n            this.setAttribute('data-promotion', 'top');\n            return;\n        }\n\n        this.removeAttribute('data-promotion');\n    }\n\n    /** Replaces the headline shimmer with the final title. */\n    private updateHeadline(title: string): void {\n        const text = this.shadow?.querySelector('.mw-text');\n        if (!text) return;\n\n        const headline = document.createElement('h2');\n        headline.className = 'mw-headline';\n        headline.textContent = title;\n        text.replaceChildren(headline);\n        text.removeAttribute('aria-busy');\n    }\n\n    private async loadPersonalisedHeadline(): Promise<void> {\n        this.abortController?.abort();\n        this.abortController = new AbortController();\n\n        const zip = await fetchTeaserZip(getTeaserZipApiUrl(), this.abortController.signal);\n        if (this.abortController.signal.aborted) return;\n\n        this.updateHeadline(formatTitle(zip));\n    }\n\n    private render(): void {\n        if (!this.shadow) return;\n\n        if (!this.shadow.querySelector('.mw-root')) {\n            this.shadow.innerHTML = `\n                <style>${clientStyles}</style>\n                ${this.getContent()}\n            `;\n        }\n    }\n\n    private getContent(): string {\n        const tiles = TILES.map((tile) => {\n            const href = buildTileUrl(tile);\n            const iconUrl = getTileIconUrl(tile.icon);\n            const price = formatPriceChip(labels.pricePrefix, TEASER_PRICES[tile.key], labels.priceSuffix);\n\n            return `\n                <a class=\"mw-tile\" href=\"${href}\">\n                    <span class=\"mw-label\">${tile.label}</span>\n                    <span class=\"mw-media\">\n                        <img class=\"mw-icon\" src=\"${iconUrl}\" alt=\"\" loading=\"lazy\" decoding=\"async\">\n                    </span>\n                    <span class=\"mw-price\">${price}</span>\n                </a>`;\n        }).join('');\n\n        return `\n            <div class=\"mw-root\">\n                <div class=\"mw-text\" aria-busy=\"true\">\n                    <div class=\"mw-headline-skel c24-dsl-teaser-skeleton-pulse\"></div>\n                    <div class=\"mw-headline-skel mw-headline-skel--short c24-dsl-teaser-skeleton-pulse\"></div>\n                </div>\n                <div class=\"mw-grid\">\n                    ${tiles}\n                </div>\n            </div>\n        `;\n    }\n}\n\ncustomElements.define('dsl-internettile', InternetTileTeaserClient);\n"],"names":["hostname","_a","_b","globalThis","location","getPssUrl","endsWith","TILES","key","label","icon","params","tid4","router","context","keyword","tariffType","TEASER_PRICES","internet","fiber","tv","labels","formatPriceChip","prefix","value","suffix","Intl","NumberFormat","minimumFractionDigits","maximumFractionDigits","format","formatPrice","getTileIconUrl","host","origin","getAssetBaseUrl","isValidZip","zip","test","InternetTileTeaserClient","HTMLElement","constructor","super","arguments","__publicField","this","updatePromotionAttribute","observedAttributes","attributeChangedCallback","_name","oldValue","newValue","applyAttributes","connectedCallback","shadow","attachShadow","mode","render","bindLayoutListeners","loadPersonalisedHeadline","disconnectedCallback","_c","abortController","abort","window","removeEventListener","boundUpdatePromotionAttribute","breakpointMedia","resizeObserver","disconnect","layoutListenersBound","addEventListener","matchMedia","ResizeObserver","slotTarget","assignedSlot","parentElement","observe","validator","C24Home","validateAttributes","validated","attributes","deviceOutput","platform","language","getAttribute","getAvailableSlotWidth","slotParent","clientWidth","slotWidth","viewportWidth","innerWidth","isHeroSlot","removeAttribute","setAttribute","updateHeadline","title","text","querySelector","headline","document","createElement","className","textContent","replaceChildren","__async","AbortController","apiUrl","signal","controller","timeoutId","setTimeout","abortFromCaller","once","aborted","response","fetch","credentials","ok","data","json","e","clearTimeout","fetchTeaserZip","getTeaserZipApiUrl","formatTitle","innerHTML","getContent","map","tile","href","url","URL","URLSearchParams","search","forEach","searchParams","set","Object","entries","toString","buildTileUrl","iconUrl","price","join","customElements","define"],"mappings":"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"}