{"version":3,"file":"client.mjs","names":["#applyAttributes","#shadow","#render","#controller","#fetchTariffs","#asString","#applyRawAttributes","#env","#environment","#isLoading","#hasFailed","#tariffs","#renderTariffCard"],"sources":["../app/utils.ts","../app/environment.ts","../app/server.scss?inline","../app/server.ts","../app/client.scss?inline","../app/client.ts"],"sourcesContent":["export function centToEuro(cents: number): string {\n    const euros = cents / 100;\n    return euros.toLocaleString('de-DE', {\n        minimumFractionDigits: 2,\n        maximumFractionDigits: 2,\n    }) + ' €';\n}\n\nexport async function httpGet<T>(url: string, deviceOutput: string = 'desktop', signal?: AbortSignal): Promise<T> {\n    const response = await fetch(url, {\n        method: 'GET',\n        headers: {\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        },\n        credentials: 'include',\n        signal,\n    });\n\n    if (!response.ok) {\n        throw new Error(`HTTP error! status: ${response.status}`);\n    }\n\n    return response.json();\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","\n\n@mixin mobile {\n    @media (max-width: 768px) {\n        @content;\n    }\n}\n\n@mixin tablet-portrait {\n    @media (min-width: 769px) and (max-width: 1023px) {\n        @content;\n    }\n}\n\n@mixin tablet-landscape {\n    @media (min-width: 1024px) {\n        @content;\n    }\n}\n\n@mixin tablet {\n    @media (min-width: 769px) {\n        @content;\n    }\n}\n\n@mixin desktop {\n    @media (min-width: 1312px) {\n        @content;\n    }\n}\n\n.c24-mw-container {\n    box-sizing: border-box;\n    width: 100%;\n}\n\n.c24-mw-title {\n    @extend %c24-mw-skeleton-shimmer;\n    height: 30px;\n    margin: 0 0 16px 0;\n    color: transparent;\n    text-align: left;\n    border-radius: 15px;\n    width: fit-content;\n\n    @include tablet() {\n        font-size: 24px;\n        line-height: 30px;\n    }\n}\n\n.c24-mw-list {\n    display: flex;\n    width: 100%;\n\n    @include mobile() {\n        flex-direction: column;\n        gap: 16px;\n    }\n\n    @include tablet() {\n        flex-direction: row;\n        justify-content: center;\n        gap: 16px;\n    }\n}\n\n.c24-mw-card {\n    display: flex;\n    flex-grow: 1;\n    height: 155px;\n    text-decoration: none;\n    color: inherit;\n    border-radius: 8px;\n    overflow: hidden;\n    box-shadow: 0 0 8px rgba(0, 0, 0, 0.16);\n\n\n    @include mobile() {\n        width: 100%;\n        height: 139px;\n        border-radius: 10px;\n    }\n\n    @include mobile() {\n        width: 100%;\n        height: 139px;\n        border-radius: 10px;\n    }\n\n    @include tablet-landscape() {\n        flex: 1;\n        min-width: 0;\n        min-height: 155px;\n        height: auto;\n        max-height: none;\n    }\n\n    @include desktop() {\n        flex: 0 1 416px;\n        width: 416px;\n        min-height: 155px;\n        height: auto;\n    }\n}\n\n.c24-mw-image-wrapper {\n    position: relative;\n    overflow: hidden;\n    background-color: var(--background-color);\n    box-sizing: border-box;\n    min-width: 144px;\n    max-width: 144px;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n\n\n    @include mobile() {\n        min-width: 102px;\n        max-width: 102px;\n    }\n\n    @include mobile() {\n        min-width: 102px;\n        max-width: 102px;\n    }\n\n    @include tablet-portrait() {\n        min-width: 82px;\n        max-width: 82px;\n        align-self: stretch;\n    }\n\n    @include tablet-landscape() {\n        min-width: 115px;\n        max-width: 115px;\n        align-self: stretch;\n    }\n\n}\n\n.c24-mw-container {\n    --skeleton-dark: rgb(235, 235, 235);\n    --skeleton-light: rgb(245, 246, 245);\n}\n\n.widget-more {\n    border-radius: 19px;\n    @extend %c24-mw-skeleton-shimmer;\n    color: transparent;\n    margin-top: 16px;\n    width: fit-content;\n\n}\n\n%c24-mw-skeleton-shimmer {\n    background-color: var(--skeleton-dark);\n    animation: c24-mw-skeleton-pulse 1100ms ease-in-out infinite;\n    animation-delay: 100ms;\n}\n\n.c24-mw-skeleton-image {\n    width: 60%;\n    border-radius: 8px;\n    @extend %c24-mw-skeleton-shimmer;\n    height: 124px;\n    display: flex;\n    margin: 0 auto;\n    padding: 10px;\n    object-fit: contain;\n    transition: transform 0.7s ease-in-out;\n\n    @media (hover: hover) and (pointer: fine) {\n        .tariff-card:hover & {\n            transform: scale(1.05);\n        }\n    }\n\n\n    @include mobile() {\n        width: 58px;\n        height: 88px;\n        padding: 0;\n    }\n\n    @include tablet-portrait() {\n        width: 60px;\n        height: 91px;\n        padding: 0;\n    }\n\n    @include tablet-landscape() {\n        width: 80px;\n        height: 121px;\n        padding: 0;\n    }\n}\n\n.c24-mw-info {\n    padding: 16px;\n    display: flex;\n    flex-direction: column;\n    justify-content: space-between;\n    flex: 1;\n}\n\n.c24-mw-skeleton-top,\n.c24-mw-skeleton-bottom {\n    display: flex;\n    flex-direction: column;\n    gap: 2px;\n}\n\n\n.price-wrapper-desktop {\n    display: none;\n    @include tablet() {\n        display: flex;\n        align-items: flex-end;\n        width: 100%;\n        flex-flow: column;\n        gap: 3px;\n    }\n}\n\n.c24-mw-skeleton-bottom {\n    align-items: end;\n    @include tablet() {\n        margin-top: 9px;\n    }\n}\n\n.c24-mw-skeleton-text {\n    @extend %c24-mw-skeleton-shimmer;\n    height: 12px;\n    border-radius: 50px;\n\n    &--manufacturer {\n        width: 60px;\n        height: 23px;\n    }\n\n    &--name {\n        width: 100px;\n        height: 21px;\n    }\n\n    &--count {\n        width: 70px;\n        height: 18px;\n    }\n\n    &--caption {\n        width: 109px;\n        height: 18px;\n    }\n\n    &--header {\n        width: 290px;\n        height: 25px;\n    }\n\n    &--price {\n        width: 75px;\n        height: 19px;\n    }\n}\n\n\n@keyframes c24-mw-skeleton-pulse {\n    0% {\n        background-color: var(--skeleton-dark);\n    }\n\n    9% {\n        background-color: var(--skeleton-dark);\n    }\n\n    50% {\n        background-color: var(--skeleton-light);\n    }\n\n    59% {\n        background-color: var(--skeleton-light);\n    }\n\n    100% {\n        background-color: var(--skeleton-dark);\n    }\n}\n","/// <reference types=\"../.check24-home/types/server\" />\n\nimport {HomeServerComponent} from '../.check24-home/types/server';\nimport style from './server.scss?inline';\n\nconst skeletonCard = `\n    <div class=\"c24-mw-card\">\n        <div class=\"c24-mw-image-wrapper\">\n            <div class=\"c24-mw-skeleton-image\"></div>\n        </div>\n        <div class=\"c24-mw-info\">\n            <div class=\"c24-mw-skeleton-top\">\n                <div class=\"c24-mw-skeleton-text c24-mw-skeleton-text--manufacturer\"></div>\n                <div class=\"c24-mw-skeleton-text c24-mw-skeleton-text--name\"></div>\n            </div>\n            <div class=\"c24-mw-skeleton-bottom\">\n                <div class=\"c24-mw-skeleton-text c24-mw-skeleton-text--count\"></div>\n                <div class=\"c24-mw-skeleton-text c24-mw-skeleton-text--price\"></div>\n                <div class=\"c24-mw-skeleton-text c24-mw-skeleton-text--caption\"></div>\n            </div>\n        </div>\n    </div>\n`;\n\nconst skeleton = (title: string): string => `\n    <div class=\"c24-mw-container\">\n        <h2 class=\"c24-mw-title\">${title}</h2>\n        <div class=\"c24-mw-list\">\n            ${skeletonCard}\n            ${skeletonCard}\n            ${skeletonCard}\n        </div>\n        <div class=\"widget-more\">Alle Angebote entdecken</div>\n    </div>\n`;\n\nexport default {\n    skeleton: {\n        'de-DE': skeleton('Handy mit Vertrag vergleichen'),\n        'en-GB': skeleton('Compare Mobile Phone with Contract'),\n    },\n    style,\n} satisfies HomeServerComponent;\n","@mixin mobile-small {\n    @media (max-width: 359px) {\n        @content;\n    }\n}\n\n@mixin mobile {\n    @media (max-width: 768px) {\n        @content;\n    }\n}\n\n@mixin tablet-portrait {\n    @media (min-width: 769px) and (max-width: 1023px) {\n        @content;\n    }\n}\n\n@mixin tablet-landscape {\n    @media (min-width: 1024px) {\n        @content;\n    }\n}\n\n@mixin tablet {\n    @media (min-width: 769px) {\n        @content;\n    }\n}\n\n@mixin desktop {\n    @media (min-width: 1312px) {\n        @content;\n    }\n}\n\n:host {\n    display: block;\n    width: 100%;\n    background: transparent;\n    --font-color: #181818;\n    --background-color: #f4f4f4;\n    line-height: normal;\n}\n\n.widget-root {\n    width: 100%;\n    box-sizing: border-box;\n    text-align: left;\n}\n\n.widget-container {\n    box-sizing: border-box;\n    width: 100%;\n}\n\n.widget-title {\n    font-size: 20px;\n    font-weight: bold;\n    line-height: 22px;\n    margin: 0 0 16px 0;\n    color: var(--font-color);\n    text-align: left;\n\n    @include tablet() {\n        font-size: 24px;\n        line-height: 30px;\n        margin: 0 0 16px 0;\n        display: flex;\n        align-items: baseline;\n    }\n}\n\n.widget-more {\n    color: #0563c1;\n    text-decoration: none;\n    font-size: 16px;\n    font-weight: normal;\n    display: block;\n    float: left;\n    text-align: left;\n    margin-top: 16px;\n    \n    &:hover {\n        color: #b65e00;\n        text-decoration: underline;\n    }\n}\n\n.tariff-list {\n    display: flex;\n    width: 100%;\n    \n    @include mobile() {\n        flex-direction: column;\n        gap: 16px;\n    }\n    \n    @include tablet() {\n        flex-direction: row;\n        justify-content: center;\n        gap: 16px;\n    }\n}\n\n.tariff-card {\n    display: flex;\n    flex-grow: 1;\n    height: 155px;\n    text-decoration: none;\n    color: inherit;\n    border-radius: 8px;\n    overflow: hidden;\n    box-shadow: 0 0 8px rgba(0, 0, 0, 0.16);\n\n    \n    @include mobile() {\n        width: 100%;\n        height: 139px;\n        border-radius: 10px;\n    }\n    \n    @include tablet-landscape() {\n        flex: 1;\n        min-width: 0;\n        min-height: 155px;\n        height: auto;\n        max-height: none;\n    }\n    \n    @include desktop() {\n        flex: 0 1 416px;\n        width: 416px;\n        min-height: 155px;\n        height: auto;\n    }\n}\n\n.tariff-image-wrapper {\n    position: relative;\n    overflow: hidden;\n    background-color: var(--background-color);\n    box-sizing: border-box;\n    min-width: 144px;\n    max-width: 144px;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    \n    @include mobile() {\n        min-width: 102px;\n        max-width: 102px;\n    }\n\n    @include tablet-portrait() {\n        min-width: 82px;\n        max-width: 82px;\n        align-self: stretch;\n    }\n\n    @include tablet-landscape() {\n        min-width: 115px;\n        max-width: 115px;\n        align-self: stretch;\n    }\n}\n\n.tariff-image {\n    height: 124px;\n    display: flex;\n    margin: 0 auto;\n    padding: 10px;\n    object-fit: contain;\n    transition: transform 0.7s ease-in-out;\n\n    @media (hover: hover) and (pointer: fine) {\n        .tariff-card:hover & {\n            transform: scale(1.05);\n        }\n    }\n\n    \n    @include mobile() {\n        width: 58px;\n        height: 88px;\n        padding: 0;\n    }\n    \n    @include tablet-portrait() {\n        width: 60px;\n        height: 91px;\n        padding: 0;\n    }\n    \n    @include tablet-landscape() {\n        width: 80px;\n        height: 121px;\n        padding: 0;\n    }\n}\n\n.tariff-info {\n    padding: 16px;\n    display: flex;\n    flex: 1;\n    flex-direction: column;\n    justify-content: space-between;\n}\n\n.tariff-manufacturer {\n    font-weight: normal;\n    font-size: 20px;\n    line-height: 23px;\n    margin-bottom: 0;\n    color: var(--font-color);\n    \n    @include mobile() {\n        display: block;\n        font-size: 18px;\n        font-weight: normal;\n        line-height: 1.2;\n    }\n    \n    @include desktop() {\n        font-size: 20px;\n        font-weight: normal;\n    }\n}\n\n.tariff-name {\n    font-weight: bold;\n    font-size: 20px;\n    line-height: 23px;\n    color: var(--font-color);\n    \n    @include mobile-small() {\n        font-size: 16px;\n        line-height: 1.2;\n    }\n\n    @include mobile() {\n        font-size: 18px;\n        font-weight: bold;\n        line-height: 1.2;\n    }\n    \n    @include tablet() {\n        font-size: 18px;\n        font-weight: bold;\n        line-height: 1.2;\n    }\n    \n    @include desktop() {\n        font-size: 20px;\n        font-weight: bold;\n    }\n}\n\n.tariff-price-wrapper {\n    margin-top: 10px;\n    text-align: right;\n    display: flex;\n    flex-flow: column;\n    align-items: flex-end;\n    font-size: 16px;\n\n    \n    @include mobile() {\n        margin-top: 10px;\n        justify-content: flex-end;\n    }\n    \n    @include tablet() {\n        margin-top: 10px;\n        flex-flow: column nowrap;\n        gap: 0;\n        align-items: flex-end;\n    }\n}\n\n.tariff-total-amount {\n    color: var(--font-color);\n    font-size: 14px;\n    margin-bottom: 2px;\n\n    \n    @include mobile() {\n        font-size: 16px;\n        font-weight: normal;\n        margin-bottom: 0;\n    }\n\n    \n    @include tablet-landscape() {\n        font-size: 14px;\n        font-weight: normal;\n        flex-basis: auto;\n    }\n    \n    @include desktop() {\n        font-size: 12px;\n    }\n}\n\n.tariff-price {\n    display: flex;\n    align-items: baseline;\n    gap: 4px;\n    justify-content: flex-end;\n    color: var(--font-color);\n    \n    @include mobile() {\n        display: inline-flex;\n    }\n    \n    @include tablet() {\n        display: flex;\n\n    }\n}\n\n.price-description {\n    font-size: 14px;\n    color: var(--font-color);\n    margin-top: 2px;\n    white-space: nowrap;\n    \n    @include mobile() {\n        font-size: 16px;\n        font-weight: normal;\n        margin-top: 0;\n        display: inline;\n    }\n    \n    @include tablet-landscape() {\n        font-size: 14px;\n        font-weight: normal;\n        margin-top: 2px;\n        display: block;\n    }\n    \n    @include desktop() {\n        font-size: 14px;\n    }\n}\n\n\n\n:host {\n    --skeleton-dark: rgb(235, 235, 235);\n    --skeleton-light: rgb(245, 246, 245);\n}\n\n@keyframes skeleton-pulse {\n    0% {\n        background-color: var(--skeleton-dark);\n    }\n\n    9% {\n        background-color: var(--skeleton-dark);\n    }\n\n    50% {\n        background-color: var(--skeleton-light);\n    }\n\n    59% {\n        background-color: var(--skeleton-light);\n    }\n\n    100% {\n        background-color: var(--skeleton-dark);\n    }\n}\n\n.skeleton {\n    pointer-events: none;\n}\n\n.skeleton-animation {\n    background-color: var(--skeleton-dark);\n    animation: skeleton-pulse 1100ms ease-in-out infinite;\n    animation-delay: 100ms;\n}\n\n.skeleton-bg-image {\n    height: 166px;\n    width: 144px;\n}\n\n.skeleton-text {\n    height: 20px;\n    margin-bottom: 5px;\n\n    &:first-child {\n        width: 115px;\n    }\n\n    &:last-child {\n        width: 115px;\n        margin-bottom: 0;\n    }\n}\n\n.skeleton-price {\n    width: 82px;\n    height: 26px;\n}\n\n.error-message,\n.no-results {\n    text-align: center;\n    color: #666666;\n    padding: 40px 20px;\n    font-size: 14px;\n}\n","/// <reference types=\"../.check24-home/types/client\" />\n\nimport {HomeClientComponentElement, HomeClientComponentProps, UserInfo} from '../.check24-home/types/client';\nimport {Language} from '../.check24-home/types/check24';\nimport {TariffInfo, TariffWidgetResponse} from './types';\nimport {centToEuro, httpGet} from './utils';\nimport {HostEnv, EnvironmentUrls, normalizeEnv, resolveEnvironment} from './environment';\nimport skeleton from './server.ts';\nimport styles from './client.scss?inline';\n\ninterface MobilfunkTopTariffsProps extends HomeClientComponentProps {}\n\n\nexport default class MobilfunkTopTariffsClient extends HTMLElement implements HomeClientComponentElement {\n    deviceOutput: 'desktop' | 'mobile' | 'tabletapp' | 'app' = 'desktop';\n    language: Language = 'de-DE';\n    user?: UserInfo | undefined;\n    platform: 'app' | 'web' = 'web';\n\n    #shadow: ShadowRoot | null = null;\n    #env: HostEnv = 'live';\n    #environment: EnvironmentUrls = resolveEnvironment('live');\n    #controller = new AbortController();\n    #tariffs: Array<TariffInfo> = [];\n    #isLoading: boolean = true;\n    #hasFailed: boolean = false;\n\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        this.#applyAttributes();\n        if (this.#shadow) {\n            this.#render();\n        }\n    }\n\n    async connectedCallback(): Promise<void> {\n        this.#controller = new AbortController();\n\n        if (!this.#shadow) {\n            this.#shadow = this.attachShadow({mode: 'closed'});\n        }\n\n        this.#applyAttributes();\n        this.#render();\n        await this.#fetchTariffs(this.#controller.signal);\n    }\n\n    disconnectedCallback(): void {\n        this.#controller.abort();\n    }\n\n    #applyAttributes(): void {\n        if (typeof C24Home !== 'undefined' && typeof C24Home.validateAttributes === 'function') {\n            try {\n                const validated = C24Home.validateAttributes<MobilfunkTopTariffsProps>(this.attributes);\n                const deviceOutput = this.#asString(validated.deviceOutput);\n                if (deviceOutput === 'desktop' || deviceOutput === 'mobile' || deviceOutput === 'tabletapp' || deviceOutput === 'app') {\n                    this.deviceOutput = deviceOutput;\n                }\n                const language = this.#asString(validated.language);\n                if (language) this.language = language as Language;\n                const platform = this.#asString(validated.platform);\n                if (platform === 'app' || platform === 'web') this.platform = platform;\n                if (validated.user && typeof validated.user === 'object' && 'id' in validated.user) {\n                    this.user = validated.user;\n                }\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 && typeof (value as Attr).value === 'string') {\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 (deviceOutput === 'desktop' || deviceOutput === 'mobile' || deviceOutput === 'tabletapp' || deviceOutput === 'app') {\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    }\n\n    async #fetchTariffs(signal: AbortSignal): Promise<void> {\n        try {\n            this.#isLoading = true;\n            this.#hasFailed = false;\n            this.#render();\n\n            const url = `${this.#environment.publicApi}/home-widgets/top-tarife`;\n            const response: TariffWidgetResponse = await httpGet<TariffWidgetResponse>(url, this.deviceOutput, signal);\n\n            this.#tariffs = response.widgets || [];\n            this.#isLoading = false;\n            this.#render();\n        } catch (err) {\n            if (err instanceof Error && err.name === 'AbortError') return;\n            this.#isLoading = false;\n            this.#hasFailed = true;\n            this.#render();\n        }\n    }\n\n    #render(): void {\n        if (!this.#shadow) return;\n\n        if (this.#isLoading || this.#hasFailed || this.#tariffs.length === 0) {\n            this.#shadow.innerHTML = `\n                <style>:host{display:block;width:100%}${skeleton.style}</style>\n                ${(this.language in skeleton.skeleton) ? skeleton.skeleton[this.language as keyof typeof skeleton.skeleton] : skeleton.skeleton['de-DE']}\n            `;\n            return;\n        }\n\n        this.#shadow.innerHTML = `\n            <style>${styles}</style>\n            <div class=\"widget-root\">\n                <div class=\"widget-container\">\n                    <h2 class=\"widget-title\">\n                        Handy mit Vertrag vergleichen\n\n                    </h2>\n                    <div class=\"widget-content\">\n                        <div class=\"tariff-list\">\n                            ${this.#tariffs.slice(0, 3).map(tariff => this.#renderTariffCard(tariff)).join('')}\n                        </div>\n                    </div>\n                    <a class=\"widget-more\" href=\"${this.#environment.host}/handy-uebersicht?tid2=homewidget\" target=\"_parent\">Alle Angebote entdecken</a>\n                </div>\n            </div>\n        `;\n    }\n    \n\n    #renderTariffCard(tariff: TariffInfo): string {\n        const tariffUrl = `${this.#environment.host}/vergleich/${tariff.uri}?tid2=homewidget`;\n\n        const price = tariff.oneTimePrice || tariff.effectivePrice;\n        const priceFormatted = centToEuro(price.amount);\n\n        return `\n            <a href=\"${tariffUrl}\" class=\"tariff-card\" target=\"_parent\">\n                <div class=\"tariff-image-wrapper\">\n                    <img src=\"${tariff.image}\" alt=\"${tariff.manufacturer} ${tariff.name}\" class=\"tariff-image\">\n                </div>\n                <div class=\"tariff-info\">\n                    <div class=\"tariff-info-top\">\n                        <div class=\"tariff-manufacturer\">${tariff.manufacturer}</div>\n                        <div class=\"tariff-name\">${tariff.name}</div>\n                    </div>\n                    <div class=\"tariff-price-wrapper\">\n                        <div class=\"tariff-total-amount\">${tariff.totalAmountTariffs} Tarife</div>\n                        <div class=\"tariff-price\">\n                            ab ${priceFormatted}\n                        </div>\n                        <div class=\"price-description\">Handy einmalig</div>\n                    </div>\n                </div>\n            </a>\n        `;\n    }\n}\n\ncustomElements.define('mobileservice-widget', MobilfunkTopTariffsClient);\n"],"mappings":"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"}