@influence-society-web/deshotelsetdesiles 4.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/constants.ts", "../../src/utils/countries/userCountry.ts", "../../src/utils/buildQueryParams.ts", "../../src/utils/ApiClient.ts", "../../src/utils/utils.ts", "../../src/utils/bindQuotationData.ts", "../../src/utils/Offers.ts", "../../src/utils/createOffersInstance.ts", "../../src/pages/OffersDeMinute.ts"],
4
+ "sourcesContent": ["export const prefix = 'data';\n\n// Selectors used within the project\nexport const SELECTORS = {\n startingPriceList: `[${prefix}=starting-price-list]`,\n price: `[${prefix}=price]`,\n discount: `[${prefix}=discount]`,\n discountContainer: `[${prefix}=discount-container]`,\n currency: `[${prefix}=currency]`,\n beHid: `[${prefix}-be-hid]`,\n destination: `[${prefix}=destination]`,\n offersList: `[${prefix}=offers-list]`,\n /** Offer slug page: wrapper with existing main offer. Match both data=\"...\" and data-... for Webflow. */\n offerSlugDetail: `[${prefix}=offer-slug-detail], [data-offer-slug-detail]`,\n /** Offer slug page: \"Nos autres offres\" list container. */\n offerSlugOthersList: `[${prefix}=offer-slug-others-list], [data-offer-slug-others-list]`,\n /** Offer slug page: card template inside offer-slug-others-list (use .offer-others_item if no data-list-item). */\n offerSlugOthersListItem: '.offer-others_item',\n /** Offer slug page: \"Nos autres offres\" section wrapper. Shown when other offers are rendered. */\n offersMoreWrapper: `[${prefix}=offers-more-wrapper]`,\n offersListContainer: `[${prefix}=offers-list-container]`,\n listItem: `[${prefix}=list-item]`,\n image: `[${prefix}=image]`,\n name: `[${prefix}=name]`,\n description: `[${prefix}=description]`,\n hotelName: `[${prefix}=hotel-name]`,\n hotelLink: `[${prefix}=hotel-link]`,\n hotelStartingPriceContainer: `[${prefix}=hotel-starting-price-container]`,\n moreDetails: `[${prefix}=more-details]`,\n offersPopup: `[${prefix}=offers-popup]`,\n offersPopupClose: `[${prefix}=close-btn]`,\n hotelReserveLink: `[${prefix}=hotel-reserve-link]`,\n hotelVillaReserveLink: `[${prefix}=hotel-villa-reserve-link]`,\n hotelURLS: `[${prefix}=hotel-urls]`,\n languageDropdown: `[${prefix}=language-dropdown]`,\n selectedLanguage: `[${prefix}=selected-language]`,\n loadingSpinner: `[${prefix}=loading-spinner]`,\n cmsFilterEmptyState: `[fs-cmsfilter-element=empty]`,\n startingfromItem: (id: string) => `[${prefix}-be-hid=${id}]`,\n popupOverlay: `[fs-smartlightbox-element=trigger-close]`,\n};\n\n// Query params keys\nexport const URL_PARAMS_KEYS = {\n checkinDate: 'checkin_date',\n};\n\n// maps the HID value gotten from the HTML attributes to the snippet code used to make API calls\nexport const BE_HID_TO_SNIPPET_CODE: {\n [key: string]: string;\n} = {\n DHDICBeach: 'gpgos12767',\n DHDIJMalanga: 'gptro12772',\n DHDIToubana: 'gpsai12770',\n DHDIMahogany: 'gpgos12769',\n DHDILangleyres: 'gpgua27143',\n DHDIJungle: 'mqros18592',\n DHDIJade: 'agste21689',\n DHDIWINDLAND: 'zzzzz25376',\n DHDILeCapMaison: 'lcgro30400',\n DHDIChastenet: 'agste21688',\n DHDILPSoleil: 'mqsai18593',\n DHDISHANTI: 'zzzzz25378',\n DHDIPavillon: 'zzzzz25377',\n DHDIBELLEMARE: 'zzzzz25379',\n DHDIPrincemaurice: 'mupos25678',\n DHDIANAHITA: 'zzzzz25380',\n DHDISamana: 'agstm21687',\n FRANTHTLGrandCaseBe1: 'frsai31536',\n DHDITInn: 'ageng20433',\n DHDIBWaters: 'agcro20496',\n DHDICuisinartgolf: 'gpang25884',\n DMDESHTLSecretBayDom: 'dmtib00001',\n};\n\n// location data\nconst GUADELOUPE = {\n en: 'Guadeloupe Islands',\n fr: 'Les \u00CEles de Guadeloupe',\n es: 'Las islas de Guadalupe',\n it: 'Le isole della Guadalupa',\n};\n\nconst DOMINIQUE = {\n en: 'La Dominique',\n fr: 'La Dominique',\n es: 'Dominica',\n it: 'Dominica',\n};\nconst SAINT_LUCIE = {\n en: 'Saint Lucia',\n fr: 'Sainte-Lucie',\n es: 'Santa Luc\u00EDa',\n it: 'Santa Lucia',\n};\n\nconst MARTINIQUE = {\n en: 'Martinique',\n fr: 'Martinique',\n es: 'Martinica',\n it: 'Martinica',\n};\n\nconst ILE_MAURICE = {\n en: 'Mauritius',\n fr: '\u00CEle Maurice',\n es: 'Mauricio',\n it: 'Mauritius',\n};\n\nconst SAINT_MARTIN = {\n en: 'Saint Martin',\n fr: 'Saint-Martin',\n es: 'Saint-Martin',\n it: 'Saint Martin',\n};\n\nconst ANTIGUA = {\n en: 'Antigua',\n fr: 'Antigua',\n es: 'Antigua',\n it: 'Antigua',\n};\n\nconst ANGUILLA = {\n en: 'Anguilla',\n fr: 'Anguilla',\n es: 'Anguila',\n it: 'Anguilla',\n};\n\n// maps the Snippet code to the hotel details\nexport const SNIPPET_CODE_TO_HOTEL: {\n [key: string]: {\n destination: Destination;\n slug: string;\n codeIPlanet: string;\n cmsId: string;\n };\n} = {\n gpgos12767: {\n destination: GUADELOUPE,\n slug: '/hotels-et-villas/creole-beach-hotel-spa',\n codeIPlanet: 'FRAN414',\n cmsId: '67c809b5f63deab8a71cf8e9',\n },\n gptro12772: {\n destination: GUADELOUPE,\n slug: '/hotels-et-villas/le-jardin-malanga',\n codeIPlanet: 'FRAN416',\n cmsId: '67c809b5f63deab8a71cf90d',\n },\n gpsai12770: {\n destination: GUADELOUPE,\n slug: '/hotels-et-villas/la-toubana-hotel-spa',\n codeIPlanet: 'FRAN411',\n cmsId: '67c809b5f63deab8a71cf8ef',\n },\n gpgos12769: {\n destination: GUADELOUPE,\n slug: '/hotels-et-villas/mahogany-hotel-residence-spa',\n codeIPlanet: 'FRAN423',\n cmsId: '67c809b5f63deab8a71cf91f',\n },\n gpgua27143: {\n destination: GUADELOUPE,\n slug: '/hotels-et-villas/langley-resort-fort-royal',\n codeIPlanet: 'GPAN32',\n cmsId: '67c809b5f63deab8a71cf8f0',\n },\n mqros18592: {\n destination: DOMINIQUE,\n slug: '/hotels-et-villas/jungle-bay-dominica',\n codeIPlanet: 'DMAN1',\n cmsId: '67c809b5f63deab8a71cf8ed',\n },\n dmtib00001: {\n destination: DOMINIQUE,\n slug: '/hotels-et-villas/secret-bay-dominique',\n codeIPlanet: 'DMAN2',\n cmsId: '67c809b5f63deab8a71cfefd',\n },\n agste21689: {\n destination: SAINT_LUCIE,\n slug: '/hotels-et-villas/jade-mountain',\n codeIPlanet: 'AGAN6',\n cmsId: '67c809b5f63deab8a71cf92a',\n },\n zzzzz25376: {\n destination: SAINT_LUCIE,\n slug: '/hotels-et-villas/windjammer-landing',\n codeIPlanet: 'LCAN4',\n cmsId: '67c809b5f63deab8a71cf92b',\n },\n lcgro30400: {\n destination: SAINT_LUCIE,\n slug: '/hotels-et-villas/cap-maison',\n codeIPlanet: 'LCLC8',\n cmsId: '67c809b5f63deab8a71cf929',\n },\n agste21688: {\n destination: SAINT_LUCIE,\n slug: '/hotels-et-villas/anse-chastanet',\n codeIPlanet: 'AGAN5',\n cmsId: '67c809b5f63deab8a71cf928',\n },\n mqsai18593: {\n destination: MARTINIQUE,\n slug: '/hotels-et-villas/plein-soleil',\n codeIPlanet: 'MQAN16',\n cmsId: '67c809b5f63deab8a71cf925',\n },\n zzzzz25378: {\n destination: ILE_MAURICE,\n slug: '/hotels-et-villas/shanti-maurice',\n codeIPlanet: 'MUAN22',\n cmsId: '67c809b5f63deab8a71cf933',\n },\n zzzzz25377: {\n destination: ILE_MAURICE,\n slug: '/hotels-et-villas/lux-le-morne',\n codeIPlanet: 'MUAN21',\n cmsId: '67c809b5f63deab8a71cf931',\n },\n zzzzz25379: {\n destination: ILE_MAURICE,\n slug: '/hotels-et-villas/constance-belle-mare-plage',\n codeIPlanet: 'MUAN20',\n cmsId: '67c809b5f63deab8a71cf92f',\n },\n mupos25678: {\n destination: ILE_MAURICE,\n slug: '/hotels-et-villas/constance-le-prince-maurice',\n codeIPlanet: 'MUAN24',\n cmsId: '67c809b5f63deab8a71cf930',\n },\n zzzzz25380: {\n destination: ILE_MAURICE,\n slug: '/hotels-et-villas/anahita-the-resort',\n codeIPlanet: 'MUAN19',\n cmsId: '67c809b5f63deab8a71cf92e',\n },\n agstm21687: {\n destination: SAINT_MARTIN,\n slug: '/hotels-et-villas/la-samanna',\n codeIPlanet: 'FRAN2350',\n cmsId: '67c809b5f63deab8a71cf926',\n },\n frsai31536: {\n destination: SAINT_MARTIN,\n slug: '/hotels-et-villas/le-grand-case-beach-club',\n codeIPlanet: 'FRFRA3',\n cmsId: '67c809b5f63deab8a71cf927',\n },\n ageng20433: {\n destination: ANTIGUA,\n slug: '/hotels-et-villas/the-inn-at-english-harbour',\n codeIPlanet: 'AGAN4',\n cmsId: '67c809b5f63deab8a71cf8ec',\n },\n agcro20496: {\n destination: ANTIGUA,\n slug: '/hotels-et-villas/blue-waters',\n codeIPlanet: 'AGAN1',\n cmsId: '67c809b5f63deab8a71cf8eb',\n },\n gpang25884: {\n destination: ANGUILLA,\n slug: '/hotels-et-villas/aurora-anguilla-resort-golf-club',\n codeIPlanet: 'GPAN30',\n cmsId: '67c809b5f63deab8a71cf8ea',\n },\n};\n\n// maps the currency code to the currency symbol\nexport const CURRENCY_TO_SYMBOL: { [key: string]: string } = {\n AED: '\u062F.\u0625.',\n AFN: 'Af',\n ALL: 'L',\n AMD: '\u058F',\n ANG: '\u0192',\n AOA: 'Kz',\n ARS: 'AR$',\n AUD: 'AU$',\n AWG: '\u0192',\n AZN: '\u043C\u0430\u043D',\n BAM: 'KM',\n BBD: 'BBD$',\n BDT: '\u09F3',\n BGN: '\u043B\u0432.',\n BHD: 'BD',\n BIF: 'FBu',\n BMD: '$',\n BND: 'B$',\n BOB: 'Bs.',\n BRL: 'R$',\n BSD: '$',\n BTN: 'Nu.',\n BWP: 'P',\n BYN: 'Br',\n BZD: 'BZ$',\n CAD: 'CA$',\n CDF: 'FC',\n CHF: 'Fr.',\n CKD: '$',\n CLP: 'CL$',\n CNY: 'CN\u00A5',\n COP: 'CO$',\n CRC: '\u20A1',\n CUC: 'CUC$',\n CUP: '$MN',\n CVE: 'CV$',\n CZK: 'K\u010D',\n DJF: 'Fdj',\n DKK: 'kr.',\n DOP: 'RD$',\n DZD: 'DA',\n EGP: 'E\u00A3',\n EHP: 'Ptas.',\n ERN: 'Nkf',\n ETB: 'Br',\n EUR: '\u20AC',\n FJD: 'FJ$',\n FKP: 'FK\u00A3',\n FOK: 'kr',\n GBP: '\u00A3',\n GEL: '\u20BE',\n GGP: '\u00A3',\n GHS: 'GH\u20B5',\n GIP: '\u00A3',\n GMD: 'D',\n GNF: 'FG',\n GTQ: 'Q',\n GYD: 'G$',\n HKD: 'HK$',\n HNL: 'L',\n HRK: 'kn',\n HTG: 'G',\n HUF: 'Ft',\n IDR: 'Rp',\n ILS: '\u20AA',\n IMP: '\u00A3',\n INR: 'Rs.',\n IQD: '\u062F.\u0639.',\n IRR: '\uFDFC',\n ISK: 'kr',\n JEP: '\u00A3',\n JMD: 'J$',\n JOD: 'JD',\n JPY: '\u00A5',\n KES: 'KSh',\n KGS: '\u0441',\n KHR: '\u17DB',\n KID: '$',\n KMF: 'CF',\n KPW: '\u20A9',\n KRW: '\u20A9',\n KWD: 'KD',\n KYD: 'CI$',\n KZT: '\u20B8',\n LAK: '\u20ADN',\n LBP: 'LL.',\n LKR: 'Rs.',\n LRD: 'L$',\n LSL: 'L',\n LYD: 'LD',\n MAD: 'DH',\n MDL: 'L',\n MGA: 'Ar',\n MKD: 'den',\n MMK: 'Ks',\n MNT: '\u20AE',\n MOP: 'MOP$',\n MRU: 'UM',\n MUR: 'Rs.',\n MVR: 'MRf',\n MWK: 'MK',\n MXN: 'MX$',\n MYR: 'RM',\n MZN: 'MTn',\n NAD: 'N$',\n NGN: '\u20A6',\n NIO: 'C$',\n NOK: 'kr',\n NPR: 'Rs.',\n NZD: 'NZ$',\n OMR: 'OR',\n PAB: 'B/.',\n PEN: 'S/.',\n PGK: 'K',\n PHP: '\u20B1',\n PKR: 'Rs.',\n PLN: 'z\u0142',\n PND: '$',\n PRB: '\u0440.',\n PYG: '\u20B2',\n QAR: 'QR',\n RON: 'L',\n RSD: 'din',\n RUB: '\u20BD',\n RWF: 'FRw',\n SAR: 'SR',\n SBD: 'SI$',\n SCR: 'Rs.',\n SDG: '\u00A3SD',\n SEK: 'kr',\n SGD: 'S$',\n SHP: '\u00A3',\n SLL: 'Le',\n SLS: 'Sl',\n SOS: 'Sh.So.',\n SRD: 'Sr$',\n SSP: 'SS\u00A3',\n STN: 'Db',\n SVC: '\u20A1',\n SYP: 'LS',\n SZL: 'L',\n THB: '\u0E3F',\n TJS: 'SM',\n TMT: 'm.',\n TND: 'DT',\n TOP: 'T$',\n TRY: 'TL',\n TTD: 'TT$',\n TVD: '$',\n TWD: 'NT$',\n TZS: 'TSh',\n UAH: '\u20B4',\n UGX: 'USh',\n USD: '$',\n UYU: '$U',\n UZS: '\u0441\u0443\u043C',\n VED: 'Bs.',\n VES: 'Bs.F',\n VND: '\u20AB',\n VUV: 'VT',\n WST: 'T',\n XAF: 'Fr',\n XCD: '$',\n XOF: '\u20A3',\n XPF: '\u20A3',\n YER: 'YR',\n ZAR: 'R',\n ZMW: 'ZK',\n ZWB: '',\n ZWL: 'Z$',\n Abkhazia: '',\n Artsakh: '\u0564\u0580.',\n};\n\n// maps the language code to the locale\nexport const LANG_TO_LOCALE: { [key: string]: string } = {\n it: 'it_IT',\n es: 'es_ES',\n fr: 'fr_FR',\n en: 'en_GB',\n};\n\n// maps the offer category to the CMS collection ID\nexport const OFFER_CATEGORIES = {\n 'DERNI\u00C8RE MINUTE': '735fe5e0858671cf3a5c14cbcc2470fe',\n 'R\u00C9SERVEZ T\u00D4T': 'c5abb23caf056891f3902ff42ae2f9e0',\n};\n\n// maps the slug to the CMS theme ID\nexport const SLUG_TO_THEME: { [key: string]: string } = {\n // Family stay\n '/thematiques/sejour-en-famille': '67c809b5f63deab8a71cf936',\n '/en/themes/family-stay': '67c809b5f63deab8a71cf936',\n '/es/temas/estancia-en-familia': '67c809b5f63deab8a71cf936',\n '/it/temi/soggiorno-in-famiglia': '67c809b5f63deab8a71cf936',\n\n // Honeymoon\n '/thematiques/voyages-de-noces': '67c809b5f63deab8a71cfb33',\n '/en/themes/honeymoons': '67c809b5f63deab8a71cfb33',\n '/es/temas/lunas-de-miel': '67c809b5f63deab8a71cfb33',\n '/it/temi/lune-di-miele': '67c809b5f63deab8a71cfb33',\n\n // Golf paradise\n '/thematiques/paradis-des-golfeurs': '67c809b5f63deab8a71cfb32',\n '/en/themes/a-golfer-s-paradise': '67c809b5f63deab8a71cfb32',\n '/es/temas/el-paraiso-del-golfista': '67c809b5f63deab8a71cfb32',\n '/it/temi/un-paradiso-per-i-golfisti': '67c809b5f63deab8a71cfb32',\n\n // All-inclusive\n '/thematiques/all-inclusives': '67c809b5f63deab8a71cf934',\n '/en/themes/all-inclusives': '67c809b5f63deab8a71cf934',\n '/es/temas/todo-incluido': '67c809b5f63deab8a71cf934',\n '/it/temi/tutto-compreso': '67c809b5f63deab8a71cf934',\n\n // Escapade SPA & Bien-\u00CAtre\n '/thematiques/escapade-spa-bien-etre': '67c809b5f63deab8a71cf935',\n '/en/themes/wellness-spa-getaway': '67c809b5f63deab8a71cf935',\n '/es/temas/escapada-spa-bienestar': '67c809b5f63deab8a71cf935',\n '/it/temi/soggiorno-benessere-alle-terme': '67c809b5f63deab8a71cf935',\n\n // Adventure\n '/thematiques/activites-et-loisirs': '67c809b5f63deab8a71cfcb4',\n '/en/themes/leisure-activities': '67c809b5f63deab8a71cfcb4',\n '/es/temas/actividades-y-ocio': '67c809b5f63deab8a71cfcb4',\n '/it/temi/attivita-e-tempo-libero': '67c809b5f63deab8a71cfcb4',\n\n // Scuba diving\n '/thematiques/plongee-sous-marine': '67c809b5f63deab8a71cf937',\n '/en/themes/scuba-diving': '67c809b5f63deab8a71cf937',\n '/es/temas/submarinismo': '67c809b5f63deab8a71cf937',\n '/it/temi/immersione-subacquea': '67c809b5f63deab8a71cf937',\n\n // Road trip\n '/thematiques/roadtrip': '67c809b5f63deab8a71cfb34',\n '/en/themes/roadtrip': '67c809b5f63deab8a71cfb34',\n '/es/temas/viaje-por-carretera': '67c809b5f63deab8a71cfb34',\n '/it/temi/viaggio-in-auto': '67c809b5f63deab8a71cfb34',\n\n // Senior\n '/thematiques/senior-60-ans-et-plus': '67c809b5f63deab8a71cfedb',\n '/en/themes/senior-60-ans-et-plus': '67c809b5f63deab8a71cfedb',\n '/es/temas/senior-60-ans-et-plus': '67c809b5f63deab8a71cfedb',\n '/it/temi/senior-60-ans-et-plus': '67c809b5f63deab8a71cfedb',\n};\n\n// base URL for the API\nexport const apiBaseUrl = 'https://deshotelsetdesiles.ccordier.workers.dev/v2/';\n// base URL for the hotel and flight API\nexport const hotelAndFlightURLBaseUrl =\n 'https://deshotelsetdesiles.i-planet.fr/dhdi-public/searchform.cgi';\n\n// default country code\nexport const DEFAULT_COUNTRY_CODE = 'FR';\n\nexport const GTM_GL =\n '1*q1lzz9*_gcl_au*MTMyMzcyMDY5NC4xNzM5Mjg5MzYx*_ga*NTAxMzI1MzMwLjE3MzkyODkzNjE.*_ga_Q0RXHLR7D4*MTczOTI5NzEzNC4zLjAuMTczOTI5NzE3Mi4yMi4wLjA.';\n", "import { DEFAULT_COUNTRY_CODE } from '$utils/constants';\n\n/**\n * Get the user's country code as described in the geoip2 library.\n * https://dev.maxmind.com/geoip/geolocate-an-ip/client-side-javascript/\n */\n\n// The script is loaded on the page\ndeclare const geoip2: {\n country: (\n success: (response: { country: { iso_code: string } }) => void,\n error: () => void\n ) => void;\n};\n\nexport const getUserCountryCode = async (): Promise<string> => {\n return new Promise((resolve) => {\n geoip2.country(\n (successResponse: { country: { iso_code: string } }) => {\n resolve(successResponse.country.iso_code);\n },\n () => {\n resolve(DEFAULT_COUNTRY_CODE);\n }\n );\n });\n};\n", "/**\n *\n * @param queryParams to build\n * @returns string representation of query params\n */\nexport const buildQueryParams = (queryParams: QueryParams) => {\n let url = '?';\n for (const [key, value] of Object.entries(queryParams)) {\n if (value) {\n url += `${key}=${value}&`;\n }\n }\n return url;\n};\n", "import { buildQueryParams } from './buildQueryParams';\nimport { apiBaseUrl } from './constants';\n\nexport class ApiClient {\n /**\n *\n * @param queryParams to include as part of query for the request\n * @returns offers data for a group of hotels\n */\n public async getGroupOffersData(queryParams: QueryParams): Promise<GroupOffersData | null> {\n const url = apiBaseUrl + 'groupOffers' + buildQueryParams(queryParams);\n\n const response = await fetch(url);\n const body = await response.json();\n if (body.error || !body.data) return null;\n\n return body as GroupOffersData;\n }\n\n /**\n *\n * @param queryParams to include as part of query for the request\n * @returns offers data for a single hotel\n */\n public async getSingleHotelOffersData(queryParams: QueryParams): Promise<OffersData | null> {\n const url = apiBaseUrl + 'offers' + buildQueryParams(queryParams);\n\n const response = await fetch(url);\n const body = await response.json();\n if (body.error || !body.data) return null;\n\n return body as OffersData;\n }\n\n /**\n *\n * @param queryParams to include as part of query for the request\n * @returns Starting CMS offers data\n */\n public async getCMSOffers(): Promise<CMSOffersData | null> {\n const url = apiBaseUrl + 'cmsOffers';\n\n const response = await fetch(url);\n const body = await response.json();\n if (!body.items) return null;\n\n return body as CMSOffersData;\n }\n\n /**\n * @returns all CMS countries\n */\n public async getCountries(): Promise<CountriesData | null> {\n const url = apiBaseUrl + 'cmsCountries';\n\n const response = await fetch(url);\n const body = await response.json();\n if (!body.items) return null;\n\n return body as CountriesData;\n }\n}\n", "import {\n GTM_GL,\n hotelAndFlightURLBaseUrl,\n LANG_TO_LOCALE,\n SNIPPET_CODE_TO_HOTEL,\n} from './constants';\n\n/**\n * Listen for language change and reload the page when the language is changed.\n */\nexport const listenForLanguageChange = () => {\n const isitProduction = isProduction();\n if (!isitProduction) {\n const currentStagingLang = localStorage.getItem('wglang') || 'fr';\n window.Weglot.switchTo(currentStagingLang);\n }\n window.Weglot.on('languageChanged', () => {\n if (isitProduction) {\n window.location.reload();\n } else {\n const newLang = window.Weglot.getCurrentLang();\n //add new language to local storage\n localStorage.setItem('wglang', newLang);\n if (window.loadFromServer) {\n window.loadFromServer();\n }\n }\n });\n};\n\nexport const isProduction = () => {\n return window.location.hostname !== 'deshotelsetdesiles.webflow.io';\n};\n\n/**\n *\n * @returns The locale of the current language.\n */\nexport const getLocale = () => {\n const lang = getLanguage();\n return LANG_TO_LOCALE[lang];\n};\n\n/**\n *\n * @returns the current language.\n */\nexport const getLanguage = (): string => {\n if (!isProduction()) {\n return localStorage.getItem('wglang') || 'fr';\n }\n try {\n const language = window.Weglot.getCurrentLang();\n if (language) {\n return language;\n }\n } catch (error) {\n console.error('Error getting language', error);\n return 'fr';\n }\n\n return 'fr';\n};\n\n/**\n *\n * @returns A map of cmsid to hotel id.\n */\nexport const cmsIDToHotelIdMap = () => {\n const map: { [key: string]: string } = {};\n Object.entries(SNIPPET_CODE_TO_HOTEL).forEach(([key, value]) => {\n map[value.cmsId] = key;\n });\n return map;\n};\n\n/**\n * gets the offer slug from the hotel id and offer name.\n * This is used to compare the offer CMS metadata with the offer data from the API.\n * @param hotelId The hotel id.\n * @param offerName The offer name.\n * @returns\n */\nexport const offerSlug = (hotelId: string, offerName: string) => {\n return `${hotelId.toLowerCase().trim()}-${offerName.toLowerCase().trim()}`;\n};\n\n/**\n * Generates the URL for the hotel and flight page.\n * @param currency iso currency code\n * @param hotelID The hotel id.\n * @param accessCodeValue for HotelPromo\n * @returns\n */\nexport const hotelAndFlightURL = (\n currency: string,\n hotelID: string,\n accessCodeValue: string | null\n) => {\n const lang = getLanguage().toUpperCase();\n const hotelCode = SNIPPET_CODE_TO_HOTEL[hotelID].codeIPlanet.toUpperCase();\n let url = `${hotelAndFlightURLBaseUrl}?Lang=${lang}&currency=${currency.toUpperCase()}&HotelCode=${hotelCode}`;\n\n // Include the Google Tag query parameter if it exists\n const gaTag = getCookie('_ga');\n const glTag = GTM_GL;\n const gclAuTag = getCookie('_gcl_au');\n url += `&_ga=${gaTag}&_gl=${glTag}&_gcl_au=${gclAuTag}`;\n\n if (accessCodeValue) {\n url = `${url}&HotelPromo=${accessCodeValue}`;\n }\n return url;\n};\n\n/**\n * Get the value of a cookie.\n * @param name The name of the cookie.\n */\nexport const getCookie = (name: string): string | null => {\n const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));\n return match ? match[2] : null;\n};\n", "import { CURRENCY_TO_SYMBOL, SELECTORS } from './constants';\nimport { hotelAndFlightURL } from './utils';\n\n/**\n *\n * @param rate data to bind\n * @param container for data items\n * @param hotelId for hotel\n * @param cmsOfferData for offer filtering\n */\nexport const bindQuotationData = (\n container: HTMLDivElement,\n rate: Rate,\n hotelId: string,\n cmsOfferData?: CMSOfferItem\n) => {\n const {\n quotation,\n rate: { distribution },\n } = rate;\n const { pricePerNight, currency, plainBookLink } = quotation;\n const { accessCode } = distribution || {};\n\n // pick the first access code if available\n let accessCodeValue = '';\n if (accessCode && accessCode.length > 0) {\n [accessCodeValue] = accessCode;\n }\n\n // update price and currency\n updatePriceElement(container, pricePerNight, currency);\n\n // update hotel reserve link\n const hotelReserveEls = container.querySelector<HTMLLinkElement>(SELECTORS.hotelReserveLink);\n if (hotelReserveEls) {\n hotelReserveEls.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n window.open(plainBookLink, '_blank');\n });\n }\n\n // update hotel villa reserve link\n const hotelVillaReserveEl = container.querySelector<HTMLLinkElement>(\n SELECTORS.hotelVillaReserveLink\n );\n if (hotelVillaReserveEl) {\n hotelVillaReserveEl.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n window.open(hotelAndFlightURL(currency, hotelId, accessCodeValue), '_blank');\n });\n }\n\n // update discount percentage if available from CMS\n if (cmsOfferData) {\n const {\n fieldData: { 'discount-percentage': discountPercentage },\n } = cmsOfferData;\n const discountEl = container.querySelector<HTMLElement>(SELECTORS.discount);\n if (discountEl && discountPercentage) discountEl.innerHTML = `-${discountPercentage}%`;\n\n const discountContainerEl = container.querySelector<HTMLDivElement>(\n SELECTORS.discountContainer\n );\n\n if (discountContainerEl && !discountPercentage) {\n discountContainerEl.style.display = 'none';\n }\n }\n};\n\n/**\n *\n * @param container to update\n * @param pricePerNight of the quotation\n * @param currency of the quotation\n */\nexport const updatePriceElement = (\n container: HTMLDivElement,\n pricePerNight: number,\n currency: string\n) => {\n const priceEl = container.querySelector<HTMLElement>(SELECTORS.price);\n if (priceEl) priceEl.innerHTML = Math.floor(pricePerNight).toString();\n\n const currencyEl = container.querySelector<HTMLElement>(SELECTORS.currency);\n if (currencyEl) currencyEl.innerHTML = CURRENCY_TO_SYMBOL[currency];\n};\n", "import type { CMSList } from '@globalTypes/CMSList';\n\nimport { getUserCountryCode } from '$utils/countries/userCountry';\n\nimport { ApiClient } from './ApiClient';\nimport { bindQuotationData } from './bindQuotationData';\nimport { DEFAULT_COUNTRY_CODE, SELECTORS, SNIPPET_CODE_TO_HOTEL } from './constants';\nimport {\n cmsIDToHotelIdMap,\n getLanguage,\n getLocale,\n listenForLanguageChange,\n offerSlug,\n} from './utils';\n\nexport class Offers {\n /** The loading spinner element */\n private loadingSpinner: HTMLElement | null;\n\n /** The empty state element */\n private cmsFilterEmptyState: HTMLDivElement | null;\n\n /** A lookup object for the cms offers data */\n private offerLookup: { [key: string]: CMSOfferItem } = {};\n\n /** The api client */\n private apiClient = new ApiClient();\n\n /** The user's country code */\n private countryCode: string;\n\n /** All available countries in CMS */\n private availableCountries: { [key: string]: string } = {};\n\n /**\n *\n * @param listInstance The list that the offers will be displayed in\n * @param itemTemplateElement The template element to create new items from\n */\n constructor(\n private listInstance: CMSList,\n private itemTemplateElement: HTMLDivElement\n ) {\n this.cmsFilterEmptyState = document.querySelector<HTMLDivElement>(\n SELECTORS.cmsFilterEmptyState\n );\n if (this.cmsFilterEmptyState) {\n this.cmsFilterEmptyState.classList.add('hide-empty-state');\n }\n\n // Remove existing items\n listInstance.clearItems();\n\n listenForLanguageChange();\n this.loadingSpinner = document.querySelector<HTMLElement>(SELECTORS.loadingSpinner);\n this.countryCode = DEFAULT_COUNTRY_CODE;\n }\n\n /**\n * Retrieve hotel offer for given hotel IDs\n * @param options to filter the offers\n */\n public async getGroupOffers(options: {\n clearItems?: boolean;\n filter: (value: CMSOfferItem) => boolean;\n }) {\n const { clearItems = true, filter } = options || {};\n\n if (clearItems) this.listInstance.clearItems();\n\n // get the cms offers data\n const cmsOffersData = await this.apiClient.getCMSOffers();\n if (!cmsOffersData) return;\n\n // get the available countries in CMS\n const cmsCountries = await this.apiClient.getCountries();\n if (!cmsCountries) return;\n\n // map the cmscountries id to the title\n cmsCountries.items.forEach((c) => {\n this.availableCountries[c.id] = c.fieldData.title?.trim();\n });\n\n // filter the cms offers data using the provided filter\n this.countryCode = await getUserCountryCode();\n const filteredOffers = cmsOffersData.items.filter(filter).filter(this.countryCodeFilter);\n\n // extract the hotelIds to use\n const generatedHotelIds = this.generateHotelIds(filteredOffers);\n let hids = this.generateHotelIds(filteredOffers).join(',');\n\n const singleHotel = generatedHotelIds.length === 1;\n\n // if there is only one hotel, duplicate the hotel id to get the offers for that hotel\n // this is a workaround for the API to get the offers for a single hotel\n if (singleHotel) {\n hids = [hids, hids].join(',');\n }\n\n // generate the offer metadata and lookup object for easy access to the cms offers data\n const { offerMetaData }: { offerMetaData: string[] } = this.generateOfferData(filteredOffers);\n\n const locale = getLocale();\n\n // get the group offers data\n const hotelOffersData = await this.apiClient.getGroupOffersData({\n hids,\n locale,\n });\n\n if (!hotelOffersData || hotelOffersData.error || !hotelOffersData.data) {\n this.hideSpinnerAndShowFilter();\n return;\n }\n\n // if there is only one hotel, get the first offer from the group offers data\n if (singleHotel) {\n hotelOffersData.data = [hotelOffersData.data[0]];\n }\n\n // get all the offers from the group offers data\n const offers = this.getAllOffers(hotelOffersData, offerMetaData);\n\n // Create rate items for each hotel and add it to the collection\n this.addHotelToCollection(offers);\n this.hideSpinnerAndShowFilter();\n }\n\n /**\n * Retrieve hotel offer for given offer category\n * @param categoryId\n * @param allOffers\n */\n public async getGroupCategoryOffers(categoryId?: string, allOffers = false) {\n const filter = (value: CMSOfferItem) => {\n const { isArchived, isDraft, fieldData } = value;\n if (isArchived || isDraft) return false;\n // if allOffers is true, return only offers without thematiques, last minute and early booking\n if (allOffers) {\n return (\n (!fieldData.thematiques || fieldData.thematiques.length === 0) &&\n !fieldData.slug.includes('derniere-minute') &&\n !fieldData.slug.includes('reservez-tot')\n );\n }\n\n return fieldData.category === categoryId;\n };\n await this.getGroupOffers({ filter });\n }\n\n /**\n * Retrieve hotel offer for given offer theme\n * @param themeId\n */\n public async getGroupThemeOffers(themeId: string) {\n const filter = (value: CMSOfferItem) => {\n const { isArchived, isDraft, fieldData } = value;\n if (isArchived || isDraft || !fieldData.thematiques) return false;\n return fieldData.thematiques.includes(themeId);\n };\n await this.getGroupOffers({ filter });\n }\n\n /**\n * Retrieve hotel offer for the given offer slug (single offer page).\n * @param slug The offer slug from the page URL (e.g. forfait-special-ete-jungle-bay).\n */\n public async getGroupSlugOffers(slug: string) {\n const filter = (value: CMSOfferItem) => {\n const { isArchived, isDraft, fieldData } = value;\n if (isArchived || isDraft) return false;\n return fieldData.slug === slug;\n };\n await this.getGroupOffers({ filter });\n }\n\n /**\n * Retrieve all other offers (same as \"all offers\" list) excluding the given slug.\n * Used for \"Nos autres offres\" on the offer detail page.\n * @param excludeSlug The current page's offer slug to exclude from the list.\n */\n public async getGroupOtherOffers(excludeSlug: string) {\n const filter = (value: CMSOfferItem) => {\n const { isArchived, isDraft, fieldData } = value;\n if (isArchived || isDraft) return false;\n if (fieldData.slug === excludeSlug) return false;\n return (\n (!fieldData.thematiques || fieldData.thematiques.length === 0) &&\n !fieldData.slug.includes('derniere-minute') &&\n !fieldData.slug.includes('reservez-tot')\n );\n };\n await this.getGroupOffers({ filter });\n }\n\n /**\n * Hide the loading spinner and show the empty state if no offers are found\n * @private\n */\n private hideSpinnerAndShowFilter() {\n // Hide the loading spinner and show the empty state if no offers are found\n if (this.loadingSpinner) this.loadingSpinner.style.display = 'none';\n if (this.cmsFilterEmptyState) {\n this.cmsFilterEmptyState.classList.remove('hide-empty-state');\n }\n }\n\n /**\n * Filter the offers based on the country code\n * @param item\n */\n private countryCodeFilter = (item: CMSOfferItem) => {\n const { fieldData } = item;\n\n if (!fieldData['supported-countries'] || fieldData['supported-countries'].length === 0)\n return true;\n\n const itemCountryCodes = fieldData['supported-countries'].map(\n (c) => this.availableCountries[c]\n );\n\n return itemCountryCodes.includes(this.countryCode);\n };\n\n /**\n *\n * @param cmsOffers to generate hotel ids from\n * @returns hotel ids based on the cms offers\n */\n private generateHotelIds(cmsOffers: CMSOfferItem[]) {\n const hotelIds: string[] = [];\n const cmsIDToHotelIds = cmsIDToHotelIdMap();\n cmsOffers.forEach((offer) => {\n const {\n fieldData: { 'hotel-villa': hotelCMSId },\n } = offer;\n hotelIds.push(cmsIDToHotelIds[hotelCMSId]);\n });\n return Array.from(new Set(hotelIds));\n }\n\n /**\n * Retrieve all offers from the group offers data in a flat structure - sorted by CMS offer order\n * @param hotelOffersData to get all rates from\n * @param offerMetaData\n * @returns the offer with each rate as a separate item\n */\n\n private getAllOffers(hotelOffersData: GroupOffersData, offerMetaData: string[]) {\n const rates: Offer[] = [];\n\n hotelOffersData.data.forEach((offer) => {\n const {\n prop: { hid },\n rates: offerRates,\n } = offer;\n\n offerRates.forEach((rate) => {\n const { name, title } = rate.rate;\n\n const includeOffer =\n offerMetaData.includes(offerSlug(hid, name)) ||\n offerMetaData.includes(offerSlug(hid, title));\n\n if (includeOffer) {\n rates.push({\n ...offer,\n rates: [rate],\n });\n }\n });\n });\n\n // sort the rates based on the order in the CMS offer\n rates.sort((a, b) => {\n const cmsOfferA =\n this.offerLookup[offerSlug(a.prop.hid, a.rates[0].rate.title)] ||\n this.offerLookup[offerSlug(a.prop.hid, a.rates[0].rate.name)];\n\n const cmsOfferB =\n this.offerLookup[offerSlug(b.prop.hid, b.rates[0].rate.title)] ||\n this.offerLookup[offerSlug(b.prop.hid, b.rates[0].rate.name)];\n\n const aOrder = Number(cmsOfferA.fieldData.order) || 0;\n const bOrder = Number(cmsOfferB.fieldData.order) || 0;\n return aOrder - bOrder;\n });\n\n return rates;\n }\n\n /**\n *\n * @param filteredOffers to generate offer data from CMS offers\n * generate the offer metadata and create a lookup object for the cms offers data (useful when looking up for offers discount percentage)\n * @returns\n */\n private generateOfferData(filteredOffers: CMSOfferItem[]) {\n const offerMetaData: string[] = [];\n\n filteredOffers.forEach((offer) => {\n const {\n fieldData: { 'hotel-or-property-api-id': hotelId, 'offer-api-name': name },\n } = offer;\n const slug = offerSlug(hotelId, name);\n offerMetaData.push(slug);\n this.offerLookup[slug] = offer;\n });\n\n return { offerMetaData };\n }\n\n /**\n *\n * @param offers\n */\n private addHotelToCollection(offers: Offer[]) {\n for (const { prop, rates } of offers) {\n const items = rates.map((item) => this.createItem(prop, item, this.itemTemplateElement));\n this.listInstance.addItems(items);\n }\n }\n\n /**\n * Creates an item from the template element.\n * @param offerProperty\n * @param rate The Rate data to create the item from.\n * @param templateElement The template element.\n *\n * @returns A new Collection Item element.\n */\n private createItem(offerProperty: OfferProperty, rate: Rate, templateElement: HTMLDivElement) {\n const { rate: rateData } = rate;\n const { hid, title: hotelName, property } = offerProperty;\n const { image, title, name } = rateData;\n const offerCMSData =\n this.offerLookup[offerSlug(hid || property, title)] ||\n this.offerLookup[offerSlug(hid || property, name)];\n\n const newItem = templateElement.cloneNode(true) as HTMLDivElement;\n const hotelMeta = SNIPPET_CODE_TO_HOTEL[hid || property];\n if (!hotelMeta) return newItem;\n const { destination, slug } = hotelMeta;\n\n this.bindOffersMetaData(newItem, { destination, image, hotelName, title, slug });\n bindQuotationData(newItem, rate, hid, offerCMSData);\n\n const moreDetails = newItem.querySelector<HTMLDivElement>(SELECTORS.moreDetails);\n if (moreDetails) {\n moreDetails.addEventListener('click', () => {\n //get slug of this offer from the offerCMSData\n const offersSlug = this.getOffersCmsSlug(hid, property, name);\n //goto /offers/offersSlug\n window.location.href = `/offers/${offersSlug}`;\n });\n }\n\n newItem.style.display = 'flex';\n return newItem;\n }\n\n private getOffersCmsSlug(hid: string, property: string, title: string): string {\n const offerCMSData = this.offerLookup[offerSlug(hid || property, title)];\n return offerCMSData?.fieldData.slug;\n }\n\n /**\n *\n * @param container for data item\n * @param destination for offer\n * @param image for offer\n * @param hotelName for hotel\n * @param title for offer\n * @param slug\n * @param description\n */\n private bindOffersMetaData(\n container: HTMLDivElement,\n {\n destination,\n image,\n hotelName,\n title,\n slug,\n description,\n }: {\n destination: Destination;\n image: Image;\n hotelName: string;\n title: string;\n slug: string;\n description?: string;\n }\n ) {\n const destinationEl = container.querySelector<HTMLElement>(SELECTORS.destination);\n const imageEl = container.querySelector<HTMLImageElement>(SELECTORS.image);\n const hotelNameEl = container.querySelector<HTMLElement>(SELECTORS.hotelName);\n const nameEl = container.querySelector<HTMLElement>(SELECTORS.name);\n const descriptionEl = container.querySelector<HTMLElement>(SELECTORS.description);\n const hotelLinkEl = container.querySelector<HTMLAnchorElement>(SELECTORS.hotelLink);\n\n const language = getLanguage() as keyof Destination;\n if (destinationEl) destinationEl.textContent = destination[language];\n if (imageEl) imageEl.src = image?.url;\n if (hotelNameEl) hotelNameEl.innerHTML = hotelName;\n if (nameEl) nameEl.innerHTML = title;\n if (descriptionEl && description) descriptionEl.innerHTML = description;\n if (hotelLinkEl && slug) {\n hotelLinkEl.addEventListener('click', () => {\n window.location.href = slug;\n });\n }\n }\n}\n\n/**\n * Binds offer metadata (image, destination, hotel name, offer name, description, hotel link)\n * to elements inside the container. Same logic as the popup / list item binding.\n */\nexport function bindOfferMetaToContainer(\n container: HTMLDivElement,\n {\n destination,\n image,\n hotelName,\n title,\n slug,\n description,\n }: {\n destination: Destination;\n image: Image;\n hotelName: string;\n title: string;\n slug: string;\n description?: string;\n }\n): void {\n const destinationEl = container.querySelectorAll<HTMLElement>(SELECTORS.destination);\n const hotelNameEl = container.querySelectorAll<HTMLElement>(SELECTORS.hotelName);\n const nameEl = container.querySelectorAll<HTMLElement>(SELECTORS.name);\n const descriptionEl = container.querySelectorAll<HTMLElement>(SELECTORS.description);\n const hotelLinkEl = container.querySelectorAll<HTMLAnchorElement>(SELECTORS.hotelLink);\n\n const language = getLanguage() as keyof Destination;\n if (destinationEl) {\n destinationEl.forEach((el) => {\n el.textContent = destination[language];\n });\n }\n if (image?.url) {\n const images = container.querySelectorAll<HTMLImageElement>(SELECTORS.image);\n images.forEach((el) => {\n el.src = image.url;\n });\n }\n if (hotelNameEl) {\n hotelNameEl.forEach((el) => {\n el.innerHTML = hotelName;\n });\n }\n if (nameEl) {\n nameEl.forEach((el) => {\n el.innerHTML = title;\n });\n }\n if (descriptionEl && description) {\n descriptionEl.forEach((el) => {\n el.innerHTML = description;\n });\n }\n if (hotelLinkEl && slug) {\n hotelLinkEl.forEach((el) => {\n el.addEventListener('click', (e) => {\n e.preventDefault();\n window.location.href = slug;\n });\n });\n }\n}\n\n/**\n * Fetches the single offer for the given slug and binds price/CTA to existing elements\n * in the container. Use on the offer slug page where the main offer block is already\n * in the DOM (no list). Container should wrap elements with data-price, data-currency,\n * data-hotel-reserve-link, data-hotel-villa-reserve-link, data-discount, data-discount-container.\n */\nexport async function bindSlugOfferToContainer(\n slug: string,\n container: HTMLDivElement\n): Promise<void> {\n const apiClient = new ApiClient();\n const cmsOffersData = await apiClient.getCMSOffers();\n if (!cmsOffersData) return;\n\n const cmsCountries = await apiClient.getCountries();\n if (!cmsCountries) return;\n\n const availableCountries: { [key: string]: string } = {};\n cmsCountries.items.forEach((c) => {\n availableCountries[c.id] = c.fieldData.title?.trim();\n });\n\n const countryCode = await getUserCountryCode();\n const countryCodeFilter = (item: CMSOfferItem) => {\n const { fieldData } = item;\n if (!fieldData['supported-countries'] || fieldData['supported-countries'].length === 0)\n return true;\n const itemCountryCodes = fieldData['supported-countries'].map((c) => availableCountries[c]);\n return itemCountryCodes.includes(countryCode);\n };\n\n const slugFilter = (value: CMSOfferItem) => {\n const { isArchived, isDraft, fieldData } = value;\n if (isArchived || isDraft) return false;\n return fieldData.slug === slug;\n };\n\n const filteredOffers = cmsOffersData.items.filter(slugFilter).filter(countryCodeFilter);\n if (filteredOffers.length === 0) return;\n\n const cmsIDToHotelIds = cmsIDToHotelIdMap();\n const hotelIds = Array.from(\n new Set(\n filteredOffers\n .map((o) => cmsIDToHotelIds[o.fieldData['hotel-villa']])\n .filter((id): id is string => id != null)\n )\n );\n if (hotelIds.length === 0) return;\n let hids = hotelIds.join(',');\n if (hotelIds.length === 1) hids = [hids, hids].join(',');\n\n const offerLookup: { [key: string]: CMSOfferItem } = {};\n const offerMetaData: string[] = [];\n filteredOffers.forEach((offer) => {\n const {\n fieldData: { 'hotel-or-property-api-id': hotelId, 'offer-api-name': name },\n } = offer;\n const s = offerSlug(hotelId, name);\n offerMetaData.push(s);\n offerLookup[s] = offer;\n });\n\n const locale = getLocale();\n const hotelOffersData = await apiClient.getGroupOffersData({ hids, locale });\n if (!hotelOffersData?.data || hotelOffersData.error) return;\n\n const data = hotelIds.length === 1 ? [hotelOffersData.data[0]] : hotelOffersData.data;\n const offers: Offer[] = [];\n data.forEach((offer) => {\n const {\n prop: { hid },\n rates: offerRates,\n } = offer;\n offerRates.forEach((rate) => {\n const { name, title } = rate.rate;\n const include =\n offerMetaData.includes(offerSlug(hid, name)) ||\n offerMetaData.includes(offerSlug(hid, title));\n if (include) offers.push({ ...offer, rates: [rate] });\n });\n });\n offers.sort((a, b) => {\n const cmsA =\n offerLookup[offerSlug(a.prop.hid, a.rates[0].rate.title)] ||\n offerLookup[offerSlug(a.prop.hid, a.rates[0].rate.name)];\n const cmsB =\n offerLookup[offerSlug(b.prop.hid, b.rates[0].rate.title)] ||\n offerLookup[offerSlug(b.prop.hid, b.rates[0].rate.name)];\n return (Number(cmsA?.fieldData.order) || 0) - (Number(cmsB?.fieldData.order) || 0);\n });\n\n const first = offers[0];\n if (!first?.rates?.[0]) return;\n const { prop, rates } = first;\n const hid = prop.hid || prop.property;\n const rate = rates[0];\n const cmsOfferData =\n offerLookup[offerSlug(hid, rate.rate.title)] || offerLookup[offerSlug(hid, rate.rate.name)];\n try {\n const hotelMeta = SNIPPET_CODE_TO_HOTEL[hid];\n if (hotelMeta) {\n bindOfferMetaToContainer(container, {\n destination: hotelMeta.destination,\n image: rate.rate.image,\n hotelName: prop.title,\n title: rate.rate.title,\n slug: hotelMeta.slug,\n description: rate.rate.html_description,\n });\n }\n bindQuotationData(container, rate, hid, cmsOfferData);\n } catch {\n // bind failed\n }\n}\n", "import type { CMSFilters } from '@globalTypes/CMSFilters';\nimport type { CMSList } from '@globalTypes/CMSList';\n\nimport { SELECTORS } from './constants';\nimport { Offers } from './Offers';\n\n/**\n * Minimal CMSList backed by a plain DOM container (no cmsfilter/cmsload).\n * Template: `[data-list-item]` or, for offer-slug-others-list, `.offer-others_item` from snapshot.\n */\nexport function createOffersFromDomContainer(listContainer: HTMLDivElement): Offers | null {\n let templateItem = listContainer.querySelector<HTMLDivElement>(SELECTORS.listItem);\n if (!templateItem && listContainer.matches(SELECTORS.offerSlugOthersList)) {\n templateItem = listContainer.querySelector<HTMLDivElement>(SELECTORS.offerSlugOthersListItem);\n }\n if (!templateItem) return null;\n\n const fakeList = {\n items: [{ element: templateItem }],\n clearItems(removeElements = true) {\n if (removeElements) {\n listContainer.innerHTML = '';\n }\n },\n addItems(itemElements: HTMLElement[]) {\n for (const el of itemElements) {\n listContainer.appendChild(el);\n }\n return Promise.resolve();\n },\n } as CMSList;\n\n return createOfferForList(fakeList);\n}\n\n/**\n * creates an instance of Offers based on the filtersInstances\n * @param filtersInstances\n * @returns @type {Offers} instance\n */\nexport const createOffersInstance = (filtersInstances: CMSFilters[]) => {\n const [filtersInstance] = filtersInstances;\n\n // Get the list instance\n const { listInstance } = filtersInstance;\n if (listInstance.items.length === 0) {\n throw new Error('No items found in the list instance - Cannot create an instance of Offers');\n }\n\n return createOfferForList(listInstance);\n};\n\n/**\n * creates an instance of Offers based on the listInstance\n * @param listInstance\n * @returns @type {Offers} instance\n */\nexport const createOfferForList = (listInstance: CMSList) => {\n const [firstItem] = listInstance.items;\n if (!firstItem) throw new Error('No items found in the list instance');\n\n const itemTemplateElement = firstItem.element;\n return new Offers(listInstance, itemTemplateElement);\n};\n", "import type { CMSFilters } from '@globalTypes/CMSFilters';\n\nimport { OFFER_CATEGORIES } from '$utils/constants';\nimport { createOffersInstance } from '$utils/createOffersInstance';\n\nwindow.fsAttributes = window.fsAttributes || [];\nwindow.loadFromServer = () => {\n window.fsAttributes.push([\n 'cmsfilter',\n async (filtersInstances: CMSFilters[]) => {\n // Get the filters instance\n const offers = createOffersInstance(filtersInstances);\n await offers.getGroupCategoryOffers(OFFER_CATEGORIES['DERNI\u00C8RE MINUTE']);\n },\n ]);\n};\n\nwindow.loadFromServer();\n"],
5
+ "mappings": ";;;AAAO,MAAM,SAAS;AAGf,MAAM,YAAY;AAAA,IACvB,mBAAmB,IAAI,MAAM;AAAA,IAC7B,OAAO,IAAI,MAAM;AAAA,IACjB,UAAU,IAAI,MAAM;AAAA,IACpB,mBAAmB,IAAI,MAAM;AAAA,IAC7B,UAAU,IAAI,MAAM;AAAA,IACpB,OAAO,IAAI,MAAM;AAAA,IACjB,aAAa,IAAI,MAAM;AAAA,IACvB,YAAY,IAAI,MAAM;AAAA;AAAA,IAEtB,iBAAiB,IAAI,MAAM;AAAA;AAAA,IAE3B,qBAAqB,IAAI,MAAM;AAAA;AAAA,IAE/B,yBAAyB;AAAA;AAAA,IAEzB,mBAAmB,IAAI,MAAM;AAAA,IAC7B,qBAAqB,IAAI,MAAM;AAAA,IAC/B,UAAU,IAAI,MAAM;AAAA,IACpB,OAAO,IAAI,MAAM;AAAA,IACjB,MAAM,IAAI,MAAM;AAAA,IAChB,aAAa,IAAI,MAAM;AAAA,IACvB,WAAW,IAAI,MAAM;AAAA,IACrB,WAAW,IAAI,MAAM;AAAA,IACrB,6BAA6B,IAAI,MAAM;AAAA,IACvC,aAAa,IAAI,MAAM;AAAA,IACvB,aAAa,IAAI,MAAM;AAAA,IACvB,kBAAkB,IAAI,MAAM;AAAA,IAC5B,kBAAkB,IAAI,MAAM;AAAA,IAC5B,uBAAuB,IAAI,MAAM;AAAA,IACjC,WAAW,IAAI,MAAM;AAAA,IACrB,kBAAkB,IAAI,MAAM;AAAA,IAC5B,kBAAkB,IAAI,MAAM;AAAA,IAC5B,gBAAgB,IAAI,MAAM;AAAA,IAC1B,qBAAqB;AAAA,IACrB,kBAAkB,CAAC,OAAe,IAAI,MAAM,WAAW,EAAE;AAAA,IACzD,cAAc;AAAA,EAChB;AAoCA,MAAM,aAAa;AAAA,IACjB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,MAAM,YAAY;AAAA,IAChB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AACA,MAAM,cAAc;AAAA,IAClB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,MAAM,aAAa;AAAA,IACjB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,MAAM,cAAc;AAAA,IAClB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,MAAM,eAAe;AAAA,IACnB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,MAAM,UAAU;AAAA,IACd,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAEA,MAAM,WAAW;AAAA,IACf,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAGO,MAAM,wBAOT;AAAA,IACF,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IACA,YAAY;AAAA,MACV,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,IACT;AAAA,EACF;AAGO,MAAM,qBAAgD;AAAA,IAC3D,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,I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",
6
+ "names": []
7
+ }