{"version":3,"sources":["webpack:///./src/frontend/localization/use-localized-price-formatter.js","webpack:///./src/frontend/state/language/selectors.js","webpack:///./src/frontend/utils/http.js","webpack:///./src/EbaySweden.TouchWeb/static/script/app/ui/google-tagmanager-service.js","webpack:///./src/frontend/lang/constants.mjs","webpack:///./src/frontend/utils/gdpr-settings.js","webpack:///./src/frontend/state/environment/selectors.js","webpack:///./src/frontend/lang/boot-languages.js","webpack:///./src/frontend/lang/shared-config.mjs","webpack:///./src/EbaySweden.TouchWeb/static/script/packages/logger.js","webpack:///./src/frontend/utils/object.js","webpack:///./src/frontend/utils/nextjs.js","webpack:///./src/backend/i18n/translation-keys.js","webpack:///./src/frontend/state/page/selectors.js","webpack:///./src/frontend/lang/translate.jsx","webpack:///./src/frontend/apps/my-tradera/app/constants/list-types.js","webpack:///./src/frontend/state/member/selectors.js","webpack:///./src/frontend/utils/cookie.js","webpack:///./src/frontend/state/multi-currency/selectors.js","webpack:///./src/frontend/hooks/use-location.js","webpack:///./src/frontend/localization/countrycode.js","webpack:///./src/frontend/utils/versions.js","webpack:///./src/frontend/state/environment/native-app-support.js","webpack:///./src/frontend/state/environment/initial-state.js","webpack:///./src/backend/utils/cookies.js","webpack:///./src/frontend/state/environment/native-app-info-helper.js","webpack:///./src/frontend/state/environment/actions.js","webpack:///./src/frontend/state/environment/reducer.js","webpack:///./src/frontend/utils/api.js","webpack:///./src/frontend/constants/hosts.js","webpack:///./src/frontend/utils/url.js","webpack:///./src/frontend/utils/prop-types.js","webpack:///./src/frontend/components/alink/alink.jsx","webpack:///./src/frontend/hooks/use-is-feature-enabled.js","webpack:///./src/frontend/apps/syi/script/app_react/utils/language.js","webpack:///./src/EbaySweden.TouchWeb/static/script/app/ui/google-tagmanager-helper.js","webpack:///./src/frontend/utils/format.js","webpack:///./src/frontend/utils/date.js","webpack:///./src/frontend/utils/cookie-helpers.js","webpack:///./src/frontend/state/shipping-region/selectors.js","webpack:///./src/frontend/constants/endpoints.js","webpack:///./src/frontend/constants/cookies.js","webpack:///./src/EbaySweden.TouchWeb/static/script/utils/environment.js","webpack:///./src/frontend/components/toasts/item-toast.module.scss","webpack:///./src/frontend/components/toasts/item-toast.jsx","webpack:///./src/frontend/components/toasts/message-toast.jsx","webpack:///./src/frontend/services/toasts.js","webpack:///./src/frontend/services/toast-queue.js","webpack:///./src/frontend/utils/is-prerender.js","webpack:///./src/EbaySweden.TouchWeb/static/script/packages/init-data.js","webpack:///./src/frontend/localization/languagecode.js"],"names":["getOptions","preferredCurrency","overrides","currency","code","minimumFractionDigits","decimals","maximumFractionDigits","useLocalizedPriceFormatter","language","useCurrentLanguage","useSelector","selectPreferredCurrency","useCallback","price","formatPrice","rate","useLocalizedPriceFormatterNoConversion","useLocalizedPriceFormatterNoSymbol","style","selectAvailableLanguages","state","available","selectAvailableLanguageCodesIso2","map","x","languageCodeIso2","selectPreferredLanguage","preferred","selectPreferredLanguageCode","DEFAULT_LANGUAGE","selectLocale","country","memberCountryCodeIso2","selectIsForeignLanguageActivated","selectAutomaticTranslationPreference","automaticTranslationPreference","ensureClientOnly","isServer","Error","httpClient","baseUrl","shouldLocalizeUrl","isWebApiClient","axiosWrapper","url","httpClientConfig","axiosCaller","cancelTokenId","axiosConfig","version","initData","utilizeCancelToken","cancel","cancelToken","isWebApiNet5FromFrontendEnabled","featureSwitches","net5Url","matches","match","length","endpointName","replace","getNet5UrlIfEnabled","safeUrl","substring","getSafeUrl","localizedUrl","toLocalizedUrl","getLanguage","axiosWithTokenRefresh","then","checkResponseVersion","response","finalizeResponse","catch","handleError","error","logError","tags","webapiNet5","get","axiosConfigs","authenticated","axios","config","post","payload","put","trpcClient","endpoint","client","unpackResponse","data","command","commandName","query","queryName","defaultClient","touchWebClient","webApiClient","ENDPOINTS","WEB_API","marketingApiClient","CMS_API","MARKETING_PUBLIC_API","searchSuggestionsClient","SEARCH_SUGGESTIONS","memberIdentificationClient","translationDynamicApiClient","shippingRecommendationsClient","spaPageViewTrackingEnabled","constructor","setupExperiments","experiments","this","pushArguments","_hasPreviouslyTrackedPage","window","dataLayer","find","item","event","isScriptLoaded","loadGtmScript","isNextJs","_newPageFromServer","accountId","process","NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ACCOUNT_ID","w","d","s","l","i","push","Date","getTime","f","getElementsByTagName","j","createElement","async","src","parentNode","insertBefore","document","arguments","_getDatalayerObject","output","entry","_reset","Object","keys","undefined","newPage","pageType","initialDataLayer","_pushInitialDataLayer","newSpaPage","buildInitialGtmDataLayerFromInitData","legacyDataLayer","trackAction","category","action","label","value","nonInteractive","eventCategory","eventAction","eventLabel","eventValue","eventNonInteractive","Sentry","type","level","message","trackGtmEvent","eventName","trackPageView","trackLinkClickAndCallback","callback","eventCallback","trackLinkClickAndGotoUrl","location","href","NS_TOUCHWEB","NS_ATTRIBUTES","NS_CATEGORIES","NS_BACKEND","URL_LANGUAGES","I18N_FRONTEND_NAMESPACES","I18N_BACKEND_NAMESPACES","SUPPORTED_LANGUAGES","TRANS_SUFFIX","GdprSettings","getCookie","setCookie","isCategoryEnabled","cookieCategory","COOKIE_CATEGORIES","Essential","encodedConsentCookie","GDPR_CONSENT_COOKIE","consentCookie","decodeURI","RegExp","test","isPerformanceEnabled","Performance","isFunctionalEnabled","Functional","isMarketingEnabled","Marketing","set","performance","functional","marketing","name","expires","options","cookieValue","cookieString","join","dayjs","add","toDate","httpOnly","path","cookie","serialize","String","getCookieFromBrowser","setCookieToBrowser","selectFeatureSwitches","environment","selectIsFeatureEnabled","featureName","i18nInitialized","missingKeyLoggingConfig","saveMissing","saveMissingTo","missingKeyHandler","namespace","key","missingInterpolationHandler","text","JSON","stringify","bootLanguages","translations","touchwebTranslations","attributeTranslations","translationResources","attributeResources","resources","concat","prev","i18n","use","initReactI18next","LanguageDetector","init","initOptions","err","logger","detection","order","htmlTag","html","defaultNS","ns","fallbackLng","debug","keySeparator","nsSeparator","interpolation","escape","str","format","formatNumberWithSeparators","react","useSuspense","whenInitialized","t","scope","sentryException","nullifyUndefinedProperties","obj","mapObject","isUndefined","getElementById","usedKeyPageTypes","getOrCreatePageTypeNamespaces","has","addKey","usedKeys","selectPageType","page","useTranslator","pathType","useTranslation","wait","ready","wrappedT","i18nKey","withTranslator","WrappedComponent","WithTranslator","props","displayName","withUrlLocalizer","WithUrlLocalizer","useUrlLocalizer","urlLocalizer","useRef","current","Trans","children","defaults","LIST_VIEW_TYPES","BASIC","NORMAL","PICK_LIST","PAGE_LIST_TYPES","BUYER_ACTIVE_ITEMS","BUYER_PURCHASES","BUYER_ITEMS_LOST","SELLER_ACTIVE","SELLER_SOLD","SELLER_NOT_SOLD","PAGE_BULK_ACTIONS","ACTIVE_CANCEL","UNSOLD_RESTART","BUYER_MARK_PAID","BUYER_SHOW_ACTIVE","BUYER_HIDE_ACTIVE","PURCHASES_SHOW","selectIsLoggedIn","member","isLoggedIn","selectGeolocation","geolocation","selectMemberId","memberId","selectMemberEmail","memberEmail","selectMemberFirstName","memberFirstName","selectMemberLastName","memberLastName","selectMemberCountryCodeIso2","selectIsOutsideSweden","isoCode","toLowerCase","showDanishFromCountry","fromCountry","selectShippingRegionCountryCodeIso2","areCountryCodesIso2Equal","selectMemberTown","memberTown","CookieUtil","gdpr","segment","convertToExpiresStr","expiresStr","Number","Infinity","toUTCString","createCookie","cookieKey","domain","secure","CATEGORIZED_COOKIES","COOKIE_DEFAULT_CATEGORY","encodeURIComponent","protocol","readCookie","hasCookie","eraseCookie","selectCurrencies","multiCurrency","currencies","c","selectIsPreferredCurrencySEK","selectShowCurrencySelection","enabled","useLocation","request","isSwedenCountryCodeOrUndefined","countryCodeIso2","isSwedenCountryNameOrUndefined","countryName","isDenmarkCountryCode","first","second","toUpperCase","parseAppVersion","split","filter","number","isNaN","major","minor","patch","isSupportedMinimumVersion","appVersionString","minimumVersionString","appVersion","minimumVersion","getNativeAppSupport","isNativeAppContext","isHybridAppContext","hybridAppDevice","hybridAppVersion","appOsVersion","isIOS","isAndroid","isHybridAppContextForAndroid","Boolean","includes","isHybridAppContextForIos","isIos13","isNativeAppWithApplyPaySupport","isNativeAppWithSwishCallbackSupport","getCookieNameForEnvironment","isDev","NATIVE_APP_COOKIE_AND_HEADER_CONFIG","osVersion","header","initDataName","appDevice","appContext","appLanguage","createNativeAppCookieValue","nativeAppInfo","valueObject","extractNativeAppInfoFromCookie","nativeAppCookieString","parse","decodeURIComponent","getVersionUrl","getState","queryParameters","next","preferredLanguageCode","updateEnvironmentHash","dispatch","a","environmentHash","headers","setEnvironmentHash","setIsSpaNavigationEnabled","getAndUpdateNativeAppInfo","nativeAppInfoFromInitData","extractNativeAppInfoFromInitData","nativeAppCookieValue","NATIVE_APP_ENVIRONMENT","initEnvironment","geoPublicApiBaseUrl","isSinglePageApp","splitTests","splitTestGroups","webLiveUrl","initialState","isMobileDevice","isMobile","isMobileSafari","isSpaNavigationEnabled","frameElement","variables","PUBLIC_GEO_PUBLIC_API_BASE_URL","PUBLIC_WEB_LIVE_URL","getInitialState","initialize","slice","createSlice","reducers","_state","actions","reducer","API_ERRORS","IGNORE_ME","ABORTED","CANCELLED","NETWORK","TIMEOUT","VERSION_MISMATCH","LOGGED_OUT","defaultJsonRequestHeaders","Accept","withCredentials","notAuthenticated","isUnauthorized","statusCode","submitOriginalRequest","antiCacheRegExp","handleMissingAuthToken","refreshAccessToken","TOUCHWEB_URL","handleErrorAfterRefresh","errorAfterRefreshToken","status","reject","handleUnauthorized","checkLoginState","errorResponseInterceptor","responseString","responseStatus","errorCode","isMissingAuthToken","axiosInstance","instance","create","interceptors","cancelTokens","tokenId","CancelToken","source","token","checkResponseLoggedOut","statusHandlers","toString","isCancel","reloadOnUnauthorized","reload","SPA_PATH_REGEX","formatQueryParams","queryParams","categoryId","formattedQueryParams","isSpaLink","urlOrPath","pathname","stripCategoryIdFromQueryParameters","stripHost","HOSTS","stripItmFromQueryParameters","itm_source","itm_medium","stripPaginationFromQueryParameters","spage","paging","fe","stripSavedQueryNameFromQueryParameters","savedQueryName","toAbsoluteUrl","relativeUrl","toAbsoluteUrlFromObject","search","webApiUrl","indexOf","isAbsolute","isAbsoluteUrl","urlObject","origin","localisedPathname","setLanguagePrefix","toQueryParameters","qs","ignoreQueryPrefix","toRelativeTraderaUrl","toSearchString","addQueryPrefix","encode","skipNulls","arrayFormat","languagePrefix","firstMatch","index","getLanguagePrefixFromUrl","getBackToHereRedirectUrl","forceRedirect","Math","round","random","host","PropTypes","relativeOrAbsoluteUrlString","propName","TypeError","URIError","PRODUCTION_ORIGIN","NEXTWEB_PATHS","vipPathRegex","useNextWebSpaLink","absoluteUrl","isNextWebLink","nextWebVip10Percent","useIsFeatureEnabled","nextWebVip30Percent","nextWebVip100Percent","lastItemIdDigit","searchParams","some","nextwebPath","ALink","isTouchwebSpaLink","useLink","givenOnClick","onClick","otherProps","useDispatch","isNextWebAddUrlParamEnabled","isNextWebSpaLink","handleSpaNavigationClick","evt","isRelativeUrl","getRelativeUrl","prefetch","onMouseEnter","e","stopPropagation","to","propTypes","defaultProps","toLocalizedRiotUrl","querySelector","getAttribute","userLanguage","memberHashedEmail","memberEmailSha256","memberEmailMd5","memberCountry","loginState","isNotInIframe","self","top","blueshiftEventApiKey","isQuantcastConsentEnabled","isTikTokPixelEnabled","isDigitalAudienceTrackingEnabled","quantcastSite","formatEndDate","endDateInput","nowDateInput","endDate","swedishTimeZoneDate","now","isSameOrAfter","hours","diff","minutes","timeParts","count","isAfter","separator","isLocaleFormattingSupportedInBrowser","toLocaleString","toLocaleStringSupportsLocales","Intl","NumberFormat","formatSellerDsrAverage","locale","overrideOptions","defaultOptions","currencyDisplay","useGrouping","priceAsNumber","suffix","formattedPrice","getCurrencySymbol","formatDateWithDayOfWeek","dateString","weekday","year","month","day","DateTimeFormat","plainDayjs","extend","isBetween","utc","timezone","localizedFormat","localizedDayjs","date","localizedDayjsFn","tz","formatUtcDateAsSwedishTimeZoneDate","getTimeSpanParts","seconds","optionsWithDefaults","startUnit","endUnit","parts","remaining","started","TIME_SPAN_UNIT_LENGTHS","part","floor","TIME_SPAN_UNITS","DAYS","HOURS","MINUTES","SECONDS","getCookieFromString","selectShowRegionSelection","selectAvailableShippingCountries","shippingRegion","availableShippingCountries","selectShippingCountry","shippingCountry","selectIsLoadingAvailableShippingCountries","isLoadingAvailableShippingCountries","selectHasLoadedAvailableShippingCountries","hasLoadedAvailableShippingCountries","selectIsSwedishVisitor","selectIsDanishVisitor","selectShowLocalizationRegionPicker","localizationRegionPickerEnabled","regionPickerDismissed","geoLocation","getLanguageFromCountryCode","gpsMatchesLanguage","getSiteBaseUrl","PUBLIC_TOUCHWEB_WINDOW_LOCATION_ORIGIN","touchWebUrl","AVAILABLE_SHIPPING_COUNTRIES","BANK_ID_AUTHENTICATE","BANK_ID_PROGRESS","BRAND_LIST_PAGE","BRAND_PAGE","CART_UPDATE_SUMMARY","CART_OVERVIEW_VIEW","CART_ADD_ITEM","CART_REMOVE_ITEMS","CART_SET_ITEM_QUANTITY","CHARITY_EARNINGS_TICKER","cmsApiUrl","COMBINED_SHIPPING_UPSELL","FAVORITE_SELLER_ADD","FAVORITE_SELLER_REMOVE","FAVOURITE_SELLERS","GET_PROFILE_FEEDBACK_ITEMS","HYPERWALLET_PAYOUT_COMPLETE","HYPERWALLET_PAYOUT_TOKEN","HYPERWALLET_PAYOUT","INTERNATIONAL_SHIPPING_CALCULATOR","ITEM_DESCRIPTION","itemId","ITEM_DISCOUNT_QUOTA","LAST_CHANCE","MEMBER_PAYOUT_SETTINGS_REMOVE","MEMBER_PAYOUT_SETTINGS","MEMBER_SYSTEM_MESSAGES","ORDER_CHECKOUT_CONFIRMATION","ORDER_CHECKOUT_PAYMENT","orderCheckoutPaymentUrl","ORDER_CHECKOUT_REQUEST_COMBINED_PRICE","ORDER_CHECKOUT_CREATE_UNCOMMITTED_PURCHASE_ORDER","ORDER_PURCHASE_SHOP_ITEMS","PAYMENT_SWISH_OPTOUT","PERSONALISED_SUGGESTIONS","SEARCH","SELLING_CAMPAING_CODE","SELLING_DRAFT_LOAD_FROM_TEMPLATE","SELLING_DRAFT_SAVE","SELLING_DRAFT","draftId","SELLING_DRAFTS_DELETE","SELLING_DRAFTS","SELLING_ITEM_PUBLISH","SELLING_ITEM_STATUS","SELLING_ITEM_UPDATE","SELLING_PREVIEW","SELLING_SCRIBE_DURATION","SELLING_SCRIBE_INCREMENT","SELLING_SCRIBE_SESSION_DURATION","SELLING_SCRIBE_SESSION_START","SELLING_SCRIBE_VALIDATION_ERRORS","SELLING_SHIPPING_CALCULATOR","SELLING_TEMPLATE_SAVE","SELLING_TEMPLATE","templateId","SELLING_TEMPLATES_COUNT","SELLING_TEMPLATES_DELETE","SELLING_TEMPLATES","SETTINGS","SWISH_APP2APP_CALLBACK","SWISH_APP2APP_CALLBACK_MARK_AS_PAID","TRANSLATE_PROFILE_FEEDBACKITEMS","WISHLIST","WISHLIST_ADD","WISHLIST_REMOVE","UPI","purchaseOrderId","MCP","MCP_CONFIRM","INR","PURCHASE_ORDER","SHIPPING_CHECKOUT_DELETE","DEFAULT_COOKIES","ITEM_LAYOUT","default","SITE_LAYOUT","MYTRADERA_DEFAULT_COOKIES","LIST_VIEW_TYPE","ITEMS_PER_PAGE","SHOW_FILTERS","LIST_VIEW_TYPE_BUYER_ACTIVE_ITEMS","LIST_VIEW_TYPE_BUYER_PURCHASES","LIST_VIEW_TYPE_BUYER_ITEMS_LOST","LIST_VIEW_TYPE_SELLER_ACTIVE","LIST_VIEW_TYPE_SELLER_SOLD","LIST_VIEW_TYPE_SELLER_NOT_SOLD","GDPR_CONSENT_ALERT_DISMISSED","FORCE_GEO_DEV","REGION_PICKER_DISMISSED","SHIPPING_COUNTRY","CART_ID","SHIP_TO_SWEDEN_DISCLAIMER_DISMISSED","EXPERIMENTS","warnIfDevBuild","moduleName","console","log","onModuleLoaded","isModuleLoaded","body","MutationObserver","mutationsList","attributeName","observe","attributes","ItemToast","imageUrl","itemUrl","shortDescription","eventData","className","styles","title","alt","ToastMessage","localizedPriceFormatter","newLeadingBid","newLeadingBidAmount","timeLeftMinutes","MessageToast","items","inProgress","queuedToasts","ttlInMinutes","timeStamp","itemData","shift","notifyDone","isInProgress","getLength","openNextToast","nextItem","queueLength","toastOptions","autoClose","max","onClose","toast","React","handleNotification","visibilityState","showItemOutbiddedToast","showItemFirstBidToast","showItemSoldToast","showItemWonToast","showItemPaidToast","showItemWishListReminderToast","showSuccessToast","TYPE","SUCCESS","showErrorToast","ERROR","showInfoToast","INFO","isPrerender","userAgent","initDataEL","getInitData","isSwedishOrUndefined","se","dk","de","getCountryCodeForFlagFromLanguage","languageCode","en","da","getCountryCodeFromLanguage","areLanguageCodesIso2Equal"],"mappings":"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","file":"script/chunks/chunk.default~resolution~swedish-company~swedish-private.1a0167d990.js","sourcesContent":["import { useCallback } from 'react';\nimport { useCurrentLanguage } from 'tradera-lang/translate';\nimport { formatPrice } from 'tradera-utils/format';\nimport { useSelector } from 'react-redux';\nimport { selectPreferredCurrency } from 'tradera-state/multi-currency/selectors';\n\nconst getOptions = (preferredCurrency, overrides = {}) => ({\n currency: preferredCurrency.code,\n minimumFractionDigits: preferredCurrency.decimals,\n maximumFractionDigits: preferredCurrency.decimals,\n ...overrides\n});\n\nexport const useLocalizedPriceFormatter = () => {\n const { language } = useCurrentLanguage();\n const preferredCurrency = useSelector(selectPreferredCurrency);\n return useCallback(\n price =>\n formatPrice(\n preferredCurrency.rate * price,\n language,\n getOptions(preferredCurrency)\n ),\n [language, preferredCurrency]\n );\n};\n\nexport const useLocalizedPriceFormatterNoConversion = () => {\n const { language } = useCurrentLanguage();\n const preferredCurrency = useSelector(selectPreferredCurrency);\n return useCallback(\n price => formatPrice(price, language, getOptions(preferredCurrency)),\n [language, preferredCurrency]\n );\n};\n\nexport const useLocalizedPriceFormatterNoSymbol = () => {\n const { language } = useCurrentLanguage();\n const preferredCurrency = useSelector(selectPreferredCurrency);\n return useCallback(\n price =>\n formatPrice(\n preferredCurrency.rate * price,\n language,\n getOptions(preferredCurrency, {\n style: 'decimal'\n })\n ),\n [language, preferredCurrency]\n );\n};\n","import { DEFAULT_LANGUAGE } from 'tradera-lang/constants.mjs';\n\nexport const selectAvailableLanguages = state => state.language.available;\n\nexport const selectAvailableLanguageCodesIso2 = state =>\n state.language.available.map(x => x.languageCodeIso2);\n\nexport const selectPreferredLanguage = state => state.language.preferred;\n\nexport const selectPreferredLanguageCode = state =>\n state.language.preferred?.languageCodeIso2 || DEFAULT_LANGUAGE;\n\nexport const selectLocale = state => {\n const language = selectPreferredLanguageCode(state);\n const country = state.language.memberCountryCodeIso2 || 'SE';\n\n return `${language}-${country}`;\n};\n\nexport const selectIsForeignLanguageActivated = state =>\n selectPreferredLanguage(state).languageCodeIso2 !== DEFAULT_LANGUAGE;\n\nexport const selectAutomaticTranslationPreference = state =>\n state.language.automaticTranslationPreference;\n","import ENDPOINTS from 'tradera-constants/endpoints';\nimport {\n axiosWithTokenRefresh,\n checkResponseVersion,\n finalizeResponse,\n handleError,\n utilizeCancelToken,\n axiosConfigs,\n logError\n} from 'tradera-utils/api';\nimport initData from 'init-data';\nimport { toLocalizedUrl } from 'tradera-utils/url';\nimport { getLanguage } from 'tradera-apps/syi/script/app_react/utils/language';\nimport { isServer } from 'tradera-utils/nextjs';\n\nconst ensureClientOnly = () => {\n // Cancel tokens would be shared per server instance so ensure we are not on server.\n if (isServer) {\n throw new Error('This HTTP client is only safe to use on frontend');\n }\n};\n\n// Prevents URL:s that begins with // when that was not intended.\nconst getSafeUrl = (baseUrl, url) => {\n if (baseUrl.endsWith('/') && url.startsWith('/')) {\n return baseUrl + url.substring(1);\n }\n return baseUrl + url;\n};\n\nconst getNet5UrlIfEnabled = url => {\n const matches = url.match(/^\\/(\\w+)\\//);\n if (matches.length == 2) {\n const endpointName = matches[1];\n\n if (initData?.featureSwitches?.[`webapi-${endpointName}-net5`]) {\n return url.replace(endpointName, `${endpointName}-net5`);\n }\n }\n\n return url;\n};\n\nconst httpClient = (baseUrl, shouldLocalizeUrl, isWebApiClient) => {\n const axiosWrapper = (url, httpClientConfig, axiosCaller) => {\n let { cancelTokenId, ...axiosConfig } = httpClientConfig;\n const version = initData.version;\n if (cancelTokenId) {\n const { cancel, cancelToken } = utilizeCancelToken(cancelTokenId);\n // eslint-disable-next-line better-mutation/no-mutation\n axiosConfig.cancelToken = cancelToken;\n if (cancel) {\n cancel();\n }\n }\n const isWebApiNet5FromFrontendEnabled =\n initData?.featureSwitches?.['webapi-net5-from-frontend'];\n const net5Url =\n isWebApiClient && isWebApiNet5FromFrontendEnabled\n ? getNet5UrlIfEnabled(url)\n : url;\n const safeUrl = getSafeUrl(baseUrl, net5Url);\n const localizedUrl = shouldLocalizeUrl\n ? toLocalizedUrl(safeUrl, getLanguage())\n : safeUrl;\n return axiosCaller(axiosWithTokenRefresh(), localizedUrl, axiosConfig)\n .then(\n version ? checkResponseVersion(version) : response => response\n )\n .then(finalizeResponse())\n .catch(handleError())\n .catch(error => {\n if (isWebApiClient && isWebApiNet5FromFrontendEnabled) {\n logError(error, {\n tags: {\n webapiNet5: net5Url !== url\n }\n });\n }\n throw error;\n });\n };\n\n return {\n get: (url, httpClientConfig = axiosConfigs.authenticated) => {\n ensureClientOnly();\n return axiosWrapper(url, httpClientConfig, (axios, url, config) =>\n axios.get(url, config)\n );\n },\n post: (url, payload, httpClientConfig = axiosConfigs.authenticated) => {\n ensureClientOnly();\n return axiosWrapper(url, httpClientConfig, (axios, url, config) =>\n axios.post(url, payload, config)\n );\n },\n put: (url, payload, httpClientConfig = axiosConfigs.authenticated) => {\n ensureClientOnly();\n return axiosWrapper(url, httpClientConfig, (axios, url, config) =>\n axios.put(url, payload, config)\n );\n }\n };\n};\n\nconst trpcClient = endpoint => {\n const client = httpClient(`/api/${endpoint}`, false);\n const unpackResponse = ({ data }) => data;\n return {\n command: (commandName, payload, httpClientConfig) =>\n client\n .post(`/commands/${commandName}`, payload, httpClientConfig)\n .then(unpackResponse),\n query: (queryName, httpClientConfig) =>\n client\n .get(`/queries/${queryName}`, httpClientConfig)\n .then(unpackResponse)\n };\n};\n\nexport const defaultClient = httpClient('');\nexport const touchWebClient = httpClient('/', true);\nexport const webApiClient = httpClient(ENDPOINTS.WEB_API, false, true);\nexport const cmsApiClient = httpClient(ENDPOINTS.CMS_API);\nexport const marketingApiClient = httpClient(ENDPOINTS.MARKETING_PUBLIC_API);\nexport const searchSuggestionsClient = httpClient(ENDPOINTS.SEARCH_SUGGESTIONS);\nexport const memberIdentificationClient = trpcClient('member-identification');\nexport const translationDynamicApiClient = trpcClient(\n 'translation-dynamic-api'\n);\nexport const shippingRecommendationsClient = trpcClient(\n 'shipping-recommendations'\n);\n","/* eslint-disable better-mutation/no-mutation */\n\n/**\n *\n * # track events:\n * import GtmService from 'static/script/app/ui/google-tagmanager-service';\n * GtmService.trackGtmEvent(\"zorro\", { marvel: false, black: true })\n *\n *\n *\n */\n\nimport * as Sentry from '@sentry/react';\nimport initData from 'init-data';\nimport { isServer, isNextJs } from 'tradera-utils/nextjs';\nimport { buildInitialGtmDataLayerFromInitData } from './google-tagmanager-helper';\n\n/**\n * SPA page view tracking becomes enabled after first\n * page view tracking which happens after the first\n * page is loaded from server.\n * This prevents reset of data layer after a SPA route has\n * changed (happens late after full page load) and prevents\n * duplicated trackPageView events.\n */\nlet spaPageViewTrackingEnabled = false;\n\nclass GoogleTagManagerService {\n constructor() {\n this.isScriptLoaded = false;\n }\n\n loadGtmScript() {\n if (!isNextJs) {\n this._newPageFromServer();\n }\n const accountId =\n process?.env.NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ACCOUNT_ID ||\n 'GTM-5TMB2D';\n (function(w, d, s, l, i) {\n w[l] = w[l] || [];\n w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });\n var f = d.getElementsByTagName(s)[0],\n j = d.createElement(s),\n dl = l != 'dataLayer' ? '&l=' + l : '';\n j.async = true;\n j.src = '//www.googletagmanager.com/gtm.js?id=' + i + dl;\n f.parentNode.insertBefore(j, f);\n })(window, document, 'script', 'dataLayer', accountId);\n this.isScriptLoaded = true;\n }\n\n push(payload) {\n if (isServer) {\n return;\n }\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push(payload);\n }\n\n pushArguments() {\n if (isServer) {\n return;\n }\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push(arguments);\n }\n\n setupExperiments = experiments => {\n if (experiments) {\n this.pushArguments('set', {\n experiments: experiments\n });\n this.pushArguments('config', 'UA-7094448-8');\n }\n };\n\n _getDatalayerObject() {\n let output = {};\n if (window.dataLayer) {\n for (let entry of window.dataLayer) {\n output = { ...output, ...entry };\n }\n }\n return output;\n }\n\n /**\n * destroy datalayer from previous loading. this is really only useful in spa pages, it's backwards compatible so it doesnt do any harm on old pages\n */\n _reset() {\n if (!window.dataLayer) {\n return;\n }\n\n let data = this._getDatalayerObject();\n for (let key of Object.keys(data)) {\n data[key] = undefined;\n }\n window.dataLayer.push({ ...data, event: 'reset' });\n }\n\n _hasPreviouslyTrackedPage = () =>\n !!window.dataLayer?.find(item => item.event === 'trackPageview');\n\n newPage(pageType, initialDataLayer) {\n if (this._hasPreviouslyTrackedPage()) {\n this._reset();\n }\n this._pushInitialDataLayer(initialDataLayer);\n // It is important that the \"Container loaded\" triggered by dataLayer.push({event: \"gtm.js\", ...})\n // happens after \"initialDataLayer\" otherwise variables for the GDPR banner may have the wrong\n // values in Tagmanager. For that reason the GTM script is loaded here after initialDatalayer is set.\n if (!this.isScriptLoaded) {\n this.loadGtmScript();\n }\n this.push({ event: 'pageType', 'page.pageType': pageType });\n }\n\n /**\n * Same as newPage but with logic for case in Touchweb where initial\n * datalayer was set on server and already tracked on landing page.\n * This function does nothing until after first call to trackPageView\n * (e.g. after a SPA-navigation away from the landing page).\n * @param {*} pageType\n * @param {*} initialDataLayer\n * @returns\n */\n newSpaPage(pageType, initialDataLayer) {\n if (!spaPageViewTrackingEnabled) {\n return;\n }\n this.newPage(pageType, initialDataLayer);\n }\n\n _newPageFromServer() {\n const initialDataLayer = buildInitialGtmDataLayerFromInitData(initData);\n this._pushInitialDataLayer(initialDataLayer);\n // ------------------------------------------------\n // backwards compatibility\n // get old datalayer info and push it in\n if (window.legacyDataLayer) {\n for (let entry of window.legacyDataLayer) {\n window.dataLayer.push({\n event: 'legacyDataLayer',\n ...entry\n });\n }\n }\n }\n\n _pushInitialDataLayer(initialDataLayer) {\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push({\n ...initialDataLayer,\n event: 'initialDataLayer'\n });\n }\n\n /**\n * tracks a google analytics event\n * @param {string} category ga category\n * @param {string} action ga action what happens, ie: \"Filter box - open/close\"\n * @param {string} label ga label what the value of the action was, ie \"close\"\n * @param {integer} [value] ga interger value of the action.\n */\n trackAction(category, action, label, value = 0, nonInteractive = false) {\n this.push({\n event: 'trackEvent',\n eventCategory: category || '',\n eventAction: action || '',\n eventLabel: label || '',\n eventValue: value || '0',\n eventNonInteractive: nonInteractive\n });\n\n Sentry.addBreadcrumb({\n type: 'default',\n level: 'info',\n category: nonInteractive ? 'tracking' : 'ui-action',\n message: 'Analytics Event',\n data: {\n category,\n action,\n label,\n value\n }\n });\n }\n\n /**\n * google tag manager event. Note: if you want to send google analytics events use trackAction instead\n * @param {string} eventName\n * @param {object} [event] data\n */\n trackGtmEvent(eventName, data = {}) {\n this.push({\n event: eventName,\n ...data\n });\n }\n\n /**\n * Track a pageview. Use this script in SPA's to make sure that analytics gets pageview information.\n * This creates a virtual page view since google analytics by default doesn't track changes to url via\n * push state.\n */\n trackPageView() {\n this.trackGtmEvent('trackPageview');\n spaPageViewTrackingEnabled = true;\n }\n\n /**\n *\n * @param {string} category\n * @param {string} action\n * @param {string} label\n * @param {string} callback\n * @param {} value\n */\n trackLinkClickAndCallback(category, action, label, callback, value = 0) {\n this.push({\n event: 'trackEvent',\n eventCategory: category || '',\n eventAction: action || '',\n eventLabel: label || '',\n eventValue: value || '0',\n eventNonInteractive: false,\n eventCallback: callback // part of google tag manager api to execute code after all tags in datalayer have been executed\n });\n }\n\n trackLinkClickAndGotoUrl(category, action, label, url, value = 0) {\n const callback = () => {\n location.href = url;\n };\n this.trackLinkClickAndCallback(\n category,\n action,\n label,\n callback,\n value\n );\n }\n}\n\nexport default new GoogleTagManagerService();\n","export const NS_TOUCHWEB = 'touchWeb';\nexport const NS_ATTRIBUTES = 'attributes';\nexport const NS_CATEGORIES = 'categories';\nexport const NS_BACKEND = 'backend';\n\nexport const DEFAULT_LANGUAGE = 'sv';\nexport const URL_LANGUAGES = ['en', 'de', 'da'];\n\nexport const I18N_FRONTEND_NAMESPACES = [NS_TOUCHWEB, NS_ATTRIBUTES];\nexport const I18N_BACKEND_NAMESPACES = [NS_CATEGORIES, NS_BACKEND];\nexport const I18N_NAMESPACES = [\n ...I18N_FRONTEND_NAMESPACES,\n ...I18N_BACKEND_NAMESPACES\n];\nexport const NAMESPACE_PROJECTID = {\n [NS_TOUCHWEB]: '414441505e1db31fcaa776.55234720',\n [NS_ATTRIBUTES]: '9959867960be20fdc7d187.66761514',\n [NS_CATEGORIES]: '894792985d6665b8f079e1.31726015',\n [NS_BACKEND]: '916557165cc061c54ae7c8.44409330'\n};\n\nexport const SUPPORTED_LANGUAGES = [DEFAULT_LANGUAGE, ...URL_LANGUAGES];\nexport const SUPPORTED_CURRENCIES = [\n 'DKK',\n 'GBP',\n 'JPY',\n 'NOK',\n 'SEK',\n 'USD',\n 'EUR'\n];\n\nexport const TRANS_SUFFIX = 'Trans';\n\nexport const I18N_CACHE_MS = 60 * 60 * 1000;\n","/***\n *\n * Keep track of users' GDPR settings.\n *\n */\nimport dayjs from 'dayjs';\nimport cookie from 'cookie';\n\nimport {\n GDPR_CONSENT_COOKIE,\n COOKIE_CATEGORIES\n} from 'tradera-constants/cookies';\nimport { getCookieFromBrowser, setCookieToBrowser } from './cookie-helpers';\n\nconst createCookie = (name, value, expires) => {\n const options = {\n expires,\n httpOnly: false,\n path: '/'\n };\n return cookie.serialize(name, String(value), options);\n};\n\nexport class GdprSettings {\n constructor(getCookie, setCookie) {\n if (!getCookie || !setCookie) {\n throw new Error('You must provide getCookie and setCookie');\n }\n this.getCookie = getCookie;\n this.setCookie = setCookie;\n }\n /**\n *\n * @param {int} cookieCategory use the constant COOKIE_CATEGORIES to get different values.\n */\n isCategoryEnabled(cookieCategory) {\n if (cookieCategory === COOKIE_CATEGORIES.Essential) {\n return true;\n }\n\n const encodedConsentCookie = this.getCookie(GDPR_CONSENT_COOKIE);\n let consentCookie = decodeURI(encodedConsentCookie);\n\n if (!consentCookie || consentCookie.length === 0) {\n return true;\n }\n\n let categoryPattern = new RegExp(`,${cookieCategory}:1`);\n return categoryPattern.test(consentCookie);\n }\n\n isPerformanceEnabled() {\n return this.isCategoryEnabled(COOKIE_CATEGORIES.Performance);\n }\n\n isFunctionalEnabled() {\n return this.isCategoryEnabled(COOKIE_CATEGORIES.Functional);\n }\n\n isMarketingEnabled() {\n return this.isCategoryEnabled(COOKIE_CATEGORIES.Marketing);\n }\n\n set(performance, functional, marketing) {\n const cookieValue = [\n `${COOKIE_CATEGORIES.Essential}:1`,\n `${COOKIE_CATEGORIES.Performance}:${performance ? '1' : '0'}`,\n `${COOKIE_CATEGORIES.Functional}:${functional ? '1' : '0'}`,\n `${COOKIE_CATEGORIES.Marketing}:${marketing ? '1' : '0'}`\n ];\n const cookieString = createCookie(\n GDPR_CONSENT_COOKIE,\n cookieValue.join(','),\n dayjs()\n .add(1, 'years')\n .toDate()\n );\n this.setCookie(cookieString);\n }\n}\n\nexport default new GdprSettings(getCookieFromBrowser, setCookieToBrowser);\n","export const selectFeatureSwitches = state => state.environment.featureSwitches;\nexport const selectIsFeatureEnabled = featureName => state =>\n selectFeatureSwitches(state)?.[featureName] === true;\n\nexport const selectAppInfo = state => ({\n isHybridAppContextForAndroid:\n state.environment.isHybridAppContextForAndroid,\n isHybridAppContextForIos: state.environment.isHybridAppContextForIos,\n isHybridAppContext: state.environment.isHybridAppContext,\n isNativeAppContext: state.environment.isNativeAppContext,\n hybridAppVersion: state.environment.hybridAppVersion\n});\n\nexport const selectEnvVariables = state => state.environment.variables;\n\nexport const selectExperiments = state => state.environment.experiments;\n","/* eslint-disable better-mutation/no-mutation */\n\nimport i18n from 'i18next';\nimport { logger } from 'packages/logger';\nimport { initReactI18next } from 'react-i18next';\nimport LanguageDetector from 'i18next-browser-languagedetector';\nimport { toLocalizedUrl } from 'tradera-utils/url';\nimport { formatNumberWithSeparators } from 'tradera-utils/format';\nimport { missingKeyLoggingConfig } from 'tradera-lang/shared-config.mjs';\nimport {\n NS_TOUCHWEB,\n NS_ATTRIBUTES,\n DEFAULT_LANGUAGE\n} from 'tradera-lang/constants.mjs';\nimport 'dayjs/locale/sv';\nimport 'dayjs/locale/da';\nimport 'dayjs/locale/de';\nimport { isServer } from 'tradera-utils/nextjs';\n\nif (isServer) {\n // Do not remove this without also removing the disable of eslint better-mutation/no-mutation at top of file.\n throw new Error(\n 'This implementation is not compatible with SSR as global properties are shared between server instances'\n );\n}\n\nlet i18nInitialized;\n\n/**\n * Initialize function for i18next\n * Must be run before doing any translations\n * @param {Array} [translations]\n * @param {Object} [options]\n * @returns {Promise} - a promise to the i18next t function\n */\nexport const bootLanguages = (\n translations = window.touchwebTranslations,\n attributeTranslations = window.attributeTranslations\n) => {\n const translationResources = Object.entries(translations).map(\n ([key, value]) => ({\n key,\n value,\n namespace: 'touchWeb'\n })\n );\n const attributeResources = Object.entries(\n attributeTranslations\n ).map(([key, value]) => ({ key, value, namespace: 'attributes' }));\n\n const resources = translationResources\n .concat(attributeResources)\n .reduce((prev, { key, value, namespace }) => {\n const s = prev[key] || {};\n s[namespace] = value;\n return {\n ...prev,\n [key]: s\n };\n }, {});\n\n i18nInitialized = i18n\n .use(initReactI18next)\n .use(LanguageDetector)\n .init(initOptions(resources), err => {\n if (err) {\n logger('error when loading translations', err);\n }\n });\n\n return i18nInitialized;\n};\n\nexport const initOptions = resources => ({\n detection: {\n order: ['htmlTag'],\n htmlTag: document.html\n },\n defaultNS: [NS_TOUCHWEB],\n ns: [NS_ATTRIBUTES],\n fallbackLng: DEFAULT_LANGUAGE,\n resources,\n debug: false,\n keySeparator: false,\n nsSeparator: ':::',\n interpolation: {\n escape: str => str.replace(/{{/g, '').replace(/}}/g, ''),\n format: (value, format) => {\n if (format === 'formatNumber') {\n return formatNumberWithSeparators(value);\n }\n\n return value;\n }\n },\n react: {\n useSuspense: false // loading from file currently breaks if this is true\n },\n ...missingKeyLoggingConfig\n});\n\n/**\n * This function helps you make sure that i18next init has completed before continuing\n */\nexport const whenInitialized = () => {\n if (!i18nInitialized) {\n throw new Error(\n \"Can't call boot-languages whenInitialized before init!\"\n );\n }\n return i18nInitialized.then(t => ({\n t,\n toLocalizedUrl: url => toLocalizedUrl(url, i18n.language)\n }));\n};\n\n/**\n * Only required for Storybook, do not use.\n */\nexport const changeLanguage = language => i18n.changeLanguage(language);\n\nexport const getCurrentLanguage = () => i18n.language;\n","import * as Sentry from '@sentry/nextjs';\n\nexport const missingKeyLoggingConfig = {\n saveMissing: true,\n saveMissingTo: 'current',\n missingKeyHandler: (language, namespace, key) => {\n Sentry.captureException(\n new Error(\n `TranslationMissing (javascript) - Unable to find key ${key} (namespace ${namespace}) in language ${language}!`\n )\n );\n },\n missingInterpolationHandler: (text, value) => {\n Sentry.captureException(\n new Error(\n `InterpolationFailure (javascript) - Unable to interpolate the text \"${text}\" fully. The following placeholder values were missing: ${JSON.stringify(\n value\n )}`\n )\n );\n return undefined;\n }\n};\n","import * as Sentry from '@sentry/react';\n\n/**\n * @param {object} error - takes an exception and logs to Sentry or the console in development\n * @param {object} [scope] - Sentry CaptureContext created with new Sentry.Scope() or plain object\n * @desc logger is designed for logging errors. It will accept an argument of any type and create a stacktrace containing a reference to the callee.\n * @TODO Migrate this functionality to a logging module that handles different levels of logs\n */\nexport const logger = (error, scope) => {\n let sentryException;\n if (error instanceof Error) {\n sentryException = error;\n } else if (typeof error === 'string') {\n sentryException = new Error(error);\n } else {\n sentryException = new Error(JSON.stringify(error));\n }\n if (scope) {\n Sentry.captureException(sentryException, scope);\n } else {\n Sentry.captureException(sentryException);\n }\n};\n","import mapObject from 'underscore/modules/mapObject';\nimport isUndefined from 'underscore/modules/isUndefined';\n\nexport const nullifyUndefinedProperties = obj =>\n mapObject(obj, value => (isUndefined(value) ? null : value));\n","export const isServer = typeof window === 'undefined';\n\nexport const isTest = process.env.NODE_ENV === 'test';\n\nexport const isClientApiRequest = req =>\n Boolean(req?.url?.startsWith('/_next/data'));\n\nexport const isNextJs = isServer || document.getElementById('__next') !== null;\n","import { I18N_FRONTEND_NAMESPACES } from 'tradera-lang/constants.mjs';\n\nconst usedKeyPageTypes = new Map();\n\nconst createNamespaces = () =>\n new Map(I18N_FRONTEND_NAMESPACES.map(namespace => [namespace, new Set()]));\n\nconst getOrCreatePageTypeNamespaces = pageType => {\n if (!usedKeyPageTypes.has(pageType)) {\n usedKeyPageTypes.set(pageType, createNamespaces());\n }\n return usedKeyPageTypes.get(pageType);\n};\n\nexport const addKey = (pageType, namespace, key) => {\n const usedKeys = getOrCreatePageTypeNamespaces(pageType).get(namespace);\n if (!usedKeys.has(key)) {\n usedKeys.add(key);\n }\n};\n\nexport const getUsedKeys = pageType => getOrCreatePageTypeNamespaces(pageType);\n","export const selectPageType = state => state.page?.type;\n","import React, { useCallback, useRef } from 'react';\nimport { useTranslation, Trans as TransComponent } from 'react-i18next';\nimport { toLocalizedUrl } from 'tradera-utils/url';\nimport {\n NS_TOUCHWEB,\n I18N_FRONTEND_NAMESPACES,\n TRANS_SUFFIX\n} from './constants.mjs';\nimport { addKey } from 'tradera-backend/i18n/translation-keys.js';\nimport { isServer } from 'tradera-utils/nextjs.js';\nimport { useSelector } from 'react-redux';\nimport { selectPageType } from 'tradera-state/page/selectors';\n\n/**\n * i18next translation wrappers for translating static text in react components\n * When to use what?\n * -----\n * 1. For functional components use `useTranslator()` hook\n * 2. For class components use `withTranslator()` HOC\n */\n\n/**\n * Translation hook, wrapper for react-i18next\n * @return {{t: Function}}\n */\n\nexport const useTranslator = () => {\n const pathType = useSelector(selectPageType);\n const { t, ready } = useTranslation(I18N_FRONTEND_NAMESPACES, {\n wait: true\n });\n const wrappedT = useCallback(\n (...args) => {\n const i18nKey = args[0];\n if (i18nKey.endsWith(TRANS_SUFFIX)) {\n throw new Error(\n `t function keys should not have \"Trans\" suffix, got key \"${i18nKey}\". Use Trans component instead.`\n );\n }\n if (isServer) {\n const options = args[1];\n const namespace = options?.ns || NS_TOUCHWEB;\n addKey(pathType, namespace, i18nKey);\n }\n return t(...args);\n },\n [t, pathType]\n );\n return { t: ready ? wrappedT : () => '...' };\n};\n\n/**\n * Translation HOC, wrapper for react-i18next\n * @param {Component} WrappedComponent\n * @return {Component} The wrapped component.\n */\nexport function withTranslator(WrappedComponent) {\n function WithTranslator(props) {\n const { t } = useTranslator();\n return ;\n }\n\n WithTranslator.displayName = `withTranslator(${WrappedComponent.displayName ||\n WrappedComponent.name}`;\n return WithTranslator;\n}\n\n/**\n * Localization HOC, wrapper for URL-localizer\n * @param {Component} WrappedComponent\n */\nexport function withUrlLocalizer(WrappedComponent) {\n function WithUrlLocalizer(props) {\n const { toLocalizedUrl } = useUrlLocalizer();\n return ;\n }\n\n WithUrlLocalizer.displayName = `withUrlLocalizer(${WrappedComponent.displayName ||\n WrappedComponent.name}`;\n\n return WithUrlLocalizer;\n}\n\n/**\n * Current language hook, wrapper for react-i18next\n * @return {{language: string}}\n */\nexport const useCurrentLanguage = () => {\n const { i18n, ready } = useTranslation(undefined, { wait: true });\n return {\n language: ready ? i18n.language : null\n };\n};\n\n/**\n * Returns function to append language prefix to link\n * @return {{toLocalizedUrl: function}}\n */\nexport const useUrlLocalizer = () => {\n const { i18n, ready } = useTranslation(undefined, { wait: true });\n const urlLocalizer = useRef(url => toLocalizedUrl(url, i18n.language));\n return { toLocalizedUrl: ready ? urlLocalizer.current : url => url };\n};\n\nexport const Trans = props => {\n const { t, ready } = useTranslation(I18N_FRONTEND_NAMESPACES, {\n wait: true\n });\n const { i18nKey, children, defaults } = props;\n if (!i18nKey) {\n throw new Error('Trans component key must have a i18nKey property');\n }\n if (!i18nKey.endsWith(TRANS_SUFFIX)) {\n throw new Error(\n `Trans component key must have the \"Trans\" suffix, got key \"${i18nKey}\"`\n );\n }\n if (children) {\n throw new Error(\n `Trans component must not have children, use components or t('${i18nKey}') function instead`\n );\n }\n if (defaults) {\n throw new Error(\n 'Trans components must not have defaults, use lokalise instead.'\n );\n }\n if (!ready) {\n return '...';\n }\n return ;\n};\n","export const LIST_VIEW_TYPES = {\n BASIC: 'Basic',\n NORMAL: 'Normal',\n PICK_LIST: 'PickList'\n};\n\nexport const PAGE_LIST_TYPES = {\n BUYER_ACTIVE_ITEMS: 'BUYER_ACTIVE_ITEMS',\n BUYER_PURCHASES: 'BUYER_PURCHASES',\n BUYER_ITEMS_LOST: 'BUYER_ITEMS_LOST',\n SELLER_ACTIVE: 'SELLER_ACTIVE',\n SELLER_SOLD: 'SELLER_SOLD',\n SELLER_NOT_SOLD: 'SELLER_NOT_SOLD'\n};\n\nexport const PAGE_BULK_ACTIONS = {\n ACTIVE_CANCEL: 'ActiveItems_Cancel',\n UNSOLD_RESTART: 'UnsoldItems_Restart',\n BUYER_MARK_PAID: 'Buyer_MarkPaid',\n BUYER_SHOW_ACTIVE: 'ShowActive',\n BUYER_HIDE_ACTIVE: 'HideActive',\n PURCHASES_SHOW: 'PurchasesShow'\n};\n","import { selectShippingRegionCountryCodeIso2 } from 'tradera-state/shipping-region/selectors';\nimport { areCountryCodesIso2Equal } from 'tradera-localization/countrycode';\n\nexport const selectMember = state => state.member;\n\nexport const selectIsLoggedIn = state => state.member?.isLoggedIn;\n\nexport const selectGeolocation = state => state.member?.geolocation;\n\nexport const selectMemberId = state => state.member?.memberId;\n\nexport const selectMemberEmail = state => state.member?.memberEmail;\n\nexport const selectMemberFirstName = state => state.member?.memberFirstName;\n\nexport const selectMemberLastName = state => state.member?.memberLastName;\n\nexport const selectCurrencyCode = state => state.member?.currencyCode;\n\nexport const selectMemberCountryCodeIso2 = state =>\n state.member?.memberCountryCodeIso2;\n\nexport const selectIsOutsideSweden = state =>\n state.member?.geolocation?.isoCode &&\n state.member?.geolocation?.isoCode.toLowerCase() !== 'se';\n\nexport const showDanishFromCountry = state => {\n const fromCountry =\n selectShippingRegionCountryCodeIso2(state) ||\n selectMemberCountryCodeIso2(state);\n return areCountryCodesIso2Equal(fromCountry, 'DK');\n};\n\nexport const selectMemberTown = state => state.member?.memberTown;\n","import {\n CATEGORIZED_COOKIES,\n COOKIE_DEFAULT_CATEGORY\n} from 'tradera-constants/cookies';\nimport { GdprSettings } from 'tradera-utils/gdpr-settings';\nimport { logger } from 'packages/logger';\nimport { isServer } from 'tradera-utils/nextjs';\nimport { getCookieFromBrowser, setCookieToBrowser } from './cookie-helpers';\n\nexport class CookieUtil {\n constructor(getCookie, setCookie) {\n if (!getCookie || !setCookie) {\n throw new Error('You must provide getCookie and setCookie');\n }\n this.getCookie = getCookie;\n this.setCookie = setCookie;\n this.gdpr = new GdprSettings(getCookie, setCookie);\n }\n\n segment(name, value) {\n return value ? '; ' + name + '=' + value : '';\n }\n\n convertToExpiresStr(expires) {\n let expiresStr = '';\n\n switch (expires.constructor) {\n case Number:\n expiresStr =\n expires === Infinity\n ? '; expires=Fri, 31 Dec 9999 23:59:59 GMT'\n : '; max-age=' + expires * 24 * 60 * 60;\n break;\n case String:\n expiresStr = '; expires=' + expires;\n break;\n case Date:\n expiresStr = '; expires=' + expires.toUTCString();\n break;\n }\n\n return expiresStr;\n }\n\n createCookie(cookieKey, cookieValue, expires, path, domain, secure) {\n let expiresStr = '';\n\n if (\n !cookieKey ||\n /^(?:expires|max-age|path|domain|secure)$/i.test(cookieKey)\n ) {\n return false;\n }\n\n // check gdpr for cookie category\n let category = CATEGORIZED_COOKIES[cookieKey];\n if (typeof category === 'undefined') {\n logger(`No category set for cookie ${cookieKey}`);\n category = COOKIE_DEFAULT_CATEGORY;\n }\n if (!this.gdpr.isCategoryEnabled(category)) {\n // console.info(\n // `Cookie category not enabled: ${cookieKey}, category: ${category}`\n // );\n return false;\n }\n\n // if expired set prepare date string\n if (expires) {\n expiresStr = this.convertToExpiresStr(expires);\n }\n\n if (isServer) {\n throw new Error('Setting cookie is not supported on the server');\n }\n\n this.setCookie(\n encodeURIComponent(cookieKey) +\n '=' +\n encodeURIComponent(cookieValue) +\n expiresStr +\n this.segment('domain', domain) +\n this.segment('path', path || '/') +\n (location.protocol == 'https:' || secure ? '; secure' : '')\n );\n\n return true;\n }\n\n readCookie(key) {\n return this.getCookie(key);\n }\n\n hasCookie(key) {\n return typeof this.readCookie(key) === 'string';\n }\n\n eraseCookie(key, path, domain) {\n if (!key || !this.hasCookie(key)) {\n return false;\n }\n\n if (isServer) {\n throw new Error('Setting cookie is not supported on the server');\n }\n\n this.setCookie(\n encodeURIComponent(key) +\n '=; expires=Thu, 01 Jan 1970 00:00:01 GMT' +\n this.segment('domain', domain) +\n this.segment('path', path || '/')\n );\n\n return true;\n }\n}\n\nexport default new CookieUtil(getCookieFromBrowser, setCookieToBrowser);\n","export const selectCurrencies = state => state.multiCurrency.currencies;\n\nexport const selectPreferredCurrency = state =>\n state.multiCurrency.preferredCurrency ||\n state.multiCurrency.currencies.find(c => c.code === 'SEK');\n\nexport const selectIsPreferredCurrencySEK = state =>\n selectPreferredCurrency(state)?.code === 'SEK';\n\nexport const selectShowCurrencySelection = state =>\n !!(\n state.multiCurrency.enabled &&\n state.multiCurrency.preferredCurrency &&\n state.multiCurrency.currencies &&\n state.multiCurrency.currencies.length > 0\n );\n","import { useSelector } from 'react-redux';\nimport { isServer } from 'tradera-utils/nextjs';\n\nexport const useLocation = () => {\n const request = useSelector(state => state.request);\n const location = isServer ? request.location : window.location;\n return new URL(location);\n};\n","export const isSwedenCountryCodeOrUndefined = countryCodeIso2 =>\n countryCodeIso2 === undefined ||\n countryCodeIso2 === null ||\n countryCodeIso2.toLowerCase() === 'se';\n\nexport const isSwedenCountryNameOrUndefined = countryName =>\n countryName === undefined ||\n countryName === null ||\n countryName.toLowerCase() === 'sweden';\n\nexport const isDenmarkCountryCode = countryCodeIso2 =>\n !isSwedenCountryCodeOrUndefined(countryCodeIso2) &&\n countryCodeIso2.toLowerCase() === 'dk';\n\nexport const areCountryCodesIso2Equal = (first, second) =>\n (first || 'SE').toUpperCase() === (second || 'SE').toUpperCase();\n","export const parseAppVersion = version => {\n const [major = 0, minor = 0, patch = 0] = String(version)\n .split('.')\n .map(Number)\n .filter(number => !Number.isNaN(number));\n return { major, minor, patch };\n};\n\nexport const isSupportedMinimumVersion = (\n appVersionString,\n minimumVersionString\n) => {\n const appVersion = parseAppVersion(appVersionString);\n const minimumVersion = parseAppVersion(minimumVersionString);\n if (appVersion.major > minimumVersion.major) {\n return true;\n }\n if (appVersion.major === minimumVersion.major) {\n if (appVersion.minor > minimumVersion.minor) {\n return true;\n }\n if (appVersion.minor === minimumVersion.minor) {\n if (appVersion.patch >= minimumVersion.patch) {\n return true;\n }\n }\n }\n\n return false;\n};\n","import { isSupportedMinimumVersion } from 'tradera-utils/versions';\n\nexport const getNativeAppSupport = ({\n isNativeAppContext,\n isHybridAppContext,\n hybridAppDevice,\n hybridAppVersion,\n appOsVersion,\n isIOS,\n isAndroid\n}) => {\n const isHybridAppContextForAndroid = Boolean(\n isHybridAppContext &&\n (hybridAppDevice?.toLowerCase().includes('android') || isAndroid)\n );\n const isHybridAppContextForIos = Boolean(\n isHybridAppContext &&\n (hybridAppDevice?.toLowerCase().includes('iphone') ||\n hybridAppDevice?.toLowerCase().includes('ipad') ||\n isIOS)\n );\n const isIos13 =\n isNativeAppContext &&\n isHybridAppContextForIos &&\n isSupportedMinimumVersion(appOsVersion, '13');\n return {\n isHybridAppContextForAndroid,\n isHybridAppContextForIos,\n isNativeAppWithApplyPaySupport:\n isIos13 && isSupportedMinimumVersion(hybridAppVersion, '3.51'),\n isNativeAppWithSwishCallbackSupport:\n isIos13 && isSupportedMinimumVersion(hybridAppVersion, '3.57')\n };\n};\n","import {\n isAndroid,\n isMobile,\n isMobileSafari,\n isIOS,\n getSelectorsByUserAgent\n} from 'react-device-detect';\nimport { nullifyUndefinedProperties } from 'tradera-utils/object';\nimport { isServer } from 'tradera-utils/nextjs';\nimport { getNativeAppSupport } from './native-app-support';\n\nconst IPHONE_USER_AGENT =\n 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1';\n\nexport const getInitialServerState = ({\n environmentHash,\n experiments = [],\n featureToggles = {},\n splitTestGroups = {},\n variables = {},\n version,\n userAgent = IPHONE_USER_AGENT,\n appOsVersion = '',\n hybridAppDevice = '',\n hybridAppVersion = '',\n isNativeAppContext = false,\n isHybridAppContext = false\n} = {}) => {\n const {\n isMobile,\n isMobileSafari,\n isIOS,\n isAndroid\n } = getSelectorsByUserAgent(userAgent);\n\n return {\n ...getNativeAppSupport({\n isNativeAppContext,\n isHybridAppContext,\n hybridAppDevice,\n hybridAppVersion,\n appOsVersion,\n isIOS,\n isAndroid\n }),\n isNativeAppContext,\n hybridAppVersion,\n environment: process.env.NODE_ENV,\n experiments,\n isHybridAppContext,\n isIOS,\n isMobileDevice: isMobile,\n isMobileSafari,\n isSpaNavigationEnabled: true,\n featureSwitches: featureToggles,\n splitTestGroups,\n variables,\n environmentHash,\n version\n // TODO: Fetch values for below\n // splitTests,\n };\n};\n\nexport const initEnvironment = () => {\n return nullifyUndefinedProperties({});\n};\n\nexport default ({\n appOsVersion,\n environment,\n environmentHash,\n experiments,\n featureSwitches,\n geoPublicApiBaseUrl,\n hybridAppDevice,\n hybridAppVersion,\n isHybridAppContext,\n isNativeAppContext,\n isSinglePageApp,\n splitTests,\n splitTestGroups,\n version,\n webLiveUrl\n}) => {\n return nullifyUndefinedProperties({\n ...getNativeAppSupport({\n isNativeAppContext,\n isHybridAppContext,\n hybridAppDevice,\n hybridAppVersion,\n appOsVersion,\n isIOS,\n isAndroid\n }),\n environment,\n experiments,\n featureSwitches,\n environmentHash,\n isHybridAppContext,\n isIOS,\n isNativeAppContext,\n isMobileDevice: isMobile,\n isMobileSafari,\n isSpaNavigationEnabled:\n !isServer &&\n isSinglePageApp &&\n !isHybridAppContext &&\n !window.frameElement\n ? true\n : false, // No SPA navigation in native apps or iFrame\n splitTests,\n splitTestGroups,\n variables: {\n // Names must be the same as NextWeb's .env variables\n PUBLIC_GEO_PUBLIC_API_BASE_URL: geoPublicApiBaseUrl,\n PUBLIC_WEB_LIVE_URL: webLiveUrl\n },\n version\n });\n};\n","import { Buffer } from 'buffer';\nimport { isDev } from 'static/script/utils/environment';\n\nconst getCookieNameForEnvironment = name => (isDev() ? `${name}_test` : name);\n\nexport const AUTH_ACCESS_TOKEN_COOKIE_NAME = getCookieNameForEnvironment(\n 'trd_at'\n);\nexport const AUTH_REFRESH_TOKEN_COOKIE_NAME = getCookieNameForEnvironment(\n 'trd_rt'\n);\nexport const AUTH_PERSIST_COOKIE_NAME = getCookieNameForEnvironment('trd_rk');\n\nexport const mightBeLoggedIn = req =>\n Boolean(req.cookies[AUTH_REFRESH_TOKEN_COOKIE_NAME]);\n\nconst getJwtPayload = jwtToken => {\n const [, payload] = (jwtToken || '').split('.');\n if (!payload) {\n return {};\n }\n try {\n return JSON.parse(Buffer.from(payload, 'base64').toString());\n } catch (error) {\n return {};\n }\n};\n\nexport const isTokenExpiringSoon = token => {\n const { exp: expiry } = getJwtPayload(token);\n if (!expiry) {\n return true;\n }\n const now = new Date();\n const expiryDate = new Date(expiry);\n const expiresSoonDate = new Date(expiryDate.getTime() - 60 * 1000);\n const isExpired = expiresSoonDate <= now;\n return isExpired;\n};\n\nexport const addCookie = (res, cookie) => {\n const previouslySetCookies = res.getHeader('Set-Cookie');\n if (Array.isArray(previouslySetCookies)) {\n res.setHeader('Set-Cookie', [...previouslySetCookies, cookie]);\n } else if (previouslySetCookies) {\n res.setHeader('Set-Cookie', [previouslySetCookies, cookie]);\n } else {\n res.setHeader('Set-Cookie', cookie);\n }\n};\n","import cookie from 'cookie';\nimport { addCookie } from 'tradera-backend/utils/cookies';\nimport { NATIVE_APP_ENVIRONMENT } from 'tradera-constants/cookies';\n\nconst NATIVE_APP_COOKIE_AND_HEADER_CONFIG = {\n osVersion: {\n header: 'x-tradera-app-os-version',\n initDataName: 'nativeAppOsVersion'\n },\n appDevice: {\n header: 'x-tradera-app-device',\n initDataName: 'nativeAppDevice'\n },\n appVersion: {\n header: 'x-tradera-app-version',\n initDataName: 'nativeAppVersion'\n },\n appContext: { header: 'x-tradera-app', initDataName: 'nativeAppContext' },\n appLanguage: {\n header: 'x-language',\n initDataName: 'nativeAppLanguage'\n }\n};\n\nconst createCookie = (name, value) => {\n const options = {\n httpOnly: false,\n path: '/'\n };\n return cookie.serialize(name, String(value), options);\n};\n\nconst isString = s => typeof s === 'string';\n\nexport const createNativeAppCookieValue = nativeAppInfo => {\n const valueObject = Object.fromEntries(\n Object.entries(nativeAppInfo).filter(\n ([key, value]) =>\n key in NATIVE_APP_COOKIE_AND_HEADER_CONFIG && isString(value)\n )\n );\n return JSON.stringify(valueObject);\n};\n\nexport const createNativeAppCookie = nativeAppInfo => {\n return createCookie(\n NATIVE_APP_ENVIRONMENT,\n createNativeAppCookieValue(nativeAppInfo)\n );\n};\n\n/**\n * Gets info about the native app if in native app context.\n * The function also updates a cookie with the same information\n * to be used for later calls to this function if the headers are\n * not present.\n * \n * @param {*} req\n * @param {*} res\n * @returns An object with these properties: {\n osVersion,\n appDevice,\n appVersion,\n appContext\n }\n */\nexport const getAndUpdateNativeAppInfo = (req, res) => {\n const nativeAppInfoFromHeaders = extractNativeAppInfoFromHeaders(\n req.headers\n );\n\n const hasAppHeaders =\n Object.values(nativeAppInfoFromHeaders).filter(Boolean).length > 0;\n if (hasAppHeaders) {\n const cookie = createNativeAppCookie(nativeAppInfoFromHeaders);\n addCookie(res, cookie);\n return nativeAppInfoFromHeaders;\n }\n\n const nativeAppInfoFromCookie = extractNativeAppInfoFromCookie(\n req.cookies[NATIVE_APP_ENVIRONMENT]\n );\n return nativeAppInfoFromCookie;\n};\n\nexport const extractNativeAppInfoFromCookie = nativeAppCookieString =>\n nativeAppCookieString\n ? Object.fromEntries(\n Object.entries(\n JSON.parse(decodeURIComponent(nativeAppCookieString))\n ).filter(([key]) => key in NATIVE_APP_COOKIE_AND_HEADER_CONFIG)\n )\n : {};\nexport const extractNativeAppInfoFromHeaders = headers => {\n return Object.entries(NATIVE_APP_COOKIE_AND_HEADER_CONFIG).reduce(\n (obj, [key, config]) => {\n obj[key] = headers[config.header] || '';\n return obj;\n },\n {}\n );\n};\n\nexport const extractNativeAppInfoFromInitData = initData => {\n return Object.entries(NATIVE_APP_COOKIE_AND_HEADER_CONFIG).reduce(\n (obj, [key, config]) => {\n obj[key] = initData[config.initDataName] || '';\n return obj;\n },\n {}\n );\n};\n","import axios from 'axios';\nimport { selectPreferredLanguageCode } from 'tradera-state/language/selectors';\nimport { toLocalizedUrl } from 'tradera-utils/url';\nimport {\n initialize,\n setEnvironmentHash,\n setIsSpaNavigationEnabled\n} from './reducer';\nimport { isNextJs } from 'tradera-utils/nextjs';\nimport { selectMemberId } from 'tradera-state/member/selectors';\nimport getInitialState from './initial-state';\nimport {\n createNativeAppCookieValue,\n extractNativeAppInfoFromCookie,\n extractNativeAppInfoFromInitData\n} from './native-app-info-helper';\nimport cookie from 'tradera-utils/cookie';\nimport { NATIVE_APP_ENVIRONMENT } from 'tradera-constants/cookies';\n\nconst getVersionUrl = getState => {\n if (isNextJs) {\n const queryParameters = new URLSearchParams({ next: 1 });\n const memberId = selectMemberId(getState());\n if (memberId) {\n queryParameters.set('memberId', memberId);\n }\n return `/api/version?${queryParameters}`;\n }\n\n const preferredLanguageCode = selectPreferredLanguageCode(getState());\n\n return toLocalizedUrl('/ping', preferredLanguageCode);\n};\n\nexport const updateEnvironmentHash = () => async (dispatch, getState) => {\n const url = getVersionUrl(getState);\n const response = await axios.get(url);\n const environmentHash = response.headers['x-tradera-environment'];\n const current = getState().environment.environmentHash;\n if (environmentHash !== current) {\n dispatch(setEnvironmentHash(environmentHash));\n dispatch(setIsSpaNavigationEnabled(false));\n }\n};\n\nconst getAndUpdateNativeAppInfo = initData => {\n const nativeAppInfoFromInitData = extractNativeAppInfoFromInitData(\n initData\n );\n const hasAnyValidProperties =\n Object.values(nativeAppInfoFromInitData).filter(Boolean).length > 0;\n if (hasAnyValidProperties) {\n const nativeAppCookieValue = createNativeAppCookieValue(\n nativeAppInfoFromInitData\n );\n cookie.createCookie(NATIVE_APP_ENVIRONMENT, nativeAppCookieValue);\n return nativeAppInfoFromInitData;\n }\n\n const cookieValue = cookie.readCookie(NATIVE_APP_ENVIRONMENT);\n const nativeAppInfo = extractNativeAppInfoFromCookie(cookieValue);\n return nativeAppInfo;\n};\n\nexport const initEnvironment = initData => dispatch => {\n const {\n osVersion,\n appDevice,\n appVersion,\n appContext\n } = getAndUpdateNativeAppInfo(initData);\n const {\n environment,\n environmentHash,\n experiments = [],\n featureSwitches,\n geoPublicApiBaseUrl,\n isSinglePageApp,\n splitTests,\n splitTestGroups,\n version,\n webLiveUrl\n } = initData;\n const initialState = getInitialState({\n appOsVersion: osVersion,\n experiments,\n environment,\n environmentHash,\n featureSwitches,\n geoPublicApiBaseUrl,\n hybridAppDevice: appDevice,\n hybridAppVersion: appVersion,\n isNativeAppContext: appContext === 'Native',\n isHybridAppContext: Boolean(appContext),\n isSinglePageApp,\n splitTests,\n splitTestGroups,\n version,\n webLiveUrl\n });\n dispatch(initialize(initialState));\n};\n","/* eslint-disable better-mutation/no-mutation */\n\nimport { createSlice } from '@reduxjs/toolkit';\nexport const initialState = {\n featureSwitches: {},\n splitTestGroups: {},\n variables: {}\n};\n\nconst slice = createSlice({\n name: 'environment',\n initialState,\n reducers: {\n initialize: (_state, { payload }) => {\n return { ...payload };\n },\n setEnvironmentHash: (state, { payload }) => {\n state.environmentHash = payload;\n },\n setIsSpaNavigationEnabled: (state, { payload }) => {\n state.isSpaNavigationEnabled = payload;\n }\n }\n});\n\nexport const {\n initialize,\n setEnvironmentHash,\n setIsSpaNavigationEnabled\n} = slice.actions;\nexport const reducer = slice.reducer;\n","import axios from 'axios';\n\nimport { logger } from 'packages/logger';\nimport ENDPOINTS from 'tradera-constants/endpoints';\nimport { isServer } from 'tradera-utils/nextjs';\n\n/**\n * Standardized api error codes\n */\nconst API_ERRORS = {\n IGNORE_ME: 'IGNORE_ME',\n ABORTED: 'ABORTED',\n CANCELLED: 'CANCELLED',\n NETWORK: 'NETWORK',\n TIMEOUT: 'TIMEOUT',\n VERSION_MISMATCH: 'VERSION_MISMATCH',\n LOGGED_OUT: 'LOGGED_OUT'\n};\n\nconst defaultJsonRequestHeaders = {\n // Force json response\n Accept: 'application/json',\n // For WebAPI and RequiresAuthorization to handle ajax request\n 'X-Requested-With': 'XMLHttpRequest'\n};\n\n/**\n * Standard Axios configs\n */\nconst axiosConfigs = {\n // Requests to endpoints with authentication\n authenticated: {\n // Send auth cookies\n withCredentials: true,\n headers: defaultJsonRequestHeaders\n },\n notAuthenticated: {\n // Dont send auth cookies\n withCredentials: false,\n headers: defaultJsonRequestHeaders\n }\n};\n\nconst isMissingAuthToken = responseString => {\n try {\n const responseObject = JSON.parse(responseString);\n const isMissing =\n responseObject.responseStatus.errorCode === 'MissingAuthToken';\n return isMissing;\n } catch {\n return false;\n }\n};\n\nconst isUnauthorized = statusCode => statusCode === 401;\n\nconst addAntiCacheParam = url => {\n const antiCacheRegExp = /([?&]_=)[^&]*/;\n return antiCacheRegExp.test(url)\n ? url.replace(antiCacheRegExp, '$1' + new Date().getTime())\n : url + (/\\?/.test(url) ? '&' : '?') + '_=' + new Date().getTime();\n};\n\nconst submitOriginalRequest = async error =>\n axios({\n ...error.config,\n url: addAntiCacheParam(error.config.url)\n });\n\nconst handleMissingAuthToken = async error => {\n const refreshAccessToken = async () =>\n axios.get(ENDPOINTS.TOUCHWEB_URL + 'login/state');\n const handleErrorAfterRefresh = async errorAfterRefreshToken => {\n if (isUnauthorized(errorAfterRefreshToken.request?.status)) {\n // eslint-disable-next-line better-mutation/no-mutation\n error.message = API_ERRORS.LOGGED_OUT;\n }\n return Promise.reject(error);\n };\n return refreshAccessToken()\n .then(() => submitOriginalRequest(error))\n .catch(handleErrorAfterRefresh);\n};\n\nconst handleUnauthorized = async error => {\n const checkLoginState = async () =>\n axios.get(ENDPOINTS.TOUCHWEB_URL + 'login/state');\n return checkLoginState().then(response => {\n const isLoggedIn = response.data?.isLoggedIn;\n if (isLoggedIn) {\n return submitOriginalRequest(error);\n }\n // eslint-disable-next-line better-mutation/no-mutation\n error.message = API_ERRORS.LOGGED_OUT;\n // eslint-disable-next-line promise/no-return-wrap\n return Promise.reject(error);\n });\n};\n\nconst errorResponseInterceptor = error => {\n if (isMissingAuthToken(error.request?.response)) {\n return handleMissingAuthToken(error);\n } else if (isUnauthorized(error.request?.status)) {\n return handleUnauthorized(error);\n }\n return Promise.reject(error);\n};\n\n/**\n * Create Axios instance or decorate existing instance with interceptor for expired token responses\n *\n * @param {AxiosInstance} [axiosInstance]\n * @returns {AxiosInstance}\n */\nfunction axiosWithTokenRefresh(axiosInstance) {\n let instance;\n if (axiosInstance === undefined) {\n instance = axios.create();\n } else {\n instance = axiosInstance;\n }\n instance.interceptors.response.use(\n response => response,\n errorResponseInterceptor\n );\n return instance;\n}\n\nconst cancelTokens = {};\n\n/**\n * Create new or return existing cancellation function\n *\n * Usage:\n * const { cancel, cancelToken } = utilizeCancelToken('tokenId')\n * if (cancel) cancel();\n * axios.get('http://api.com/...', { cancelToken });\n *\n * @param {string} tokenId - A string ID shared between requests that cancel together\n * @returns {{ cancel: function, cancelToken: function }}\n */\nfunction utilizeCancelToken(tokenId) {\n if (isServer) {\n throw new Error(\n 'This implementation is not compatible with SSR as global properties like cancelTokens here are shared between server instances'\n );\n }\n let cancel;\n if (tokenId in cancelTokens) {\n cancel = cancelTokens[tokenId].cancel;\n }\n // eslint-disable-next-line better-mutation/no-mutation\n cancelTokens[tokenId] = axios.CancelToken.source();\n return {\n cancel,\n cancelToken: cancelTokens[tokenId].token\n };\n}\n\n/**\n * Check response version and throw error if different from current\n *\n * @param {string} version\n * @return {function(*): object|void}\n */\nfunction checkResponseVersion(version = '12.0.0') {\n return response => {\n if (\n response.headers &&\n response.headers['X-Tradera-Version'] &&\n response.headers['X-Tradera-Version'] !== version\n ) {\n throw new Error(API_ERRORS.VERSION_MISMATCH);\n } else {\n return response;\n }\n };\n}\n\n/**\n * Checks redirect response for logged out user\n * This is an old solution. New solutions return a 401 response instead (see handleError).\n * Requires Axios config to include { withCredentials: true }\n *\n * @returns {Function}\n */\nfunction checkResponseLoggedOut() {\n return response => {\n if (\n response.data &&\n typeof response.data === 'string' &&\n response.data.includes('Logga in')\n ) {\n throw new Error(API_ERRORS.LOGGED_OUT);\n } else {\n return response;\n }\n };\n}\n\n/**\n * Final standardized formatting of an api response\n *\n * @returns { function(*): { data: *, status: integer }}\n */\nfunction finalizeResponse() {\n return response => {\n const { data, status } = response;\n return {\n data,\n status\n };\n };\n}\n\n/**\n * Common network request error handling\n *\n * @param {Object.} statusHandlers - { code: message }\n * @returns {function(*=): Promise}\n */\nfunction handleError(statusHandlers = {}) {\n return error => {\n let status = error.response && error.response.status;\n let message = error.message ? error.message : error.toString();\n /* eslint-disable better-mutation/no-mutation */\n if (axios.isCancel(error)) {\n error.message = API_ERRORS.CANCELLED;\n } else if (message.includes('timeout') || status === 408) {\n error.message = API_ERRORS.TIMEOUT;\n } else if (message.includes('Network')) {\n error.message = API_ERRORS.NETWORK;\n } else if (message.includes('Request aborted')) {\n error.message = API_ERRORS.ABORTED;\n } else if (status === 401) {\n error.message = API_ERRORS.LOGGED_OUT;\n } else if (status in statusHandlers) {\n error.message = statusHandlers[status];\n }\n /* eslint-enable better-mutation/no-mutation */\n throw error;\n };\n}\n\nfunction reloadOnUnauthorized(error) {\n switch (error.message) {\n case API_ERRORS.LOGGED_OUT:\n window.location.reload();\n break;\n default:\n throw error;\n }\n}\n\nfunction logError(error, scope) {\n switch (error.message) {\n case API_ERRORS.IGNORE_ME:\n case API_ERRORS.CANCELLED:\n case API_ERRORS.NETWORK:\n case API_ERRORS.TIMEOUT:\n break;\n default:\n logger(error, scope);\n break;\n }\n}\n\nexport {\n addAntiCacheParam,\n API_ERRORS,\n axiosConfigs,\n axiosWithTokenRefresh,\n checkResponseVersion,\n checkResponseLoggedOut,\n defaultJsonRequestHeaders,\n errorResponseInterceptor,\n finalizeResponse,\n handleError,\n logError,\n reloadOnUnauthorized,\n utilizeCancelToken\n};\n","export default {\n TRADERA: 'https://www.tradera.com'\n};\n","import qs from 'qs';\nimport HOSTS from 'tradera-constants/hosts';\nimport initData from 'init-data';\nimport { logger } from 'packages/logger';\nimport { URL_LANGUAGES } from 'tradera-lang/constants.mjs';\n\n// List of SPA paths for the regex match, without initial slash\nconst SPA_REGEX_PATHS = [\n 'search',\n 'campaign',\n 'charity',\n 'kategorier',\n 'profile\\\\/items',\n 'brand\\\\/.+',\n // Category\n '[a-z]+[\\\\w\\\\-]+[\\\\-|_]\\\\d+'\n];\nconst SPA_PATH_REGEX = new RegExp(\n `^(\\\\/en|\\\\/da|\\\\/de)?/(${SPA_REGEX_PATHS.join('|')})`\n);\n\n/**\n * Returns language parameter from url\n * @param {*} url\n */\nconst getLanguagePrefixFromUrl = url => {\n const matches = url.match(/\\/([a-z][a-z])((\\/.*$)|$)/);\n\n if (matches === null) {\n return null;\n }\n\n const firstMatch = matches.find((match, index) => index > 0 && match);\n\n if (URL_LANGUAGES.indexOf(firstMatch) !== -1) {\n return firstMatch;\n }\n\n return null;\n};\n\n/**\n * Format query params parsed from query string\n *\n * @param {object} queryParams\n * @returns {object}\n */\nconst formatQueryParams = queryParams => {\n const { categoryId, ...rest } = queryParams;\n const formattedQueryParams = rest;\n if (categoryId !== undefined) {\n formattedQueryParams.categoryId = parseInt(categoryId, 10);\n }\n return formattedQueryParams;\n};\n\n/**\n * Check if url is absolute\n *\n * @param {string} url\n * @returns {boolean}\n */\nconst isAbsoluteUrl = url => new RegExp('^(?:[a-z]+:)?//', 'i').test(url);\n\n/**\n * Tests if a given url or path is an SPA link or not\n *\n * @param {string} urlOrPath\n * @returns {boolean}\n */\nfunction isSpaLink(urlOrPath) {\n let pathname;\n if (/(^http)s?:\\/\\//i.test(urlOrPath)) {\n try {\n pathname = new URL(urlOrPath).pathname;\n } catch {\n return false;\n }\n } else {\n pathname = urlOrPath;\n }\n return SPA_PATH_REGEX.test(pathname);\n}\n\n/**\n * Takes an object and returns a new object without attribute properties\n * @param {object} queryParams\n * @returns {object}\n */\nconst stripAttributesFromQueryParameters = queryParams => {\n // Using object spread to exclude listed variables from 'rest'\n const { attributes, ...rest } = queryParams;\n return rest;\n};\n\n/**\n * Takes an object and returns a new object without pagination properties\n * @param {object} queryParams\n * @returns {object}\n */\nconst stripCategoryIdFromQueryParameters = queryParams => {\n // Using object spread to exclude listed variables from 'rest'\n const { categoryId, ...rest } = queryParams;\n return rest;\n};\n\n/**\n * Removes tradera base from a url, leaving path and query\n *\n * @param {string} url\n * @returns {string}\n */\nconst stripHost = url =>\n url.startsWith('http') ? url.replace(HOSTS.TRADERA, '') : url;\n\n/**\n * Takes an object and returns a new object without itm properties\n * Itm tags should no longer be used, so this method will then be obsolete\n * @param {object} queryParams\n * @returns {object}\n */\nconst stripItmFromQueryParameters = queryParams => {\n // Using object spread to exclude listed variables from 'rest'\n const { itm_source, itm_medium, ...rest } = queryParams;\n return rest;\n};\n\n/**\n * Takes an object and returns a new object without pagination properties\n * @param {object} queryParams\n * @returns {object}\n */\nconst stripPaginationFromQueryParameters = queryParams => {\n // Using object spread to exclude listed variables from 'rest'\n const { spage, paging, page, fe, ...rest } = queryParams;\n return rest;\n};\n\n/**\n * Takes an object and returns a new object without savedQueryName properties\n * @param {object} queryParams\n * @returns {object}\n */\nconst stripSavedQueryNameFromQueryParameters = queryParams => {\n // Using object spread to exclude listed variables from 'rest'\n const { savedQueryName, ...rest } = queryParams;\n return rest;\n};\n\n/**\n * Takes an url and adds tradera base url if it is not already an absolute url\n *\n * @param {string} relativeUrl\n * @returns {string}\n */\nconst toAbsoluteUrl = relativeUrl =>\n relativeUrl.startsWith('http')\n ? relativeUrl\n : `${HOSTS.TRADERA}${\n relativeUrl.startsWith('/') ? relativeUrl : '/' + relativeUrl\n }`;\n\n/**\n * From react router location object to absolute url string\n * @param {{pathname: string, search: string}} url\n * @returns {string}\n */\nconst toAbsoluteUrlFromObject = url =>\n toAbsoluteUrl(\n `${url.pathname ? url.pathname : ''}${url.search ? url.search : ''}`\n );\n\n/**\n * From URL to URL with language prefix\n * @param {*} url\n * @param {*} languageCodeIso2\n */\nconst toLocalizedUrl = (url, languageCodeIso2) => {\n if (url === null || url === undefined || url === '' || url === false) {\n return url;\n }\n\n const ignoredUrls = [initData.webApiUrl, '/api/webapi/'];\n const isIgnoredUrl = ignoredUrls.find(domain => url.indexOf(domain) !== -1);\n if (isIgnoredUrl) {\n return url;\n }\n\n if (!languageCodeIso2) {\n logger(`Missing language code for URL ${url}`);\n return url;\n }\n\n const isAbsolute = isAbsoluteUrl(url);\n\n const urlObject = isAbsolute\n ? new URL(url)\n : new URL(url, 'http://dummy.com');\n const origin = isAbsolute ? urlObject.origin : '';\n const localisedPathname = setLanguagePrefix(\n urlObject.pathname,\n languageCodeIso2\n );\n\n return `${origin}${localisedPathname}${urlObject.search}`;\n};\n\n/**\n * Creates query parameters object from search string\n * @param {string} search\n */\nconst toQueryParameters = search =>\n qs.parse(search, { ignoreQueryPrefix: true });\n\n/**\n * Removes the Tradera host from a url, making it relative\n * @param {string} url\n * @returns {string}\n */\nconst toRelativeTraderaUrl = url => {\n if (url.startsWith(HOSTS.TRADERA)) {\n return url.replace(HOSTS.TRADERA, '');\n } else {\n return url;\n }\n};\n\n/**\n * Creates search string from all properties in object\n * @param {object} queryParams\n * @param {{[addQueryPrefix]: bool, [encode]: bool, [skipNulls]: bool }}\n * @returns {string}\n */\nconst toSearchString = (\n queryParams,\n {\n addQueryPrefix = true,\n encode = true,\n skipNulls = true,\n arrayFormat = 'repeat' //qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' }) ==> 'a=b&a=c'\n } = {}\n) =>\n qs.stringify(queryParams, {\n addQueryPrefix: addQueryPrefix,\n encode: encode,\n skipNulls: skipNulls,\n arrayFormat: arrayFormat\n });\n\nconst setLanguagePrefix = (path, languageCodeIso2) => {\n const languagePrefix = getLanguagePrefixFromUrl(path);\n const defaultLanguage = 'sv';\n\n if (languagePrefix) {\n if (languageCodeIso2 === defaultLanguage) {\n return path.replace(`/${languagePrefix}`, '');\n } else {\n return path.replace(languagePrefix, languageCodeIso2);\n }\n } else {\n if (languageCodeIso2 === defaultLanguage) {\n return path;\n } else {\n return `/${languageCodeIso2}${path}`;\n }\n }\n};\n\nconst getBackToHereRedirectUrl = () => {\n // Add random query parameter to force reload when redirecting to this url\n // and only the hash differs\n const queryParams = {\n ...qs.parse(location.search, { ignoreQueryPrefix: true }),\n forceRedirect: Math.round(Math.random() * 100000)\n };\n return (\n location.protocol +\n '//' +\n location.host +\n location.pathname +\n qs.stringify(queryParams, { addQueryPrefix: true })\n );\n};\n\nexport {\n getLanguagePrefixFromUrl,\n formatQueryParams,\n getBackToHereRedirectUrl,\n isAbsoluteUrl,\n isSpaLink,\n stripAttributesFromQueryParameters,\n stripCategoryIdFromQueryParameters,\n stripHost,\n stripItmFromQueryParameters,\n stripPaginationFromQueryParameters,\n stripSavedQueryNameFromQueryParameters,\n toAbsoluteUrl,\n toAbsoluteUrlFromObject,\n toLocalizedUrl,\n toQueryParameters,\n toRelativeTraderaUrl,\n toSearchString\n};\n","import PropTypes from 'prop-types';\n\nexport const relativeOrAbsoluteUrlString = (props, propName) => {\n const prop = props[propName];\n if (typeof prop !== 'string') {\n return new TypeError('URL must be a string');\n }\n try {\n const origin = 'https://example.com';\n const url = new URL(props[propName], origin);\n\n if (!['http:', 'https:'].includes(url.protocol)) {\n return new URIError('URL protocol must be http: or https:');\n }\n } catch (error) {\n return error;\n }\n};\n\nexport default {\n ...PropTypes,\n relativeOrAbsoluteUrlString\n};\n","import React, { useCallback } from 'react';\nimport PropTypes from 'tradera-utils/prop-types';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { Link } from 'react-router-dom';\nimport NextLink from 'next/link';\nimport { updateEnvironmentHash } from 'tradera-state/environment/actions';\nimport { useIsFeatureEnabled } from 'tradera-hooks/use-is-feature-enabled';\nimport { useLocation } from 'tradera-hooks/use-location';\nimport { isNextJs } from 'tradera-utils/nextjs';\nimport { URL_LANGUAGES } from 'tradera-lang/constants.mjs';\n\nconst PRODUCTION_ORIGIN = 'https://www.tradera.com';\nconst NEXTWEB_PATHS = ['/how-to-buy', '/how-to-sell'];\n\nconst vipPathRegex = new RegExp(\n `(/(${URL_LANGUAGES.join('|')}))?/item/[0-9]+/([0-9]+)/`\n);\nconst isVipLink = pathname => vipPathRegex.test(pathname);\n\nconst isLinkToNextWebPage = (url, isNextWebLink) =>\n isNextWebLink ||\n url.searchParams.get('next') === '1' ||\n NEXTWEB_PATHS.some(nextwebPath => url.pathname.endsWith(nextwebPath));\n\nconst getRelativeUrl = url => `${url.pathname}${url.search}`;\n\nconst useNextWebSpaLink = absoluteUrl => {\n const nextWebVip10Percent = useIsFeatureEnabled('next-web-vip-10-percent');\n const nextWebVip30Percent = useIsFeatureEnabled('next-web-vip-30-percent');\n const nextWebVip100Percent = useIsFeatureEnabled(\n 'next-web-vip-100-percent'\n );\n if (isVipLink(absoluteUrl?.pathname)) {\n if (nextWebVip100Percent) {\n return true;\n }\n const itemId = absoluteUrl.pathname.match(vipPathRegex)?.[3] || '';\n const lastItemIdDigit = itemId.slice(-1);\n if (nextWebVip30Percent && ['1', '2', '3'].includes(lastItemIdDigit)) {\n return true;\n }\n if (nextWebVip10Percent && lastItemIdDigit === '1') {\n return true;\n }\n }\n if (isLinkToNextWebPage(absoluteUrl)) {\n return true;\n }\n\n return false;\n};\n\nconst ALink = ({\n useLink: isTouchwebSpaLink,\n href,\n children,\n onClick: givenOnClick,\n ...otherProps\n}) => {\n const dispatch = useDispatch();\n const location = useLocation();\n const isSpaNavigationEnabled = useSelector(\n state => state.environment.isSpaNavigationEnabled\n );\n const isNextWebAddUrlParamEnabled = useIsFeatureEnabled(\n 'next-web-add-url-param'\n );\n const absoluteUrl = new URL(href, PRODUCTION_ORIGIN);\n const isNextWebSpaLink = useNextWebSpaLink(absoluteUrl);\n const handleSpaNavigationClick = useCallback(\n evt => {\n dispatch(updateEnvironmentHash());\n if (givenOnClick) givenOnClick(evt);\n },\n [dispatch, givenOnClick]\n );\n\n const spaNavigationOrigins = [PRODUCTION_ORIGIN, location?.origin];\n const isRelativeUrl = spaNavigationOrigins.includes(absoluteUrl.origin);\n\n if (isNextWebAddUrlParamEnabled) {\n absoluteUrl.searchParams.set('next', '1');\n }\n\n // Strip away origin for SPA links\n const relativeUrl = getRelativeUrl(absoluteUrl);\n\n if (isSpaNavigationEnabled && isRelativeUrl) {\n if (isNextJs && isNextWebSpaLink) {\n // NextJS routing\n return (\n \n e.stopPropagation()}>\n {children}\n \n \n );\n } else if (!isNextJs && !isNextWebSpaLink && isTouchwebSpaLink) {\n // react-router-dom\n return (\n \n {children}\n \n );\n }\n }\n\n const url = isRelativeUrl ? relativeUrl : absoluteUrl.toString();\n return (\n \n {children}\n \n );\n};\n\nALink.propTypes = {\n useLink: PropTypes.bool,\n href: PropTypes.relativeOrAbsoluteUrlString,\n children: PropTypes.node.isRequired,\n onClick: PropTypes.func\n};\n\nALink.defaultProps = {\n useLink: false,\n onClick: null\n};\n\nexport default ALink;\n","import { useSelector } from 'react-redux';\nimport { selectIsFeatureEnabled } from 'tradera-state/environment/selectors';\n\nexport const useIsFeatureEnabled = featureName =>\n useSelector(selectIsFeatureEnabled(featureName));\n","import { toLocalizedUrl } from 'tradera-utils/url';\nimport { isServer } from 'tradera-utils/nextjs';\n\nexport const toLocalizedRiotUrl = url => toLocalizedUrl(url, getLanguage());\n\nlet language;\nexport const getLanguage = () => {\n if (isServer) {\n return;\n }\n if (language === '' || language === null || language === undefined) {\n // If we did this on the server in NextWeb all requests to the\n // same server would get the same language. This code is only\n // OK to run in the browser.\n // eslint-disable-next-line better-mutation/no-mutation\n language = document.querySelector('html').getAttribute('lang');\n }\n\n return language;\n};\n","import { isDev } from 'static/script/utils/environment';\n\nexport const buildInitialGtmDataLayerFromInitData = initData => {\n // ***** ATTENTION !!! *****\n // If you change anything here you must\n // also change in buildInitialGtmDataLayerFromState\n // so that they match. Otherwise values\n // between Touchweb and NextWeb don't match.\n const initialDataLayer = {\n memberId: initData.memberId || 0,\n userLanguage: initData.languageCodeIso2,\n memberEmail: initData.isLoggedIn ? initData.memberEmail : '',\n memberHashedEmail: initData.isLoggedIn\n ? initData.memberEmailSha256\n : '',\n 'criteo.hashedEmail': initData.isLoggedIn\n ? initData.memberEmailMd5\n : '',\n memberFirstName: initData.isLoggedIn ? initData.memberFirstName : '',\n memberLastName: initData.isLoggedIn ? initData.memberLastName : '',\n memberCountry: initData.isLoggedIn ? initData.memberCountry : '',\n loginState: initData.isLoggedIn ? 'logged in' : 'not logged in',\n isNotInIframe: window.self === window.top,\n 'blueshift.event-api-key': initData.blueshiftEventApiKey,\n isSinglePageApp: initData.isSinglePageApp,\n isNativeAppContext: initData.isNativeAppContext,\n isQuantcastConsentEnabled:\n initData.featureSwitches['quantcast-consent'],\n isTikTokPixelEnabled: initData.featureSwitches['tiktok-pixel'],\n isDigitalAudienceTrackingEnabled:\n initData.featureSwitches['digital-audience-tracking'],\n quantcastSite: initData.quantcastSite\n };\n // add split tests to datalayer\n if (initData.splitTestGroups) {\n for (let [key, value] of Object.entries(initData.splitTestGroups)) {\n initialDataLayer[`splittest_${key}`] = value;\n }\n }\n return initialDataLayer;\n};\n\nexport const buildInitialGtmDataLayerFromState = state => {\n const quantcastSite = isDev() ? 'beta.tradera.com' : 'www.tradera.com';\n const { environment, language, member } = state;\n const { featureSwitches } = environment;\n const isQuantcastConsentEnabled = featureSwitches['quantcast-consent'];\n const isTikTokPixelEnabled = featureSwitches['tiktok-pixel'];\n const isDigitalAudienceTrackingEnabled =\n featureSwitches['digital-audience-tracking'];\n const splitTestGroups = Object.entries(environment.splitTestGroups).reduce(\n (groups, [key, value]) => {\n return {\n ...groups,\n [`splittest_${key}`]: value\n };\n },\n {}\n );\n // ***** ATTENTION !!! *****\n // If you change anything here you must\n // also change in buildInitialGtmDataLayerFromInitData\n // so that they match. Otherwise values\n // between Touchweb and NextWeb don't match.\n return {\n memberId: member.memberId || 0,\n userLanguage: language.preferred.languageCodeIso2,\n memberEmail: member.memberEmail || '',\n memberHashedEmail: member.memberEmailSha256 || '',\n 'criteo.hashedEmail': member.memberEmailMd5 || '',\n memberFirstName: member.memberFirstName || '',\n memberLastName: member.memberLastName || '',\n memberCountry: member.memberCountry || '',\n loginState: member.isLoggedIn ? 'logged in' : 'not logged in',\n isNotInIframe: window.self === window.top,\n 'blueshift.event-api-key':\n process.env.NEXT_PUBLIC_BLUESHIFT_EVENT_API_KEY,\n isSinglePageApp: true,\n isNativeAppContext: environment.isNativeAppContext,\n isQuantcastConsentEnabled,\n isDigitalAudienceTrackingEnabled,\n isTikTokPixelEnabled,\n quantcastSite,\n ...splitTestGroups\n };\n};\n","import { swedishTimeZoneDate } from 'tradera-utils/date';\n\nexport const formatEndDate = (endDateInput, t, nowDateInput, dayjs) => {\n if (!endDateInput || !nowDateInput) return '';\n\n const endDate = swedishTimeZoneDate(endDateInput, dayjs);\n const now = swedishTimeZoneDate(nowDateInput, dayjs);\n if (endDate.isSameOrAfter(now.add(1, 'week'), 'day')) {\n return endDate.format('D MMM HH:mm');\n }\n if (endDate.isSameOrAfter(now.add(2, 'day'), 'day')) {\n return endDate.format('ddd HH:mm');\n }\n if (endDate.isSameOrAfter(now.add(1, 'day'))) {\n return `${t('vip_tomorrow')} ${endDate.format('HH:mm')}`;\n }\n if (endDate.isSameOrAfter(now.add(1, 'minute'))) {\n const hours = endDate.diff(now, 'hour');\n const minutes = endDate.diff(now, 'minute') % 60;\n const timeParts = [];\n if (hours > 0) {\n timeParts.push(t('vip_hours', { count: hours }));\n }\n if (minutes > 0) {\n timeParts.push(t('vip_minutes', { count: minutes }));\n }\n return timeParts.join(' ');\n }\n if (endDate.isAfter(now)) {\n return t('vip_less_than_1_min_left');\n }\n return t('vip_ended');\n};\n\nexport const formatNumberWithSeparators = (number, separator = '\\u2006') => {\n return number\n .toString()\n .replace(/(\\d)(?=(\\d{3})+(?!\\d))/g, '$1' + separator);\n};\n\n// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString\nfunction toLocaleStringSupportsLocales() {\n try {\n Number(0).toLocaleString('i');\n } catch (e) {\n return e.name === 'RangeError';\n }\n return false;\n}\n\n// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString\nfunction toLocaleStringSupportsOptions() {\n return !!(\n typeof Intl === 'object' &&\n Intl &&\n typeof Intl.NumberFormat === 'function'\n );\n}\n\nconst isLocaleFormattingSupportedInBrowser =\n toLocaleStringSupportsLocales() && toLocaleStringSupportsOptions();\n\nexport const formatSellerDsrAverage = (value, locale = 'sv-SE') => {\n return value?.toLocaleString(locale, {\n minimumFractionDigits: 1,\n maximumFractionDigits: 1\n });\n};\n\nexport const formatPrice = (price, locale = 'sv-SE', overrideOptions = {}) => {\n const defaultOptions = {\n style: 'currency',\n currency: 'SEK',\n currencyDisplay:\n locale.startsWith('sv') &&\n (overrideOptions.currency || 'SEK') === 'SEK'\n ? 'symbol'\n : 'code',\n useGrouping: false,\n minimumFractionDigits: 0,\n maximumFractionDigits: 2\n };\n const options = {\n ...defaultOptions,\n ...overrideOptions\n };\n const priceAsNumber = typeof price !== 'number' ? parseInt(price) : price;\n\n if (!isLocaleFormattingSupportedInBrowser) {\n const suffix =\n options.currencyDisplay === 'code' && options.currency === 'SEK'\n ? 'kr'\n : options.currency;\n return `${priceAsNumber} ${suffix}`;\n }\n\n const formattedPrice = priceAsNumber.toLocaleString(locale, options);\n return formatNumberWithSeparators(formattedPrice);\n};\n\nexport const getCurrencySymbol = (locale = 'sv-SE', overrideOptions = {}) => {\n const defaultOptions = {\n style: 'currency',\n currency: 'SEK',\n currencyDisplay:\n locale.startsWith('sv') &&\n (overrideOptions.currency || 'SEK') === 'SEK'\n ? 'symbol'\n : 'code',\n useGrouping: false,\n minimumFractionDigits: 0,\n maximumFractionDigits: 0\n };\n return (0)\n .toLocaleString(locale, {\n ...defaultOptions,\n ...overrideOptions\n })\n .replace(/\\d/g, '')\n .trim();\n};\n\nexport const formatDateWithDayOfWeek = (dateString, locale) => {\n if (!isLocaleFormattingSupportedInBrowser) {\n return dateString;\n }\n\n const options = {\n weekday: 'long',\n year: undefined,\n month: 'long',\n day: 'numeric'\n };\n return new Intl.DateTimeFormat(locale, options).format(\n Date.parse(dateString)\n );\n};\n","import plainDayjs from 'dayjs';\nimport isBetween from 'dayjs/plugin/isBetween';\nimport isSameOrAfter from 'dayjs/plugin/isSameOrAfter';\nimport utc from 'dayjs/plugin/utc';\nimport timezone from 'dayjs/plugin/timezone';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\nimport 'dayjs/locale/sv';\nimport 'dayjs/locale/da';\nimport 'dayjs/locale/de';\n\nplainDayjs.extend(isBetween);\nplainDayjs.extend(isSameOrAfter);\nplainDayjs.extend(utc);\nplainDayjs.extend(timezone);\nplainDayjs.extend(localizedFormat);\n\nexport const dayjs = plainDayjs;\n\nexport const localizedDayjs = locale => (...args) =>\n dayjs(...args).locale(locale);\n\nexport const swedishTimeZoneDate = (date, localizedDayjsFn) => {\n // This is a workaround for locale being lost when using .tz() in Nextweb\n const locale = localizedDayjsFn().locale();\n return localizedDayjsFn(date)\n .tz('Europe/Stockholm')\n .locale(locale);\n};\n\nexport const formatUtcDateAsSwedishTimeZoneDate = (date, localizedDayjsFn) =>\n swedishTimeZoneDate(date, localizedDayjsFn).format('D MMM HH:mm');\n\n/**\n * Format a number of seconds to an object of time units\n *\n * @param {number} seconds\n * @param {object} [options]\n * @param {string} [options.startUnit] - Time part to start counting from, empty for all parts\n * @param {string} [options.endUnit] - Time part to stop counting on, empty for all parts\n * @returns {{string: integer}}\n */\nexport const getTimeSpanParts = (seconds, options = {}) => {\n const optionsWithDefaults = {\n startUnit: '',\n endUnit: '',\n ...options\n };\n const parts = {};\n let remaining = seconds;\n let started = !optionsWithDefaults.startUnit;\n for (const [part, length] of Object.entries(TIME_SPAN_UNIT_LENGTHS)) {\n if (!started && part === optionsWithDefaults.startUnit) started = true;\n if (started) {\n if (remaining >= length) {\n parts[part] = Math.floor(remaining / length);\n }\n // eslint-disable-next-line better-mutation/no-mutation\n remaining %= length;\n if (remaining === 0 || optionsWithDefaults.endUnit === part) break;\n }\n }\n return parts;\n};\n\nexport const TIME_SPAN_UNITS = {\n DAYS: 'days',\n HOURS: 'hours',\n MINUTES: 'minutes',\n SECONDS: 'seconds'\n};\n\nconst TIME_SPAN_UNIT_LENGTHS = {\n [TIME_SPAN_UNITS.DAYS]: 24 * 60 * 60,\n [TIME_SPAN_UNITS.HOURS]: 60 * 60,\n [TIME_SPAN_UNITS.MINUTES]: 60,\n [TIME_SPAN_UNITS.SECONDS]: 1\n};\n","import cookie from 'cookie';\n\nexport const getCookieFromString = (cookieString, key) =>\n cookie.parse(cookieString)[key] || null;\n\n/**\n * Helper function for cookie and GDPR utilities do NOT use this directly. Use the cookie\n * utility instead as that is GDPR compliant.\n * @param {*} key\n * @returns\n */\nexport const getCookieFromBrowser = key =>\n getCookieFromString(window.document.cookie, key);\n\n/**\n * Helper function for cookie and GDPR utilities do NOT use this directly. Use the cookie\n * utility instead as that is GDPR compliant.\n * @param {*} key\n * @returns\n */\nexport const setCookieToBrowser = s => {\n window.document.cookie = s;\n};\n","import {\n selectGeolocation,\n selectIsLoggedIn,\n selectIsOutsideSweden\n} from 'tradera-state/member/selectors';\nimport { selectPreferredLanguage } from 'tradera-state/language/selectors';\nimport { getLanguageFromCountryCode } from 'tradera-localization/languagecode';\nimport {\n isSwedenCountryCodeOrUndefined,\n isDenmarkCountryCode\n} from 'tradera-localization/countrycode';\n\nexport const selectShowRegionSelection = state =>\n !selectIsLoggedIn(state) && selectIsOutsideSweden(state);\nexport const selectAvailableShippingCountries = state =>\n state.shippingRegion.availableShippingCountries;\nexport const selectShippingCountry = state =>\n state.shippingRegion.shippingCountry;\nexport const selectIsLoadingAvailableShippingCountries = state =>\n state.shippingRegion.isLoadingAvailableShippingCountries;\nexport const selectHasLoadedAvailableShippingCountries = state =>\n state.shippingRegion.hasLoadedAvailableShippingCountries;\nexport const selectShippingRegionCountryCodeIso2 = state =>\n state.shippingRegion.shippingCountry?.countryCodeIso2;\nexport const selectIsSwedishVisitor = state =>\n isSwedenCountryCodeOrUndefined(selectShippingRegionCountryCodeIso2(state));\nexport const selectIsDanishVisitor = state =>\n isDenmarkCountryCode(selectShippingRegionCountryCodeIso2(state));\n\nconst gpsMatchesLanguage = state => {\n const geoLocation = selectGeolocation(state);\n if (!geoLocation) {\n return true;\n }\n const country = geoLocation?.isoCode?.toLowerCase();\n const expectedLang = getLanguageFromCountryCode(country);\n const language =\n selectPreferredLanguage(state)?.languageCodeIso2?.toLowerCase() || 'sv';\n return expectedLang === language;\n};\n\nexport const selectShowLocalizationRegionPicker = state =>\n !selectIsLoggedIn(state) &&\n state.shippingRegion.localizationRegionPickerEnabled &&\n !state.shippingRegion.regionPickerDismissed &&\n !gpsMatchesLanguage(state);\n","import initData from 'init-data';\nimport { isNextJs, isServer } from 'tradera-utils/nextjs';\n\nconst getSiteBaseUrl = () =>\n isServer\n ? process.env.PUBLIC_TOUCHWEB_WINDOW_LOCATION_ORIGIN\n : window.location.origin;\n\nconst webApiUrl = isNextJs\n ? `${getSiteBaseUrl()}/api/webapi`\n : initData.webApiUrl;\n\nconst touchWebUrl = isNextJs ? `${getSiteBaseUrl()}/` : initData.touchWebUrl;\n\nexport default {\n AVAILABLE_SHIPPING_COUNTRIES:\n webApiUrl + '/member/getavailablecountriesforshipping',\n BANK_ID_AUTHENTICATE: touchWebUrl + 'bankid/authenticate',\n BANK_ID_PROGRESS: touchWebUrl + 'bankid/progress',\n BRAND_LIST_PAGE: touchWebUrl + 'brands/api',\n BRAND_PAGE: touchWebUrl + 'brand/api/',\n CART_UPDATE_SUMMARY: touchWebUrl + 'shopping/managecart/updatecartsummary',\n CART_OVERVIEW_VIEW: webApiUrl + '/shopping/checkout/cartoverview',\n CART_ADD_ITEM: webApiUrl + '/shopping/cart/item',\n CART_REMOVE_ITEMS: webApiUrl + '/shopping/cart/removeitems',\n CART_SET_ITEM_QUANTITY: webApiUrl + '/shopping/cart/setitemquantity',\n CHARITY_EARNINGS_TICKER:\n touchWebUrl + 'cache/kampanjer/earningsticker/earnings',\n CMS_API: initData.cmsApiUrl,\n COMBINED_SHIPPING_UPSELL: touchWebUrl + 'combined-shipping-upsell/items',\n FAVORITE_SELLER_ADD: touchWebUrl + 'my/favourite-sellers/add',\n FAVORITE_SELLER_REMOVE: touchWebUrl + 'my/favourite-sellers/remove',\n FAVOURITE_SELLERS: webApiUrl + `/discover/favouritesellers-and-items2`,\n GET_PROFILE_FEEDBACK_ITEMS: touchWebUrl + 'profile/model',\n HYPERWALLET_PAYOUT_COMPLETE:\n webApiUrl + '/member/paymentprovider/completehyperwallettransfermethod',\n HYPERWALLET_PAYOUT_TOKEN:\n webApiUrl + '/member/paymentprovider/hyperwalletauthenticationtoken',\n HYPERWALLET_PAYOUT:\n webApiUrl +\n '/member/paymentprovider/hyperwallettransfermethodviewmodel',\n INTERNATIONAL_SHIPPING_CALCULATOR:\n webApiUrl + '/browse/internationalshippingcalculator',\n ITEM_DESCRIPTION: itemId =>\n `${webApiUrl}/browse/item/${itemId}/description`,\n ITEM_DISCOUNT_QUOTA: touchWebUrl + 'profile/shop-item-settings/quotas',\n LAST_CHANCE: touchWebUrl + 'StartPage/LastChance',\n MEMBER_PAYOUT_SETTINGS_REMOVE:\n webApiUrl + '/member/profile/removetraderapaypayoutdestination',\n MEMBER_PAYOUT_SETTINGS:\n webApiUrl + '/member/paymentprovider/memberpayoutsettingsviewmodel',\n MEMBER_SYSTEM_MESSAGES: webApiUrl + '/member/system-messages',\n ORDER_CHECKOUT_CONFIRMATION:\n webApiUrl +\n '/shopping/ordercheckout/purchaseordercheckoutconfirmationviewmodel',\n ORDER_CHECKOUT_PAYMENT: initData.orderCheckoutPaymentUrl,\n ORDER_CHECKOUT_REQUEST_COMBINED_PRICE:\n webApiUrl + '/shopping/ordercheckout/requestcombinedshippingprice',\n ORDER_CHECKOUT_CREATE_UNCOMMITTED_PURCHASE_ORDER:\n webApiUrl + '/shopping/ordercheckout/createuncommittedpurchaseorder',\n ORDER_PURCHASE_SHOP_ITEMS:\n webApiUrl + '/shopping/ordercheckout/purchaseshopitems',\n PAYMENT_SWISH_OPTOUT: touchWebUrl + 'my/payments2/OptOut',\n PERSONALISED_SUGGESTIONS: '/api/personalised-suggestions',\n SEARCH_SUGGESTIONS: touchWebUrl + 'search/suggestions',\n SEARCH: touchWebUrl + 'search',\n SELLING_CAMPAING_CODE: touchWebUrl + 'selling/api/campaign',\n SELLING_DRAFT_LOAD_FROM_TEMPLATE:\n touchWebUrl + 'selling/api/drafts/from-template',\n SELLING_DRAFT_SAVE: touchWebUrl + 'selling/api/drafts/',\n SELLING_DRAFT: draftId => touchWebUrl + `selling/api/drafts/${draftId}`,\n SELLING_DRAFTS_DELETE: touchWebUrl + 'selling/api/drafts/delete',\n SELLING_DRAFTS: touchWebUrl + 'selling/api/drafts/',\n SELLING_ITEM_PUBLISH: touchWebUrl + 'selling/api/items',\n SELLING_ITEM_STATUS: itemId =>\n touchWebUrl + `selling/api/items/${itemId}/status`,\n SELLING_ITEM_UPDATE: itemId =>\n touchWebUrl + `selling/api/items/${itemId}/update`,\n SELLING_PREVIEW: draftId =>\n touchWebUrl + `selling/api/drafts/preview/${draftId}`,\n SELLING_SCRIBE_DURATION: touchWebUrl + 'selling/api/scribe/duration',\n SELLING_SCRIBE_INCREMENT: touchWebUrl + 'selling/api/scribe/increment',\n SELLING_SCRIBE_SESSION_DURATION:\n touchWebUrl + 'selling/api/scribe/session-duration',\n SELLING_SCRIBE_SESSION_START:\n touchWebUrl + 'selling/api/scribe/session-start',\n SELLING_SCRIBE_VALIDATION_ERRORS:\n touchWebUrl + 'selling/api/scribe/form-validation-errors',\n SELLING_SHIPPING_CALCULATOR: touchWebUrl + 'selling/shippingcalculator',\n SELLING_TEMPLATE_SAVE: touchWebUrl + 'selling/api/templates',\n SELLING_TEMPLATE: templateId =>\n touchWebUrl + `selling/api/templates/${templateId}`,\n SELLING_TEMPLATES_COUNT: touchWebUrl + 'selling/api/templates-count',\n SELLING_TEMPLATES_DELETE: touchWebUrl + 'selling/api/templates/delete',\n SELLING_TEMPLATES: touchWebUrl + 'selling/api/templates',\n SETTINGS: touchWebUrl + 'profile/shop-item-settings/settings',\n SWISH_APP2APP_CALLBACK: 'shopping/payment/swish',\n SWISH_APP2APP_CALLBACK_MARK_AS_PAID:\n webApiUrl + '/shopping/payment/swish-app2app-paymentcallback',\n TOUCHWEB_URL: touchWebUrl,\n TRANSLATE_PROFILE_FEEDBACKITEMS: webApiUrl + '/member/feedback/translated',\n WEB_API: webApiUrl,\n WISHLIST: touchWebUrl + 'my/api/wish-list',\n WISHLIST_ADD: touchWebUrl + 'shopping/wishlist/add',\n WISHLIST_REMOVE: touchWebUrl + 'shopping/wishlist/remove',\n UPI: purchaseOrderId =>\n webApiUrl + '/member/uppo-strike/?PurchaseOrderId=' + purchaseOrderId,\n MCP: purchaseOrderId =>\n webApiUrl + '/member/mcp-strike/?PurchaseOrderId=' + purchaseOrderId,\n MCP_CONFIRM: purchaseOrderId =>\n webApiUrl +\n '/member/mcp-strike-confirm/?PurchaseOrderId=' +\n purchaseOrderId,\n INR: purchaseOrderId =>\n webApiUrl + '/member/ponr-strike/?PurchaseOrderId=' + purchaseOrderId,\n PURCHASE_ORDER: purchaseOrderId =>\n webApiUrl + '/member/purchaseorder/?PurchaseOrderId=' + purchaseOrderId,\n MARKETING_PUBLIC_API: '/api/marketing',\n SHIPPING_CHECKOUT_DELETE: '/my/shipping/checkout/delete'\n};\n","import { PAGE_LIST_TYPES } from 'tradera-apps/my-tradera/app/constants/list-types';\n\n/**\n * @returns {object} list of default cookies that could be set in Touchweb\n * @desc\n * key: Cookie Name\n * default: Default Value if not set\n * length: Time to be stored (months)\n */\nexport const DEFAULT_COOKIES = {\n ITEM_LAYOUT: {\n key: 'Srp_Item_Layout',\n default: 'layout-grid',\n length: 365\n },\n SITE_LAYOUT: {\n key: 'Srp_Site_Layout',\n default: 'site-width-default',\n length: 365\n }\n};\n\nexport const MYTRADERA_DEFAULT_COOKIES = {\n LIST_VIEW_TYPE: {\n key: 'MyTradera_ListViewType',\n default: 'Basic',\n length: 365\n },\n ITEMS_PER_PAGE: {\n key: 'MyTradera_ItemsPerPage',\n default: '25',\n length: 365\n },\n SHOW_FILTERS: {\n key: 'MyTradera_ShowFiltersToolbar',\n default: 'hidden',\n length: 365\n },\n LIST_VIEW_TYPE_BUYER_ACTIVE_ITEMS: {\n key: 'MyTradera_ListViewType_' + PAGE_LIST_TYPES.BUYER_ACTIVE_ITEMS,\n default: null,\n length: 365\n },\n LIST_VIEW_TYPE_BUYER_PURCHASES: {\n key: 'MyTradera_ListViewType_' + PAGE_LIST_TYPES.BUYER_PURCHASES,\n default: null,\n length: 365\n },\n LIST_VIEW_TYPE_BUYER_ITEMS_LOST: {\n key: 'MyTradera_ListViewType_' + PAGE_LIST_TYPES.BUYER_ITEMS_LOST,\n default: null,\n length: 365\n },\n LIST_VIEW_TYPE_SELLER_ACTIVE: {\n key: 'MyTradera_ListViewType_' + PAGE_LIST_TYPES.SELLER_ACTIVE,\n default: null,\n length: 365\n },\n LIST_VIEW_TYPE_SELLER_SOLD: {\n key: 'MyTradera_ListViewType_' + PAGE_LIST_TYPES.SELLER_SOLD,\n default: null,\n length: 365\n },\n LIST_VIEW_TYPE_SELLER_NOT_SOLD: {\n key: 'MyTradera_ListViewType_' + PAGE_LIST_TYPES.SELLER_NOT_SOLD,\n default: null,\n length: 365\n }\n};\n\nexport const CURRENCY_SELECTED_BY_USER = 'currency_selected_by_user';\nexport const GDPR_CONSENT_ALERT_DISMISSED = 'gdpr_dismissed_v1';\nexport const GDPR_CONSENT_COOKIE = 'gdpr_consent_v1';\nexport const FORCE_GEO_DEV = 'force-geo-dev';\nexport const ITEMS_PER_PAGE = 'ITEMS_PER_PAGE';\nexport const LIST_VIEW_TYPE = 'LIST_VIEW_TYPE';\nexport const MOBILE_OPT_IN_TAGS = 'mobile-opt-in-tags';\nexport const NATIVE_APP_ENVIRONMENT = 'native-app-environment';\nexport const PREFERRED_CURRENCY = 'preferred_currency';\nexport const REGION_PICKER_DISMISSED = 'region_picker_dismissed_session';\nexport const S = 's';\nexport const SHIPPING_COUNTRY = 'shipping_country';\nexport const SHOW_FILTERS = 'SHOW_FILTERS';\nexport const SIGNUP_REFERRAL_PATH = 'signup_referral_path';\nexport const SOLD_VIEW_PICKLIST = 'sold_view_picklist';\nexport const TEST = 'test';\nexport const USERPREFERENCES = 'UserPreferences';\nexport const CART_ID = 'cartId';\nexport const VIEWPORT_WIDTH = 'viewport-width';\nexport const SHIP_TO_SWEDEN_DISCLAIMER_DISMISSED =\n 'ship-to-sweden-disclaimer-dismissed';\nexport const EXPERIMENTS = 'experiments';\n\nexport const COOKIE_CATEGORIES = {\n Essential: 1,\n Performance: 2,\n Functional: 3,\n Marketing: 4\n};\n\n/**\n * all cookies that are used by tradera must be categorized in the array below.\n */\nexport const CATEGORIZED_COOKIES = {\n [GDPR_CONSENT_ALERT_DISMISSED]: COOKIE_CATEGORIES.Essential,\n [GDPR_CONSENT_COOKIE]: COOKIE_CATEGORIES.Essential,\n [NATIVE_APP_ENVIRONMENT]: COOKIE_CATEGORIES.Essential,\n [TEST]: COOKIE_CATEGORIES.Essential, // Unit test cookie\n\n [CURRENCY_SELECTED_BY_USER]: COOKIE_CATEGORIES.Functional,\n [DEFAULT_COOKIES.ITEM_LAYOUT.key]: COOKIE_CATEGORIES.Functional,\n [DEFAULT_COOKIES.SITE_LAYOUT.key]: COOKIE_CATEGORIES.Functional,\n [EXPERIMENTS]: COOKIE_CATEGORIES.Functional,\n [FORCE_GEO_DEV]: COOKIE_CATEGORIES.Functional,\n [ITEMS_PER_PAGE]: COOKIE_CATEGORIES.Functional,\n [LIST_VIEW_TYPE]: COOKIE_CATEGORIES.Functional,\n [MOBILE_OPT_IN_TAGS]: COOKIE_CATEGORIES.Functional,\n [MYTRADERA_DEFAULT_COOKIES.ITEMS_PER_PAGE.key]:\n COOKIE_CATEGORIES.Functional,\n [MYTRADERA_DEFAULT_COOKIES.LIST_VIEW_TYPE.key]:\n COOKIE_CATEGORIES.Functional,\n [MYTRADERA_DEFAULT_COOKIES.SHOW_FILTERS.key]: COOKIE_CATEGORIES.Functional,\n [PREFERRED_CURRENCY]: COOKIE_CATEGORIES.Functional,\n [REGION_PICKER_DISMISSED]: COOKIE_CATEGORIES.Functional,\n [S]: COOKIE_CATEGORIES.Functional, // saved search\n [SHIPPING_COUNTRY]: COOKIE_CATEGORIES.Functional,\n [SHOW_FILTERS]: COOKIE_CATEGORIES.Functional,\n [SIGNUP_REFERRAL_PATH]: COOKIE_CATEGORIES.Functional,\n [SOLD_VIEW_PICKLIST]: COOKIE_CATEGORIES.Functional,\n [USERPREFERENCES]: COOKIE_CATEGORIES.Functional,\n [CART_ID]: COOKIE_CATEGORIES.Functional,\n [VIEWPORT_WIDTH]: COOKIE_CATEGORIES.Functional,\n [SHIP_TO_SWEDEN_DISCLAIMER_DISMISSED]: COOKIE_CATEGORIES.Functional,\n [MYTRADERA_DEFAULT_COOKIES.LIST_VIEW_TYPE_BUYER_ACTIVE_ITEMS.key]:\n COOKIE_CATEGORIES.Functional,\n [MYTRADERA_DEFAULT_COOKIES.LIST_VIEW_TYPE_BUYER_ITEMS_LOST.key]:\n COOKIE_CATEGORIES.Functional,\n [MYTRADERA_DEFAULT_COOKIES.LIST_VIEW_TYPE_BUYER_PURCHASES.key]:\n COOKIE_CATEGORIES.Functional,\n [MYTRADERA_DEFAULT_COOKIES.LIST_VIEW_TYPE_SELLER_ACTIVE.key]:\n COOKIE_CATEGORIES.Functional,\n [MYTRADERA_DEFAULT_COOKIES.LIST_VIEW_TYPE_SELLER_NOT_SOLD.key]:\n COOKIE_CATEGORIES.Functional,\n [MYTRADERA_DEFAULT_COOKIES.LIST_VIEW_TYPE_SELLER_SOLD.key]:\n COOKIE_CATEGORIES.Functional\n};\n\nexport const COOKIE_DEFAULT_CATEGORY = COOKIE_CATEGORIES.Functional;\n\n/**\n * List of cookies which are OK for any JavaScript to access. Never add cookies\n * that would be a security risk if exposed to third party scripts.\n */\nexport const COOKIES_REQUIRED_FOR_SSR_EXPOSED_TO_JS_IN_BROWSER = [\n EXPERIMENTS,\n GDPR_CONSENT_COOKIE,\n REGION_PICKER_DISMISSED,\n SHIPPING_COUNTRY\n];\n","export const isDev = () =>\n process && process.env && process.env.NODE_ENV !== 'production';\n\nexport const warnIfDevBuild = moduleName => {\n if (isDev()) {\n console.log(\n `%c Warning: This is a Dev build of ${moduleName}`,\n 'background:red; color:white; font-size:18px;'\n );\n }\n};\n\n/**\n * helper function that is called after the header has been loaded. useful when you want to have the redux loaded before you start\n * to dispatch actions.\n * @param {func} callback\n */\nexport const onModuleLoaded = callback => {\n const isModuleLoaded = () =>\n window.document.body.getAttribute('data-module-loaded') === 'true';\n\n try {\n if (isModuleLoaded()) {\n callback();\n }\n let observer = new MutationObserver(mutationsList => {\n const element = mutationsList.filter(\n item => item.attributeName === 'data-module-loaded'\n );\n if (element !== null && isModuleLoaded()) {\n callback();\n }\n });\n observer.observe(window.document.body, { attributes: true });\n // eslint-disable-next-line no-empty\n } catch (error) {}\n};\n","// extracted by mini-css-extract-plugin\nexport default {\"item-toast\":\"item-toast--QaLFk\",\"itemToast\":\"item-toast--QaLFk\",\"item-toast-image\":\"item-toast-image--i_l4w\",\"itemToastImage\":\"item-toast-image--i_l4w\"};","import React from 'react';\nimport ALink from 'tradera-components/alink/alink';\nimport { useTranslator, useUrlLocalizer } from 'tradera-lang/translate';\nimport styles from './item-toast.module.scss';\nimport { useLocalizedPriceFormatter } from 'tradera-localization/use-localized-price-formatter';\n\nexport const ItemToast = ({\n imageUrl,\n itemUrl,\n shortDescription,\n type,\n eventData\n}) => {\n const { toLocalizedUrl } = useUrlLocalizer();\n\n return (\n \n
\n \n \n
\n
\n );\n};\n\nconst ToastMessage = ({ type, shortDescription, eventData }) => {\n const { t } = useTranslator();\n const localizedPriceFormatter = useLocalizedPriceFormatter();\n let message;\n switch (type) {\n case 'ItemOutbidded':\n message = t('siteWideNotifications_itemOutbidded_localized', {\n newLeadingBid: localizedPriceFormatter(\n eventData.newLeadingBidAmount\n ),\n shortDescription\n });\n break;\n case 'ItemFirstBid':\n message = t('siteWideNotifications_itemFirstBid', {\n shortDescription\n });\n break;\n case 'ItemSold':\n message = t('siteWideNotifications_itemSold_localized', {\n price: localizedPriceFormatter(eventData.price),\n shortDescription\n });\n break;\n case 'ItemWon':\n message = t('siteWideNotifications_itemWon_localized', {\n price: localizedPriceFormatter(eventData.price),\n shortDescription\n });\n break;\n case 'ItemPaid':\n message = t('siteWideNotifications_itemPaid', {\n shortDescription\n });\n break;\n case 'ItemWishListReminder':\n message = t('siteWideNotifications_itemWishListReminder', {\n shortDescription,\n timeLeftMinutes: eventData.timeLeftMinutes\n });\n }\n return
{message}
;\n};\n","import React from 'react';\nimport { useTranslator } from 'tradera-lang/translate';\n\nconst MessageToast = ({ message, header }) => {\n const { t } = useTranslator();\n\n return (\n
\n {header &&

{t(header)}

}\n {message && (\n {t(message)}\n )}\n
\n );\n};\n\nexport default MessageToast;\n","import React from 'react';\nimport { toast } from 'react-toastify';\n\nimport { ItemToast } from 'tradera-components/toasts/item-toast';\nimport MessageToast from 'tradera-components/toasts/message-toast';\nimport { isServer } from 'tradera-utils/nextjs';\nimport { webApiClient } from '../utils/http';\nimport { createQueue } from './toast-queue';\n\nconst queuedToasts = createQueue();\n\nexport const ToastTestButton = () => (\n {\n e.preventDefault();\n showItemWishListReminderToast(85391643, 3);\n showItemOutbiddedToast(85391639, 99);\n showItemFirstBidToast(85391639);\n showItemSoldToast(85391639, 1234);\n showItemWonToast(85391639, 1234);\n showItemPaidToast(85391639);\n showSuccessToast(\n 'checkout_shipping_requestCombinedShippingPriceInfo',\n 'checkout_shipping_combinedShippingPriceRequested'\n );\n showErrorToast('siteWideNotifications_profileUpdateFailed');\n showInfoToast('siteWideNotifications_profileUpdateFailed');\n }}>\n Test\n \n);\n\nconst openNextToast = async () => {\n if (isServer) {\n return;\n }\n if (queuedToasts.isInProgress()) {\n return;\n }\n const nextItem = queuedToasts.next();\n if (nextItem) {\n try {\n const queueLength = queuedToasts.getLength();\n const toastOptions = {\n autoClose: Math.max(2, 5 - queueLength) * 1000,\n onClose: () => {\n queuedToasts.notifyDone();\n openNextToast();\n }\n };\n if (nextItem.eventData.itemId) {\n const response = await webApiClient.get(\n `/browse/item-basic-info/${nextItem.eventData.itemId}`\n );\n const {\n imageUrl,\n itemUrl,\n shortDescription\n } = response.data.item;\n toast(\n React.createElement(ItemToast, {\n imageUrl,\n itemUrl,\n shortDescription,\n type: nextItem.type,\n eventData: nextItem.eventData\n }),\n toastOptions\n );\n } else if (nextItem.eventData.message) {\n const { message, header } = nextItem.eventData;\n toast(\n React.createElement(MessageToast, {\n message,\n header\n }),\n { ...toastOptions, type: nextItem.eventData.type }\n );\n }\n } catch (e) {\n queuedToasts.notifyDone();\n openNextToast();\n throw e;\n }\n }\n};\n\nconst handleNotification = async (type, eventData, ttlInMinutes = 10) => {\n if (document.visibilityState !== 'visible') {\n // We don't want to show messages if page is not visible. If we do they will queue up!\n return;\n }\n\n queuedToasts.add({ type, eventData }, ttlInMinutes);\n openNextToast();\n};\n\nexport const showItemOutbiddedToast = (itemId, newLeadingBidAmount) =>\n handleNotification('ItemOutbidded', {\n itemId,\n newLeadingBidAmount\n });\n\nexport const showItemFirstBidToast = itemId =>\n handleNotification('ItemFirstBid', { itemId });\n\nexport const showItemSoldToast = (itemId, price) =>\n handleNotification('ItemSold', { itemId, price });\n\nexport const showItemWonToast = (itemId, price) =>\n handleNotification('ItemWon', { itemId, price });\n\nexport const showItemPaidToast = itemId =>\n handleNotification('ItemPaid', { itemId });\n\nexport const showItemWishListReminderToast = (itemId, timeLeftMinutes) =>\n handleNotification(\n 'ItemWishListReminder',\n { itemId, timeLeftMinutes },\n timeLeftMinutes > 10 ? 10 : 2\n );\n\nexport const showSuccessToast = (message, header) => {\n handleNotification('Message', {\n message,\n header,\n type: toast.TYPE.SUCCESS\n });\n};\n\nexport const showErrorToast = (message, header) => {\n handleNotification('Message', {\n message,\n header,\n type: toast.TYPE.ERROR\n });\n};\n\nexport const showInfoToast = (message, header) => {\n handleNotification('Message', {\n message,\n header,\n type: toast.TYPE.INFO\n });\n};\n","/**\n * A queue with a that handled max age (ttl) for messages.\n * @returns\n */\nexport const createQueue = () => {\n const items = [];\n const dayInMinutes = 60 * 24;\n const add = (item, ttlInMinutes = dayInMinutes) => {\n const timeStamp = Date.now();\n items.push({ item, ttlInMinutes, timeStamp });\n };\n const isAlive = ({ ttlInMinutes, timeStamp }) => {\n return timeStamp + ttlInMinutes * 60 * 1000 >= Date.now();\n };\n let inProgress = null;\n return {\n add,\n next: () => {\n let itemData = items.shift();\n while (itemData && !isAlive(itemData)) {\n itemData = items.shift();\n }\n // eslint-disable-next-line better-mutation/no-mutation\n inProgress = itemData?.item || null;\n return inProgress;\n },\n notifyDone: () => {\n // eslint-disable-next-line better-mutation/no-mutation\n inProgress = null;\n },\n isInProgress: () => inProgress !== null,\n getLength: () => items.length\n };\n};\n","export const isPrerender = userAgent =>\n Boolean(\n userAgent?.includes(\n 'Prerender (+https://github.com/prerender/prerender)'\n )\n );\n","/**\n * @returns initData as JSON;\n * Default\n */\nconst initData = function() {\n if (typeof window === 'undefined') {\n return {};\n } else if (!window.initData) {\n const initDataEL = document.getElementById('init-data');\n if (initDataEL) {\n const data = initDataEL.getAttribute('data-init-data');\n const parsed = JSON.parse(data);\n return parsed;\n } else {\n return null;\n }\n } else {\n return window.initData;\n }\n};\n\nexport const getInitData = initData;\nexport default new initData();\n","export const isSwedishOrUndefined = languageCodeIso2 =>\n languageCodeIso2 === undefined || languageCodeIso2.toLowerCase() === 'sv';\n\nexport const getLanguageFromCountryCode = countryCodeIso2 => {\n const key = countryCodeIso2?.toLowerCase() || 'se';\n const languageMap = {\n se: 'sv',\n dk: 'da',\n de: 'de'\n };\n return languageMap[key] || 'en';\n};\n\nexport const getCountryCodeForFlagFromLanguage = languageCode => {\n const key = languageCode?.toLowerCase() || 'sv';\n const countryMap = {\n en: 'gb', // We default to GB which isn't strictly correct\n da: 'dk',\n de: 'de'\n };\n return countryMap[key] || 'se';\n};\n\nexport const getCountryCodeFromLanguage = languageCode => {\n const key = languageCode?.toLowerCase() || 'sv';\n const countryMap = {\n da: 'dk',\n de: 'de'\n };\n return countryMap[key] || 'se';\n};\n\nexport const areLanguageCodesIso2Equal = (first, second) =>\n (first || 'SV').toUpperCase() === (second || 'SV').toUpperCase();\n"],"sourceRoot":""}