{"version":3,"file":"node_modules-4902474e.js","sources":["../../../node_modules/object-assign/index.js","../../../node_modules/react/cjs/react.production.min.js","../../../node_modules/react/index.js","../../../node_modules/react/cjs/react-jsx-runtime.production.min.js","../../../node_modules/react/jsx-runtime.js","../../../node_modules/regenerator-runtime/runtime.js","../../../node_modules/whatwg-fetch/fetch.js","../../../node_modules/smoothscroll-polyfill/dist/smoothscroll.js","../../../node_modules/scheduler/cjs/scheduler.production.min.js","../../../node_modules/scheduler/index.js","../../../node_modules/react-dom/cjs/react-dom.production.min.js","../../../node_modules/react-dom/index.js","../../../node_modules/prop-types/lib/ReactPropTypesSecret.js","../../../node_modules/prop-types/factoryWithThrowingShims.js","../../../node_modules/prop-types/index.js","../../../node_modules/react-redux/es/components/Context.js","../../../node_modules/react-redux/es/utils/batch.js","../../../node_modules/react-redux/es/utils/Subscription.js","../../../node_modules/react-redux/es/utils/useIsomorphicLayoutEffect.js","../../../node_modules/react-redux/es/components/Provider.js","../../../node_modules/@babel/runtime/helpers/esm/extends.js","../../../node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js","../../../node_modules/react-is/cjs/react-is.production.min.js","../../../node_modules/react-is/index.js","../../../node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js","../../../node_modules/react-redux/node_modules/react-is/cjs/react-is.production.min.js","../../../node_modules/react-redux/node_modules/react-is/index.js","../../../node_modules/react-redux/es/components/connectAdvanced.js","../../../node_modules/react-redux/es/utils/shallowEqual.js","../../../node_modules/react-redux/es/utils/bindActionCreators.js","../../../node_modules/react-redux/es/connect/wrapMapToProps.js","../../../node_modules/react-redux/es/connect/mapDispatchToProps.js","../../../node_modules/react-redux/es/connect/mapStateToProps.js","../../../node_modules/react-redux/es/connect/mergeProps.js","../../../node_modules/react-redux/es/connect/selectorFactory.js","../../../node_modules/react-redux/es/connect/connect.js","../../../node_modules/react-redux/es/hooks/useReduxContext.js","../../../node_modules/react-redux/es/hooks/useStore.js","../../../node_modules/react-redux/es/hooks/useDispatch.js","../../../node_modules/react-redux/es/hooks/useSelector.js","../../../node_modules/react-redux/es/index.js","../../../node_modules/@babel/runtime/helpers/esm/typeof.js","../../../node_modules/@babel/runtime/helpers/esm/toPrimitive.js","../../../node_modules/@babel/runtime/helpers/esm/toPropertyKey.js","../../../node_modules/@babel/runtime/helpers/esm/defineProperty.js","../../../node_modules/@babel/runtime/helpers/esm/objectSpread2.js","../../../node_modules/redux/es/redux.js","../../../node_modules/redux-devtools-extension/utils/assign.js","../../../node_modules/redux-devtools-extension/logOnly.js","../../../node_modules/redux-devtools-extension/logOnlyInProduction.js","../../../node_modules/redux-thunk/es/index.js","../../../node_modules/redux-undo/lib/actions.js","../../../node_modules/redux-undo/lib/helpers.js","../../../node_modules/redux-undo/lib/debug.js","../../../node_modules/redux-undo/lib/reducer.js","../../../node_modules/redux-undo/lib/index.js","../../../node_modules/@insights/insights-data-provider/lib/utilities/MetadataManager.js","../../../node_modules/@insights/insights-data-provider/lib/utilities/SequenceNumberHandler.js","../../../node_modules/@insights/insights-data-provider/lib/enums/TrackingIdEnum.js","../../../node_modules/@insights/insights-data-provider/lib/utilities/IdGenerator.js","../../../node_modules/@insights/insights-data-provider/lib/utilities/SessionManager.js","../../../node_modules/@insights/insights-data-provider/lib/enums/IpexMomentEnum.js","../../../node_modules/@insights/insights-data-provider/lib/utilities/CookieReader.js","../../../node_modules/@insights/insights-data-provider/lib/utilities/EntryPoint.js","../../../node_modules/@insights/insights-data-provider/lib/enums/DesignInteractionEnum.js","../../../node_modules/@insights/insights-data-provider/lib/enums/InsightsEventEnum.js","../../../node_modules/@insights/insights-data-provider/lib/targets/InsightsTarget.js","../../../node_modules/@insights/insights-data-provider/lib/targets/GoogleAnalyticsTarget.js","../../../node_modules/@insights/insights-data-provider/lib/enums/GaEventEnum.js","../../../node_modules/@insights/insights-data-provider/lib/enums/GaCategoryEnum.js","../../../node_modules/@insights/insights-data-provider/lib/enums/DesignSourceEnum.js","../../../node_modules/@insights/insights-data-provider/lib/enums/ArticleActionEnum.js","../../../node_modules/@insights/insights-data-provider/lib/EventSender.js","../../../node_modules/@insights/insights-data-provider/lib/utilities/GAScriptLoader.js","../../../node_modules/@insights/insights-data-provider/lib/enums/PlatformEnum.js","../../../node_modules/@insights/insights-data-provider/lib/ModuleClient.js","../../../node_modules/@insights/insights-data-provider/lib/InsightsApi.js","../../../node_modules/@insights/insights-data-provider/lib/index.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ABTestNameEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ABTestVariationEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ApiPlatformEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/AutoCompleteEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/CookieConsentDataSourceEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/DexfSettingsEnvironmentEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/EcommerceCartDataSourceEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/EcommerceShoppingListDataSourceEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/FinancingOptionDataSourceEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/HeadingsEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/IksaShoppingBagTypeEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ImageSizeTypeEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ImageTypeNameEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/InvalidProductReasonEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/IowsShoppingBagTypeEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ItemTypeEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/MeasurementSystemEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/MvEcomIrwBagTypeEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/MvEcomShoppingBagTypeEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/NotificationDataSourceEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/NotificationLinkTypeEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ProductComplianceLabelTypeEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ProductComplianceTechnicalHeadingTypeEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ProductOptionalFieldNameEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/SalesSystemEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/SalesTypeCodeEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/SheetAlignmentEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/StoreAvailabilityDataSourceEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/StoreAvailabilityProbabilityEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/StoreBuTypeEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/StoreDataSourceEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/TemporaryPricePeriodEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ThemeBreakpointEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ThemeBreakpointIndexEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ThemeFontStyleTypeEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ZipAvailabilityDataSourceEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ZipAvailabilityProbabilityEnum.js","../../../node_modules/@inter-ikea-kompis/enums/lib/ZipValidationDataSourceEnum.js","../../../node_modules/@inter-ikea-kompis/services/lib/enums/CacheStoreType.js","../../../node_modules/@inter-ikea-kompis/exceptions/lib/enums/ExceptionTypeEnum.js","../../../node_modules/@inter-ikea-kompis/exceptions/lib/AbstractException.js","../../../node_modules/@inter-ikea-kompis/exceptions/lib/exceptions/ComponentElementException.js","../../../node_modules/@inter-ikea-kompis/exceptions/lib/exceptions/ComponentException.js","../../../node_modules/@inter-ikea-kompis/exceptions/lib/exceptions/ConnectionProblemException.js","../../../node_modules/@inter-ikea-kompis/exceptions/lib/exceptions/Exception.js","../../../node_modules/@inter-ikea-kompis/exceptions/lib/exceptions/ServerErrorResponseException.js","../../../node_modules/@inter-ikea-kompis/exceptions/lib/exceptions/ServiceException.js","../../../node_modules/@inter-ikea-kompis/exceptions/lib/exceptions/ShoppingCartException.js","../../../node_modules/@inter-ikea-kompis/exceptions/lib/exceptions/UnableToParseServerResponseException.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/alternate-language/LocalizedInformationAlternateLanguage.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/animation/EasingAnimation.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/availability/AvailabilityUtility.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/cache/CacheStore.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/cache/GlobalCacheStore.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/color-converter/ColorConverter.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/date/DateFormatter.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/debounce/DebounceManager.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/energy-class/EnergyClassParser.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/generator/IdGenerator.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/iframe/IframeConfig.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/iframe/IframeUtility.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/iframe/IframeVisibleArea.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/iframe/IframeVisibleAreaObserver.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/image/ImageUtility.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/locale/LocaleUtility.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/measurement/MeasurementUtility.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/price/PriceFormatterUtility.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/price/ProductPriceInformationSummaryTransformer.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/price/PriceUtility.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/price/TotalPriceCalculator.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/product/ProductDescriptionProductMeasureEnum.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/string/StringUtility.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/product/ProductUtility.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/product/ProductDescriptionUtility.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/settings/DexfSettingsUtility.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/shopping-support/ShoppingSupport.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/url-utility/UrlUtility.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/weight/WeightUtility.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/write-direction/SafariWriteDirectionUtility.js","../../../node_modules/@inter-ikea-kompis/utilities/lib/zip-availability/ZipAvailabilityUtility.js","../../../node_modules/@inter-ikea-kompis/services/lib/utilities/ServiceFetch.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/localization/OversattaTransformer.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/localization/OversattaService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/localization/LocalizationService.js","../../../node_modules/@inter-ikea-kompis/services/lib/utilities/DexfConfiguration.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/authentication/china/ChinaAuthenticationServiceCookieNameEnum.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/authentication/china/ChinaAuthenticationService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/authentication/iows/IowsAuthenticationService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/authentication/nif/NifAuthenticationService.js","../../../node_modules/@inter-ikea-kompis/services/lib/utilities/IframeManager.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/authentication/one-web/OneWebAuthenticationService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/shopping/AuthenticationQueue.js","../../../node_modules/@inter-ikea-kompis/services/lib/utilities/ItemUtility.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/store-availability/DexfStoreAvailabilityService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/zip-availability/DexfZipAvailabilityService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/checkout-availability/CheckoutAvailabilityService.js","../../../node_modules/@inter-ikea-kompis/services/lib/utilities/BitBoxUtility.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/cookie-consent/BitboxCookieConsentService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/cookie-consent/OneWebCookieConsentService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/cookie-consent/CookieConsentService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/financing/OneWebFinancingService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/financing/FinancingService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/localization/DexfSettingsTransformer.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/localization/DexfSettingsService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/localization/SettingsService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/localization/TranslationsTransformer.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/localization/InternalTranslationsService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/localization/TranslationsService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/notification/DexfNotificationService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/notification/NotificationService.js","../../../node_modules/@inter-ikea-kompis/services/lib/utilities/platform-communication/IrwPlatformCommunication.js","../../../node_modules/@inter-ikea-kompis/services/lib/utilities/platform-communication/RoigPlatformCommunication.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/platform/PlatformService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/product/KompisDefaultFields.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/product/ProductCache.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/product/DexfWebplannerService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/product/ProductItemQueue.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/product/ProductService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/shopping/china/cart/ChinaCartService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/shopping/iksa/IksaShoppingBagErrorCodes.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/shopping/iksa/IksaShoppingBagService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/shopping/ingka/cart/enums/IngkaCartErrorCodeEnum.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/shopping/ingka/cart/IngkaCartService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/shopping/iows/IowsShoppingBagErrorCodes.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/shopping/iows/IowsShoppingBagService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/shopping/mvecom/MvEcomShoppingBagErrorCodes.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/shopping/mvecom/MvEcomShoppingBagService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/shopping/nif/enums/NifUnitTypeEnum.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/shopping/nif/NifCartService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/shopping/ShoppingCartService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/shopping/china/shopping-list/ChinaShoppingListService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/shopping/ingka/shopping-list/IngkaShoppingListService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/shopping/ShoppingListService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/store/StoreCache.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/store/DexfStoreService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/store/IowsStoreTransformer.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/store/IowsStoreService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/store/StoreService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/vpc/dexf/DexfVpcService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/vpc/VpcService.js","../../../node_modules/@inter-ikea-kompis/services/lib/services/zip-availability/DexfZipValidationService.js","../../../node_modules/@inter-ikea-kompis/services/lib/facades/zip-validation/ZipValidationService.js","../../../node_modules/@inter-ikea-kompis/analytics/lib/enums/NavigationToEnum.js","../../../node_modules/@inter-ikea-kompis/analytics/lib/utilities/KioskABTestVariation.js","../../../node_modules/@inter-ikea-kompis/analytics/lib/utilities/ABTestUtility.js","../../../node_modules/@inter-ikea-kompis/analytics/lib/utilities/AnalyticsManager.js","../../../node_modules/@inter-ikea-kompis/analytics/lib/reporters/InsightsReporter.js","../../../node_modules/@inter-ikea-kompis/analytics/lib/utilities/ReporterManager.js","../../../node_modules/@inter-ikea-kompis/analytics/lib/version.js","../../../node_modules/@inter-ikea-kompis/analytics/lib/trackers/AbstractAnalyticsTracker.js","../../../node_modules/@sentry/utils/build/esm/is.js","../../../node_modules/@sentry/utils/build/esm/string.js","../../../node_modules/@sentry/utils/build/esm/aggregate-errors.js","../../../node_modules/@sentry/utils/build/esm/breadcrumb-log-level.js","../../../node_modules/@sentry/utils/build/esm/version.js","../../../node_modules/@sentry/utils/build/esm/worldwide.js","../../../node_modules/@sentry/utils/build/esm/browser.js","../../../node_modules/@sentry/utils/build/esm/debug-build.js","../../../node_modules/@sentry/utils/build/esm/logger.js","../../../node_modules/@sentry/utils/build/esm/dsn.js","../../../node_modules/@sentry/utils/build/esm/error.js","../../../node_modules/@sentry/utils/build/esm/object.js","../../../node_modules/@sentry/utils/build/esm/stacktrace.js","../../../node_modules/@sentry/utils/build/esm/instrument/handlers.js","../../../node_modules/@sentry/utils/build/esm/instrument/console.js","../../../node_modules/@sentry/utils/build/esm/supports.js","../../../node_modules/@sentry/utils/build/esm/time.js","../../../node_modules/@sentry/utils/build/esm/instrument/fetch.js","../../../node_modules/@sentry/utils/build/esm/instrument/globalError.js","../../../node_modules/@sentry/utils/build/esm/instrument/globalUnhandledRejection.js","../../../node_modules/@sentry/utils/build/esm/env.js","../../../node_modules/@sentry/utils/build/esm/memo.js","../../../node_modules/@sentry/utils/build/esm/misc.js","../../../node_modules/@sentry/utils/build/esm/normalize.js","../../../node_modules/@sentry/utils/build/esm/syncpromise.js","../../../node_modules/@sentry/utils/build/esm/promisebuffer.js","../../../node_modules/@sentry/utils/build/esm/url.js","../../../node_modules/@sentry/utils/build/esm/severity.js","../../../node_modules/@sentry/utils/build/esm/baggage.js","../../../node_modules/@sentry/utils/build/esm/tracing.js","../../../node_modules/@sentry/utils/build/esm/envelope.js","../../../node_modules/@sentry/utils/build/esm/clientreport.js","../../../node_modules/@sentry/utils/build/esm/ratelimit.js","../../../node_modules/@sentry/utils/build/esm/propagationContext.js","../../../node_modules/@sentry/utils/build/esm/debug-ids.js","../../../node_modules/@sentry/utils/build/esm/vendor/supportsHistory.js","../../../node_modules/@sentry/utils/build/esm/buildPolyfills/_optionalChain.js","../../../node_modules/@sentry/core/build/esm/debug-build.js","../../../node_modules/@sentry/core/build/esm/carrier.js","../../../node_modules/@sentry/core/build/esm/session.js","../../../node_modules/@sentry/core/build/esm/utils/spanOnScope.js","../../../node_modules/@sentry/core/build/esm/scope.js","../../../node_modules/@sentry/core/build/esm/defaultScopes.js","../../../node_modules/@sentry/core/build/esm/asyncContext/stackStrategy.js","../../../node_modules/@sentry/core/build/esm/asyncContext/index.js","../../../node_modules/@sentry/core/build/esm/currentScopes.js","../../../node_modules/@sentry/core/build/esm/metrics/metric-summary.js","../../../node_modules/@sentry/core/build/esm/semanticAttributes.js","../../../node_modules/@sentry/core/build/esm/tracing/spanstatus.js","../../../node_modules/@sentry/core/build/esm/utils/spanUtils.js","../../../node_modules/@sentry/core/build/esm/tracing/errors.js","../../../node_modules/@sentry/core/build/esm/tracing/utils.js","../../../node_modules/@sentry/core/build/esm/utils/hasTracingEnabled.js","../../../node_modules/@sentry/core/build/esm/tracing/sentryNonRecordingSpan.js","../../../node_modules/@sentry/core/build/esm/constants.js","../../../node_modules/@sentry/core/build/esm/tracing/dynamicSamplingContext.js","../../../node_modules/@sentry/core/build/esm/tracing/logSpans.js","../../../node_modules/@sentry/core/build/esm/utils/parseSampleRate.js","../../../node_modules/@sentry/core/build/esm/tracing/sampling.js","../../../node_modules/@sentry/core/build/esm/envelope.js","../../../node_modules/@sentry/core/build/esm/tracing/measurement.js","../../../node_modules/@sentry/core/build/esm/tracing/sentrySpan.js","../../../node_modules/@sentry/core/build/esm/tracing/trace.js","../../../node_modules/@sentry/core/build/esm/tracing/idleSpan.js","../../../node_modules/@sentry/core/build/esm/eventProcessors.js","../../../node_modules/@sentry/core/build/esm/utils/applyScopeDataToEvent.js","../../../node_modules/@sentry/core/build/esm/utils/prepareEvent.js","../../../node_modules/@sentry/core/build/esm/exports.js","../../../node_modules/@sentry/core/build/esm/api.js","../../../node_modules/@sentry/core/build/esm/integration.js","../../../node_modules/@sentry/core/build/esm/baseclient.js","../../../node_modules/@sentry/core/build/esm/sdk.js","../../../node_modules/@sentry/core/build/esm/transports/base.js","../../../node_modules/@sentry/core/build/esm/utils/sdkMetadata.js","../../../node_modules/@sentry/core/build/esm/breadcrumbs.js","../../../node_modules/@sentry/core/build/esm/integrations/functiontostring.js","../../../node_modules/@sentry/core/build/esm/integrations/inboundfilters.js","../../../node_modules/@sentry/core/build/esm/integrations/captureconsole.js","../../../node_modules/@sentry/core/build/esm/integrations/dedupe.js","../../../node_modules/@sentry/core/build/esm/fetch.js","../../../node_modules/@sentry/browser/build/npm/esm/helpers.js","../../../node_modules/@sentry/browser/build/npm/esm/debug-build.js","../../../node_modules/@sentry/browser/build/npm/esm/eventbuilder.js","../../../node_modules/@sentry/browser/build/npm/esm/userfeedback.js","../../../node_modules/@sentry/browser/build/npm/esm/client.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/debug-build.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/lib/bindReporter.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/types.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/lib/generateUniqueID.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/lib/getNavigationEntry.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/lib/getActivationStart.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/lib/initMetric.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/lib/observe.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/lib/onHidden.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/lib/runOnce.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/lib/getVisibilityWatcher.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/lib/whenActivated.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/onFCP.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/getCLS.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/getFID.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/lib/polyfills/interactionCountPolyfill.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/getINP.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/getLCP.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/web-vitals/onTTFB.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/instrument.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/utils.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/cls.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/browserMetrics.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/instrument/dom.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/instrument/history.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/getNativeImplementation.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/instrument/xhr.js","../../../node_modules/@sentry-internal/browser-utils/build/esm/metrics/inp.js","../../../node_modules/@sentry/browser/build/npm/esm/transports/fetch.js","../../../node_modules/@sentry/browser/build/npm/esm/stack-parsers.js","../../../node_modules/@sentry/browser/build/npm/esm/integrations/breadcrumbs.js","../../../node_modules/@sentry/browser/build/npm/esm/integrations/browserapierrors.js","../../../node_modules/@sentry/browser/build/npm/esm/integrations/globalhandlers.js","../../../node_modules/@sentry/browser/build/npm/esm/integrations/httpcontext.js","../../../node_modules/@sentry/browser/build/npm/esm/integrations/linkederrors.js","../../../node_modules/@sentry/browser/build/npm/esm/sdk.js","../../../node_modules/@sentry/browser/build/npm/esm/tracing/request.js","../../../node_modules/@sentry/browser/build/npm/esm/tracing/backgroundtab.js","../../../node_modules/@sentry/browser/build/npm/esm/tracing/browserTracingIntegration.js","../../../node_modules/@sentry/react/build/esm/sdk.js","../../../node_modules/@sentry/react/build/esm/redux.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/DateFormatter.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/node_modules/file-saver/FileSaver.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/FileUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/IframeConfig.json.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/animation/EasingAnimation.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/IframeUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/JsonUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/PriceFormatter.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/UrlUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/StringUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/StyleUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/AkamaiImageSizes.json.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/ImageUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/constant/ExceptionTypeConstant.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/exception/Exception.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/exception/ComponentException.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/event/EventHandler.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/ApplicationResizeObserver.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/EventSupport.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/CacheStore.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/exception/UnsupportedException.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/exception/AbstractMethodException.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/settings/AbstractSettingsManager.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/settings/ComponentSettings.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/ScrollUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/ResourceTagLoader.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/Mutex.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/util/Latch.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/index.js","../../../node_modules/lit-html/lib/directive.js","../../../node_modules/lit-html/lib/dom.js","../../../node_modules/lit-html/lib/part.js","../../../node_modules/lit-html/lib/template.js","../../../node_modules/lit-html/lib/template-instance.js","../../../node_modules/lit-html/lib/template-result.js","../../../node_modules/lit-html/lib/parts.js","../../../node_modules/lit-html/lib/default-template-processor.js","../../../node_modules/lit-html/lib/template-factory.js","../../../node_modules/lit-html/lib/render.js","../../../node_modules/lit-html/lit-html.js","../../../node_modules/lit-html/directives/class-map.js","../../../node_modules/lit-html/directives/unsafe-html.js","../../../node_modules/@inter-ikea-kompis/web-component/lib/utilties/EqualsUtility.js","../../../node_modules/@inter-ikea-kompis/web-component/lib/kompis-element/decorators/KompisElementPropertyDecorator.js","../../../node_modules/@inter-ikea-kompis/themes/lib/themes/skapa/enums/SkapaDelayEnum.js","../../../node_modules/@inter-ikea-kompis/themes/lib/themes/skapa/enums/SkapaDurationEnum.js","../../../node_modules/@inter-ikea-kompis/themes/lib/themes/skapa/enums/SkapaFontSizeEnum.js","../../../node_modules/@inter-ikea-kompis/themes/lib/themes/skapa/enums/SkapaIconDurationEnum.js","../../../node_modules/@inter-ikea-kompis/themes/lib/themes/skapa/SkapaTheme.js","../../../node_modules/@inter-ikea-kompis/themes/lib/utilities/FontFace.js","../../../node_modules/@inter-ikea-kompis/themes/lib/utilities/FontLoader.js","../../../node_modules/@inter-ikea-kompis/themes/lib/utilities/FontStyle.js","../../../node_modules/@inter-ikea-kompis/themes/lib/utilities/ThemeBreakpointObserver.js","../../../node_modules/@ingka/webc-tools/src/features/focus-visible-poly.js","../../../node_modules/@ingka/webc-tools/src/features/cachedValue.js","../../../node_modules/@ingka/webc-tools/src/features/toggleAttributePolyfill.js","../../../node_modules/@ingka/webc-tools/src/features/isRTL.js","../../../node_modules/@ingka/webc-tools/src/features/resizeListener.js","../../../node_modules/@ingka/webc-tools/src/features/rtlObserver.js","../../../node_modules/@ingka/webc-tools/src/features/preDefinitionProperties.js","../../../node_modules/@ingka/webc-tools/src/features/evaluateSlot.js","../../../node_modules/@ingka/webc-tools/src/features/breakpointInfo.js","../../../node_modules/@ingka/singleton-store/esm/index.mjs","../../../node_modules/@ingka/icon-registry/esm/index.mjs","../../../node_modules/@ingka/webc-tools/src/features/customPrefixRegistry.js","../../../node_modules/@ingka/webc-tools/index.js","../../../node_modules/@inter-ikea-kompis/web-component/lib/version.js","../../../node_modules/@inter-ikea-kompis/web-component/lib/registry/KompisElementRegistry.js","../../../node_modules/@inter-ikea-kompis/web-component/lib/kompis-element/KompisElementInternalRegistryRewriter.js","../../../node_modules/@inter-ikea-kompis/web-component/lib/kompis-element/KompisElement.js","../../../node_modules/@inter-ikea-kompis/web-component/lib/template/CssTemplateLiteralTag.js","../../../node_modules/@inter-ikea-kompis/web-component/lib/index.js","../../../node_modules/@inter-ikea-kompis/component-accordion/lib/components/accordion-item-padding/AccordionItemPadding.js","../../../node_modules/@inter-ikea-kompis/component-collapsible/lib/components/collapsible/CollapsibleStyle.js","../../../node_modules/@inter-ikea-kompis/component-collapsible/lib/components/collapsible/Collapsible.js","../../../node_modules/@inter-ikea-kompis/component-icon/lib/utilities/IconSizeCalculator.js","../../../node_modules/@inter-ikea-kompis/component-icon/lib/components/icon/Icon.js","../../../node_modules/@inter-ikea-kompis/component-text/lib/components/text/Text.js","../../../node_modules/@ingka/icons-shared/esm/paths/arrow-left.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/arrow-right.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/arrow-up-arrow-down.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/arrow-up-from-base.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/checkmark-circle.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/checkmark-green-small.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/checkmark.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/chevron-down-small.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/chevron-left-small.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/chevron-left.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/chevron-right-small.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/chevron-right.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/copy.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/cross-small.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/cross.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/delivery-truck.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/drill.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/globe.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/heart.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/image-strikethrough.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/image.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/incorrect.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/information-circle.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/laptop-checkmark.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/link.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/notice-red-small.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/pencil.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/plus-small.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/printer.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/shopping-bag-add.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/sort-descending.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/speech-bubble.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/store.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/trash-can.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/warning-triangle-orange-small.mjs","../../../node_modules/@ingka/icons-shared/esm/paths/warning-triangle.mjs","../../../node_modules/@ingka/skapa-webc-element/src/SkapaElement.js","../../../node_modules/@ingka/skapa-webc-element/index.js","../../../node_modules/@ingka/icon-webc/src/tools/svg-renderer.js","../../../node_modules/@ingka/icon-webc/src/Icon.js","../../../node_modules/@inter-ikea-kompis/component-accordion/lib/enums/AccordionItemAriaDisabledEnum.js","../../../node_modules/@inter-ikea-kompis/component-accordion/lib/components/accordion-item/AccordionItemStyle.js","../../../node_modules/@inter-ikea-kompis/component-accordion/lib/components/accordion-item/AccordionItem.js","../../../node_modules/@inter-ikea-kompis/component-accordion/lib/components/accordion/AccordionStyle.js","../../../node_modules/@inter-ikea-kompis/component-accordion/lib/components/accordion/Accordion.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/AccessibilityIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/AccessibleDisabledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/AddOnIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/AdjustableBackrestIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/AirIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/AllenKeyIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/AluminiumCanIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EnergyAIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EnergyApIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EnergyAppIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EnergyApppIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EnergyBIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EnergyBlankIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EnergyCIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EnergyDIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EnergyEIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EnergyFIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/AppleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ARIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArchiveBoxIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowClockwiseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowCloudInIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowCloudOutIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowCounterclockwiseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowDownBackwardsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowDownForwardsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowDownfromBaseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowDowntoBaseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowDowntoLineIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowDowntoLineSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowForkRightIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowLeftIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowLeftArrowRightIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowLeftfromBaseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowLeftRightIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowLefttoBaseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowLefttoLineIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowLefttoLineSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowLevelDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowLevelUpIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowonPathIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowPairSquarepathIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowRightIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowRightfromBaseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowRighttoBaseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowRighttoLineIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowRighttoLineSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowsInwardIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowUTurnBackwardsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowUTurnForwardsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowUpIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowUpArrowDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowUpBackwardsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowUpDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowUpForwardsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowUpfromBaseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowUptoBaseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowUptoLineIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ArrowUptoLineSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ATMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BabyStrollerIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BackwardEndIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BandaidIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BarChartDowntrendIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BarChartUptrendIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Battery0Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Battery100Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Battery25Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Battery50Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Battery75Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BatteryChargingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BeamAngleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BedIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BedsideTableIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BeefIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BellIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BikeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BlockOutIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BluetoothIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BoardIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BoldIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BookcaseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BookmarkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BookmarkFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BoxIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BoxCancelIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BoxExchangeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BoxExpressIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BoxRepeatIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BoxReturnIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BriefcaseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BriefcaseCheckmarkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BriefcaseSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BrightnessDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BrightnessUpIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BucketIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BulldozerIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/BulletIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CalculatorFinancialIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CalendarIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Calendar90Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CameraIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CandleLight1800Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CandleLight1800DMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CanvasIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CarIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CarElectricIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CarFittingBoldIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CargoBikeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CartonIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CeilingHeightReducerIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CertificateIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChairIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChargingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChatIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CheckmarkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CheckmarkBoxIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CheckmarkCircleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CheckmarkSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChestofDrawersIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronDoubleDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronDoubleDownSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronDoubleLeftIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronDoubleLeftSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronDoubleRightIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronDoubleRightSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronDoubleUpIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronDoubleUpSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronDownSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronLeftIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronLeftSlashChevronRightIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronLeftSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronRightIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronRightSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronUpIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronUpChevronDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronUpChevronDownSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChevronUpSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ChickenIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CircleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CircleFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CircleFourSegmentsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CircleFourSegmentsFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CircleHalfIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CirclepathThreeTrianglesIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CirclepathTwoTrianglesIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CircleThreeSegmentsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CircleThreeSegmentsFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CleanSparklesIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ClickandCollectIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ClickandCollectStrikethroughIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ClipboardIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ClipboardCheckmarkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ClipboardStrikethroughIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ClockIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ClosedCaptionsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CoatHangerIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CoffeeTableIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CoffeeWasteIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ColdDrinkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ColdDrinkContentsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ColourfanIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ColourSpectrumIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ColourSpectrumDMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CommandLineIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ContactlessPaymentIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ContractIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CoolDaylight5000Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CoolDaylight5000DMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CoolDaylight5200Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CoolDaylight5200DMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CoolingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CoolSky6000Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CoolSky6000DMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CoolWhite4000Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CoolWhite4000DMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CopyIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CouponIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CoverIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CreateNewIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CreditCardIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CropIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CrossIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CrossBoxIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CrossCircleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CrosshairIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CrossSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Cube3DIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Cube3DBottomFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Cube3DLeftFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Cube3DRightFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Cube3DTopFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CupIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CupFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CurtainsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/CutleryIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DarkModeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DatabaseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DataChartIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DefineSpaceIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DeliveryTruckIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DeliveryTruckStrikethroughIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DepthIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DimmableIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DirtIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DiscountTagIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DisplayIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DocumentIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DocumentAddIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DocumentAlertIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DocumentCheckmarkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DocumentFinancialIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DocumentMagnifyingGlassIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DocumentPencilIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DocumentUploadIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DogIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DoorIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DoorLayoutIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DoubleDoorsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DresserIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DressingTableIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DrillIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DuvetDoubleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/DuvetSingleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EarIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EarStrikethroughIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EggIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EggStrikethroughIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ElectronicCircleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EllipsesHorizontalIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EllipsesVerticalIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EscalatorDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EscalatorUpIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/EscalatorUpDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ExpandIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ExtraSoftIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FabricIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FactoryIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FallingboxesIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FamilyGenderMenIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FamilyGenderMixedIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FamilyGenderWomenIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FanIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FastForwardIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FauxLeatherIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FeedbackDissatisfiedIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FeedbackHappyIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FeedbackNeutralIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FeedbackSadIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FeedbackSatisfiedIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FillBucketIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FiltersIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FinancingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FirstAidRoomCrescentIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FirstAidRoomCrossIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FirstPersonIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FishIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FlagIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FlameIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FlipHorizontalIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FloorLampIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FlowerIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FluorescentLampIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FolderIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FootprintIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ForkliftIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ForkliftLoadedIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ForwardEndIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FrameIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FramewithLegsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FullscreenIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FurnitureSetIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FurnitureTrolleyIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/FurnitureTrolleyLoadedIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GalleryLayoutAlternativesIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GarbageTruckIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GearIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GiftBagIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GiftBagActiveIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GiftBagActiveDMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GiftBagAddIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GiftBoxIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GiftBoxActiveIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GiftBoxActiveDMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GiftBoxFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GiftCardIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GlobeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GlobeStrikethroughIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/GroupIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Guarantee10Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Guarantee15Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Guarantee2Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Guarantee25Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Guarantee3Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Guarantee5Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandgesturesIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandMoveIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandPointIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandStrikethroughIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandTouchIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandwithBagIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandwithBoxIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandwithDiscountIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandwithDropIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandwithDropsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandwithHeartIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandwithKeyIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandwithPlateIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HandwithSparklesIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HeadphonesIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HeartIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HeartFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HeatPumpIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HeightIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HistoryIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HomeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HotDogIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HotDrinkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/HourglassIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/IceCreamIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/IDIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ImageIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ImageStackIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ImageStrikethroughIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/IncorrectIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/InformationIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/InformationCircleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/InformationCircleSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/InstitutionIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/InteriorsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/InverterIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ItalicIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/KickScooterIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/KitchenIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LambIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LaptopIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LaptopCheckmarkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LaptopMagnifyingGlassIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LaptopPencilIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LayoutIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LayoutAlternativeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LeafIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LeatherIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LeatherandFauxLeatherIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LiftDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LiftFurnitureTrolleyIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LiftShoppingTrolleyIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LiftUpIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LiftUpDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LightbulbIncandescentIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LightbulbLEDIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LightbulbLEDAlternativeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LightbulbwithRaysIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LightFilteringIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LinkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LinkOutIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LinkStrikethroughIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ListIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LiveVideoIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LocationPinIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LocationPinFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LocationPinSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LocationPinSmallFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LocationPointerIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LocationPointerFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LockIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LockersIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LockOpenIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/LockSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MagnifyingGlassIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MagnifyingGlassListIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MailIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MapIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressComfortZonesIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressExtraFirmIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressFeatherIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressFirmIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressFoamIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressHybridIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressLatexIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressMaterialGenericIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressMaterialNaturalIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressMaterialVeganIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressMediumFirmIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressMemoryFoamIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressPlushIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressRollPackedIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressSilkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressSpringsBonnellIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressSpringsMiniIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressSpringsPocketIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressTopperIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MattressWoolIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MedicIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MedicCrescentIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MembershipCardIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MembershipDigitalCardIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MenuIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MetalSawIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MicrophoneIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MilkBottleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MilkBottleStrikethroughIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MinusIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MinusSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MirrorIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MissingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MobileIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MobileHandoverIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MoneyBillsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MoneyCashIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MoneyCoinsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MotionSensorIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/MotorBikeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/NetworkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/NoteIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/NoticeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/NoticeCircleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/NoticeSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/NursingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/OfficeChairIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/OilContainerIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/OpenDoorIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/OpeningsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/OrderedListIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/OvalIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PaintbrushIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PairingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PalletLoadedIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PalletMixedIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PalletwithBoxesIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PanIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PanelsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PaperclipIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PaperTowelsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ParasolIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ParkingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ParkingGarageIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PassIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PauseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PedestrianIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PedestrianwithWalkingStickIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PencilIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PeopleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PersonIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PersonActiveIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PersonActiveDMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PersonHeightIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PersoninBedIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PersonSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PersonwithBackgroundIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PhoneIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PhonePaymentIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PhoneRotationIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PickingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PictureFrameIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PictureFramesIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PictureFramewithImageIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PictureinPictureIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PieChartIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PillowIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PillowHighIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PillowLowIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PinIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PlantinPotIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PlasticBagIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PlasticBottleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PlasticBottleCapIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PlayIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PlayAreaIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PlusIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PlusCircleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PlusSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PodcastIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PorkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PotwithLidIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PowerIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PramIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PriceTagIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PriceTagDigitalIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/PrinterIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/QuestionMarkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/QuestionMarkCircleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/QuietRoomIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ReceiptIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ReceiptAlertIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RectangleHorizontalIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RectangleHorizontalDoubleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RectangleHorizontalThinIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RectangleHorizontalThinTrippleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RectanglePairUnevenIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RectangleVerticalIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RectangleVerticalDoubleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RectangleVerticalThinIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RecycleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RefillingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ReplaceMeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ReplaceMeSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ResizeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RestroomIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RestroomBabyCareIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RestroomManIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RestroomManandChildIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RestroomWomanIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RestroomWomanandChildIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ReturnsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RewardIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RewindIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RobotArmIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RoomDarkeningIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RoomLayoutIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RoomWithoutFurnitureIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RotateIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RotateDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RotateLeftIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RotateRightIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RotateUpIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RugIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/RulerIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ScanBarcodeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ScanQRCodeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ScissorsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ScooterIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ScrewIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SeafoodIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SeatHeightIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SeatLumbarSupportIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SeatTensionIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SeatTiltIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SectionsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SecurityCameraIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SelectionAddIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SelectionHiddenIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SewingMachineIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShapeCornerIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShapeFreeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShapeLIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShapeOrganicIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShapeUIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShareNetworkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SheerFabricIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShelvesIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShelvingUnitIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShieldCheckmarkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShoppingBagIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShoppingBagActiveIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShoppingBagActiveDMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShoppingBagAddIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShoppingBagPrideIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShoppingBagPrideActiveIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShoppingBagPrideActiveDMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShoppingBagPrideDMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShoppingBagTrolleyIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShoppingBasketIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShoppingTrolleyIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShoppingTrolleyFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShowerIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ShuffleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SinkIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SkipNextIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SkipPreviousIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SleepingPositionBackIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SleepingPositionMixedIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SleepingPositionSideIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SleepingPositionStomachIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SmokingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SmokingStrikethroughIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SofaIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SofaBedIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SofaStorageIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SolarEnergyIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SolarPanelsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SolarStorageBatteryIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SortAscendingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SortDescendingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SoundAbsorptionIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SoundBlockingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SpeechBubbleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SpeechBubbleActiveIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SpeechBubbleActiveDMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SquareIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SquareCutIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SquareGrid2x2Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SquareGrid3x3FilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SquareSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StackIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StackStrikethroughIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StairsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StairsDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StairsUpIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StarIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StarFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StarFilledSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StarHalfFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StarHalfFilledRTLIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StarHalfFilledSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StarHalfFilledSmallRTLIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StarSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StopIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StopbarsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StoreIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/StoreStrikethroughIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SubtitlesIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SuitcaseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Sunrise3000Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/Sunrise3000DMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SurgicalMaskIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/SurgicalMaskonFaceIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TShirtIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TableIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TagIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TagFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TakeBackIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TextIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ThemeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ThermometerIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ThermometerExtraWarmIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ThermometerExtraWarmDMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ThermometerLightIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ThermometerLightDMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ThermometerWarmIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ThermometerWarmDMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ThermoregulationIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ThumbsDownIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ThumbsDownFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ThumbsUpIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ThumbsUpFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TinCanIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ToiletIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TonerCartridgeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TouchscreenIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TrailerIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TransportBusIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TransportTaxiIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TransportTrainIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TransportTramIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TransportTrolleybusIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TrashCanIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/TrolleyIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/UnderscoreIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/UngroupIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/USBPoweredIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/UtilityKnifeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/VaseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/VideoIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/VideoCameraIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/VisibilityHideIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/VisibilityShowIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/VoiceIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/VolumeMuteIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/VolumeOffIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/VolumeUpIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WallDividerIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WallRailsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WardrobeIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WarehouseIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WarmGlow2200Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WarmGlow2200DMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WarmWhite2500Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WarmWhite2500DMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WarmWhite2700Icon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WarmWhite2700DMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WarningTriangleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WarningTriangleColourIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WarningTriangleColourDMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WarningTriangleSmallIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WashableCoverIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WashingMachineIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WaterdropIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WaterproofIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WeightIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WeightsIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WheatIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WheatStrikethroughIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WheelIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WhiteSpectrumIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WhiteSpectrumDMIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WidthIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WifiIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WindFarmIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WindowIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WineBottleIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WineBottleFilledIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WineGlassIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WirelessChargingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WirelessDimmingIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WoodIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/WrenchIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ZoomInIcon.js","../../../node_modules/@inter-ikea-kompis/icons/lib/icons/ZoomOutIcon.js","../../../node_modules/@inter-ikea-kompis/component-checkbox/lib/enums/CheckboxAlignButtonEnum.js","../../../node_modules/@inter-ikea-kompis/component-checkbox/lib/enums/CheckboxLayoutEnum.js","../../../node_modules/@inter-ikea-kompis/component-checkbox/lib/components/checkbox/CheckboxStyle.js","../../../node_modules/@inter-ikea-kompis/component-checkbox/lib/components/checkbox/Checkbox.js","../../../node_modules/@inter-ikea-kompis/component-radio-button/lib/enums/RadioLayoutEnum.js","../../../node_modules/@inter-ikea-kompis/component-radio-button/lib/components/radio-button/RadioButtonStyle.js","../../../node_modules/@inter-ikea-kompis/component-radio-button/lib/components/radio-button/RadioButton.js","../../../node_modules/@ingka/switch-webc/src/Switch.js","../../../node_modules/@inter-ikea-kompis/component-action-list/lib/enums/ActionListBorderEnum.js","../../../node_modules/@inter-ikea-kompis/component-action-list/lib/enums/ActionListControlEnum.js","../../../node_modules/@inter-ikea-kompis/component-action-list/lib/components/action-list-item/ActionListItemStyle.js","../../../node_modules/@inter-ikea-kompis/component-action-list/lib/components/action-list-item/ActionListItem.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisActionListItem.js","../../../node_modules/@inter-ikea-kompis/component-action-list/lib/components/action-list/ActionList.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisActionList.js","../../../node_modules/@ingka/button-webc/src/common/DangerIcon.js","../../../node_modules/@ingka/loading-webc/src/LoadingBall.js","../../../node_modules/@ingka/button-webc/src/common/LoadingBall.js","../../../node_modules/@ingka/button-webc/src/common/ButtonAbstract.js","../../../node_modules/@ingka/button-webc/src/Button.js","../../../node_modules/@ingka/button-webc/src/IconButton.js","../../../node_modules/@inter-ikea-kompis/component-add-to-list/lib/enums/AddToListLayoutEnum.js","../../../node_modules/@inter-ikea-kompis/component-add-to-list/lib/enums/AddToListStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-add-to-list/lib/trackers/AddToListTracker.js","../../../node_modules/@inter-ikea-kompis/component-add-to-list/lib/components/add-to-list/AddToListStyle.js","../../../node_modules/@inter-ikea-kompis/component-add-to-list/lib/components/add-to-list/AddToList.js","../../../node_modules/@inter-ikea-kompis/component-add-to-list/lib/utilities/AddToListToastMessage.js","../../../node_modules/@ingka/common-styles-webc/src/utils/feature-configurator.js","../../../node_modules/@ingka/common-styles-webc/src/FocusRing.js","../../../node_modules/@ingka/common-styles-webc/src/Hyperlink.js","../../../node_modules/@ingka/common-styles-webc/src/Table.js","../../../node_modules/@ingka/common-styles-webc/src/Text.js","../../../node_modules/@ingka/inline-message-webc/src/InlineMessage.js","../../../node_modules/@ingka/modal-webc/src/utils/scroll-lock.js","../../../node_modules/@ingka/focus-lock-shared/esm/utils/focus-lock-event.mjs","../../../node_modules/@ingka/focus-lock-shared/esm/utils/helpers.mjs","../../../node_modules/@ingka/focus-lock-shared/esm/utils/focus-catcher.mjs","../../../node_modules/@ingka/focus-lock-shared/esm/index.mjs","../../../node_modules/@ingka/modal-webc/src/ModalAbstract.js","../../../node_modules/@ingka/modal-webc/src/Sheet.js","../../../node_modules/@ingka/modal-webc/node_modules/@ingka/icons-shared/esm/paths/arrow-left.mjs","../../../node_modules/@ingka/modal-webc/node_modules/@ingka/icons-shared/esm/paths/cross.mjs","../../../node_modules/@ingka/modal-webc/node_modules/@ingka/icons-shared/esm/paths/warning-triangle.mjs","../../../node_modules/@ingka/modal-webc/node_modules/@ingka/icon-webc/src/tools/svg-renderer.js","../../../node_modules/@ingka/modal-webc/node_modules/@ingka/icon-webc/src/Icon.js","../../../node_modules/@ingka/modal-webc/node_modules/@ingka/button-webc/src/common/DangerIcon.js","../../../node_modules/@ingka/modal-webc/node_modules/@ingka/button-webc/src/common/LoadingBall.js","../../../node_modules/@ingka/modal-webc/node_modules/@ingka/button-webc/src/common/ButtonAbstract.js","../../../node_modules/@ingka/modal-webc/node_modules/@ingka/button-webc/src/Button.js","../../../node_modules/@ingka/modal-webc/node_modules/@ingka/button-webc/src/IconButton.js","../../../node_modules/@ingka/modal-webc/src/ModalFooter.js","../../../node_modules/@ingka/modal-webc/src/ModalHeader.js","../../../node_modules/@ingka/modal-webc/src/Prompt.js","../../../node_modules/@inter-ikea-kompis/component-add-to-bag/lib/enums/AddToBagLayoutEnum.js","../../../node_modules/@inter-ikea-kompis/component-add-to-bag/lib/enums/AddToBagModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-add-to-bag/lib/enums/AddToBagStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-add-to-bag/lib/enums/AddToListLayoutEnum.js","../../../node_modules/@inter-ikea-kompis/component-add-to-bag/lib/enums/UnavailableOnlineBehaviourEnum.js","../../../node_modules/@inter-ikea-kompis/component-add-to-bag/lib/trackers/AddToBagTracker.js","../../../node_modules/@inter-ikea-kompis/component-do-not-diy/lib/components/do-not-diy/DoNotDiyStyle.js","../../../node_modules/@inter-ikea-kompis/component-do-not-diy/lib/components/do-not-diy/DoNotDiy.js","../../../node_modules/@ingka/skeleton-webc/src/Skeleton.js","../../../node_modules/@inter-ikea-kompis/component-image/lib/enums/ImageAspectRatioEnum.js","../../../node_modules/@inter-ikea-kompis/component-image/lib/components/image/ImageStyle.js","../../../node_modules/@inter-ikea-kompis/component-image/lib/components/image/Image.js","../../../node_modules/@inter-ikea-kompis/component-price-formatter/lib/enums/VerticalAlignmentEnum.js","../../../node_modules/@inter-ikea-kompis/component-price-formatter/lib/components/price-formatter/PriceFormatterStyle.js","../../../node_modules/@inter-ikea-kompis/component-price-formatter/lib/components/price-formatter/PriceFormatter.js","../../../node_modules/@inter-ikea-kompis/component-focus-outline/lib/enums/FocusOutlinePositionWatcherEnum.js","../../../node_modules/@inter-ikea-kompis/component-focus-outline/lib/enums/FocusOutlineStyleTypeEnum.js","../../../node_modules/@inter-ikea-kompis/component-focus-outline/lib/components/focus-outline/FocusOutlineStyle.js","../../../node_modules/@inter-ikea-kompis/component-focus-outline/lib/components/focus-outline/FocusOutline.js","../../../node_modules/@inter-ikea-kompis/component-hyperlink/lib/enums/HyperlinkColorEnum.js","../../../node_modules/@inter-ikea-kompis/component-hyperlink/lib/enums/HyperlinkTargetEnum.js","../../../node_modules/@inter-ikea-kompis/component-hyperlink/lib/components/hyperlink/HyperlinkStyle.js","../../../node_modules/@inter-ikea-kompis/component-hyperlink/lib/components/hyperlink/Hyperlink.js","../../../node_modules/@inter-ikea-kompis/keyboard-manager/lib/enums/InputModeEnum.js","../../../node_modules/@inter-ikea-kompis/keyboard-manager/lib/enums/KeyboardTypeEnum.js","../../../node_modules/@inter-ikea-kompis/keyboard-manager/lib/KeyboardManager.js","../../../node_modules/@inter-ikea-kompis/component-keyboard/lib/enums/KeyboardKeyCodeEnum.js","../../../node_modules/@inter-ikea-kompis/component-keyboard/lib/enums/KeyboardLayout.js","../../../node_modules/@inter-ikea-kompis/component-keyboard/lib/components/keyboard-button/KeyboardButtonStyle.js","../../../node_modules/@inter-ikea-kompis/component-keyboard/lib/components/keyboard-button/KeyboardButton.js","../../../node_modules/@inter-ikea-kompis/component-keyboard/lib/enums/KeyboardTransition.js","../../../node_modules/@inter-ikea-kompis/component-keyboard/lib/components/keyboard/KeyboardStyle.js","../../../node_modules/@inter-ikea-kompis/component-keyboard/lib/components/keyboard/Keyboard.js","../../../node_modules/@inter-ikea-kompis/component-keyboard/lib/components/keyboard-injector/KeyboardInjectorStyle.js","../../../node_modules/@inter-ikea-kompis/component-keyboard/lib/components/keyboard-injector/KeyboardInjector.js","../../../node_modules/@inter-ikea-kompis/component-keyboard/lib/utility/KeyboardInjectorFinder.js","../../../node_modules/@inter-ikea-kompis/component-eco-fee/lib/enums/EcoFeeModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-eco-fee/lib/components/eco-fee-card/EcoFeeCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-eco-fee/lib/components/eco-fee-card/EcoFeeCard.js","../../../node_modules/@inter-ikea-kompis/component-eco-fee/lib/components/eco-fee/EcoFeeStyle.js","../../../node_modules/@inter-ikea-kompis/component-eco-fee/lib/components/eco-fee/EcoFee.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/enums/EnergyEfficiencyClassMediaEnum.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/enums/EnergyEfficiencyClassModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/components/energy-efficiency-non-rescaled/EnergyEfficiencyNonRescaled.js","../../../node_modules/qrcode-generator/qrcode.js","../../../node_modules/@inter-ikea-kompis/component-qr-code/lib/components/qr-code/QrCode.js","../../../node_modules/@inter-ikea-kompis/component-text-toggle/lib/enums/TextToggleLayoutEnum.js","../../../node_modules/@inter-ikea-kompis/component-text-toggle/lib/enums/TextToggleSizeEnum.js","../../../node_modules/@inter-ikea-kompis/component-text-toggle/lib/components/text-toggle/TextToggleStyle.js","../../../node_modules/@inter-ikea-kompis/component-text-toggle/lib/components/text-toggle/TextToggle.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/components/eprel-qr/EprelQrStyle.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/components/eprel-qr/EprelQr.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/components/eprel-qr-toggle/EprelQrToggle.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/components/energy-label-card/EnergyLabelCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/components/energy-label-card/EnergyLabelCard.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/components/energy-efficiency-class/EnergyEfficiencyClassStyle.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/components/energy-efficiency-class/EnergyEfficiencyClass.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/components/energy-fiche-card/EnergyFicheCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/components/energy-fiche-card/EnergyFicheCard.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/enums/EprelLinkModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/components/eprel-link/EprelLink.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/enums/ChileSecLinkModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-energy-efficiency-class/lib/components/sec-link/SecLink.js","../../../node_modules/@inter-ikea-kompis/component-repairability-index/lib/enums/RepairabilityIndexModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-repairability-index/lib/utilities/RepairabilityIndexUtility.js","../../../node_modules/@inter-ikea-kompis/component-repairability-index/lib/components/repairability-index-card/RepairabilityIndexCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-repairability-index/lib/components/repairability-index-card/RepairabilityIndexCard.js","../../../node_modules/@inter-ikea-kompis/component-repairability-index/lib/components/repairability-index/RepairabilityIndexStyle.js","../../../node_modules/@inter-ikea-kompis/component-repairability-index/lib/components/repairability-index/RepairabilityIndex.js","../../../node_modules/@inter-ikea-kompis/component-water-efficiency-class/lib/enums/WaterEfficiencyClassMediaEnum.js","../../../node_modules/@inter-ikea-kompis/component-water-efficiency-class/lib/enums/WaterEfficiencyClassModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-water-efficiency-class/lib/components/water-label-card/WaterLabelCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-water-efficiency-class/lib/components/water-label-card/WaterLabelCard.js","../../../node_modules/@inter-ikea-kompis/component-water-efficiency-class/lib/components/water-efficiency-class/WaterEfficiencyClassStyle.js","../../../node_modules/@inter-ikea-kompis/component-water-efficiency-class/lib/components/water-efficiency-class/WaterEfficiencyClass.js","../../../node_modules/@ingka/commercial-message-webc/src/CommercialMessage.js","../../../node_modules/@inter-ikea-kompis/component-price-module/lib/enums/PriceModuleLayoutTypeEnum.js","../../../node_modules/@inter-ikea-kompis/component-price-module/lib/enums/PriceModuleModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-price-module/lib/enums/PriceModuleProductLinkEnum.js","../../../node_modules/@inter-ikea-kompis/component-price-module/lib/utilities/PriceModuleUtility.js","../../../node_modules/@inter-ikea-kompis/component-price-module/lib/components/price-module/PriceModuleStyle.js","../../../node_modules/@inter-ikea-kompis/component-price-module/lib/components/price-module/PriceModule.js","../../../node_modules/@inter-ikea-kompis/component-quantity/lib/components/quantity/QuantityStyle.js","../../../node_modules/@inter-ikea-kompis/component-quantity/lib/components/quantity/Quantity.js","../../../node_modules/@ingka/fieldset-webc/src/Fieldset.js","../../../node_modules/@ingka/checkbox-webc/src/CheckboxGroup.js","../../../node_modules/@ingka/product-identifier-webc/src/ProductIdentifier.js","../../../node_modules/@ingka/status-webc/src/elements/icons.js","../../../node_modules/@ingka/status-webc/src/Status.js","../../../node_modules/@inter-ikea-kompis/component-product-row/lib/enums/ProductRowLayoutEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-row/lib/enums/ProductRowOptionalStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-row/lib/enums/ProductRowProductLinkEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-row/lib/enums/ProductRowProductMeasureEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-row/lib/utilities/ProductRowUtility.js","../../../node_modules/@inter-ikea-kompis/component-product-row/lib/components/compact-product-row/CompactProductRowStyle.js","../../../node_modules/@inter-ikea-kompis/component-product-row/lib/components/compact-product-row/LowInStockStatusDot.js","../../../node_modules/@inter-ikea-kompis/component-product-row/lib/components/compact-product-row/CompactProductRow.js","../../../node_modules/@inter-ikea-kompis/component-product-row/node_modules/@ingka/variables/esm/colours-css.mjs","../../../node_modules/@inter-ikea-kompis/component-product-row/lib/components/product-row/ProductRowStyle.js","../../../node_modules/@inter-ikea-kompis/component-product-row/lib/components/product-row/ProductRow.js","../../../node_modules/@inter-ikea-kompis/component-add-to-bag/lib/components/unavailable-products-card/UnavailableProductsCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-add-to-bag/lib/components/unavailable-products-card/UnavailableProductsCard.js","../../../node_modules/@inter-ikea-kompis/component-add-to-bag/lib/components/add-to-bag/AddToBagStyle.js","../../../node_modules/@inter-ikea-kompis/component-add-to-bag/lib/components/add-to-bag/AddToBag.js","../../../node_modules/@inter-ikea-kompis/component-assembly-services/lib/components/assembly-services-status-button/AssemblyServicesStatusButtonStyle.js","../../../node_modules/@inter-ikea-kompis/component-assembly-services/lib/components/assembly-services-status-button/AssemblyServicesStatusButton.js","../../../node_modules/@inter-ikea-kompis/component-assembly-services/lib/trackers/AssemblyServicesTracker.js","../../../node_modules/@inter-ikea-kompis/component-assembly-services/lib/components/assembly-services/AssemblyServicesStyle.js","../../../node_modules/@inter-ikea-kompis/component-assembly-services/lib/components/assembly-services/AssemblyServices.js","../../../node_modules/@inter-ikea-kompis/component-assistance-card/lib/components/assistance-card/AssistanceCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-assistance-card/lib/components/assistance-card/AssistanceCard.js","../../../node_modules/@inter-ikea-kompis/component-button/lib/enums/ButtonAlignEnum.js","../../../node_modules/@inter-ikea-kompis/component-button/lib/enums/ButtonSizeEnum.js","../../../node_modules/@inter-ikea-kompis/component-button/lib/enums/ButtonTypeEnum.js","../../../node_modules/@inter-ikea-kompis/component-button/lib/enums/ButtonOverlayColorEnum.js","../../../node_modules/@inter-ikea-kompis/component-button/lib/components/button/ButtonStyle.js","../../../node_modules/@inter-ikea-kompis/component-button/lib/components/button/Button.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisButton.js","../../../node_modules/@inter-ikea-kompis/component-buy-in-store/node_modules/@ingka/variables/esm/colours-css.mjs","../../../node_modules/@inter-ikea-kompis/component-buy-in-store/node_modules/@ingka/variables/esm/design-tokens.mjs","../../../node_modules/@inter-ikea-kompis/component-buy-in-store/lib/components/buy-in-store-card/BuyInStoreCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-buy-in-store/lib/components/buy-in-store-card/BuyInStoreCard.js","../../../node_modules/@inter-ikea-kompis/component-buy-in-store/lib/enums/BuyInStoreModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-buy-in-store/lib/components/buy-in-store/BuyInStore.js","../../../node_modules/@inter-ikea-kompis/component-carousel/lib/enums/CarouselLayoutEnum.js","../../../node_modules/@inter-ikea-kompis/component-carousel/lib/components/carousel-controls/CarouselControls.js","../../../node_modules/@inter-ikea-kompis/component-carousel/lib/components/carousel-item/CarouselItem.js","../../../node_modules/@inter-ikea-kompis/component-carousel/lib/components/carousel/CarouselStyle.js","../../../node_modules/@inter-ikea-kompis/component-carousel/lib/components/carousel/Carousel.js","../../../node_modules/@inter-ikea-kompis/component-popover/lib/enums/PopoverAlignmentEnum.js","../../../node_modules/@inter-ikea-kompis/component-popover/lib/enums/PopoverDirectionEnum.js","../../../node_modules/@inter-ikea-kompis/component-popover/lib/components/popover-positioner/PopoverPositionerStyle.js","../../../node_modules/@inter-ikea-kompis/component-popover/lib/components/popover-positioner/PopoverPositioner.js","../../../node_modules/@inter-ikea-kompis/component-popover/lib/components/popover/Popover.js","../../../node_modules/@inter-ikea-kompis/component-popover/lib/components/popover-padding/PopoverPadding.js","../../../node_modules/@inter-ikea-kompis/component-popover/lib/components/popover-position/PopoverPosition.js","../../../node_modules/@inter-ikea-kompis/component-tooltip/lib/components/tooltip/Tooltip.js","../../../node_modules/@ingka/tooltip-webc/node_modules/@ingka/icons-shared/esm/paths/question-mark.mjs","../../../node_modules/@ingka/tooltip-webc/node_modules/@ingka/icons-shared/esm/paths/warning-triangle.mjs","../../../node_modules/@ingka/tooltip-webc/node_modules/@ingka/icon-webc/src/tools/svg-renderer.js","../../../node_modules/@ingka/tooltip-webc/node_modules/@ingka/icon-webc/src/Icon.js","../../../node_modules/@ingka/tooltip-webc/node_modules/@ingka/button-webc/src/common/DangerIcon.js","../../../node_modules/@ingka/tooltip-webc/node_modules/@ingka/button-webc/src/common/LoadingBall.js","../../../node_modules/@ingka/tooltip-webc/node_modules/@ingka/button-webc/src/common/ButtonAbstract.js","../../../node_modules/@ingka/tooltip-webc/node_modules/@ingka/button-webc/src/IconButton.js","../../../node_modules/@ingka/tooltip-shared/esm/index.mjs","../../../node_modules/@ingka/tooltip-webc/src/tools/escapeListener.js","../../../node_modules/@ingka/tooltip-webc/src/Tooltip.js","../../../node_modules/@inter-ikea-kompis/component-copy-design-code/lib/enums/CopyDesignCodeStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-copy-design-code/lib/components/copy-design-code/CopyDesignCodeStyle.js","../../../node_modules/@inter-ikea-kompis/component-copy-design-code/lib/components/copy-design-code/CopyDesignCode.js","../../../node_modules/@ingka/card-webc/node_modules/@ingka/icons-shared/esm/paths/arrow-right.mjs","../../../node_modules/@ingka/card-webc/node_modules/@ingka/icons-shared/esm/paths/image-strikethrough.mjs","../../../node_modules/@ingka/card-webc/node_modules/@ingka/icons-shared/esm/paths/image.mjs","../../../node_modules/@ingka/card-webc/node_modules/@ingka/icons-shared/esm/paths/warning-triangle.mjs","../../../node_modules/@ingka/card-webc/node_modules/@ingka/icon-webc/src/tools/svg-renderer.js","../../../node_modules/@ingka/card-webc/node_modules/@ingka/icon-webc/src/Icon.js","../../../node_modules/@ingka/card-webc/node_modules/@ingka/button-webc/src/common/DangerIcon.js","../../../node_modules/@ingka/card-webc/node_modules/@ingka/button-webc/src/common/LoadingBall.js","../../../node_modules/@ingka/card-webc/node_modules/@ingka/button-webc/src/common/ButtonAbstract.js","../../../node_modules/@ingka/card-webc/node_modules/@ingka/button-webc/src/IconButton.js","../../../node_modules/@ingka/aspect-ratio-box-webc/src/AspectRatioBox.js","../../../node_modules/@ingka/card-webc/node_modules/@ingka/image-webc/src/Image.js","../../../node_modules/@ingka/card-webc/src/Card.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/enums/ConfigurationSummaryConfirmationCardLogInAndSaveStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/enums/ConfigurationSummaryConfirmationCardStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/enums/ConfigurationSummaryConfirmationCardTypeEnum.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/enums/ConfirmationSummaryCopyDesignCodeStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/trackers/ConfigurationSummaryConfirmationCardTracker.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/components/configuration-summary-confirmation-card/ConfigurationSummaryConfirmationCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/components/configuration-summary-confirmation-card/ConfigurationSummaryConfirmationCard.js","../../../node_modules/@inter-ikea-kompis/component-input/lib/enums/InputLayoutEnum.js","../../../node_modules/@inter-ikea-kompis/component-input/lib/enums/InputTypeEnum.js","../../../node_modules/@inter-ikea-kompis/component-input/lib/components/input/InputStyle.js","../../../node_modules/@inter-ikea-kompis/component-input/lib/components/input/Input.js","../../../node_modules/@inter-ikea-kompis/component-send-by-email/lib/enums/SendByEmailStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-send-by-email/lib/components/send-by-email/SendByEmailStyle.js","../../../node_modules/@inter-ikea-kompis/component-send-by-email/lib/components/send-by-email/SendByEmail.js","../../../node_modules/@ingka/image-webc/src/Image.js","../../../node_modules/@inter-ikea-kompis/component-share-design-card/lib/enums/ShareDesignCardCopyStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-share-design-card/lib/enums/ShareDesignCardStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-share-design-card/lib/trackers/ShareDesignCardTracker.js","../../../node_modules/@inter-ikea-kompis/component-share-design-card/lib/components/share-design-card/ShareDesignCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-share-design-card/lib/components/share-design-card/ShareDesignCard.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/enums/ConfigurationSummaryModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/components/configuration-summary-share-design-sheet/ConfigurationSummaryShareDesignSheet.js","../../../node_modules/@inter-ikea-kompis/component-add-to-bag/lib/utilities/AddToBagToastMessage.js","../../../node_modules/@inter-ikea-kompis/component-sheet/lib/enums/SheetAlignmentEnum.js","../../../node_modules/@inter-ikea-kompis/component-sheet/lib/enums/SheetAnimationNameEnum.js","../../../node_modules/@inter-ikea-kompis/component-sheet/lib/enums/SheetSizeEnum.js","../../../node_modules/@inter-ikea-kompis/component-sheet/lib/enums/SheetStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-sheet/lib/components/sheet-backdrop/SheetBackdropStyle.js","../../../node_modules/@inter-ikea-kompis/component-sheet/lib/components/sheet-backdrop/SheetBackdrop.js","../../../node_modules/@inter-ikea-kompis/component-sheet/lib/components/sheet-header/SheetHeaderStyle.js","../../../node_modules/@inter-ikea-kompis/component-sheet/lib/components/sheet-header/SheetHeader.js","../../../node_modules/@inter-ikea-kompis/component-sheet/lib/components/sheet/SheetStyle.js","../../../node_modules/@inter-ikea-kompis/component-sheet/lib/components/sheet/Sheet.js","../../../node_modules/@inter-ikea-kompis/component-sheet/lib/components/sheet-body/SheetBody.js","../../../node_modules/@inter-ikea-kompis/component-sheet/lib/components/sheet-body-padding/SheetBodyPadding.js","../../../node_modules/@inter-ikea-kompis/component-sheet/lib/components/sheet-footer/SheetFooterStyle.js","../../../node_modules/@inter-ikea-kompis/component-sheet/lib/components/sheet-footer/SheetFooter.js","../../../node_modules/@inter-ikea-kompis/component-financial-services/lib/enums/FinancialServicesModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-financial-services/lib/trackers/FinancialServicesTracker.js","../../../node_modules/@inter-ikea-kompis/component-financial-services/lib/components/financial-services-buttons/FinancialServicesButtonsStyle.js","../../../node_modules/@inter-ikea-kompis/component-financial-services/lib/components/financial-services-buttons/FinancialServicesButtons.js","../../../node_modules/@inter-ikea-kompis/component-financial-services/lib/components/financial-services-card/FinancialServicesCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-financial-services/lib/components/financial-services-card/FinancialServicesCard.js","../../../node_modules/@inter-ikea-kompis/component-financial-services/lib/components/financial-services-link/FinancialServicesLink.js","../../../node_modules/@inter-ikea-kompis/component-financial-services/lib/components/financial-services/FinancialServicesStyle.js","../../../node_modules/@inter-ikea-kompis/component-financial-services/lib/components/financial-services/FinancialServices.js","../../../node_modules/@inter-ikea-kompis/component-save-design-to-profile/lib/enums/SaveDesignToProfileModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-save-design-to-profile/lib/enums/SaveDesignToProfileStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-save-design-to-profile/lib/components/save-design-to-profile-card/SaveDesignToProfileCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-save-design-to-profile/lib/components/save-design-to-profile-card/SaveDesignToProfileCard.js","../../../node_modules/@inter-ikea-kompis/component-save-design-to-profile/lib/components/save-design-to-profile/SaveDesignToProfile.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/enums/ConfirmationSummaryKioskMainCTAButtonStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/enums/ConfirmationSummaryShareDesignStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/trackers/ConfigurationSummaryTracker.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/utilities/ConfigurationSummaryWeightUtility.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/components/configuration-summary/ConfigurationSummaryStyle.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/components/configuration-summary/ConfigurationSummary.js","../../../node_modules/@inter-ikea-kompis/component-content-margins/lib/utilities/StyleUtility.js","../../../node_modules/@inter-ikea-kompis/component-countdown-banner/lib/enums/CountdownBannerAnimationNameEnum.js","../../../node_modules/@inter-ikea-kompis/component-countdown-banner/lib/components/countdown/CountdownStyle.js","../../../node_modules/@inter-ikea-kompis/component-countdown-banner/lib/components/countdown/Countdown.js","../../../node_modules/@inter-ikea-kompis/component-countdown-banner/lib/components/countdown-banner/CountdownBannerStyle.js","../../../node_modules/@inter-ikea-kompis/component-countdown-banner/lib/components/countdown-banner/CountdownBanner.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisCountdownBanner.js","../../../node_modules/@inter-ikea-kompis/component-divider/lib/enums/DividerTypeEnum.js","../../../node_modules/@inter-ikea-kompis/component-divider/lib/components/divider/DividerStyle.js","../../../node_modules/@inter-ikea-kompis/component-divider/lib/components/divider/Divider.js","../../../node_modules/@inter-ikea-kompis/component-fake-data/lib/components/fake-data/FakeDataStyle.js","../../../node_modules/@inter-ikea-kompis/component-fake-data/lib/components/fake-data/FakeData.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisFakeData.js","../../../node_modules/@inter-ikea-kompis/component-function-icon/lib/enums/FunctionIconEnum.js","../../../node_modules/@inter-ikea-kompis/component-function-icon/lib/components/function-icon/FunctionIconStyle.js","../../../node_modules/@inter-ikea-kompis/component-function-icon/lib/components/function-icon/FunctionIcon.js","../../../node_modules/@inter-ikea-kompis/component-home-delivery/lib/enums/HomeDeliveryAvailabilityEnum.js","../../../node_modules/@inter-ikea-kompis/component-home-delivery/lib/enums/HomeDeliveryLevelEnum.js","../../../node_modules/@inter-ikea-kompis/component-home-delivery/lib/utilities/HomeDeliveryUtility.js","../../../node_modules/@inter-ikea-kompis/component-home-delivery/lib/components/home-delivery/HomeDeliveryStyle.js","../../../node_modules/@inter-ikea-kompis/component-home-delivery/lib/components/home-delivery/HomeDelivery.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisHyperlink.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisIcon.js","../../../node_modules/@inter-ikea-kompis/component-icon-button/lib/enums/IconButtonSizeEnum.js","../../../node_modules/@inter-ikea-kompis/component-icon-button/lib/enums/IconButtonOverlayColorEnum.js","../../../node_modules/@inter-ikea-kompis/component-icon-button/lib/components/icon-button/IconButtonStyle.js","../../../node_modules/@inter-ikea-kompis/component-icon-button/lib/components/icon-button/IconButton.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisIconButton.js","../../../node_modules/@inter-ikea-kompis/component-icon-pill/lib/enums/IconPillSizeOptionsEnum.js","../../../node_modules/@inter-ikea-kompis/component-icon-pill/lib/components/icon-pill/IconPillStyle.js","../../../node_modules/@inter-ikea-kompis/component-icon-pill/lib/components/icon-pill/IconPill.js","../../../node_modules/@inter-ikea-kompis/component-icon-pill/lib/components/icon-pill-group/IconPillGroupStyle.js","../../../node_modules/@inter-ikea-kompis/component-icon-pill/lib/components/icon-pill-group/IconPillGroup.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisIconPill.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisImage.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisKeyboardInjector.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisKeyboard.js","../../../node_modules/@ingka/collapsible-webc/src/Collapsible.js","../../../node_modules/@ingka/choice-webc/src/ChoiceItem.js","../../../node_modules/@ingka/choice-webc/src/Choice.js","../../../node_modules/@inter-ikea-kompis/component-language-selector/lib/components/language-selector-card/LanguageSelectorCard.js","../../../node_modules/@inter-ikea-kompis/component-language-selector/lib/components/language-selector-link-group/LanguageSelectorLinkGroupStyle.js","../../../node_modules/@inter-ikea-kompis/component-language-selector/lib/components/language-selector-link-group/LanguageSelectorLinkGroup.js","../../../node_modules/@inter-ikea-kompis/component-language-selector/lib/enums/LanguageSelectorLayoutEnum.js","../../../node_modules/@inter-ikea-kompis/component-language-selector/lib/enums/LanguageSelectorModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-language-selector/lib/enums/LanguageSelectorSizeEnum.js","../../../node_modules/@inter-ikea-kompis/component-language-selector/lib/components/language-selector/LanguageSelectorStyle.js","../../../node_modules/@inter-ikea-kompis/component-language-selector/lib/components/language-selector/LanguageSelector.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisLanguageSelector.js","../../../node_modules/@ingka/carousel-webc/src/features/utils/speed-tracker.js","../../../node_modules/@ingka/carousel-webc/src/elements/CarouselControls.js","../../../node_modules/@ingka/carousel-webc/src/elements/Scrollbar.js","../../../node_modules/@ingka/carousel-webc/src/features/utils/smooth-scroll.js","../../../node_modules/@ingka/carousel-webc/src/features/feature-base.js","../../../node_modules/@ingka/carousel-webc/src/features/rtl-handler.js","../../../node_modules/@ingka/carousel-webc/src/features/scroll-handler.js","../../../node_modules/@ingka/carousel-webc/src/features/slide-visibility.js","../../../node_modules/@ingka/carousel-webc/src/features/slide-index.js","../../../node_modules/@ingka/carousel-webc/src/features/paging-controls.js","../../../node_modules/@ingka/carousel-webc/src/features/child-focus-handler.js","../../../node_modules/@ingka/carousel-webc/src/features/touch-mode-detection.js","../../../node_modules/@ingka/carousel-webc/src/features/resize-handler.js","../../../node_modules/@ingka/carousel-webc/src/features/auto-slide-size.js","../../../node_modules/@ingka/carousel-webc/src/CarouselBase.js","../../../node_modules/@ingka/carousel-webc/src/features/slide-show.js","../../../node_modules/@ingka/carousel-webc/src/features/skip-listing.js","../../../node_modules/@ingka/carousel-webc/src/features/scrollbar-handler.js","../../../node_modules/@ingka/carousel-webc/src/Carousel.js","../../../node_modules/@inter-ikea-kompis/component-media-carousel/lib/components/media-carousel/MediaCarouselStyle.js","../../../node_modules/@inter-ikea-kompis/component-media-carousel/lib/components/media-carousel/MediaCarousel.js","../../../node_modules/@inter-ikea-kompis/component-mini-price/lib/enums/MiniPriceAlignmentEnum.js","../../../node_modules/@inter-ikea-kompis/component-mini-price/lib/enums/MiniPriceModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-mini-price/lib/components/mini-price/MiniPriceStyle.js","../../../node_modules/@inter-ikea-kompis/component-mini-price/lib/components/mini-price/MiniPrice.js","../../../node_modules/@inter-ikea-kompis/component-mini-configuration-summary/lib/enums/MiniConfigurationSummaryIconTypeEnum.js","../../../node_modules/@inter-ikea-kompis/component-mini-configuration-summary/lib/components/mini-configuration-summary/MiniConfigurationSummaryStyle.js","../../../node_modules/@inter-ikea-kompis/component-mini-configuration-summary/lib/components/mini-configuration-summary/MiniConfigurationSummary.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisMiniConfigurationSummary.js","../../../node_modules/@inter-ikea-kompis/component-mini-survey/lib/enums/MiniSurveyAnswerEnum.js","../../../node_modules/@inter-ikea-kompis/component-mini-survey/lib/enums/MiniSurveyLayoutEnum.js","../../../node_modules/@inter-ikea-kompis/component-mini-survey/lib/enums/MiniSurveyStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-mini-survey/lib/components/mini-survey-card/MiniSurveyCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-mini-survey/lib/components/mini-survey-card/MiniSurveyCard.js","../../../node_modules/@inter-ikea-kompis/component-mini-survey/lib/enums/MiniSurveyAnimationNameEnum.js","../../../node_modules/@inter-ikea-kompis/component-mini-survey/lib/components/mini-survey/MiniSurveyStyle.js","../../../node_modules/@inter-ikea-kompis/component-mini-survey/lib/components/mini-survey/MiniSurvey.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisMiniSurvey.js","../../../node_modules/@inter-ikea-kompis/component-open-design-code/lib/enums/OpenDesignCodeStateEnum.js","../../../node_modules/@ingka/input-field-webc/node_modules/@ingka/icons-shared/esm/paths/checkmark-green-small.mjs","../../../node_modules/@ingka/input-field-webc/node_modules/@ingka/icons-shared/esm/paths/notice-red-small.mjs","../../../node_modules/@ingka/input-field-webc/node_modules/@ingka/icons-shared/esm/paths/warning-triangle-orange-small.mjs","../../../node_modules/@ingka/input-field-webc/node_modules/@ingka/icon-webc/src/tools/svg-renderer.js","../../../node_modules/@ingka/input-field-webc/node_modules/@ingka/icon-webc/src/Icon.js","../../../node_modules/@ingka/input-field-webc/node_modules/@ingka/helper-text-webc/src/HelperText.js","../../../node_modules/@ingka/input-field-webc/src/InputField.js","../../../node_modules/@inter-ikea-kompis/component-open-design-code/lib/enums/OpenDesignCodeLengthEnum.js","../../../node_modules/@inter-ikea-kompis/component-open-design-code/lib/components/open-design-code-input/OpenDesignCodeInputStyle.js","../../../node_modules/@inter-ikea-kompis/component-open-design-code/lib/components/open-design-code-input/OpenDesignCodeInput.js","../../../node_modules/@inter-ikea-kompis/component-open-design-code/lib/components/open-design-code/OpenDesignCodeStyle.js","../../../node_modules/@inter-ikea-kompis/component-open-design-code/lib/components/open-design-code/OpenDesignCode.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/icons-shared/esm/paths/chevron-left-small.mjs","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/icons-shared/esm/paths/chevron-left.mjs","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/icons-shared/esm/paths/chevron-right-small.mjs","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/icons-shared/esm/paths/chevron-right.mjs","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/icons-shared/esm/paths/warning-triangle.mjs","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/icon-webc/src/tools/svg-renderer.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/icon-webc/src/Icon.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/button-webc/src/common/DangerIcon.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/button-webc/src/common/LoadingBall.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/button-webc/src/common/ButtonAbstract.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/button-webc/src/IconButton.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/carousel-webc/src/elements/CarouselControls.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/carousel-webc/src/features/utils/smooth-scroll.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/carousel-webc/src/features/feature-base.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/carousel-webc/src/features/rtl-handler.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/carousel-webc/src/features/scroll-handler.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/carousel-webc/src/features/slide-visibility.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/carousel-webc/src/features/slide-index.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/carousel-webc/src/features/paging-controls.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/carousel-webc/src/features/child-focus-handler.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/carousel-webc/src/features/touch-mode-detection.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/carousel-webc/src/features/resize-handler.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/carousel-webc/src/features/auto-slide-size.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/carousel-webc/src/CarouselBase.js","../../../node_modules/@ingka/tabs-webc/node_modules/@ingka/carousel-webc/src/OverflowCarousel.js","../../../node_modules/@ingka/tabs-webc/src/features/selection-highlight.js","../../../node_modules/@ingka/tabs-webc/src/utils/accessible-tab.js","../../../node_modules/@ingka/tabs-webc/src/features/key-handler.js","../../../node_modules/@ingka/tabs-webc/src/features/tab-decorator.js","../../../node_modules/@ingka/tabs-webc/src/features/selection-event.js","../../../node_modules/@ingka/tabs-webc/src/Tabs.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisOpenDesignCode.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisPopoverPadding.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisPopoverPosition.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisPopover.js","../../../node_modules/@inter-ikea-kompis/component-product-information-section/lib/components/measurements-card/MeasurementsCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-product-information-section/lib/components/measurements-card/MeasurementsCard.js","../../../node_modules/@inter-ikea-kompis/component-wood-declaration/lib/components/wood-declaration-card/WoodDeclarationCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-wood-declaration/lib/components/wood-declaration-card/WoodDeclarationCard.js","../../../node_modules/@inter-ikea-kompis/component-wood-declaration/lib/components/wood-declaration/WoodDeclarationStyle.js","../../../node_modules/@inter-ikea-kompis/component-wood-declaration/lib/components/wood-declaration/WoodDeclaration.js","../../../node_modules/@inter-ikea-kompis/component-product-information-section/lib/enums/ProductInformationExpandedAccordionEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-information-section/lib/enums/ProductInformationSectionSecurityAndComplianceEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-information-section/lib/components/product-details-card/ProductDetailsCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-product-information-section/lib/components/product-details-card/ProductDetailsCard.js","../../../node_modules/@inter-ikea-kompis/component-product-information-section/lib/enums/ProductInformationSectionModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-information-section/lib/components/technical-information-card/TechnicalInformationCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-product-information-section/lib/components/technical-information-card/TechnicalInformationCard.js","../../../node_modules/@inter-ikea-kompis/component-product-information-section/lib/components/product-information-section/ProductInformationSection.js","../../../node_modules/@inter-ikea-kompis/component-store-selector/lib/enums/StoreSelectorLayoutEnum.js","../../../node_modules/@inter-ikea-kompis/component-store-selector/lib/enums/StoreSelectorModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-store-selector/lib/enums/StoreSelectorTagNameEnum.js","../../../node_modules/@inter-ikea-kompis/component-store-selector/lib/components/store-selector-card/StoreSelectorCard.js","../../../node_modules/@inter-ikea-kompis/component-store-selector/lib/components/store-selector/StoreSelectorStyle.js","../../../node_modules/@inter-ikea-kompis/component-store-selector/lib/components/store-selector/StoreSelector.js","../../../node_modules/@inter-ikea-kompis/component-zip-in/lib/enums/ZipInActionEnum.js","../../../node_modules/@inter-ikea-kompis/component-zip-in/lib/enums/ZipInCardStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-zip-in/lib/enums/ZipInModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-zip-in/lib/trackers/ZipInTracker.js","../../../node_modules/@ingka/helper-text-webc/src/HelperText.js","../../../node_modules/@inter-ikea-kompis/component-zip-in/lib/components/zip-in-card/ZipInCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-zip-in/lib/components/zip-in-card/ZipInCard.js","../../../node_modules/@inter-ikea-kompis/component-zip-in/lib/components/zip-in/ZipIn.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/enums/ProductCardMediaEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/enums/ProductCardModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/enums/ProductCardPriceLayoutTypeEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/components/product-card-media/ProductCardMediaStyle.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/components/product-card-media/ProductCardMedia.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/components/product-card-water-sense-image/ProductCardWaterSenseImage.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/enums/ProductCardOrderEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/components/information-card/InformationCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/components/information-card/InformationCard.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/enums/ListGalleryCardMediaEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/enums/ProductCardInfoIconButtonLinkTargetEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/enums/ProductCardLayoutEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/enums/ProductCardSelectBehaviourEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/enums/ProductCardSelectedStateEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/components/product-card-variants/ProductCardVariantsStyle.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/components/product-card-variants/ProductCardVariants.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/components/list-gallery-card/ListGalleryCardStyle.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/components/list-gallery-card/ListGalleryCard.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/trackers/ProductCardTracker.js","../../../node_modules/@inter-ikea-kompis/component-product-card/lib/components/product-card/ProductCard.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisProductCard.js","../../../node_modules/@ingka/badge-webc/src/Badge.js","../../../node_modules/@inter-ikea-kompis/component-product-list/lib/components/product-list-section/ProductListSectionStyle.js","../../../node_modules/@inter-ikea-kompis/component-product-list/lib/components/product-list-section/ProductListSection.js","../../../node_modules/@inter-ikea-kompis/component-product-list/lib/enums/ProductListModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-list/lib/components/product-list-total-price/ProductListTotalPriceStyle.js","../../../node_modules/@inter-ikea-kompis/component-product-list/lib/components/product-list-total-price/ProductListTotalPrice.js","../../../node_modules/@inter-ikea-kompis/component-sort-list/lib/enums/SortListModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-sort-list/lib/enums/SortListOptionsEnum.js","../../../node_modules/@inter-ikea-kompis/component-sort-list/lib/utilities/LabelUtility.js","../../../node_modules/@inter-ikea-kompis/component-sort-list/lib/components/sort-list-card/SortListCard.js","../../../node_modules/@inter-ikea-kompis/component-sort-list/lib/components/sort-list/SortListStyle.js","../../../node_modules/@inter-ikea-kompis/component-sort-list/lib/components/sort-list/SortList.js","../../../node_modules/@inter-ikea-kompis/component-product-list/lib/utilities/ProductListSorting.js","../../../node_modules/@inter-ikea-kompis/component-product-list/lib/utilities/ProductListSprUtility.js","../../../node_modules/@inter-ikea-kompis/component-product-list/lib/components/product-list/ProductListStyle.js","../../../node_modules/@inter-ikea-kompis/component-product-list/lib/components/product-list/ProductList.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisProductList.js","../../../node_modules/@inter-ikea-kompis/component-product-shelf/lib/enums/ProductShelfProductCardMediaEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-shelf/lib/enums/ProductShelfProductLinkEnum.js","../../../node_modules/@inter-ikea-kompis/component-product-shelf/lib/components/product-shelf/ProductShelfStyle.js","../../../node_modules/@inter-ikea-kompis/component-product-shelf/lib/components/product-shelf/ProductShelf.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisProductShelf.js","../../../node_modules/@inter-ikea-kompis/component-prompt/lib/enums/PromptButtonTypeEnum.js","../../../node_modules/@inter-ikea-kompis/component-prompt/lib/enums/PromptAnimationNameEnum.js","../../../node_modules/@inter-ikea-kompis/component-prompt/lib/components/prompt/PromptStyle.js","../../../node_modules/@inter-ikea-kompis/component-prompt/lib/components/prompt/Prompt.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisPrompt.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisSheetBodyPadding.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisSheetBody.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisSheetHeader.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisSheet.js","../../../node_modules/@inter-ikea-kompis/component-configuration-summary/lib/utilities/ConfigurationSummaryToastMessage.js","../../../node_modules/@inter-ikea-kompis/component-toast/lib/enums/ToastAnimationNameEnum.js","../../../node_modules/@inter-ikea-kompis/component-toast/lib/utils/ToastFocusUtil.js","../../../node_modules/@inter-ikea-kompis/component-toast/lib/components/toast/ToastStyle.js","../../../node_modules/@inter-ikea-kompis/component-toast/lib/components/toast/Toast.js","../../../node_modules/@inter-ikea-kompis/component-toast/lib/ToastManager.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/enums/SummaryPageConfigurationMeasureEnum.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/enums/SummaryPageConfirmationCardTypeEnum.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/enums/SummaryPageModalEnum.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/utilities/SummaryPageCustomTabsUtility.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/enums/InlineMessageIconEnum.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/enums/InlineMessageLayoutEnum.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/enums/SummaryPageTabEnum.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/trackers/SummaryPageAnalyticsContext.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/trackers/SummaryPageTracker.js","../../../node_modules/@inter-ikea-kompis/browser-support/node_modules/bowser/src/constants.js","../../../node_modules/@inter-ikea-kompis/browser-support/node_modules/bowser/src/utils.js","../../../node_modules/@inter-ikea-kompis/browser-support/node_modules/bowser/src/parser-browsers.js","../../../node_modules/@inter-ikea-kompis/browser-support/node_modules/bowser/src/parser-os.js","../../../node_modules/@inter-ikea-kompis/browser-support/node_modules/bowser/src/parser-platforms.js","../../../node_modules/@inter-ikea-kompis/browser-support/node_modules/bowser/src/parser-engines.js","../../../node_modules/@inter-ikea-kompis/browser-support/node_modules/bowser/src/parser.js","../../../node_modules/@inter-ikea-kompis/browser-support/node_modules/bowser/src/bowser.js","../../../node_modules/@inter-ikea-kompis/browser-support/lib/browser-detection/BrowserDetection.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/utilities/SummaryPageBrowserUtility.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/utilities/SummaryPageMeasurementUtility.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/components/summary-page-images/SummaryPageImages.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/components/summary-page-header/IkeaLogo.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/node_modules/@ingka/variables/esm/colours-css.mjs","../../../node_modules/@inter-ikea-kompis/component-summary-page/node_modules/@ingka/variables/esm/design-tokens.mjs","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/components/summary-page-print/SummaryPagePrintStyle.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/components/summary-page-print/SummaryPagePrint.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/components/summary-page-product-list/SummaryPageProductListStyle.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/components/summary-page-product-list/SummaryPageProductList.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/components/summary-page-security/SummaryPageSecurityStyle.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/components/summary-page-security/SummaryPageSecurity.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/enums/PrintableContentEnum.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/components/summary-page-tabs/SummaryPageTabsStyle.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/components/summary-page-tabs/SummaryPageTabs.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/utilities/SummaryPagePaddingUtility.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/components/summary-page/SummaryPageStyle.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/components/summary-page/SummaryPage.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/components/summary-page-footer/SummaryPageFooterStyle.js","../../../node_modules/@inter-ikea-kompis/component-summary-page/lib/components/summary-page-footer/SummaryPageFooter.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisSummaryPageFooter.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisSummaryPage.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisText.js","../../../node_modules/@inter-ikea-kompis/component-toggle/lib/components/toggle/ToggleStyle.js","../../../node_modules/@inter-ikea-kompis/component-toggle/lib/components/toggle/Toggle.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisToggle.js","../../../node_modules/@inter-ikea-kompis/react-components/lib/KompisTooltip.js","../../../node_modules/polybooljs/lib/build-log.js","../../../node_modules/polybooljs/lib/epsilon.js","../../../node_modules/polybooljs/lib/linked-list.js","../../../node_modules/polybooljs/lib/intersecter.js","../../../node_modules/polybooljs/lib/segment-chainer.js","../../../node_modules/polybooljs/lib/segment-selector.js","../../../node_modules/polybooljs/lib/geojson.js","../../../node_modules/polybooljs/index.js","../../../node_modules/two-product/two-product.js","../../../node_modules/robust-sum/robust-sum.js","../../../node_modules/two-sum/two-sum.js","../../../node_modules/robust-scale/robust-scale.js","../../../node_modules/robust-subtract/robust-diff.js","../../../node_modules/robust-orientation/orientation.js","../../../node_modules/robust-point-in-polygon/robust-pnp.js","../../../node_modules/lodash/lodash.js","../../../node_modules/@ikea-aoa/ikea-shared-styles/lib/variables/Screen.json.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/exception/AbstractClassException.js","../../../node_modules/@ikea-aoa/ikea-shared-component/lib/dom/ComponentBody.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/Console.js","../../../node_modules/@ikea-aoa/ikea-shared-component/lib/utility/UniqueComponentVerifier.js","../../../node_modules/@ikea-aoa/ikea-shared-component/lib/ComponentManager.js","../../../node_modules/@ikea-aoa/ikea-shared-component/lib/dom/DomMutation.js","../../../node_modules/@ikea-aoa/ikea-shared-component/lib/dom/ComponentDom.js","../../../node_modules/@ikea-aoa/ikea-shared-component/lib/prop/ComponentPropHandler.js","../../../node_modules/@ikea-aoa/ikea-shared-component/lib/event/ComponentEventHandler.js","../../../node_modules/@ikea-aoa/ikea-shared-component/lib/utility/ComponentCacheStore.js","../../../node_modules/@ikea-aoa/ikea-shared-component/lib/utility/ComponentResizeHandler.js","../../../node_modules/@ikea-aoa/ikea-shared-component/lib/utility/ComponentAttributeObserver.js","../../../node_modules/@ikea-aoa/ikea-shared-component/lib/AbstractComponent.js","../../../node_modules/@ikea-aoa/ikea-shared-component/lib/mock/SupportedMock.js","../../../node_modules/@ikea-aoa/ikea-shared-component/lib/prop/SupportedProp.js","../../../node_modules/@ikea-aoa/ikea-shared-component/lib/index.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/exception/ServiceException.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/ServiceSettings.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/CacheWaitItem.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/CacheNotFoundItem.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/exception/ServiceFacadeException.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/exception/TypeException.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/AbstractServiceFacade.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/AbstractService.js","../../../node_modules/@ikea-aoa/ikea-shared-utils/lib/exception/FactoryException.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/util/ServiceUrlUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/auth/IrwAuthService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/auth/NifAuthService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/platform/AbstractPlatformService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/platform/irw/IrwPlatformService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/platform/nwp/NwpPlatformClient.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/platform/nwp/NwpPlatformService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/platform/roig/RoigPlatformService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/article/AbstractArticleService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/article/retailitem/RetailItemParser.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/article/retailitem/IrwRetailItemService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/article/retailitem/NwpRetailItemService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/article/retailitem/WprwRetailItemService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/article/dexf/TypeCodeToGlobalTypeMap.json.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/facade/LocalizationServiceFacade.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/constant/EcommerceCartDataSourceConstant.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/util/LocalizationUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/article/dexf/DexfWebPlannerParser.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/article/dexf/DexfWebPlannerService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/shoppingbag/ShoppingBagService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/shoppingbag/NifCartService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/storeavailability/irw/IrwStoreAvailabilityParser.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/storeavailability/irw/IrwStoreAvailabilityService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/store/IrwStoreService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/store/NwpStoreService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/storeavailability/nwp/NwpStoreItemParser.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/storeavailability/nwp/NwpStoreItemService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/url/ApplicationUrlService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/vpc/AbstractVpcService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/vpc/iows/VpcSkeleton.json.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/vpc/iows/IowsVpcService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/vpc/dexf/DexfVpcService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/localization/LocalizationService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/seriesgallery/SeriesGalleryService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/auth/OneWebAuthService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/shoppingbag/OneWebCartService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/shoppingbag/OneWebShoppingListService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/shoppingbag/MvEcomService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/ServiceFactory.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/AbstractServiceConfig.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/article/ArticleServiceConfig.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/facade/ApplicationUrlServiceFacade.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/constant/ApiPlatformConstant.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/constant/ProductDataSourceConstant.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/facade/ArticleServiceFacade.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/facade/AuthServiceFacade.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/facade/PlatformServiceFacade.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/model/TotalPriceModel.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/util/TotalPriceCalculator.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/facade/PriceServiceFacade.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/constant/EcommerceShoppingListDataSourceConstant.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/enums/CacheStoreType.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/animation/EasingAnimation.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/debounce/DebounceManager.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/encoding/HtmlEncoder.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/iframe/IframeUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/string/StringUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/cache/CacheStore.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/cache/GlobalCacheStore.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/latch/Latch.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/locale/LocaleUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/date/DateFormatter.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/iframe/IframeVisibleArea.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/iframe/IframeVisibleAreaObserver.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/image/ImageUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/energy-class/EnergyClassParser.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/exceptions/lib/AbstractException.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/exceptions/lib/enums/ExceptionTypeEnum.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/exceptions/lib/exceptions/ComponentElementException.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/exceptions/lib/exceptions/ComponentException.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/exceptions/lib/exceptions/Exception.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/exceptions/lib/exceptions/ServerErrorResponseException.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/exceptions/lib/exceptions/ConnectionProblemException.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/exceptions/lib/exceptions/UnableToParseServerResponseException.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/exceptions/lib/exceptions/ServiceException.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/exceptions/lib/index.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/price/ProductPriceInformationSummaryTransformer.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/price/TotalPriceCalculator.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/measurement/MeasurementUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/price/PriceFormatter.js","../../../node_modules/@ikea-aoa/enums/lib/ApiPlatformEnum.js","../../../node_modules/@ikea-aoa/enums/lib/ImageTypeNameEnum.js","../../../node_modules/@ikea-aoa/enums/lib/SalesMethodCodeEnum.js","../../../node_modules/@ikea-aoa/enums/lib/InStockProbabilityEnum.js","../../../node_modules/@ikea-aoa/enums/lib/ProductDataSourceEnum.js","../../../node_modules/@ikea-aoa/enums/lib/VpcDataSourceEnum.js","../../../node_modules/@ikea-aoa/enums/lib/WriteDirectionEnum.js","../../../node_modules/@ikea-aoa/enums/lib/EcommerceCartDataSourceEnum.js","../../../node_modules/@ikea-aoa/enums/lib/EcommerceShoppingListDataSourceEnum.js","../../../node_modules/@ikea-aoa/enums/lib/CookieConsentDataSourceEnum.js","../../../node_modules/@ikea-aoa/enums/lib/SalesSystemEnum.js","../../../node_modules/@ikea-aoa/enums/lib/IowsShoppingBagTypeEnum.js","../../../node_modules/@ikea-aoa/enums/lib/ThemeBreakpointIndexEnum.js","../../../node_modules/@ikea-aoa/enums/lib/ThemeFontStyleTypeEnum.js","../../../node_modules/@ikea-aoa/enums/lib/ThemeIconSizeEnum.js","../../../node_modules/@ikea-aoa/enums/lib/ThemeSpacingEnum.js","../../../node_modules/@ikea-aoa/enums/lib/ThemeMotionDurationEnum.js","../../../node_modules/@ikea-aoa/enums/lib/ThemeBreakpointEnum.js","../../../node_modules/@ikea-aoa/enums/lib/ThemeMotionEaseEnum.js","../../../node_modules/@ikea-aoa/enums/lib/ThemeMotionIconDurationEnum.js","../../../node_modules/@ikea-aoa/enums/lib/DexfNotificationTypeEnum.js","../../../node_modules/@ikea-aoa/enums/lib/TemporaryPricePeriodEnum.js","../../../node_modules/@ikea-aoa/enums/lib/AutoCompleteEnum.js","../../../node_modules/@ikea-aoa/enums/lib/NotificationLinkTypeEnum.js","../../../node_modules/@ikea-aoa/enums/lib/InvalidProductReasonEnum.js","../../../node_modules/@ikea-aoa/enums/lib/index.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/price/PriceUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/write-direction/SafariWriteDirectionUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/product/ProductUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/cssLoader/CssLoader.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/javascriptLoader/JavascriptLoader.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/utilities/lib/index.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/utilities/platform-communication/IrwPlatformCommunication.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/platform/PlatformService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/utilities/ServiceFetch.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/product/DexfWebplannerService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/product/ProductCache.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/product/ProductItemQueue.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/localization/OversattaTransformer.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/localization/OversattaService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/localization/LocalizationService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/product/ProductService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/shopping/iows/IowsShoppingBagErrorCodes.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/shopping/iows/IowsShoppingBagService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/shopping/ingka/cart/IngkaCartService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/shopping/china/cart/ChinaCartService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/shopping/nif/enums/NifUnitTypeEnum.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/shopping/nif/NifCartService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/utilities/platform-communication/RoigPlatformCommunication.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/authentication/iows/IowsAuthenticationService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/utilities/IframeManager.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/authentication/one-web/OneWebAuthenticationService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/authentication/nif/NifAuthenticationService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/authentication/china/ChinaAuthenticationServiceCookieNameEnum.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/authentication/china/ChinaAuthenticationService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/shopping/AuthenticationQueue.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/shopping/ShoppingCartService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/shopping/ingka/shopping-list/IngkaShoppingListService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/shopping/china/shopping-list/ChinaShoppingListService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/shopping/ShoppingListService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/store/IowsStoreTransformer.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/store/IowsStoreService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/store/StoreCache.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/store/StoreService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/store-availability/IowsStoreAvailabilityListTransformer.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/store-availability/IowsStoreAvailabilityListService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/store-availability/StoreAvailabilityQueue.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/store-availability/StoreAvailabilityCache.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/store-availability/StoreAvailabilityService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/localization/LocalizationServiceKompis1Migration.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/vpc/dexf/DexfVpcService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/vpc/VpcService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/cookie-consent/OneWebCookieConsentService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/cookie-consent/CookieConsentService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/services/notification/DexfNotificationService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/facades/notification/NotificationService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/utilities/shopping-support/ShoppingSupport.js","../../../node_modules/@ikea-aoa/ikea-shared-services/node_modules/@ikea-aoa/services/lib/index.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/facade/ShoppingServiceFacade.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/article/dexf/DexfStoreAvailabilityService.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/facade/StoreAvailabilityServiceFacade.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/facade/StoreServiceFacade.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/service/vpc/VpcServiceConfig.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/facade/VpcServiceFacade.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/facade/SeriesGalleryServiceFacade.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/util/PriceFormatter.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/util/DateFormatter.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/util/IframeUtility.js","../../../node_modules/@ikea-aoa/ikea-shared-services/lib/index.js","../../../node_modules/@ikea-aoa/ikea-shared-localized-component/lib/AbstractLocalizedComponent.js","../../../node_modules/@ikea-aoa/ikea-shared-localized-component/lib/index.js","../../../node_modules/@ikea-aoa/ikea-component-swiper/lib/Swiper.ejs.js","../../../node_modules/@ikea-aoa/ikea-component-swiper/lib/pagination/SwiperPage.js","../../../node_modules/@ikea-aoa/ikea-component-swiper/lib/render/SwiperRenderSize.js","../../../node_modules/@ikea-aoa/ikea-component-swiper/lib/render/SwiperBodyRenderer.js","../../../node_modules/@ikea-aoa/ikea-component-swiper/lib/event/SwiperPointer.js","../../../node_modules/@ikea-aoa/ikea-component-swiper/lib/event/SwiperScroll.js","../../../node_modules/@ikea-aoa/ikea-component-swiper/lib/render/SwiperAnimation.js","../../../node_modules/@ikea-aoa/ikea-component-swiper/lib/utility/PageObserver.js","../../../node_modules/@ikea-aoa/ikea-component-swiper/lib/pagination/SwiperPosition.js","../../../node_modules/@ikea-aoa/ikea-component-swiper/lib/pagination/SwiperInfo.js","../../../node_modules/@ikea-aoa/ikea-component-swiper/lib/Swiper.js","../../../node_modules/@ikea-aoa/ikea-component-button/lib/Button.ejs.js","../../../node_modules/@ikea-aoa/ikea-component-button/lib/Button.js","../../../node_modules/@ikea-aoa/ikea-component-keyboard/lib/Layout.js","../../../node_modules/@ikea-aoa/ikea-component-keyboard/lib/Keyboard.ejs.js","../../../node_modules/@ikea-aoa/ikea-component-keyboard/lib/Keyboard.js","../../../node_modules/@ikea-aoa/ikea-component-load-vpc/lib/LoadVpc.ejs.js","../../../node_modules/@ikea-aoa/ikea-component-load-vpc/lib/LoadVpc.js","../../../node_modules/@ikea-aoa/ikea-component-language-picker/lib/LanguagePicker.ejs.js","../../../node_modules/@ikea-aoa/ikea-component-language-picker/lib/IkeaLocale.js","../../../node_modules/@ikea-aoa/ikea-component-language-picker/lib/LanguagePicker.js","../../../node_modules/@ikea-aoa/ikea-component-image/lib/Image.ejs.js","../../../node_modules/@ikea-aoa/ikea-component-image/lib/Image.js","../../../node_modules/@ikea-aoa/ikea-component-series-gallery/lib/SeriesGallery.ejs.js","../../../node_modules/@ikea-aoa/ikea-component-series-gallery/lib/SeriesGallery.js","../../../node_modules/@inter-ikea-gallery/integration/build/index.js","../../../node_modules/reselect/es/defaultMemoize.js","../../../node_modules/reselect/es/index.js","../../../node_modules/classnames/index.js","../../../node_modules/eventemitter3/index.js","../../../node_modules/bowser/src/bowser.js","../../../node_modules/@babel/runtime/helpers/interopRequireDefault.js","../../../node_modules/dom-helpers/class/hasClass.js","../../../node_modules/dom-helpers/class/addClass.js","../../../node_modules/dom-helpers/class/removeClass.js","../../../node_modules/react-lifecycles-compat/react-lifecycles-compat.es.js","../../../node_modules/react-transition-group/utils/PropTypes.js","../../../node_modules/react-transition-group/TransitionGroupContext.js","../../../node_modules/react-transition-group/Transition.js","../../../node_modules/react-transition-group/CSSTransition.js","../../../node_modules/react-transition-group/utils/ChildMapping.js","../../../node_modules/react-transition-group/TransitionGroup.js","../../../node_modules/react-transition-group/ReplaceTransition.js","../../../node_modules/react-transition-group/index.js","../../../node_modules/dom7/node_modules/ssr-window/dist/ssr-window.esm.js","../../../node_modules/dom7/dist/dom7.modular.js","../../../node_modules/ssr-window/dist/ssr-window.esm.js","../../../node_modules/swiper/dist/js/swiper.esm.bundle.js","../../../node_modules/intrinsic-scale/dist/intrinsic-scale.es-modules.js","../../../node_modules/@ingka/label/esm/Label.js","../../../node_modules/@ingka/label/esm/index.js","../../../node_modules/@ingka/switch/esm/Switch.js","../../../node_modules/@ingka/switch/esm/index.js","../../../node_modules/es6-promise-polyfill/promise.js","../../../node_modules/@pixi/polyfill/lib/polyfill.es.js","../../../node_modules/ismobilejs/esm/isMobile.js","../../../node_modules/@pixi/settings/lib/settings.es.js","../../../node_modules/@pixi/utils/node_modules/eventemitter3/index.js","../../../node_modules/earcut/src/earcut.js","../../../node_modules/url/node_modules/punycode/punycode.js","../../../node_modules/url/util.js","../../../node_modules/querystring/decode.js","../../../node_modules/querystring/encode.js","../../../node_modules/querystring/index.js","../../../node_modules/url/url.js","../../../node_modules/@pixi/constants/lib/constants.es.js","../../../node_modules/@pixi/utils/lib/utils.es.js","../../../node_modules/@pixi/math/lib/math.es.js","../../../node_modules/@pixi/display/lib/display.es.js","../../../node_modules/@pixi/accessibility/lib/accessibility.es.js","../../../node_modules/@pixi/ticker/lib/ticker.es.js","../../../node_modules/@pixi/interaction/lib/interaction.es.js","../../../node_modules/@pixi/runner/lib/runner.es.js","../../../node_modules/@pixi/core/lib/core.es.js","../../../node_modules/@pixi/app/lib/app.es.js","../../../node_modules/@pixi/extract/lib/extract.es.js","../../../node_modules/parse-uri/src/index.js","../../../node_modules/mini-signals/src/mini-signals.js","../../../node_modules/resource-loader/dist/resource-loader.esm.js","../../../node_modules/@pixi/loaders/lib/loaders.es.js","../../../node_modules/@pixi/particles/lib/particles.es.js","../../../node_modules/@pixi/graphics/lib/graphics.es.js","../../../node_modules/@pixi/sprite/lib/sprite.es.js","../../../node_modules/@pixi/text/lib/text.es.js","../../../node_modules/@pixi/prepare/lib/prepare.es.js","../../../node_modules/@pixi/spritesheet/lib/spritesheet.es.js","../../../node_modules/@pixi/sprite-tiling/lib/sprite-tiling.es.js","../../../node_modules/@pixi/text-bitmap/lib/text-bitmap.es.js","../../../node_modules/@pixi/filter-alpha/lib/filter-alpha.es.js","../../../node_modules/@pixi/filter-blur/lib/filter-blur.es.js","../../../node_modules/@pixi/filter-color-matrix/lib/filter-color-matrix.es.js","../../../node_modules/@pixi/filter-displacement/lib/filter-displacement.es.js","../../../node_modules/@pixi/filter-fxaa/lib/filter-fxaa.es.js","../../../node_modules/@pixi/filter-noise/lib/filter-noise.es.js","../../../node_modules/@pixi/mixin-cache-as-bitmap/lib/mixin-cache-as-bitmap.es.js","../../../node_modules/@pixi/mixin-get-child-by-name/lib/mixin-get-child-by-name.es.js","../../../node_modules/@pixi/mixin-get-global-position/lib/mixin-get-global-position.es.js","../../../node_modules/@pixi/mesh/lib/mesh.es.js","../../../node_modules/pixi.js/lib/pixi.es.js","../../../node_modules/@pixi/canvas-renderer/lib/canvas-renderer.es.js","../../../node_modules/@pixi/canvas-mesh/lib/canvas-mesh.es.js","../../../node_modules/@pixi/canvas-graphics/lib/canvas-graphics.es.js","../../../node_modules/@pixi/canvas-sprite/lib/canvas-sprite.es.js","../../../node_modules/@pixi/canvas-extract/lib/canvas-extract.es.js","../../../node_modules/@pixi/canvas-prepare/lib/canvas-prepare.es.js","../../../node_modules/@pixi/canvas-display/lib/canvas-display.es.js","../../../node_modules/@pixi/canvas-text/lib/canvas-text.es.js","../../../node_modules/pixi.js-legacy/lib/pixi-legacy.es.js","../../../node_modules/fast-deep-equal/index.js","../../../node_modules/gl-matrix/lib/gl-matrix/common.js","../../../node_modules/gl-matrix/lib/gl-matrix/mat4.js","../../../node_modules/gl-matrix/lib/gl-matrix/vec3.js","../../../node_modules/@ingka/ssr-icon/esm/SSRIcon.js","../../../node_modules/@ingka/ssr-icon/esm/index.js","../../../node_modules/@ingka/ssr-icon/esm/paths/warning-triangle.js","../../../node_modules/@ingka/button/esm/Button.js","../../../node_modules/@ingka/button/esm/index.js","../../../node_modules/@ingka/hyperlink/esm/Hyperlink.js","../../../node_modules/@ingka/hyperlink/esm/index.js","../../../node_modules/@ingka/ssr-icon/esm/paths/cross-small.js","../../../node_modules/@ingka/ssr-icon/esm/paths/incorrect.js","../../../node_modules/@ingka/ssr-icon/esm/paths/checkmark-circle.js","../../../node_modules/@ingka/ssr-icon/esm/paths/information-circle.js","../../../node_modules/@ingka/inline-message/esm/InlineMessage.js","../../../node_modules/@ingka/inline-message/esm/index.js","../../../node_modules/@ingka/loading/esm/Loading.js","../../../node_modules/@ingka/loading/esm/LoadingBall.js","../../../node_modules/file-saver/dist/FileSaver.min.js","../../../node_modules/@inter-ikea-kompis/navision-export/lib/NavisionExport.js","../../../node_modules/gsap/TweenLite.js","../../../node_modules/gsap/TimelineLite.js","../../../node_modules/gsap/TimelineMax.js","../../../node_modules/gsap/TweenMaxBase.js","../../../node_modules/gsap/CSSPlugin.js","../../../node_modules/gsap/AttrPlugin.js","../../../node_modules/gsap/RoundPropsPlugin.js","../../../node_modules/gsap/DirectionalRotationPlugin.js","../../../node_modules/gsap/BezierPlugin.js","../../../node_modules/gsap/EasePack.js","../../../node_modules/gsap/TweenMax.js","../../../node_modules/focus-visible/dist/focus-visible.js"],"sourcesContent":["/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n\n'use strict';\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n","/** @license React v16.14.0\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';var l=require(\"object-assign\"),n=\"function\"===typeof Symbol&&Symbol.for,p=n?Symbol.for(\"react.element\"):60103,q=n?Symbol.for(\"react.portal\"):60106,r=n?Symbol.for(\"react.fragment\"):60107,t=n?Symbol.for(\"react.strict_mode\"):60108,u=n?Symbol.for(\"react.profiler\"):60114,v=n?Symbol.for(\"react.provider\"):60109,w=n?Symbol.for(\"react.context\"):60110,x=n?Symbol.for(\"react.forward_ref\"):60112,y=n?Symbol.for(\"react.suspense\"):60113,z=n?Symbol.for(\"react.memo\"):60115,A=n?Symbol.for(\"react.lazy\"):\n60116,B=\"function\"===typeof Symbol&&Symbol.iterator;function C(a){for(var b=\"https://reactjs.org/docs/error-decoder.html?invariant=\"+a,c=1;cQ.length&&Q.push(a)}\nfunction T(a,b,c,e){var d=typeof a;if(\"undefined\"===d||\"boolean\"===d)a=null;var g=!1;if(null===a)g=!0;else switch(d){case \"string\":case \"number\":g=!0;break;case \"object\":switch(a.$$typeof){case p:case q:g=!0}}if(g)return c(e,a,\"\"===b?\".\"+U(a,0):b),1;g=0;b=\"\"===b?\".\":b+\":\";if(Array.isArray(a))for(var k=0;k result for the\n // current iteration.\n result.value = unwrapped;\n resolve(result);\n }, function(error) {\n // If a rejected Promise was yielded, throw the rejection back\n // into the async generator function so it can be handled there.\n return invoke(\"throw\", error, resolve, reject);\n });\n }\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new PromiseImpl(function(resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(\n callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg\n ) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n defineProperty(this, \"_invoke\", { value: enqueue });\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n define(AsyncIterator.prototype, asyncIteratorSymbol, function () {\n return this;\n });\n exports.AsyncIterator = AsyncIterator;\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) {\n if (PromiseImpl === void 0) PromiseImpl = Promise;\n\n var iter = new AsyncIterator(\n wrap(innerFn, outerFn, self, tryLocsList),\n PromiseImpl\n );\n\n return exports.isGeneratorFunction(outerFn)\n ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function(result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error(\"Generator is already running\");\n }\n\n if (state === GenStateCompleted) {\n if (method === \"throw\") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n context.method = method;\n context.arg = arg;\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n var delegateResult = maybeInvokeDelegate(delegate, context);\n if (delegateResult) {\n if (delegateResult === ContinueSentinel) continue;\n return delegateResult;\n }\n }\n\n if (context.method === \"next\") {\n // Setting context._sent for legacy support of Babel's\n // function.sent implementation.\n context.sent = context._sent = context.arg;\n\n } else if (context.method === \"throw\") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw context.arg;\n }\n\n context.dispatchException(context.arg);\n\n } else if (context.method === \"return\") {\n context.abrupt(\"return\", context.arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === \"normal\") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done\n ? GenStateCompleted\n : GenStateSuspendedYield;\n\n if (record.arg === ContinueSentinel) {\n continue;\n }\n\n return {\n value: record.arg,\n done: context.done\n };\n\n } else if (record.type === \"throw\") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(context.arg) call above.\n context.method = \"throw\";\n context.arg = record.arg;\n }\n }\n };\n }\n\n // Call delegate.iterator[context.method](context.arg) and handle the\n // result, either by returning a { value, done } result from the\n // delegate iterator, or by modifying context.method and context.arg,\n // setting context.delegate to null, and returning the ContinueSentinel.\n function maybeInvokeDelegate(delegate, context) {\n var methodName = context.method;\n var method = delegate.iterator[methodName];\n if (method === undefined) {\n // A .throw or .return when the delegate iterator has no .throw\n // method, or a missing .next mehtod, always terminate the\n // yield* loop.\n context.delegate = null;\n\n // Note: [\"return\"] must be used for ES3 parsing compatibility.\n if (methodName === \"throw\" && delegate.iterator[\"return\"]) {\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n context.method = \"return\";\n context.arg = undefined;\n maybeInvokeDelegate(delegate, context);\n\n if (context.method === \"throw\") {\n // If maybeInvokeDelegate(context) changed context.method from\n // \"return\" to \"throw\", let that override the TypeError below.\n return ContinueSentinel;\n }\n }\n if (methodName !== \"return\") {\n context.method = \"throw\";\n context.arg = new TypeError(\n \"The iterator does not provide a '\" + methodName + \"' method\");\n }\n\n return ContinueSentinel;\n }\n\n var record = tryCatch(method, delegate.iterator, context.arg);\n\n if (record.type === \"throw\") {\n context.method = \"throw\";\n context.arg = record.arg;\n context.delegate = null;\n return ContinueSentinel;\n }\n\n var info = record.arg;\n\n if (! info) {\n context.method = \"throw\";\n context.arg = new TypeError(\"iterator result is not an object\");\n context.delegate = null;\n return ContinueSentinel;\n }\n\n if (info.done) {\n // Assign the result of the finished delegate to the temporary\n // variable specified by delegate.resultName (see delegateYield).\n context[delegate.resultName] = info.value;\n\n // Resume execution at the desired location (see delegateYield).\n context.next = delegate.nextLoc;\n\n // If context.method was \"throw\" but the delegate handled the\n // exception, let the outer generator proceed normally. If\n // context.method was \"next\", forget context.arg since it has been\n // \"consumed\" by the delegate iterator. If context.method was\n // \"return\", allow the original .return call to continue in the\n // outer generator.\n if (context.method !== \"return\") {\n context.method = \"next\";\n context.arg = undefined;\n }\n\n } else {\n // Re-yield the result returned by the delegate method.\n return info;\n }\n\n // The delegate iterator is finished, so forget it and continue with\n // the outer generator.\n context.delegate = null;\n return ContinueSentinel;\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n define(Gp, toStringTagSymbol, \"Generator\");\n\n // A Generator should always return itself as the iterator object when the\n // @@iterator function is called on it. Some browsers' implementations of the\n // iterator prototype chain incorrectly implement this, causing the Generator\n // object to not be returned from this call. This ensures that doesn't happen.\n // See https://github.com/facebook/regenerator/issues/274 for more details.\n define(Gp, iteratorSymbol, function() {\n return this;\n });\n\n define(Gp, \"toString\", function() {\n return \"[object Generator]\";\n });\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: \"root\" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n exports.keys = function(val) {\n var object = Object(val);\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === \"function\") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1, next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n exports.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n // Resetting context._sent for legacy support of Babel's\n // function.sent implementation.\n this.sent = this._sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.method = \"next\";\n this.arg = undefined;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === \"t\" &&\n hasOwn.call(this, name) &&\n !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === \"throw\") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = \"throw\";\n record.arg = exception;\n context.next = loc;\n\n if (caught) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n context.method = \"next\";\n context.arg = undefined;\n }\n\n return !! caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === \"root\") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle(\"end\");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\");\n var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else {\n throw new Error(\"try statement without catch or finally\");\n }\n }\n }\n },\n\n abrupt: function(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev &&\n hasOwn.call(entry, \"finallyLoc\") &&\n this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry &&\n (type === \"break\" ||\n type === \"continue\") &&\n finallyEntry.tryLoc <= arg &&\n arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.method = \"next\";\n this.next = finallyEntry.finallyLoc;\n return ContinueSentinel;\n }\n\n return this.complete(record);\n },\n\n complete: function(record, afterLoc) {\n if (record.type === \"throw\") {\n throw record.arg;\n }\n\n if (record.type === \"break\" ||\n record.type === \"continue\") {\n this.next = record.arg;\n } else if (record.type === \"return\") {\n this.rval = this.arg = record.arg;\n this.method = \"return\";\n this.next = \"end\";\n } else if (record.type === \"normal\" && afterLoc) {\n this.next = afterLoc;\n }\n\n return ContinueSentinel;\n },\n\n finish: function(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n \"catch\": function(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === \"throw\") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error(\"illegal catch attempt\");\n },\n\n delegateYield: function(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n if (this.method === \"next\") {\n // Deliberately forget the last sent value so that we don't\n // accidentally pass it on to the delegate.\n this.arg = undefined;\n }\n\n return ContinueSentinel;\n }\n };\n\n // Regardless of whether this script is executing as a CommonJS module\n // or not, return the runtime object so that we can declare the variable\n // regeneratorRuntime in the outer scope, which allows this module to be\n // injected easily by `bin/regenerator --include-runtime script.js`.\n return exports;\n\n}(\n // If this script is executing as a CommonJS module, use module.exports\n // as the regeneratorRuntime namespace. Otherwise create a new empty\n // object. Either way, the resulting object will be used to initialize\n // the regeneratorRuntime variable at the top of this file.\n typeof module === \"object\" ? module.exports : {}\n));\n\ntry {\n regeneratorRuntime = runtime;\n} catch (accidentalStrictMode) {\n // This module should not be running in strict mode, so the above\n // assignment should always work unless something is misconfigured. Just\n // in case runtime.js accidentally runs in strict mode, in modern engines\n // we can explicitly access globalThis. In older engines we can escape\n // strict mode using a global Function call. This could conceivably fail\n // if a Content Security Policy forbids using Function, but in that case\n // the proper solution is to fix the accidental strict mode problem. If\n // you've misconfigured your bundler to force strict mode and applied a\n // CSP to forbid Function, and you're not willing to fix either of those\n // problems, please detail your unique predicament in a GitHub issue.\n if (typeof globalThis === \"object\") {\n globalThis.regeneratorRuntime = runtime;\n } else {\n Function(\"r\", \"regeneratorRuntime = r\")(runtime);\n }\n}\n","var global =\n (typeof globalThis !== 'undefined' && globalThis) ||\n (typeof self !== 'undefined' && self) ||\n (typeof global !== 'undefined' && global)\n\nvar support = {\n searchParams: 'URLSearchParams' in global,\n iterable: 'Symbol' in global && 'iterator' in Symbol,\n blob:\n 'FileReader' in global &&\n 'Blob' in global &&\n (function() {\n try {\n new Blob()\n return true\n } catch (e) {\n return false\n }\n })(),\n formData: 'FormData' in global,\n arrayBuffer: 'ArrayBuffer' in global\n}\n\nfunction isDataView(obj) {\n return obj && DataView.prototype.isPrototypeOf(obj)\n}\n\nif (support.arrayBuffer) {\n var viewClasses = [\n '[object Int8Array]',\n '[object Uint8Array]',\n '[object Uint8ClampedArray]',\n '[object Int16Array]',\n '[object Uint16Array]',\n '[object Int32Array]',\n '[object Uint32Array]',\n '[object Float32Array]',\n '[object Float64Array]'\n ]\n\n var isArrayBufferView =\n ArrayBuffer.isView ||\n function(obj) {\n return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1\n }\n}\n\nfunction normalizeName(name) {\n if (typeof name !== 'string') {\n name = String(name)\n }\n if (/[^a-z0-9\\-#$%&'*+.^_`|~!]/i.test(name) || name === '') {\n throw new TypeError('Invalid character in header field name: \"' + name + '\"')\n }\n return name.toLowerCase()\n}\n\nfunction normalizeValue(value) {\n if (typeof value !== 'string') {\n value = String(value)\n }\n return value\n}\n\n// Build a destructive iterator for the value list\nfunction iteratorFor(items) {\n var iterator = {\n next: function() {\n var value = items.shift()\n return {done: value === undefined, value: value}\n }\n }\n\n if (support.iterable) {\n iterator[Symbol.iterator] = function() {\n return iterator\n }\n }\n\n return iterator\n}\n\nexport function Headers(headers) {\n this.map = {}\n\n if (headers instanceof Headers) {\n headers.forEach(function(value, name) {\n this.append(name, value)\n }, this)\n } else if (Array.isArray(headers)) {\n headers.forEach(function(header) {\n this.append(header[0], header[1])\n }, this)\n } else if (headers) {\n Object.getOwnPropertyNames(headers).forEach(function(name) {\n this.append(name, headers[name])\n }, this)\n }\n}\n\nHeaders.prototype.append = function(name, value) {\n name = normalizeName(name)\n value = normalizeValue(value)\n var oldValue = this.map[name]\n this.map[name] = oldValue ? oldValue + ', ' + value : value\n}\n\nHeaders.prototype['delete'] = function(name) {\n delete this.map[normalizeName(name)]\n}\n\nHeaders.prototype.get = function(name) {\n name = normalizeName(name)\n return this.has(name) ? this.map[name] : null\n}\n\nHeaders.prototype.has = function(name) {\n return this.map.hasOwnProperty(normalizeName(name))\n}\n\nHeaders.prototype.set = function(name, value) {\n this.map[normalizeName(name)] = normalizeValue(value)\n}\n\nHeaders.prototype.forEach = function(callback, thisArg) {\n for (var name in this.map) {\n if (this.map.hasOwnProperty(name)) {\n callback.call(thisArg, this.map[name], name, this)\n }\n }\n}\n\nHeaders.prototype.keys = function() {\n var items = []\n this.forEach(function(value, name) {\n items.push(name)\n })\n return iteratorFor(items)\n}\n\nHeaders.prototype.values = function() {\n var items = []\n this.forEach(function(value) {\n items.push(value)\n })\n return iteratorFor(items)\n}\n\nHeaders.prototype.entries = function() {\n var items = []\n this.forEach(function(value, name) {\n items.push([name, value])\n })\n return iteratorFor(items)\n}\n\nif (support.iterable) {\n Headers.prototype[Symbol.iterator] = Headers.prototype.entries\n}\n\nfunction consumed(body) {\n if (body.bodyUsed) {\n return Promise.reject(new TypeError('Already read'))\n }\n body.bodyUsed = true\n}\n\nfunction fileReaderReady(reader) {\n return new Promise(function(resolve, reject) {\n reader.onload = function() {\n resolve(reader.result)\n }\n reader.onerror = function() {\n reject(reader.error)\n }\n })\n}\n\nfunction readBlobAsArrayBuffer(blob) {\n var reader = new FileReader()\n var promise = fileReaderReady(reader)\n reader.readAsArrayBuffer(blob)\n return promise\n}\n\nfunction readBlobAsText(blob) {\n var reader = new FileReader()\n var promise = fileReaderReady(reader)\n reader.readAsText(blob)\n return promise\n}\n\nfunction readArrayBufferAsText(buf) {\n var view = new Uint8Array(buf)\n var chars = new Array(view.length)\n\n for (var i = 0; i < view.length; i++) {\n chars[i] = String.fromCharCode(view[i])\n }\n return chars.join('')\n}\n\nfunction bufferClone(buf) {\n if (buf.slice) {\n return buf.slice(0)\n } else {\n var view = new Uint8Array(buf.byteLength)\n view.set(new Uint8Array(buf))\n return view.buffer\n }\n}\n\nfunction Body() {\n this.bodyUsed = false\n\n this._initBody = function(body) {\n /*\n fetch-mock wraps the Response object in an ES6 Proxy to\n provide useful test harness features such as flush. However, on\n ES5 browsers without fetch or Proxy support pollyfills must be used;\n the proxy-pollyfill is unable to proxy an attribute unless it exists\n on the object before the Proxy is created. This change ensures\n Response.bodyUsed exists on the instance, while maintaining the\n semantic of setting Request.bodyUsed in the constructor before\n _initBody is called.\n */\n this.bodyUsed = this.bodyUsed\n this._bodyInit = body\n if (!body) {\n this._bodyText = ''\n } else if (typeof body === 'string') {\n this._bodyText = body\n } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {\n this._bodyBlob = body\n } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {\n this._bodyFormData = body\n } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {\n this._bodyText = body.toString()\n } else if (support.arrayBuffer && support.blob && isDataView(body)) {\n this._bodyArrayBuffer = bufferClone(body.buffer)\n // IE 10-11 can't handle a DataView body.\n this._bodyInit = new Blob([this._bodyArrayBuffer])\n } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {\n this._bodyArrayBuffer = bufferClone(body)\n } else {\n this._bodyText = body = Object.prototype.toString.call(body)\n }\n\n if (!this.headers.get('content-type')) {\n if (typeof body === 'string') {\n this.headers.set('content-type', 'text/plain;charset=UTF-8')\n } else if (this._bodyBlob && this._bodyBlob.type) {\n this.headers.set('content-type', this._bodyBlob.type)\n } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {\n this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8')\n }\n }\n }\n\n if (support.blob) {\n this.blob = function() {\n var rejected = consumed(this)\n if (rejected) {\n return rejected\n }\n\n if (this._bodyBlob) {\n return Promise.resolve(this._bodyBlob)\n } else if (this._bodyArrayBuffer) {\n return Promise.resolve(new Blob([this._bodyArrayBuffer]))\n } else if (this._bodyFormData) {\n throw new Error('could not read FormData body as blob')\n } else {\n return Promise.resolve(new Blob([this._bodyText]))\n }\n }\n\n this.arrayBuffer = function() {\n if (this._bodyArrayBuffer) {\n var isConsumed = consumed(this)\n if (isConsumed) {\n return isConsumed\n }\n if (ArrayBuffer.isView(this._bodyArrayBuffer)) {\n return Promise.resolve(\n this._bodyArrayBuffer.buffer.slice(\n this._bodyArrayBuffer.byteOffset,\n this._bodyArrayBuffer.byteOffset + this._bodyArrayBuffer.byteLength\n )\n )\n } else {\n return Promise.resolve(this._bodyArrayBuffer)\n }\n } else {\n return this.blob().then(readBlobAsArrayBuffer)\n }\n }\n }\n\n this.text = function() {\n var rejected = consumed(this)\n if (rejected) {\n return rejected\n }\n\n if (this._bodyBlob) {\n return readBlobAsText(this._bodyBlob)\n } else if (this._bodyArrayBuffer) {\n return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))\n } else if (this._bodyFormData) {\n throw new Error('could not read FormData body as text')\n } else {\n return Promise.resolve(this._bodyText)\n }\n }\n\n if (support.formData) {\n this.formData = function() {\n return this.text().then(decode)\n }\n }\n\n this.json = function() {\n return this.text().then(JSON.parse)\n }\n\n return this\n}\n\n// HTTP methods whose capitalization should be normalized\nvar methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']\n\nfunction normalizeMethod(method) {\n var upcased = method.toUpperCase()\n return methods.indexOf(upcased) > -1 ? upcased : method\n}\n\nexport function Request(input, options) {\n if (!(this instanceof Request)) {\n throw new TypeError('Please use the \"new\" operator, this DOM object constructor cannot be called as a function.')\n }\n\n options = options || {}\n var body = options.body\n\n if (input instanceof Request) {\n if (input.bodyUsed) {\n throw new TypeError('Already read')\n }\n this.url = input.url\n this.credentials = input.credentials\n if (!options.headers) {\n this.headers = new Headers(input.headers)\n }\n this.method = input.method\n this.mode = input.mode\n this.signal = input.signal\n if (!body && input._bodyInit != null) {\n body = input._bodyInit\n input.bodyUsed = true\n }\n } else {\n this.url = String(input)\n }\n\n this.credentials = options.credentials || this.credentials || 'same-origin'\n if (options.headers || !this.headers) {\n this.headers = new Headers(options.headers)\n }\n this.method = normalizeMethod(options.method || this.method || 'GET')\n this.mode = options.mode || this.mode || null\n this.signal = options.signal || this.signal\n this.referrer = null\n\n if ((this.method === 'GET' || this.method === 'HEAD') && body) {\n throw new TypeError('Body not allowed for GET or HEAD requests')\n }\n this._initBody(body)\n\n if (this.method === 'GET' || this.method === 'HEAD') {\n if (options.cache === 'no-store' || options.cache === 'no-cache') {\n // Search for a '_' parameter in the query string\n var reParamSearch = /([?&])_=[^&]*/\n if (reParamSearch.test(this.url)) {\n // If it already exists then set the value with the current time\n this.url = this.url.replace(reParamSearch, '$1_=' + new Date().getTime())\n } else {\n // Otherwise add a new '_' parameter to the end with the current time\n var reQueryString = /\\?/\n this.url += (reQueryString.test(this.url) ? '&' : '?') + '_=' + new Date().getTime()\n }\n }\n }\n}\n\nRequest.prototype.clone = function() {\n return new Request(this, {body: this._bodyInit})\n}\n\nfunction decode(body) {\n var form = new FormData()\n body\n .trim()\n .split('&')\n .forEach(function(bytes) {\n if (bytes) {\n var split = bytes.split('=')\n var name = split.shift().replace(/\\+/g, ' ')\n var value = split.join('=').replace(/\\+/g, ' ')\n form.append(decodeURIComponent(name), decodeURIComponent(value))\n }\n })\n return form\n}\n\nfunction parseHeaders(rawHeaders) {\n var headers = new Headers()\n // Replace instances of \\r\\n and \\n followed by at least one space or horizontal tab with a space\n // https://tools.ietf.org/html/rfc7230#section-3.2\n var preProcessedHeaders = rawHeaders.replace(/\\r?\\n[\\t ]+/g, ' ')\n // Avoiding split via regex to work around a common IE11 bug with the core-js 3.6.0 regex polyfill\n // https://github.com/github/fetch/issues/748\n // https://github.com/zloirock/core-js/issues/751\n preProcessedHeaders\n .split('\\r')\n .map(function(header) {\n return header.indexOf('\\n') === 0 ? header.substr(1, header.length) : header\n })\n .forEach(function(line) {\n var parts = line.split(':')\n var key = parts.shift().trim()\n if (key) {\n var value = parts.join(':').trim()\n headers.append(key, value)\n }\n })\n return headers\n}\n\nBody.call(Request.prototype)\n\nexport function Response(bodyInit, options) {\n if (!(this instanceof Response)) {\n throw new TypeError('Please use the \"new\" operator, this DOM object constructor cannot be called as a function.')\n }\n if (!options) {\n options = {}\n }\n\n this.type = 'default'\n this.status = options.status === undefined ? 200 : options.status\n this.ok = this.status >= 200 && this.status < 300\n this.statusText = options.statusText === undefined ? '' : '' + options.statusText\n this.headers = new Headers(options.headers)\n this.url = options.url || ''\n this._initBody(bodyInit)\n}\n\nBody.call(Response.prototype)\n\nResponse.prototype.clone = function() {\n return new Response(this._bodyInit, {\n status: this.status,\n statusText: this.statusText,\n headers: new Headers(this.headers),\n url: this.url\n })\n}\n\nResponse.error = function() {\n var response = new Response(null, {status: 0, statusText: ''})\n response.type = 'error'\n return response\n}\n\nvar redirectStatuses = [301, 302, 303, 307, 308]\n\nResponse.redirect = function(url, status) {\n if (redirectStatuses.indexOf(status) === -1) {\n throw new RangeError('Invalid status code')\n }\n\n return new Response(null, {status: status, headers: {location: url}})\n}\n\nexport var DOMException = global.DOMException\ntry {\n new DOMException()\n} catch (err) {\n DOMException = function(message, name) {\n this.message = message\n this.name = name\n var error = Error(message)\n this.stack = error.stack\n }\n DOMException.prototype = Object.create(Error.prototype)\n DOMException.prototype.constructor = DOMException\n}\n\nexport function fetch(input, init) {\n return new Promise(function(resolve, reject) {\n var request = new Request(input, init)\n\n if (request.signal && request.signal.aborted) {\n return reject(new DOMException('Aborted', 'AbortError'))\n }\n\n var xhr = new XMLHttpRequest()\n\n function abortXhr() {\n xhr.abort()\n }\n\n xhr.onload = function() {\n var options = {\n status: xhr.status,\n statusText: xhr.statusText,\n headers: parseHeaders(xhr.getAllResponseHeaders() || '')\n }\n options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL')\n var body = 'response' in xhr ? xhr.response : xhr.responseText\n setTimeout(function() {\n resolve(new Response(body, options))\n }, 0)\n }\n\n xhr.onerror = function() {\n setTimeout(function() {\n reject(new TypeError('Network request failed'))\n }, 0)\n }\n\n xhr.ontimeout = function() {\n setTimeout(function() {\n reject(new TypeError('Network request failed'))\n }, 0)\n }\n\n xhr.onabort = function() {\n setTimeout(function() {\n reject(new DOMException('Aborted', 'AbortError'))\n }, 0)\n }\n\n function fixUrl(url) {\n try {\n return url === '' && global.location.href ? global.location.href : url\n } catch (e) {\n return url\n }\n }\n\n xhr.open(request.method, fixUrl(request.url), true)\n\n if (request.credentials === 'include') {\n xhr.withCredentials = true\n } else if (request.credentials === 'omit') {\n xhr.withCredentials = false\n }\n\n if ('responseType' in xhr) {\n if (support.blob) {\n xhr.responseType = 'blob'\n } else if (\n support.arrayBuffer &&\n request.headers.get('Content-Type') &&\n request.headers.get('Content-Type').indexOf('application/octet-stream') !== -1\n ) {\n xhr.responseType = 'arraybuffer'\n }\n }\n\n if (init && typeof init.headers === 'object' && !(init.headers instanceof Headers)) {\n Object.getOwnPropertyNames(init.headers).forEach(function(name) {\n xhr.setRequestHeader(name, normalizeValue(init.headers[name]))\n })\n } else {\n request.headers.forEach(function(value, name) {\n xhr.setRequestHeader(name, value)\n })\n }\n\n if (request.signal) {\n request.signal.addEventListener('abort', abortXhr)\n\n xhr.onreadystatechange = function() {\n // DONE (success or failure)\n if (xhr.readyState === 4) {\n request.signal.removeEventListener('abort', abortXhr)\n }\n }\n }\n\n xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)\n })\n}\n\nfetch.polyfill = true\n\nif (!global.fetch) {\n global.fetch = fetch\n global.Headers = Headers\n global.Request = Request\n global.Response = Response\n}\n","/* smoothscroll v0.4.4 - 2019 - Dustan Kasten, Jeremias Menichelli - MIT License */\n(function () {\n 'use strict';\n\n // polyfill\n function polyfill() {\n // aliases\n var w = window;\n var d = document;\n\n // return if scroll behavior is supported and polyfill is not forced\n if (\n 'scrollBehavior' in d.documentElement.style &&\n w.__forceSmoothScrollPolyfill__ !== true\n ) {\n return;\n }\n\n // globals\n var Element = w.HTMLElement || w.Element;\n var SCROLL_TIME = 468;\n\n // object gathering original scroll methods\n var original = {\n scroll: w.scroll || w.scrollTo,\n scrollBy: w.scrollBy,\n elementScroll: Element.prototype.scroll || scrollElement,\n scrollIntoView: Element.prototype.scrollIntoView\n };\n\n // define timing method\n var now =\n w.performance && w.performance.now\n ? w.performance.now.bind(w.performance)\n : Date.now;\n\n /**\n * indicates if a the current browser is made by Microsoft\n * @method isMicrosoftBrowser\n * @param {String} userAgent\n * @returns {Boolean}\n */\n function isMicrosoftBrowser(userAgent) {\n var userAgentPatterns = ['MSIE ', 'Trident/', 'Edge/'];\n\n return new RegExp(userAgentPatterns.join('|')).test(userAgent);\n }\n\n /*\n * IE has rounding bug rounding down clientHeight and clientWidth and\n * rounding up scrollHeight and scrollWidth causing false positives\n * on hasScrollableSpace\n */\n var ROUNDING_TOLERANCE = isMicrosoftBrowser(w.navigator.userAgent) ? 1 : 0;\n\n /**\n * changes scroll position inside an element\n * @method scrollElement\n * @param {Number} x\n * @param {Number} y\n * @returns {undefined}\n */\n function scrollElement(x, y) {\n this.scrollLeft = x;\n this.scrollTop = y;\n }\n\n /**\n * returns result of applying ease math function to a number\n * @method ease\n * @param {Number} k\n * @returns {Number}\n */\n function ease(k) {\n return 0.5 * (1 - Math.cos(Math.PI * k));\n }\n\n /**\n * indicates if a smooth behavior should be applied\n * @method shouldBailOut\n * @param {Number|Object} firstArg\n * @returns {Boolean}\n */\n function shouldBailOut(firstArg) {\n if (\n firstArg === null ||\n typeof firstArg !== 'object' ||\n firstArg.behavior === undefined ||\n firstArg.behavior === 'auto' ||\n firstArg.behavior === 'instant'\n ) {\n // first argument is not an object/null\n // or behavior is auto, instant or undefined\n return true;\n }\n\n if (typeof firstArg === 'object' && firstArg.behavior === 'smooth') {\n // first argument is an object and behavior is smooth\n return false;\n }\n\n // throw error when behavior is not supported\n throw new TypeError(\n 'behavior member of ScrollOptions ' +\n firstArg.behavior +\n ' is not a valid value for enumeration ScrollBehavior.'\n );\n }\n\n /**\n * indicates if an element has scrollable space in the provided axis\n * @method hasScrollableSpace\n * @param {Node} el\n * @param {String} axis\n * @returns {Boolean}\n */\n function hasScrollableSpace(el, axis) {\n if (axis === 'Y') {\n return el.clientHeight + ROUNDING_TOLERANCE < el.scrollHeight;\n }\n\n if (axis === 'X') {\n return el.clientWidth + ROUNDING_TOLERANCE < el.scrollWidth;\n }\n }\n\n /**\n * indicates if an element has a scrollable overflow property in the axis\n * @method canOverflow\n * @param {Node} el\n * @param {String} axis\n * @returns {Boolean}\n */\n function canOverflow(el, axis) {\n var overflowValue = w.getComputedStyle(el, null)['overflow' + axis];\n\n return overflowValue === 'auto' || overflowValue === 'scroll';\n }\n\n /**\n * indicates if an element can be scrolled in either axis\n * @method isScrollable\n * @param {Node} el\n * @param {String} axis\n * @returns {Boolean}\n */\n function isScrollable(el) {\n var isScrollableY = hasScrollableSpace(el, 'Y') && canOverflow(el, 'Y');\n var isScrollableX = hasScrollableSpace(el, 'X') && canOverflow(el, 'X');\n\n return isScrollableY || isScrollableX;\n }\n\n /**\n * finds scrollable parent of an element\n * @method findScrollableParent\n * @param {Node} el\n * @returns {Node} el\n */\n function findScrollableParent(el) {\n while (el !== d.body && isScrollable(el) === false) {\n el = el.parentNode || el.host;\n }\n\n return el;\n }\n\n /**\n * self invoked function that, given a context, steps through scrolling\n * @method step\n * @param {Object} context\n * @returns {undefined}\n */\n function step(context) {\n var time = now();\n var value;\n var currentX;\n var currentY;\n var elapsed = (time - context.startTime) / SCROLL_TIME;\n\n // avoid elapsed times higher than one\n elapsed = elapsed > 1 ? 1 : elapsed;\n\n // apply easing to elapsed time\n value = ease(elapsed);\n\n currentX = context.startX + (context.x - context.startX) * value;\n currentY = context.startY + (context.y - context.startY) * value;\n\n context.method.call(context.scrollable, currentX, currentY);\n\n // scroll more if we have not reached our destination\n if (currentX !== context.x || currentY !== context.y) {\n w.requestAnimationFrame(step.bind(w, context));\n }\n }\n\n /**\n * scrolls window or element with a smooth behavior\n * @method smoothScroll\n * @param {Object|Node} el\n * @param {Number} x\n * @param {Number} y\n * @returns {undefined}\n */\n function smoothScroll(el, x, y) {\n var scrollable;\n var startX;\n var startY;\n var method;\n var startTime = now();\n\n // define scroll context\n if (el === d.body) {\n scrollable = w;\n startX = w.scrollX || w.pageXOffset;\n startY = w.scrollY || w.pageYOffset;\n method = original.scroll;\n } else {\n scrollable = el;\n startX = el.scrollLeft;\n startY = el.scrollTop;\n method = scrollElement;\n }\n\n // scroll looping over a frame\n step({\n scrollable: scrollable,\n method: method,\n startTime: startTime,\n startX: startX,\n startY: startY,\n x: x,\n y: y\n });\n }\n\n // ORIGINAL METHODS OVERRIDES\n // w.scroll and w.scrollTo\n w.scroll = w.scrollTo = function() {\n // avoid action when no arguments are passed\n if (arguments[0] === undefined) {\n return;\n }\n\n // avoid smooth behavior if not required\n if (shouldBailOut(arguments[0]) === true) {\n original.scroll.call(\n w,\n arguments[0].left !== undefined\n ? arguments[0].left\n : typeof arguments[0] !== 'object'\n ? arguments[0]\n : w.scrollX || w.pageXOffset,\n // use top prop, second argument if present or fallback to scrollY\n arguments[0].top !== undefined\n ? arguments[0].top\n : arguments[1] !== undefined\n ? arguments[1]\n : w.scrollY || w.pageYOffset\n );\n\n return;\n }\n\n // LET THE SMOOTHNESS BEGIN!\n smoothScroll.call(\n w,\n d.body,\n arguments[0].left !== undefined\n ? ~~arguments[0].left\n : w.scrollX || w.pageXOffset,\n arguments[0].top !== undefined\n ? ~~arguments[0].top\n : w.scrollY || w.pageYOffset\n );\n };\n\n // w.scrollBy\n w.scrollBy = function() {\n // avoid action when no arguments are passed\n if (arguments[0] === undefined) {\n return;\n }\n\n // avoid smooth behavior if not required\n if (shouldBailOut(arguments[0])) {\n original.scrollBy.call(\n w,\n arguments[0].left !== undefined\n ? arguments[0].left\n : typeof arguments[0] !== 'object' ? arguments[0] : 0,\n arguments[0].top !== undefined\n ? arguments[0].top\n : arguments[1] !== undefined ? arguments[1] : 0\n );\n\n return;\n }\n\n // LET THE SMOOTHNESS BEGIN!\n smoothScroll.call(\n w,\n d.body,\n ~~arguments[0].left + (w.scrollX || w.pageXOffset),\n ~~arguments[0].top + (w.scrollY || w.pageYOffset)\n );\n };\n\n // Element.prototype.scroll and Element.prototype.scrollTo\n Element.prototype.scroll = Element.prototype.scrollTo = function() {\n // avoid action when no arguments are passed\n if (arguments[0] === undefined) {\n return;\n }\n\n // avoid smooth behavior if not required\n if (shouldBailOut(arguments[0]) === true) {\n // if one number is passed, throw error to match Firefox implementation\n if (typeof arguments[0] === 'number' && arguments[1] === undefined) {\n throw new SyntaxError('Value could not be converted');\n }\n\n original.elementScroll.call(\n this,\n // use left prop, first number argument or fallback to scrollLeft\n arguments[0].left !== undefined\n ? ~~arguments[0].left\n : typeof arguments[0] !== 'object' ? ~~arguments[0] : this.scrollLeft,\n // use top prop, second argument or fallback to scrollTop\n arguments[0].top !== undefined\n ? ~~arguments[0].top\n : arguments[1] !== undefined ? ~~arguments[1] : this.scrollTop\n );\n\n return;\n }\n\n var left = arguments[0].left;\n var top = arguments[0].top;\n\n // LET THE SMOOTHNESS BEGIN!\n smoothScroll.call(\n this,\n this,\n typeof left === 'undefined' ? this.scrollLeft : ~~left,\n typeof top === 'undefined' ? this.scrollTop : ~~top\n );\n };\n\n // Element.prototype.scrollBy\n Element.prototype.scrollBy = function() {\n // avoid action when no arguments are passed\n if (arguments[0] === undefined) {\n return;\n }\n\n // avoid smooth behavior if not required\n if (shouldBailOut(arguments[0]) === true) {\n original.elementScroll.call(\n this,\n arguments[0].left !== undefined\n ? ~~arguments[0].left + this.scrollLeft\n : ~~arguments[0] + this.scrollLeft,\n arguments[0].top !== undefined\n ? ~~arguments[0].top + this.scrollTop\n : ~~arguments[1] + this.scrollTop\n );\n\n return;\n }\n\n this.scroll({\n left: ~~arguments[0].left + this.scrollLeft,\n top: ~~arguments[0].top + this.scrollTop,\n behavior: arguments[0].behavior\n });\n };\n\n // Element.prototype.scrollIntoView\n Element.prototype.scrollIntoView = function() {\n // avoid smooth behavior if not required\n if (shouldBailOut(arguments[0]) === true) {\n original.scrollIntoView.call(\n this,\n arguments[0] === undefined ? true : arguments[0]\n );\n\n return;\n }\n\n // LET THE SMOOTHNESS BEGIN!\n var scrollableParent = findScrollableParent(this);\n var parentRects = scrollableParent.getBoundingClientRect();\n var clientRects = this.getBoundingClientRect();\n\n if (scrollableParent !== d.body) {\n // reveal element inside parent\n smoothScroll.call(\n this,\n scrollableParent,\n scrollableParent.scrollLeft + clientRects.left - parentRects.left,\n scrollableParent.scrollTop + clientRects.top - parentRects.top\n );\n\n // reveal parent in viewport unless is fixed\n if (w.getComputedStyle(scrollableParent).position !== 'fixed') {\n w.scrollBy({\n left: parentRects.left,\n top: parentRects.top,\n behavior: 'smooth'\n });\n }\n } else {\n // reveal element in viewport\n w.scrollBy({\n left: clientRects.left,\n top: clientRects.top,\n behavior: 'smooth'\n });\n }\n };\n }\n\n if (typeof exports === 'object' && typeof module !== 'undefined') {\n // commonjs\n module.exports = { polyfill: polyfill };\n } else {\n // global\n polyfill();\n }\n\n}());\n","/** @license React v0.19.1\n * scheduler.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';var f,g,h,k,l;\nif(\"undefined\"===typeof window||\"function\"!==typeof MessageChannel){var p=null,q=null,t=function(){if(null!==p)try{var a=exports.unstable_now();p(!0,a);p=null}catch(b){throw setTimeout(t,0),b;}},u=Date.now();exports.unstable_now=function(){return Date.now()-u};f=function(a){null!==p?setTimeout(f,0,a):(p=a,setTimeout(t,0))};g=function(a,b){q=setTimeout(a,b)};h=function(){clearTimeout(q)};k=function(){return!1};l=exports.unstable_forceFrameRate=function(){}}else{var w=window.performance,x=window.Date,\ny=window.setTimeout,z=window.clearTimeout;if(\"undefined\"!==typeof console){var A=window.cancelAnimationFrame;\"function\"!==typeof window.requestAnimationFrame&&console.error(\"This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills\");\"function\"!==typeof A&&console.error(\"This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills\")}if(\"object\"===\ntypeof w&&\"function\"===typeof w.now)exports.unstable_now=function(){return w.now()};else{var B=x.now();exports.unstable_now=function(){return x.now()-B}}var C=!1,D=null,E=-1,F=5,G=0;k=function(){return exports.unstable_now()>=G};l=function(){};exports.unstable_forceFrameRate=function(a){0>a||125>>1,e=a[d];if(void 0!==e&&0K(n,c))void 0!==r&&0>K(r,n)?(a[d]=r,a[v]=c,d=v):(a[d]=n,a[m]=c,d=m);else if(void 0!==r&&0>K(r,c))a[d]=r,a[v]=c,d=v;else break a}}return b}return null}function K(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}var N=[],O=[],P=1,Q=null,R=3,S=!1,T=!1,U=!1;\nfunction V(a){for(var b=L(O);null!==b;){if(null===b.callback)M(O);else if(b.startTime<=a)M(O),b.sortIndex=b.expirationTime,J(N,b);else break;b=L(O)}}function W(a){U=!1;V(a);if(!T)if(null!==L(N))T=!0,f(X);else{var b=L(O);null!==b&&g(W,b.startTime-a)}}\nfunction X(a,b){T=!1;U&&(U=!1,h());S=!0;var c=R;try{V(b);for(Q=L(N);null!==Q&&(!(Q.expirationTime>b)||a&&!k());){var d=Q.callback;if(null!==d){Q.callback=null;R=Q.priorityLevel;var e=d(Q.expirationTime<=b);b=exports.unstable_now();\"function\"===typeof e?Q.callback=e:Q===L(N)&&M(N);V(b)}else M(N);Q=L(N)}if(null!==Q)var m=!0;else{var n=L(O);null!==n&&g(W,n.startTime-b);m=!1}return m}finally{Q=null,R=c,S=!1}}\nfunction Y(a){switch(a){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1E4;default:return 5E3}}var Z=l;exports.unstable_IdlePriority=5;exports.unstable_ImmediatePriority=1;exports.unstable_LowPriority=4;exports.unstable_NormalPriority=3;exports.unstable_Profiling=null;exports.unstable_UserBlockingPriority=2;exports.unstable_cancelCallback=function(a){a.callback=null};exports.unstable_continueExecution=function(){T||S||(T=!0,f(X))};\nexports.unstable_getCurrentPriorityLevel=function(){return R};exports.unstable_getFirstCallbackNode=function(){return L(N)};exports.unstable_next=function(a){switch(R){case 1:case 2:case 3:var b=3;break;default:b=R}var c=R;R=b;try{return a()}finally{R=c}};exports.unstable_pauseExecution=function(){};exports.unstable_requestPaint=Z;exports.unstable_runWithPriority=function(a,b){switch(a){case 1:case 2:case 3:case 4:case 5:break;default:a=3}var c=R;R=a;try{return b()}finally{R=c}};\nexports.unstable_scheduleCallback=function(a,b,c){var d=exports.unstable_now();if(\"object\"===typeof c&&null!==c){var e=c.delay;e=\"number\"===typeof e&&0d?(a.sortIndex=e,J(O,a),null===L(N)&&a===L(O)&&(U?h():U=!0,g(W,e-d))):(a.sortIndex=c,J(N,a),T||S||(T=!0,f(X)));return a};\nexports.unstable_shouldYield=function(){var a=exports.unstable_now();V(a);var b=L(N);return b!==Q&&null!==Q&&null!==b&&null!==b.callback&&b.startTime<=a&&b.expirationTimeb}return!1}function v(a,b,c,d,e,f){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b;this.sanitizeURL=f}var C={};\n\"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style\".split(\" \").forEach(function(a){C[a]=new v(a,0,!1,a,null,!1)});[[\"acceptCharset\",\"accept-charset\"],[\"className\",\"class\"],[\"htmlFor\",\"for\"],[\"httpEquiv\",\"http-equiv\"]].forEach(function(a){var b=a[0];C[b]=new v(b,1,!1,a[1],null,!1)});[\"contentEditable\",\"draggable\",\"spellCheck\",\"value\"].forEach(function(a){C[a]=new v(a,2,!1,a.toLowerCase(),null,!1)});\n[\"autoReverse\",\"externalResourcesRequired\",\"focusable\",\"preserveAlpha\"].forEach(function(a){C[a]=new v(a,2,!1,a,null,!1)});\"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope\".split(\" \").forEach(function(a){C[a]=new v(a,3,!1,a.toLowerCase(),null,!1)});\n[\"checked\",\"multiple\",\"muted\",\"selected\"].forEach(function(a){C[a]=new v(a,3,!0,a,null,!1)});[\"capture\",\"download\"].forEach(function(a){C[a]=new v(a,4,!1,a,null,!1)});[\"cols\",\"rows\",\"size\",\"span\"].forEach(function(a){C[a]=new v(a,6,!1,a,null,!1)});[\"rowSpan\",\"start\"].forEach(function(a){C[a]=new v(a,5,!1,a.toLowerCase(),null,!1)});var Ua=/[\\-:]([a-z])/g;function Va(a){return a[1].toUpperCase()}\n\"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height\".split(\" \").forEach(function(a){var b=a.replace(Ua,\nVa);C[b]=new v(b,1,!1,a,null,!1)});\"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type\".split(\" \").forEach(function(a){var b=a.replace(Ua,Va);C[b]=new v(b,1,!1,a,\"http://www.w3.org/1999/xlink\",!1)});[\"xml:base\",\"xml:lang\",\"xml:space\"].forEach(function(a){var b=a.replace(Ua,Va);C[b]=new v(b,1,!1,a,\"http://www.w3.org/XML/1998/namespace\",!1)});[\"tabIndex\",\"crossOrigin\"].forEach(function(a){C[a]=new v(a,1,!1,a.toLowerCase(),null,!1)});\nC.xlinkHref=new v(\"xlinkHref\",1,!1,\"xlink:href\",\"http://www.w3.org/1999/xlink\",!0);[\"src\",\"href\",\"action\",\"formAction\"].forEach(function(a){C[a]=new v(a,1,!1,a.toLowerCase(),null,!0)});var Wa=aa.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;Wa.hasOwnProperty(\"ReactCurrentDispatcher\")||(Wa.ReactCurrentDispatcher={current:null});Wa.hasOwnProperty(\"ReactCurrentBatchConfig\")||(Wa.ReactCurrentBatchConfig={suspense:null});\nfunction Xa(a,b,c,d){var e=C.hasOwnProperty(b)?C[b]:null;var f=null!==e?0===e.type:d?!1:!(2=c.length))throw Error(u(93));c=c[0]}b=c}null==b&&(b=\"\");c=b}a._wrapperState={initialValue:rb(c)}}\nfunction Kb(a,b){var c=rb(b.value),d=rb(b.defaultValue);null!=c&&(c=\"\"+c,c!==a.value&&(a.value=c),null==b.defaultValue&&a.defaultValue!==c&&(a.defaultValue=c));null!=d&&(a.defaultValue=\"\"+d)}function Lb(a){var b=a.textContent;b===a._wrapperState.initialValue&&\"\"!==b&&null!==b&&(a.value=b)}var Mb={html:\"http://www.w3.org/1999/xhtml\",mathml:\"http://www.w3.org/1998/Math/MathML\",svg:\"http://www.w3.org/2000/svg\"};\nfunction Nb(a){switch(a){case \"svg\":return\"http://www.w3.org/2000/svg\";case \"math\":return\"http://www.w3.org/1998/Math/MathML\";default:return\"http://www.w3.org/1999/xhtml\"}}function Ob(a,b){return null==a||\"http://www.w3.org/1999/xhtml\"===a?Nb(b):\"http://www.w3.org/2000/svg\"===a&&\"foreignObject\"===b?\"http://www.w3.org/1999/xhtml\":a}\nvar Pb,Qb=function(a){return\"undefined\"!==typeof MSApp&&MSApp.execUnsafeLocalFunction?function(b,c,d,e){MSApp.execUnsafeLocalFunction(function(){return a(b,c,d,e)})}:a}(function(a,b){if(a.namespaceURI!==Mb.svg||\"innerHTML\"in a)a.innerHTML=b;else{Pb=Pb||document.createElement(\"div\");Pb.innerHTML=\"\"+b.valueOf().toString()+\"\";for(b=Pb.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;b.firstChild;)a.appendChild(b.firstChild)}});\nfunction Rb(a,b){if(b){var c=a.firstChild;if(c&&c===a.lastChild&&3===c.nodeType){c.nodeValue=b;return}}a.textContent=b}function Sb(a,b){var c={};c[a.toLowerCase()]=b.toLowerCase();c[\"Webkit\"+a]=\"webkit\"+b;c[\"Moz\"+a]=\"moz\"+b;return c}var Tb={animationend:Sb(\"Animation\",\"AnimationEnd\"),animationiteration:Sb(\"Animation\",\"AnimationIteration\"),animationstart:Sb(\"Animation\",\"AnimationStart\"),transitionend:Sb(\"Transition\",\"TransitionEnd\")},Ub={},Vb={};\nya&&(Vb=document.createElement(\"div\").style,\"AnimationEvent\"in window||(delete Tb.animationend.animation,delete Tb.animationiteration.animation,delete Tb.animationstart.animation),\"TransitionEvent\"in window||delete Tb.transitionend.transition);function Wb(a){if(Ub[a])return Ub[a];if(!Tb[a])return a;var b=Tb[a],c;for(c in b)if(b.hasOwnProperty(c)&&c in Vb)return Ub[a]=b[c];return a}\nvar Xb=Wb(\"animationend\"),Yb=Wb(\"animationiteration\"),Zb=Wb(\"animationstart\"),$b=Wb(\"transitionend\"),ac=\"abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting\".split(\" \"),bc=new (\"function\"===typeof WeakMap?WeakMap:Map);function cc(a){var b=bc.get(a);void 0===b&&(b=new Map,bc.set(a,b));return b}\nfunction dc(a){var b=a,c=a;if(a.alternate)for(;b.return;)b=b.return;else{a=b;do b=a,0!==(b.effectTag&1026)&&(c=b.return),a=b.return;while(a)}return 3===b.tag?c:null}function ec(a){if(13===a.tag){var b=a.memoizedState;null===b&&(a=a.alternate,null!==a&&(b=a.memoizedState));if(null!==b)return b.dehydrated}return null}function fc(a){if(dc(a)!==a)throw Error(u(188));}\nfunction gc(a){var b=a.alternate;if(!b){b=dc(a);if(null===b)throw Error(u(188));return b!==a?null:a}for(var c=a,d=b;;){var e=c.return;if(null===e)break;var f=e.alternate;if(null===f){d=e.return;if(null!==d){c=d;continue}break}if(e.child===f.child){for(f=e.child;f;){if(f===c)return fc(e),a;if(f===d)return fc(e),b;f=f.sibling}throw Error(u(188));}if(c.return!==d.return)c=e,d=f;else{for(var g=!1,h=e.child;h;){if(h===c){g=!0;c=e;d=f;break}if(h===d){g=!0;d=e;c=f;break}h=h.sibling}if(!g){for(h=f.child;h;){if(h===\nc){g=!0;c=f;d=e;break}if(h===d){g=!0;d=f;c=e;break}h=h.sibling}if(!g)throw Error(u(189));}}if(c.alternate!==d)throw Error(u(190));}if(3!==c.tag)throw Error(u(188));return c.stateNode.current===c?a:b}function hc(a){a=gc(a);if(!a)return null;for(var b=a;;){if(5===b.tag||6===b.tag)return b;if(b.child)b.child.return=b,b=b.child;else{if(b===a)break;for(;!b.sibling;){if(!b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}}return null}\nfunction ic(a,b){if(null==b)throw Error(u(30));if(null==a)return b;if(Array.isArray(a)){if(Array.isArray(b))return a.push.apply(a,b),a;a.push(b);return a}return Array.isArray(b)?[a].concat(b):[a,b]}function jc(a,b,c){Array.isArray(a)?a.forEach(b,c):a&&b.call(c,a)}var kc=null;\nfunction lc(a){if(a){var b=a._dispatchListeners,c=a._dispatchInstances;if(Array.isArray(b))for(var d=0;dpc.length&&pc.push(a)}\nfunction rc(a,b,c,d){if(pc.length){var e=pc.pop();e.topLevelType=a;e.eventSystemFlags=d;e.nativeEvent=b;e.targetInst=c;return e}return{topLevelType:a,eventSystemFlags:d,nativeEvent:b,targetInst:c,ancestors:[]}}\nfunction sc(a){var b=a.targetInst,c=b;do{if(!c){a.ancestors.push(c);break}var d=c;if(3===d.tag)d=d.stateNode.containerInfo;else{for(;d.return;)d=d.return;d=3!==d.tag?null:d.stateNode.containerInfo}if(!d)break;b=c.tag;5!==b&&6!==b||a.ancestors.push(c);c=tc(d)}while(c);for(c=0;c=b)return{node:c,offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=ud(c)}}\nfunction wd(a,b){return a&&b?a===b?!0:a&&3===a.nodeType?!1:b&&3===b.nodeType?wd(a,b.parentNode):\"contains\"in a?a.contains(b):a.compareDocumentPosition?!!(a.compareDocumentPosition(b)&16):!1:!1}function xd(){for(var a=window,b=td();b instanceof a.HTMLIFrameElement;){try{var c=\"string\"===typeof b.contentWindow.location.href}catch(d){c=!1}if(c)a=b.contentWindow;else break;b=td(a.document)}return b}\nfunction yd(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&(\"input\"===b&&(\"text\"===a.type||\"search\"===a.type||\"tel\"===a.type||\"url\"===a.type||\"password\"===a.type)||\"textarea\"===b||\"true\"===a.contentEditable)}var zd=\"$\",Ad=\"/$\",Bd=\"$?\",Cd=\"$!\",Dd=null,Ed=null;function Fd(a,b){switch(a){case \"button\":case \"input\":case \"select\":case \"textarea\":return!!b.autoFocus}return!1}\nfunction Gd(a,b){return\"textarea\"===a||\"option\"===a||\"noscript\"===a||\"string\"===typeof b.children||\"number\"===typeof b.children||\"object\"===typeof b.dangerouslySetInnerHTML&&null!==b.dangerouslySetInnerHTML&&null!=b.dangerouslySetInnerHTML.__html}var Hd=\"function\"===typeof setTimeout?setTimeout:void 0,Id=\"function\"===typeof clearTimeout?clearTimeout:void 0;function Jd(a){for(;null!=a;a=a.nextSibling){var b=a.nodeType;if(1===b||3===b)break}return a}\nfunction Kd(a){a=a.previousSibling;for(var b=0;a;){if(8===a.nodeType){var c=a.data;if(c===zd||c===Cd||c===Bd){if(0===b)return a;b--}else c===Ad&&b++}a=a.previousSibling}return null}var Ld=Math.random().toString(36).slice(2),Md=\"__reactInternalInstance$\"+Ld,Nd=\"__reactEventHandlers$\"+Ld,Od=\"__reactContainere$\"+Ld;\nfunction tc(a){var b=a[Md];if(b)return b;for(var c=a.parentNode;c;){if(b=c[Od]||c[Md]){c=b.alternate;if(null!==b.child||null!==c&&null!==c.child)for(a=Kd(a);null!==a;){if(c=a[Md])return c;a=Kd(a)}return b}a=c;c=a.parentNode}return null}function Nc(a){a=a[Md]||a[Od];return!a||5!==a.tag&&6!==a.tag&&13!==a.tag&&3!==a.tag?null:a}function Pd(a){if(5===a.tag||6===a.tag)return a.stateNode;throw Error(u(33));}function Qd(a){return a[Nd]||null}\nfunction Rd(a){do a=a.return;while(a&&5!==a.tag);return a?a:null}\nfunction Sd(a,b){var c=a.stateNode;if(!c)return null;var d=la(c);if(!d)return null;c=d[b];a:switch(b){case \"onClick\":case \"onClickCapture\":case \"onDoubleClick\":case \"onDoubleClickCapture\":case \"onMouseDown\":case \"onMouseDownCapture\":case \"onMouseMove\":case \"onMouseMoveCapture\":case \"onMouseUp\":case \"onMouseUpCapture\":case \"onMouseEnter\":(d=!d.disabled)||(a=a.type,d=!(\"button\"===a||\"input\"===a||\"select\"===a||\"textarea\"===a));a=!d;break a;default:a=!1}if(a)return null;if(c&&\"function\"!==typeof c)throw Error(u(231,\nb,typeof c));return c}function Td(a,b,c){if(b=Sd(a,c.dispatchConfig.phasedRegistrationNames[b]))c._dispatchListeners=ic(c._dispatchListeners,b),c._dispatchInstances=ic(c._dispatchInstances,a)}function Ud(a){if(a&&a.dispatchConfig.phasedRegistrationNames){for(var b=a._targetInst,c=[];b;)c.push(b),b=Rd(b);for(b=c.length;0this.eventPool.length&&this.eventPool.push(a)}function de(a){a.eventPool=[];a.getPooled=ee;a.release=fe}var ge=G.extend({data:null}),he=G.extend({data:null}),ie=[9,13,27,32],je=ya&&\"CompositionEvent\"in window,ke=null;ya&&\"documentMode\"in document&&(ke=document.documentMode);\nvar le=ya&&\"TextEvent\"in window&&!ke,me=ya&&(!je||ke&&8=ke),ne=String.fromCharCode(32),oe={beforeInput:{phasedRegistrationNames:{bubbled:\"onBeforeInput\",captured:\"onBeforeInputCapture\"},dependencies:[\"compositionend\",\"keypress\",\"textInput\",\"paste\"]},compositionEnd:{phasedRegistrationNames:{bubbled:\"onCompositionEnd\",captured:\"onCompositionEndCapture\"},dependencies:\"blur compositionend keydown keypress keyup mousedown\".split(\" \")},compositionStart:{phasedRegistrationNames:{bubbled:\"onCompositionStart\",\ncaptured:\"onCompositionStartCapture\"},dependencies:\"blur compositionstart keydown keypress keyup mousedown\".split(\" \")},compositionUpdate:{phasedRegistrationNames:{bubbled:\"onCompositionUpdate\",captured:\"onCompositionUpdateCapture\"},dependencies:\"blur compositionupdate keydown keypress keyup mousedown\".split(\" \")}},pe=!1;\nfunction qe(a,b){switch(a){case \"keyup\":return-1!==ie.indexOf(b.keyCode);case \"keydown\":return 229!==b.keyCode;case \"keypress\":case \"mousedown\":case \"blur\":return!0;default:return!1}}function re(a){a=a.detail;return\"object\"===typeof a&&\"data\"in a?a.data:null}var se=!1;function te(a,b){switch(a){case \"compositionend\":return re(b);case \"keypress\":if(32!==b.which)return null;pe=!0;return ne;case \"textInput\":return a=b.data,a===ne&&pe?null:a;default:return null}}\nfunction ue(a,b){if(se)return\"compositionend\"===a||!je&&qe(a,b)?(a=ae(),$d=Zd=Yd=null,se=!1,a):null;switch(a){case \"paste\":return null;case \"keypress\":if(!(b.ctrlKey||b.altKey||b.metaKey)||b.ctrlKey&&b.altKey){if(b.char&&1=document.documentMode,df={select:{phasedRegistrationNames:{bubbled:\"onSelect\",captured:\"onSelectCapture\"},dependencies:\"blur contextmenu dragend focus keydown keyup mousedown mouseup selectionchange\".split(\" \")}},ef=null,ff=null,gf=null,hf=!1;\nfunction jf(a,b){var c=b.window===b?b.document:9===b.nodeType?b:b.ownerDocument;if(hf||null==ef||ef!==td(c))return null;c=ef;\"selectionStart\"in c&&yd(c)?c={start:c.selectionStart,end:c.selectionEnd}:(c=(c.ownerDocument&&c.ownerDocument.defaultView||window).getSelection(),c={anchorNode:c.anchorNode,anchorOffset:c.anchorOffset,focusNode:c.focusNode,focusOffset:c.focusOffset});return gf&&bf(gf,c)?null:(gf=c,a=G.getPooled(df.select,ff,a,b),a.type=\"select\",a.target=ef,Xd(a),a)}\nvar kf={eventTypes:df,extractEvents:function(a,b,c,d,e,f){e=f||(d.window===d?d.document:9===d.nodeType?d:d.ownerDocument);if(!(f=!e)){a:{e=cc(e);f=wa.onSelect;for(var g=0;gzf||(a.current=yf[zf],yf[zf]=null,zf--)}\nfunction I(a,b){zf++;yf[zf]=a.current;a.current=b}var Af={},J={current:Af},K={current:!1},Bf=Af;function Cf(a,b){var c=a.type.contextTypes;if(!c)return Af;var d=a.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b)return d.__reactInternalMemoizedMaskedChildContext;var e={},f;for(f in c)e[f]=b[f];d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=b,a.__reactInternalMemoizedMaskedChildContext=e);return e}function L(a){a=a.childContextTypes;return null!==a&&void 0!==a}\nfunction Df(){H(K);H(J)}function Ef(a,b,c){if(J.current!==Af)throw Error(u(168));I(J,b);I(K,c)}function Ff(a,b,c){var d=a.stateNode;a=b.childContextTypes;if(\"function\"!==typeof d.getChildContext)return c;d=d.getChildContext();for(var e in d)if(!(e in a))throw Error(u(108,pb(b)||\"Unknown\",e));return n({},c,{},d)}function Gf(a){a=(a=a.stateNode)&&a.__reactInternalMemoizedMergedChildContext||Af;Bf=J.current;I(J,a);I(K,K.current);return!0}\nfunction Hf(a,b,c){var d=a.stateNode;if(!d)throw Error(u(169));c?(a=Ff(a,b,Bf),d.__reactInternalMemoizedMergedChildContext=a,H(K),H(J),I(J,a)):H(K);I(K,c)}\nvar If=r.unstable_runWithPriority,Jf=r.unstable_scheduleCallback,Kf=r.unstable_cancelCallback,Lf=r.unstable_requestPaint,Mf=r.unstable_now,Nf=r.unstable_getCurrentPriorityLevel,Of=r.unstable_ImmediatePriority,Pf=r.unstable_UserBlockingPriority,Qf=r.unstable_NormalPriority,Rf=r.unstable_LowPriority,Sf=r.unstable_IdlePriority,Tf={},Uf=r.unstable_shouldYield,Vf=void 0!==Lf?Lf:function(){},Wf=null,Xf=null,Yf=!1,Zf=Mf(),$f=1E4>Zf?Mf:function(){return Mf()-Zf};\nfunction ag(){switch(Nf()){case Of:return 99;case Pf:return 98;case Qf:return 97;case Rf:return 96;case Sf:return 95;default:throw Error(u(332));}}function bg(a){switch(a){case 99:return Of;case 98:return Pf;case 97:return Qf;case 96:return Rf;case 95:return Sf;default:throw Error(u(332));}}function cg(a,b){a=bg(a);return If(a,b)}function dg(a,b,c){a=bg(a);return Jf(a,b,c)}function eg(a){null===Wf?(Wf=[a],Xf=Jf(Of,fg)):Wf.push(a);return Tf}function gg(){if(null!==Xf){var a=Xf;Xf=null;Kf(a)}fg()}\nfunction fg(){if(!Yf&&null!==Wf){Yf=!0;var a=0;try{var b=Wf;cg(99,function(){for(;a=b&&(rg=!0),a.firstContext=null)}\nfunction sg(a,b){if(mg!==a&&!1!==b&&0!==b){if(\"number\"!==typeof b||1073741823===b)mg=a,b=1073741823;b={context:a,observedBits:b,next:null};if(null===lg){if(null===kg)throw Error(u(308));lg=b;kg.dependencies={expirationTime:0,firstContext:b,responders:null}}else lg=lg.next=b}return a._currentValue}var tg=!1;function ug(a){a.updateQueue={baseState:a.memoizedState,baseQueue:null,shared:{pending:null},effects:null}}\nfunction vg(a,b){a=a.updateQueue;b.updateQueue===a&&(b.updateQueue={baseState:a.baseState,baseQueue:a.baseQueue,shared:a.shared,effects:a.effects})}function wg(a,b){a={expirationTime:a,suspenseConfig:b,tag:0,payload:null,callback:null,next:null};return a.next=a}function xg(a,b){a=a.updateQueue;if(null!==a){a=a.shared;var c=a.pending;null===c?b.next=b:(b.next=c.next,c.next=b);a.pending=b}}\nfunction yg(a,b){var c=a.alternate;null!==c&&vg(c,a);a=a.updateQueue;c=a.baseQueue;null===c?(a.baseQueue=b.next=b,b.next=b):(b.next=c.next,c.next=b)}\nfunction zg(a,b,c,d){var e=a.updateQueue;tg=!1;var f=e.baseQueue,g=e.shared.pending;if(null!==g){if(null!==f){var h=f.next;f.next=g.next;g.next=h}f=g;e.shared.pending=null;h=a.alternate;null!==h&&(h=h.updateQueue,null!==h&&(h.baseQueue=g))}if(null!==f){h=f.next;var k=e.baseState,l=0,m=null,p=null,x=null;if(null!==h){var z=h;do{g=z.expirationTime;if(gl&&(l=g)}else{null!==x&&(x=x.next={expirationTime:1073741823,suspenseConfig:z.suspenseConfig,tag:z.tag,payload:z.payload,callback:z.callback,next:null});Ag(g,z.suspenseConfig);a:{var D=a,t=z;g=b;ca=c;switch(t.tag){case 1:D=t.payload;if(\"function\"===typeof D){k=D.call(ca,k,g);break a}k=D;break a;case 3:D.effectTag=D.effectTag&-4097|64;case 0:D=t.payload;g=\"function\"===typeof D?D.call(ca,k,g):D;if(null===g||void 0===g)break a;k=n({},k,g);break a;case 2:tg=!0}}null!==z.callback&&\n(a.effectTag|=32,g=e.effects,null===g?e.effects=[z]:g.push(z))}z=z.next;if(null===z||z===h)if(g=e.shared.pending,null===g)break;else z=f.next=g.next,g.next=h,e.baseQueue=f=g,e.shared.pending=null}while(1)}null===x?m=k:x.next=p;e.baseState=m;e.baseQueue=x;Bg(l);a.expirationTime=l;a.memoizedState=k}}\nfunction Cg(a,b,c){a=b.effects;b.effects=null;if(null!==a)for(b=0;by?(A=m,m=null):A=m.sibling;var q=x(e,m,h[y],k);if(null===q){null===m&&(m=A);break}a&&\nm&&null===q.alternate&&b(e,m);g=f(q,g,y);null===t?l=q:t.sibling=q;t=q;m=A}if(y===h.length)return c(e,m),l;if(null===m){for(;yy?(A=t,t=null):A=t.sibling;var D=x(e,t,q.value,l);if(null===D){null===t&&(t=A);break}a&&t&&null===D.alternate&&b(e,t);g=f(D,g,y);null===m?k=D:m.sibling=D;m=D;t=A}if(q.done)return c(e,t),k;if(null===t){for(;!q.done;y++,q=h.next())q=p(e,q.value,l),null!==q&&(g=f(q,g,y),null===m?k=q:m.sibling=q,m=q);return k}for(t=d(e,t);!q.done;y++,q=h.next())q=z(t,e,y,q.value,l),null!==q&&(a&&null!==\nq.alternate&&t.delete(null===q.key?y:q.key),g=f(q,g,y),null===m?k=q:m.sibling=q,m=q);a&&t.forEach(function(a){return b(e,a)});return k}return function(a,d,f,h){var k=\"object\"===typeof f&&null!==f&&f.type===ab&&null===f.key;k&&(f=f.props.children);var l=\"object\"===typeof f&&null!==f;if(l)switch(f.$$typeof){case Za:a:{l=f.key;for(k=d;null!==k;){if(k.key===l){switch(k.tag){case 7:if(f.type===ab){c(a,k.sibling);d=e(k,f.props.children);d.return=a;a=d;break a}break;default:if(k.elementType===f.type){c(a,\nk.sibling);d=e(k,f.props);d.ref=Pg(a,k,f);d.return=a;a=d;break a}}c(a,k);break}else b(a,k);k=k.sibling}f.type===ab?(d=Wg(f.props.children,a.mode,h,f.key),d.return=a,a=d):(h=Ug(f.type,f.key,f.props,null,a.mode,h),h.ref=Pg(a,d,f),h.return=a,a=h)}return g(a);case $a:a:{for(k=f.key;null!==d;){if(d.key===k)if(4===d.tag&&d.stateNode.containerInfo===f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[]);d.return=a;a=d;break a}else{c(a,d);break}else b(a,d);d=\nd.sibling}d=Vg(f,a.mode,h);d.return=a;a=d}return g(a)}if(\"string\"===typeof f||\"number\"===typeof f)return f=\"\"+f,null!==d&&6===d.tag?(c(a,d.sibling),d=e(d,f),d.return=a,a=d):(c(a,d),d=Tg(f,a.mode,h),d.return=a,a=d),g(a);if(Og(f))return ca(a,d,f,h);if(nb(f))return D(a,d,f,h);l&&Qg(a,f);if(\"undefined\"===typeof f&&!k)switch(a.tag){case 1:case 0:throw a=a.type,Error(u(152,a.displayName||a.name||\"Component\"));}return c(a,d)}}var Xg=Rg(!0),Yg=Rg(!1),Zg={},$g={current:Zg},ah={current:Zg},bh={current:Zg};\nfunction ch(a){if(a===Zg)throw Error(u(174));return a}function dh(a,b){I(bh,b);I(ah,a);I($g,Zg);a=b.nodeType;switch(a){case 9:case 11:b=(b=b.documentElement)?b.namespaceURI:Ob(null,\"\");break;default:a=8===a?b.parentNode:b,b=a.namespaceURI||null,a=a.tagName,b=Ob(b,a)}H($g);I($g,b)}function eh(){H($g);H(ah);H(bh)}function fh(a){ch(bh.current);var b=ch($g.current);var c=Ob(b,a.type);b!==c&&(I(ah,a),I($g,c))}function gh(a){ah.current===a&&(H($g),H(ah))}var M={current:0};\nfunction hh(a){for(var b=a;null!==b;){if(13===b.tag){var c=b.memoizedState;if(null!==c&&(c=c.dehydrated,null===c||c.data===Bd||c.data===Cd))return b}else if(19===b.tag&&void 0!==b.memoizedProps.revealOrder){if(0!==(b.effectTag&64))return b}else if(null!==b.child){b.child.return=b;b=b.child;continue}if(b===a)break;for(;null===b.sibling;){if(null===b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}return null}function ih(a,b){return{responder:a,props:b}}\nvar jh=Wa.ReactCurrentDispatcher,kh=Wa.ReactCurrentBatchConfig,lh=0,N=null,O=null,P=null,mh=!1;function Q(){throw Error(u(321));}function nh(a,b){if(null===b)return!1;for(var c=0;cf))throw Error(u(301));f+=1;P=O=null;b.updateQueue=null;jh.current=rh;a=c(d,e)}while(b.expirationTime===lh)}jh.current=sh;b=null!==O&&null!==O.next;lh=0;P=O=N=null;mh=!1;if(b)throw Error(u(300));return a}\nfunction th(){var a={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};null===P?N.memoizedState=P=a:P=P.next=a;return P}function uh(){if(null===O){var a=N.alternate;a=null!==a?a.memoizedState:null}else a=O.next;var b=null===P?N.memoizedState:P.next;if(null!==b)P=b,O=a;else{if(null===a)throw Error(u(310));O=a;a={memoizedState:O.memoizedState,baseState:O.baseState,baseQueue:O.baseQueue,queue:O.queue,next:null};null===P?N.memoizedState=P=a:P=P.next=a}return P}\nfunction vh(a,b){return\"function\"===typeof b?b(a):b}\nfunction wh(a){var b=uh(),c=b.queue;if(null===c)throw Error(u(311));c.lastRenderedReducer=a;var d=O,e=d.baseQueue,f=c.pending;if(null!==f){if(null!==e){var g=e.next;e.next=f.next;f.next=g}d.baseQueue=e=f;c.pending=null}if(null!==e){e=e.next;d=d.baseState;var h=g=f=null,k=e;do{var l=k.expirationTime;if(lN.expirationTime&&\n(N.expirationTime=l,Bg(l))}else null!==h&&(h=h.next={expirationTime:1073741823,suspenseConfig:k.suspenseConfig,action:k.action,eagerReducer:k.eagerReducer,eagerState:k.eagerState,next:null}),Ag(l,k.suspenseConfig),d=k.eagerReducer===a?k.eagerState:a(d,k.action);k=k.next}while(null!==k&&k!==e);null===h?f=d:h.next=g;$e(d,b.memoizedState)||(rg=!0);b.memoizedState=d;b.baseState=f;b.baseQueue=h;c.lastRenderedState=d}return[b.memoizedState,c.dispatch]}\nfunction xh(a){var b=uh(),c=b.queue;if(null===c)throw Error(u(311));c.lastRenderedReducer=a;var d=c.dispatch,e=c.pending,f=b.memoizedState;if(null!==e){c.pending=null;var g=e=e.next;do f=a(f,g.action),g=g.next;while(g!==e);$e(f,b.memoizedState)||(rg=!0);b.memoizedState=f;null===b.baseQueue&&(b.baseState=f);c.lastRenderedState=f}return[f,d]}\nfunction yh(a){var b=th();\"function\"===typeof a&&(a=a());b.memoizedState=b.baseState=a;a=b.queue={pending:null,dispatch:null,lastRenderedReducer:vh,lastRenderedState:a};a=a.dispatch=zh.bind(null,N,a);return[b.memoizedState,a]}function Ah(a,b,c,d){a={tag:a,create:b,destroy:c,deps:d,next:null};b=N.updateQueue;null===b?(b={lastEffect:null},N.updateQueue=b,b.lastEffect=a.next=a):(c=b.lastEffect,null===c?b.lastEffect=a.next=a:(d=c.next,c.next=a,a.next=d,b.lastEffect=a));return a}\nfunction Bh(){return uh().memoizedState}function Ch(a,b,c,d){var e=th();N.effectTag|=a;e.memoizedState=Ah(1|b,c,void 0,void 0===d?null:d)}function Dh(a,b,c,d){var e=uh();d=void 0===d?null:d;var f=void 0;if(null!==O){var g=O.memoizedState;f=g.destroy;if(null!==d&&nh(d,g.deps)){Ah(b,c,f,d);return}}N.effectTag|=a;e.memoizedState=Ah(1|b,c,f,d)}function Eh(a,b){return Ch(516,4,a,b)}function Fh(a,b){return Dh(516,4,a,b)}function Gh(a,b){return Dh(4,2,a,b)}\nfunction Hh(a,b){if(\"function\"===typeof b)return a=a(),b(a),function(){b(null)};if(null!==b&&void 0!==b)return a=a(),b.current=a,function(){b.current=null}}function Ih(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return Dh(4,2,Hh.bind(null,b,a),c)}function Jh(){}function Kh(a,b){th().memoizedState=[a,void 0===b?null:b];return a}function Lh(a,b){var c=uh();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&nh(b,d[1]))return d[0];c.memoizedState=[a,b];return a}\nfunction Mh(a,b){var c=uh();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&nh(b,d[1]))return d[0];a=a();c.memoizedState=[a,b];return a}function Nh(a,b,c){var d=ag();cg(98>d?98:d,function(){a(!0)});cg(97\\x3c/script>\",a=a.removeChild(a.firstChild)):\"string\"===typeof d.is?a=g.createElement(e,{is:d.is}):(a=g.createElement(e),\"select\"===e&&(g=a,d.multiple?g.multiple=!0:d.size&&(g.size=d.size))):a=g.createElementNS(a,e);a[Md]=b;a[Nd]=d;ni(a,b,!1,!1);b.stateNode=a;g=pd(e,d);switch(e){case \"iframe\":case \"object\":case \"embed\":F(\"load\",\na);h=d;break;case \"video\":case \"audio\":for(h=0;hd.tailExpiration&&1b)&&tj.set(a,b)))}}\nfunction xj(a,b){a.expirationTimea?c:a;return 2>=a&&b!==a?0:a}\nfunction Z(a){if(0!==a.lastExpiredTime)a.callbackExpirationTime=1073741823,a.callbackPriority=99,a.callbackNode=eg(yj.bind(null,a));else{var b=zj(a),c=a.callbackNode;if(0===b)null!==c&&(a.callbackNode=null,a.callbackExpirationTime=0,a.callbackPriority=90);else{var d=Gg();1073741823===b?d=99:1===b||2===b?d=95:(d=10*(1073741821-b)-10*(1073741821-d),d=0>=d?99:250>=d?98:5250>=d?97:95);if(null!==c){var e=a.callbackPriority;if(a.callbackExpirationTime===b&&e>=d)return;c!==Tf&&Kf(c)}a.callbackExpirationTime=\nb;a.callbackPriority=d;b=1073741823===b?eg(yj.bind(null,a)):dg(d,Bj.bind(null,a),{timeout:10*(1073741821-b)-$f()});a.callbackNode=b}}}\nfunction Bj(a,b){wj=0;if(b)return b=Gg(),Cj(a,b),Z(a),null;var c=zj(a);if(0!==c){b=a.callbackNode;if((W&(fj|gj))!==V)throw Error(u(327));Dj();a===T&&c===U||Ej(a,c);if(null!==X){var d=W;W|=fj;var e=Fj();do try{Gj();break}catch(h){Hj(a,h)}while(1);ng();W=d;cj.current=e;if(S===hj)throw b=kj,Ej(a,c),xi(a,c),Z(a),b;if(null===X)switch(e=a.finishedWork=a.current.alternate,a.finishedExpirationTime=c,d=S,T=null,d){case ti:case hj:throw Error(u(345));case ij:Cj(a,2=c){a.lastPingedTime=c;Ej(a,c);break}}f=zj(a);if(0!==f&&f!==c)break;if(0!==d&&d!==c){a.lastPingedTime=d;break}a.timeoutHandle=Hd(Jj.bind(null,a),e);break}Jj(a);break;case vi:xi(a,c);d=a.lastSuspendedTime;c===d&&(a.nextKnownPendingLevel=Ij(e));if(oj&&(e=a.lastPingedTime,0===e||e>=c)){a.lastPingedTime=c;Ej(a,c);break}e=zj(a);if(0!==e&&e!==c)break;if(0!==d&&d!==c){a.lastPingedTime=\nd;break}1073741823!==mj?d=10*(1073741821-mj)-$f():1073741823===lj?d=0:(d=10*(1073741821-lj)-5E3,e=$f(),c=10*(1073741821-c)-e,d=e-d,0>d&&(d=0),d=(120>d?120:480>d?480:1080>d?1080:1920>d?1920:3E3>d?3E3:4320>d?4320:1960*bj(d/1960))-d,c=d?d=0:(e=g.busyDelayMs|0,f=$f()-(10*(1073741821-f)-(g.timeoutMs|0||5E3)),d=f<=e?0:e+d-f);if(10 component higher in the tree to provide a loading indicator or placeholder to display.\"+qb(g))}S!==\njj&&(S=ij);h=Ai(h,g);p=f;do{switch(p.tag){case 3:k=h;p.effectTag|=4096;p.expirationTime=b;var B=Xi(p,k,b);yg(p,B);break a;case 1:k=h;var w=p.type,ub=p.stateNode;if(0===(p.effectTag&64)&&(\"function\"===typeof w.getDerivedStateFromError||null!==ub&&\"function\"===typeof ub.componentDidCatch&&(null===aj||!aj.has(ub)))){p.effectTag|=4096;p.expirationTime=b;var vb=$i(p,k,b);yg(p,vb);break a}}p=p.return}while(null!==p)}X=Pj(X)}catch(Xc){b=Xc;continue}break}while(1)}\nfunction Fj(){var a=cj.current;cj.current=sh;return null===a?sh:a}function Ag(a,b){awi&&(wi=a)}function Kj(){for(;null!==X;)X=Qj(X)}function Gj(){for(;null!==X&&!Uf();)X=Qj(X)}function Qj(a){var b=Rj(a.alternate,a,U);a.memoizedProps=a.pendingProps;null===b&&(b=Pj(a));dj.current=null;return b}\nfunction Pj(a){X=a;do{var b=X.alternate;a=X.return;if(0===(X.effectTag&2048)){b=si(b,X,U);if(1===U||1!==X.childExpirationTime){for(var c=0,d=X.child;null!==d;){var e=d.expirationTime,f=d.childExpirationTime;e>c&&(c=e);f>c&&(c=f);d=d.sibling}X.childExpirationTime=c}if(null!==b)return b;null!==a&&0===(a.effectTag&2048)&&(null===a.firstEffect&&(a.firstEffect=X.firstEffect),null!==X.lastEffect&&(null!==a.lastEffect&&(a.lastEffect.nextEffect=X.firstEffect),a.lastEffect=X.lastEffect),1a?b:a}function Jj(a){var b=ag();cg(99,Sj.bind(null,a,b));return null}\nfunction Sj(a,b){do Dj();while(null!==rj);if((W&(fj|gj))!==V)throw Error(u(327));var c=a.finishedWork,d=a.finishedExpirationTime;if(null===c)return null;a.finishedWork=null;a.finishedExpirationTime=0;if(c===a.current)throw Error(u(177));a.callbackNode=null;a.callbackExpirationTime=0;a.callbackPriority=90;a.nextKnownPendingLevel=0;var e=Ij(c);a.firstPendingTime=e;d<=a.lastSuspendedTime?a.firstSuspendedTime=a.lastSuspendedTime=a.nextKnownPendingLevel=0:d<=a.firstSuspendedTime&&(a.firstSuspendedTime=\nd-1);d<=a.lastPingedTime&&(a.lastPingedTime=0);d<=a.lastExpiredTime&&(a.lastExpiredTime=0);a===T&&(X=T=null,U=0);1h&&(l=h,h=g,g=l),l=vd(q,g),m=vd(q,h),l&&m&&(1!==w.rangeCount||w.anchorNode!==l.node||w.anchorOffset!==l.offset||w.focusNode!==m.node||w.focusOffset!==m.offset)&&(B=B.createRange(),B.setStart(l.node,l.offset),w.removeAllRanges(),g>h?(w.addRange(B),w.extend(m.node,m.offset)):(B.setEnd(m.node,m.offset),w.addRange(B))))));B=[];for(w=q;w=w.parentNode;)1===w.nodeType&&B.push({element:w,left:w.scrollLeft,\ntop:w.scrollTop});\"function\"===typeof q.focus&&q.focus();for(q=0;q=c)return ji(a,b,c);I(M,M.current&1);b=$h(a,b,c);return null!==b?b.sibling:null}I(M,M.current&1);break;case 19:d=b.childExpirationTime>=c;if(0!==(a.effectTag&64)){if(d)return mi(a,b,c);b.effectTag|=64}e=b.memoizedState;null!==e&&(e.rendering=null,e.tail=null);I(M,M.current);if(!d)return null}return $h(a,b,c)}rg=!1}}else rg=!1;b.expirationTime=0;switch(b.tag){case 2:d=b.type;null!==a&&(a.alternate=null,b.alternate=null,b.effectTag|=2);a=b.pendingProps;e=Cf(b,J.current);qg(b,c);e=oh(null,\nb,d,a,e,c);b.effectTag|=1;if(\"object\"===typeof e&&null!==e&&\"function\"===typeof e.render&&void 0===e.$$typeof){b.tag=1;b.memoizedState=null;b.updateQueue=null;if(L(d)){var f=!0;Gf(b)}else f=!1;b.memoizedState=null!==e.state&&void 0!==e.state?e.state:null;ug(b);var g=d.getDerivedStateFromProps;\"function\"===typeof g&&Fg(b,d,g,a);e.updater=Jg;b.stateNode=e;e._reactInternalFiber=b;Ng(b,d,a,c);b=gi(null,b,d,!0,f,c)}else b.tag=0,R(null,b,e,c),b=b.child;return b;case 16:a:{e=b.elementType;null!==a&&(a.alternate=\nnull,b.alternate=null,b.effectTag|=2);a=b.pendingProps;ob(e);if(1!==e._status)throw e._result;e=e._result;b.type=e;f=b.tag=Xj(e);a=ig(e,a);switch(f){case 0:b=di(null,b,e,a,c);break a;case 1:b=fi(null,b,e,a,c);break a;case 11:b=Zh(null,b,e,a,c);break a;case 14:b=ai(null,b,e,ig(e.type,a),d,c);break a}throw Error(u(306,e,\"\"));}return b;case 0:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:ig(d,e),di(a,b,d,e,c);case 1:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:ig(d,e),fi(a,b,d,e,c);\ncase 3:hi(b);d=b.updateQueue;if(null===a||null===d)throw Error(u(282));d=b.pendingProps;e=b.memoizedState;e=null!==e?e.element:null;vg(a,b);zg(b,d,null,c);d=b.memoizedState.element;if(d===e)Xh(),b=$h(a,b,c);else{if(e=b.stateNode.hydrate)Ph=Jd(b.stateNode.containerInfo.firstChild),Oh=b,e=Qh=!0;if(e)for(c=Yg(b,null,d,c),b.child=c;c;)c.effectTag=c.effectTag&-3|1024,c=c.sibling;else R(a,b,d,c),Xh();b=b.child}return b;case 5:return fh(b),null===a&&Uh(b),d=b.type,e=b.pendingProps,f=null!==a?a.memoizedProps:\nnull,g=e.children,Gd(d,e)?g=null:null!==f&&Gd(d,f)&&(b.effectTag|=16),ei(a,b),b.mode&4&&1!==c&&e.hidden?(b.expirationTime=b.childExpirationTime=1,b=null):(R(a,b,g,c),b=b.child),b;case 6:return null===a&&Uh(b),null;case 13:return ji(a,b,c);case 4:return dh(b,b.stateNode.containerInfo),d=b.pendingProps,null===a?b.child=Xg(b,null,d,c):R(a,b,d,c),b.child;case 11:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:ig(d,e),Zh(a,b,d,e,c);case 7:return R(a,b,b.pendingProps,c),b.child;case 8:return R(a,\nb,b.pendingProps.children,c),b.child;case 12:return R(a,b,b.pendingProps.children,c),b.child;case 10:a:{d=b.type._context;e=b.pendingProps;g=b.memoizedProps;f=e.value;var h=b.type._context;I(jg,h._currentValue);h._currentValue=f;if(null!==g)if(h=g.value,f=$e(h,f)?0:(\"function\"===typeof d._calculateChangedBits?d._calculateChangedBits(h,f):1073741823)|0,0===f){if(g.children===e.children&&!K.current){b=$h(a,b,c);break a}}else for(h=b.child,null!==h&&(h.return=b);null!==h;){var k=h.dependencies;if(null!==\nk){g=h.child;for(var l=k.firstContext;null!==l;){if(l.context===d&&0!==(l.observedBits&f)){1===h.tag&&(l=wg(c,null),l.tag=2,xg(h,l));h.expirationTime=b&&a<=b}function xi(a,b){var c=a.firstSuspendedTime,d=a.lastSuspendedTime;cb||0===c)a.lastSuspendedTime=b;b<=a.lastPingedTime&&(a.lastPingedTime=0);b<=a.lastExpiredTime&&(a.lastExpiredTime=0)}\nfunction yi(a,b){b>a.firstPendingTime&&(a.firstPendingTime=b);var c=a.firstSuspendedTime;0!==c&&(b>=c?a.firstSuspendedTime=a.lastSuspendedTime=a.nextKnownPendingLevel=0:b>=a.lastSuspendedTime&&(a.lastSuspendedTime=b+1),b>a.nextKnownPendingLevel&&(a.nextKnownPendingLevel=b))}function Cj(a,b){var c=a.lastExpiredTime;if(0===c||c>b)a.lastExpiredTime=b}\nfunction bk(a,b,c,d){var e=b.current,f=Gg(),g=Dg.suspense;f=Hg(f,e,g);a:if(c){c=c._reactInternalFiber;b:{if(dc(c)!==c||1!==c.tag)throw Error(u(170));var h=c;do{switch(h.tag){case 3:h=h.stateNode.context;break b;case 1:if(L(h.type)){h=h.stateNode.__reactInternalMemoizedMergedChildContext;break b}}h=h.return}while(null!==h);throw Error(u(171));}if(1===c.tag){var k=c.type;if(L(k)){c=Ff(c,k,h);break a}}c=h}else c=Af;null===b.context?b.context=c:b.pendingContext=c;b=wg(f,g);b.payload={element:a};d=void 0===\nd?null:d;null!==d&&(b.callback=d);xg(e,b);Ig(e,f);return f}function ck(a){a=a.current;if(!a.child)return null;switch(a.child.tag){case 5:return a.child.stateNode;default:return a.child.stateNode}}function dk(a,b){a=a.memoizedState;null!==a&&null!==a.dehydrated&&a.retryTime= 0) continue;\n target[key] = source[key];\n }\n return target;\n}","/** @license React v16.13.1\n * react-is.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';var b=\"function\"===typeof Symbol&&Symbol.for,c=b?Symbol.for(\"react.element\"):60103,d=b?Symbol.for(\"react.portal\"):60106,e=b?Symbol.for(\"react.fragment\"):60107,f=b?Symbol.for(\"react.strict_mode\"):60108,g=b?Symbol.for(\"react.profiler\"):60114,h=b?Symbol.for(\"react.provider\"):60109,k=b?Symbol.for(\"react.context\"):60110,l=b?Symbol.for(\"react.async_mode\"):60111,m=b?Symbol.for(\"react.concurrent_mode\"):60111,n=b?Symbol.for(\"react.forward_ref\"):60112,p=b?Symbol.for(\"react.suspense\"):60113,q=b?\nSymbol.for(\"react.suspense_list\"):60120,r=b?Symbol.for(\"react.memo\"):60115,t=b?Symbol.for(\"react.lazy\"):60116,v=b?Symbol.for(\"react.block\"):60121,w=b?Symbol.for(\"react.fundamental\"):60117,x=b?Symbol.for(\"react.responder\"):60118,y=b?Symbol.for(\"react.scope\"):60119;\nfunction z(a){if(\"object\"===typeof a&&null!==a){var u=a.$$typeof;switch(u){case c:switch(a=a.type,a){case l:case m:case e:case g:case f:case p:return a;default:switch(a=a&&a.$$typeof,a){case k:case n:case t:case r:case h:return a;default:return u}}case d:return u}}}function A(a){return z(a)===m}exports.AsyncMode=l;exports.ConcurrentMode=m;exports.ContextConsumer=k;exports.ContextProvider=h;exports.Element=c;exports.ForwardRef=n;exports.Fragment=e;exports.Lazy=t;exports.Memo=r;exports.Portal=d;\nexports.Profiler=g;exports.StrictMode=f;exports.Suspense=p;exports.isAsyncMode=function(a){return A(a)||z(a)===l};exports.isConcurrentMode=A;exports.isContextConsumer=function(a){return z(a)===k};exports.isContextProvider=function(a){return z(a)===h};exports.isElement=function(a){return\"object\"===typeof a&&null!==a&&a.$$typeof===c};exports.isForwardRef=function(a){return z(a)===n};exports.isFragment=function(a){return z(a)===e};exports.isLazy=function(a){return z(a)===t};\nexports.isMemo=function(a){return z(a)===r};exports.isPortal=function(a){return z(a)===d};exports.isProfiler=function(a){return z(a)===g};exports.isStrictMode=function(a){return z(a)===f};exports.isSuspense=function(a){return z(a)===p};\nexports.isValidElementType=function(a){return\"string\"===typeof a||\"function\"===typeof a||a===e||a===m||a===g||a===f||a===p||a===q||\"object\"===typeof a&&null!==a&&(a.$$typeof===t||a.$$typeof===r||a.$$typeof===h||a.$$typeof===k||a.$$typeof===n||a.$$typeof===w||a.$$typeof===x||a.$$typeof===y||a.$$typeof===v)};exports.typeOf=z;\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-is.production.min.js');\n} else {\n module.exports = require('./cjs/react-is.development.js');\n}\n","'use strict';\n\nvar reactIs = require('react-is');\n\n/**\n * Copyright 2015, Yahoo! Inc.\n * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.\n */\nvar REACT_STATICS = {\n childContextTypes: true,\n contextType: true,\n contextTypes: true,\n defaultProps: true,\n displayName: true,\n getDefaultProps: true,\n getDerivedStateFromError: true,\n getDerivedStateFromProps: true,\n mixins: true,\n propTypes: true,\n type: true\n};\nvar KNOWN_STATICS = {\n name: true,\n length: true,\n prototype: true,\n caller: true,\n callee: true,\n arguments: true,\n arity: true\n};\nvar FORWARD_REF_STATICS = {\n '$$typeof': true,\n render: true,\n defaultProps: true,\n displayName: true,\n propTypes: true\n};\nvar MEMO_STATICS = {\n '$$typeof': true,\n compare: true,\n defaultProps: true,\n displayName: true,\n propTypes: true,\n type: true\n};\nvar TYPE_STATICS = {};\nTYPE_STATICS[reactIs.ForwardRef] = FORWARD_REF_STATICS;\nTYPE_STATICS[reactIs.Memo] = MEMO_STATICS;\n\nfunction getStatics(component) {\n // React v16.11 and below\n if (reactIs.isMemo(component)) {\n return MEMO_STATICS;\n } // React v16.12 and above\n\n\n return TYPE_STATICS[component['$$typeof']] || REACT_STATICS;\n}\n\nvar defineProperty = Object.defineProperty;\nvar getOwnPropertyNames = Object.getOwnPropertyNames;\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar getPrototypeOf = Object.getPrototypeOf;\nvar objectPrototype = Object.prototype;\nfunction hoistNonReactStatics(targetComponent, sourceComponent, blacklist) {\n if (typeof sourceComponent !== 'string') {\n // don't hoist over string (html) components\n if (objectPrototype) {\n var inheritedComponent = getPrototypeOf(sourceComponent);\n\n if (inheritedComponent && inheritedComponent !== objectPrototype) {\n hoistNonReactStatics(targetComponent, inheritedComponent, blacklist);\n }\n }\n\n var keys = getOwnPropertyNames(sourceComponent);\n\n if (getOwnPropertySymbols) {\n keys = keys.concat(getOwnPropertySymbols(sourceComponent));\n }\n\n var targetStatics = getStatics(targetComponent);\n var sourceStatics = getStatics(sourceComponent);\n\n for (var i = 0; i < keys.length; ++i) {\n var key = keys[i];\n\n if (!KNOWN_STATICS[key] && !(blacklist && blacklist[key]) && !(sourceStatics && sourceStatics[key]) && !(targetStatics && targetStatics[key])) {\n var descriptor = getOwnPropertyDescriptor(sourceComponent, key);\n\n try {\n // Avoid failures from read-only properties\n defineProperty(targetComponent, key, descriptor);\n } catch (e) {}\n }\n }\n }\n\n return targetComponent;\n}\n\nmodule.exports = hoistNonReactStatics;\n","/** @license React v17.0.2\n * react-is.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var b=60103,c=60106,d=60107,e=60108,f=60114,g=60109,h=60110,k=60112,l=60113,m=60120,n=60115,p=60116,q=60121,r=60122,u=60117,v=60129,w=60131;\nif(\"function\"===typeof Symbol&&Symbol.for){var x=Symbol.for;b=x(\"react.element\");c=x(\"react.portal\");d=x(\"react.fragment\");e=x(\"react.strict_mode\");f=x(\"react.profiler\");g=x(\"react.provider\");h=x(\"react.context\");k=x(\"react.forward_ref\");l=x(\"react.suspense\");m=x(\"react.suspense_list\");n=x(\"react.memo\");p=x(\"react.lazy\");q=x(\"react.block\");r=x(\"react.server.block\");u=x(\"react.fundamental\");v=x(\"react.debug_trace_mode\");w=x(\"react.legacy_hidden\")}\nfunction y(a){if(\"object\"===typeof a&&null!==a){var t=a.$$typeof;switch(t){case b:switch(a=a.type,a){case d:case f:case e:case l:case m:return a;default:switch(a=a&&a.$$typeof,a){case h:case k:case p:case n:case g:return a;default:return t}}case c:return t}}}var z=g,A=b,B=k,C=d,D=p,E=n,F=c,G=f,H=e,I=l;exports.ContextConsumer=h;exports.ContextProvider=z;exports.Element=A;exports.ForwardRef=B;exports.Fragment=C;exports.Lazy=D;exports.Memo=E;exports.Portal=F;exports.Profiler=G;exports.StrictMode=H;\nexports.Suspense=I;exports.isAsyncMode=function(){return!1};exports.isConcurrentMode=function(){return!1};exports.isContextConsumer=function(a){return y(a)===h};exports.isContextProvider=function(a){return y(a)===g};exports.isElement=function(a){return\"object\"===typeof a&&null!==a&&a.$$typeof===b};exports.isForwardRef=function(a){return y(a)===k};exports.isFragment=function(a){return y(a)===d};exports.isLazy=function(a){return y(a)===p};exports.isMemo=function(a){return y(a)===n};\nexports.isPortal=function(a){return y(a)===c};exports.isProfiler=function(a){return y(a)===f};exports.isStrictMode=function(a){return y(a)===e};exports.isSuspense=function(a){return y(a)===l};exports.isValidElementType=function(a){return\"string\"===typeof a||\"function\"===typeof a||a===d||a===f||a===v||a===e||a===l||a===m||a===w||\"object\"===typeof a&&null!==a&&(a.$$typeof===p||a.$$typeof===n||a.$$typeof===g||a.$$typeof===h||a.$$typeof===k||a.$$typeof===u||a.$$typeof===q||a[0]===r)?!0:!1};\nexports.typeOf=y;\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-is.production.min.js');\n} else {\n module.exports = require('./cjs/react-is.development.js');\n}\n","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nvar _excluded = [\"getDisplayName\", \"methodName\", \"renderCountProp\", \"shouldHandleStateChanges\", \"storeKey\", \"withRef\", \"forwardRef\", \"context\"],\n _excluded2 = [\"reactReduxForwardedRef\"];\nimport hoistStatics from 'hoist-non-react-statics';\nimport React, { useContext, useMemo, useRef, useReducer } from 'react';\nimport { isValidElementType, isContextConsumer } from 'react-is';\nimport { createSubscription } from '../utils/Subscription';\nimport { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect';\nimport { ReactReduxContext } from './Context'; // Define some constant arrays just to avoid re-creating these\n\nvar EMPTY_ARRAY = [];\nvar NO_SUBSCRIPTION_ARRAY = [null, null];\n\nvar stringifyComponent = function stringifyComponent(Comp) {\n try {\n return JSON.stringify(Comp);\n } catch (err) {\n return String(Comp);\n }\n};\n\nfunction storeStateUpdatesReducer(state, action) {\n var updateCount = state[1];\n return [action.payload, updateCount + 1];\n}\n\nfunction useIsomorphicLayoutEffectWithArgs(effectFunc, effectArgs, dependencies) {\n useIsomorphicLayoutEffect(function () {\n return effectFunc.apply(void 0, effectArgs);\n }, dependencies);\n}\n\nfunction captureWrapperProps(lastWrapperProps, lastChildProps, renderIsScheduled, wrapperProps, actualChildProps, childPropsFromStoreUpdate, notifyNestedSubs) {\n // We want to capture the wrapper props and child props we used for later comparisons\n lastWrapperProps.current = wrapperProps;\n lastChildProps.current = actualChildProps;\n renderIsScheduled.current = false; // If the render was from a store update, clear out that reference and cascade the subscriber update\n\n if (childPropsFromStoreUpdate.current) {\n childPropsFromStoreUpdate.current = null;\n notifyNestedSubs();\n }\n}\n\nfunction subscribeUpdates(shouldHandleStateChanges, store, subscription, childPropsSelector, lastWrapperProps, lastChildProps, renderIsScheduled, childPropsFromStoreUpdate, notifyNestedSubs, forceComponentUpdateDispatch) {\n // If we're not subscribed to the store, nothing to do here\n if (!shouldHandleStateChanges) return; // Capture values for checking if and when this component unmounts\n\n var didUnsubscribe = false;\n var lastThrownError = null; // We'll run this callback every time a store subscription update propagates to this component\n\n var checkForUpdates = function checkForUpdates() {\n if (didUnsubscribe) {\n // Don't run stale listeners.\n // Redux doesn't guarantee unsubscriptions happen until next dispatch.\n return;\n }\n\n var latestStoreState = store.getState();\n var newChildProps, error;\n\n try {\n // Actually run the selector with the most recent store state and wrapper props\n // to determine what the child props should be\n newChildProps = childPropsSelector(latestStoreState, lastWrapperProps.current);\n } catch (e) {\n error = e;\n lastThrownError = e;\n }\n\n if (!error) {\n lastThrownError = null;\n } // If the child props haven't changed, nothing to do here - cascade the subscription update\n\n\n if (newChildProps === lastChildProps.current) {\n if (!renderIsScheduled.current) {\n notifyNestedSubs();\n }\n } else {\n // Save references to the new child props. Note that we track the \"child props from store update\"\n // as a ref instead of a useState/useReducer because we need a way to determine if that value has\n // been processed. If this went into useState/useReducer, we couldn't clear out the value without\n // forcing another re-render, which we don't want.\n lastChildProps.current = newChildProps;\n childPropsFromStoreUpdate.current = newChildProps;\n renderIsScheduled.current = true; // If the child props _did_ change (or we caught an error), this wrapper component needs to re-render\n\n forceComponentUpdateDispatch({\n type: 'STORE_UPDATED',\n payload: {\n error: error\n }\n });\n }\n }; // Actually subscribe to the nearest connected ancestor (or store)\n\n\n subscription.onStateChange = checkForUpdates;\n subscription.trySubscribe(); // Pull data from the store after first render in case the store has\n // changed since we began.\n\n checkForUpdates();\n\n var unsubscribeWrapper = function unsubscribeWrapper() {\n didUnsubscribe = true;\n subscription.tryUnsubscribe();\n subscription.onStateChange = null;\n\n if (lastThrownError) {\n // It's possible that we caught an error due to a bad mapState function, but the\n // parent re-rendered without this component and we're about to unmount.\n // This shouldn't happen as long as we do top-down subscriptions correctly, but\n // if we ever do those wrong, this throw will surface the error in our tests.\n // In that case, throw the error from here so it doesn't get lost.\n throw lastThrownError;\n }\n };\n\n return unsubscribeWrapper;\n}\n\nvar initStateUpdates = function initStateUpdates() {\n return [null, 0];\n};\n\nexport default function connectAdvanced(\n/*\r\n selectorFactory is a func that is responsible for returning the selector function used to\r\n compute new props from state, props, and dispatch. For example:\r\n export default connectAdvanced((dispatch, options) => (state, props) => ({\r\n thing: state.things[props.thingId],\r\n saveThing: fields => dispatch(actionCreators.saveThing(props.thingId, fields)),\r\n }))(YourComponent)\r\n Access to dispatch is provided to the factory so selectorFactories can bind actionCreators\r\n outside of their selector as an optimization. Options passed to connectAdvanced are passed to\r\n the selectorFactory, along with displayName and WrappedComponent, as the second argument.\r\n Note that selectorFactory is responsible for all caching/memoization of inbound and outbound\r\n props. Do not use connectAdvanced directly without memoizing results between calls to your\r\n selector, otherwise the Connect component will re-render on every state or props change.\r\n*/\nselectorFactory, // options object:\n_ref) {\n if (_ref === void 0) {\n _ref = {};\n }\n\n var _ref2 = _ref,\n _ref2$getDisplayName = _ref2.getDisplayName,\n getDisplayName = _ref2$getDisplayName === void 0 ? function (name) {\n return \"ConnectAdvanced(\" + name + \")\";\n } : _ref2$getDisplayName,\n _ref2$methodName = _ref2.methodName,\n methodName = _ref2$methodName === void 0 ? 'connectAdvanced' : _ref2$methodName,\n _ref2$renderCountProp = _ref2.renderCountProp,\n renderCountProp = _ref2$renderCountProp === void 0 ? undefined : _ref2$renderCountProp,\n _ref2$shouldHandleSta = _ref2.shouldHandleStateChanges,\n shouldHandleStateChanges = _ref2$shouldHandleSta === void 0 ? true : _ref2$shouldHandleSta,\n _ref2$storeKey = _ref2.storeKey,\n storeKey = _ref2$storeKey === void 0 ? 'store' : _ref2$storeKey,\n _ref2$withRef = _ref2.withRef,\n withRef = _ref2$withRef === void 0 ? false : _ref2$withRef,\n _ref2$forwardRef = _ref2.forwardRef,\n forwardRef = _ref2$forwardRef === void 0 ? false : _ref2$forwardRef,\n _ref2$context = _ref2.context,\n context = _ref2$context === void 0 ? ReactReduxContext : _ref2$context,\n connectOptions = _objectWithoutPropertiesLoose(_ref2, _excluded);\n\n if (process.env.NODE_ENV !== 'production') {\n if (renderCountProp !== undefined) {\n throw new Error(\"renderCountProp is removed. render counting is built into the latest React Dev Tools profiling extension\");\n }\n\n if (withRef) {\n throw new Error('withRef is removed. To access the wrapped instance, use a ref on the connected component');\n }\n\n var customStoreWarningMessage = 'To use a custom Redux store for specific components, create a custom React context with ' + \"React.createContext(), and pass the context object to React Redux's Provider and specific components\" + ' like: . ' + 'You may also pass a {context : MyContext} option to connect';\n\n if (storeKey !== 'store') {\n throw new Error('storeKey has been removed and does not do anything. ' + customStoreWarningMessage);\n }\n }\n\n var Context = context;\n return function wrapWithConnect(WrappedComponent) {\n if (process.env.NODE_ENV !== 'production' && !isValidElementType(WrappedComponent)) {\n throw new Error(\"You must pass a component to the function returned by \" + (methodName + \". Instead received \" + stringifyComponent(WrappedComponent)));\n }\n\n var wrappedComponentName = WrappedComponent.displayName || WrappedComponent.name || 'Component';\n var displayName = getDisplayName(wrappedComponentName);\n\n var selectorFactoryOptions = _extends({}, connectOptions, {\n getDisplayName: getDisplayName,\n methodName: methodName,\n renderCountProp: renderCountProp,\n shouldHandleStateChanges: shouldHandleStateChanges,\n storeKey: storeKey,\n displayName: displayName,\n wrappedComponentName: wrappedComponentName,\n WrappedComponent: WrappedComponent\n });\n\n var pure = connectOptions.pure;\n\n function createChildSelector(store) {\n return selectorFactory(store.dispatch, selectorFactoryOptions);\n } // If we aren't running in \"pure\" mode, we don't want to memoize values.\n // To avoid conditionally calling hooks, we fall back to a tiny wrapper\n // that just executes the given callback immediately.\n\n\n var usePureOnlyMemo = pure ? useMemo : function (callback) {\n return callback();\n };\n\n function ConnectFunction(props) {\n var _useMemo = useMemo(function () {\n // Distinguish between actual \"data\" props that were passed to the wrapper component,\n // and values needed to control behavior (forwarded refs, alternate context instances).\n // To maintain the wrapperProps object reference, memoize this destructuring.\n var reactReduxForwardedRef = props.reactReduxForwardedRef,\n wrapperProps = _objectWithoutPropertiesLoose(props, _excluded2);\n\n return [props.context, reactReduxForwardedRef, wrapperProps];\n }, [props]),\n propsContext = _useMemo[0],\n reactReduxForwardedRef = _useMemo[1],\n wrapperProps = _useMemo[2];\n\n var ContextToUse = useMemo(function () {\n // Users may optionally pass in a custom context instance to use instead of our ReactReduxContext.\n // Memoize the check that determines which context instance we should use.\n return propsContext && propsContext.Consumer && isContextConsumer( /*#__PURE__*/React.createElement(propsContext.Consumer, null)) ? propsContext : Context;\n }, [propsContext, Context]); // Retrieve the store and ancestor subscription via context, if available\n\n var contextValue = useContext(ContextToUse); // The store _must_ exist as either a prop or in context.\n // We'll check to see if it _looks_ like a Redux store first.\n // This allows us to pass through a `store` prop that is just a plain value.\n\n var didStoreComeFromProps = Boolean(props.store) && Boolean(props.store.getState) && Boolean(props.store.dispatch);\n var didStoreComeFromContext = Boolean(contextValue) && Boolean(contextValue.store);\n\n if (process.env.NODE_ENV !== 'production' && !didStoreComeFromProps && !didStoreComeFromContext) {\n throw new Error(\"Could not find \\\"store\\\" in the context of \" + (\"\\\"\" + displayName + \"\\\". Either wrap the root component in a , \") + \"or pass a custom React context provider to and the corresponding \" + (\"React context consumer to \" + displayName + \" in connect options.\"));\n } // Based on the previous check, one of these must be true\n\n\n var store = didStoreComeFromProps ? props.store : contextValue.store;\n var childPropsSelector = useMemo(function () {\n // The child props selector needs the store reference as an input.\n // Re-create this selector whenever the store changes.\n return createChildSelector(store);\n }, [store]);\n\n var _useMemo2 = useMemo(function () {\n if (!shouldHandleStateChanges) return NO_SUBSCRIPTION_ARRAY; // This Subscription's source should match where store came from: props vs. context. A component\n // connected to the store via props shouldn't use subscription from context, or vice versa.\n\n // This Subscription's source should match where store came from: props vs. context. A component\n // connected to the store via props shouldn't use subscription from context, or vice versa.\n var subscription = createSubscription(store, didStoreComeFromProps ? null : contextValue.subscription); // `notifyNestedSubs` is duplicated to handle the case where the component is unmounted in\n // the middle of the notification loop, where `subscription` will then be null. This can\n // probably be avoided if Subscription's listeners logic is changed to not call listeners\n // that have been unsubscribed in the middle of the notification loop.\n\n // `notifyNestedSubs` is duplicated to handle the case where the component is unmounted in\n // the middle of the notification loop, where `subscription` will then be null. This can\n // probably be avoided if Subscription's listeners logic is changed to not call listeners\n // that have been unsubscribed in the middle of the notification loop.\n var notifyNestedSubs = subscription.notifyNestedSubs.bind(subscription);\n return [subscription, notifyNestedSubs];\n }, [store, didStoreComeFromProps, contextValue]),\n subscription = _useMemo2[0],\n notifyNestedSubs = _useMemo2[1]; // Determine what {store, subscription} value should be put into nested context, if necessary,\n // and memoize that value to avoid unnecessary context updates.\n\n\n var overriddenContextValue = useMemo(function () {\n if (didStoreComeFromProps) {\n // This component is directly subscribed to a store from props.\n // We don't want descendants reading from this store - pass down whatever\n // the existing context value is from the nearest connected ancestor.\n return contextValue;\n } // Otherwise, put this component's subscription instance into context, so that\n // connected descendants won't update until after this component is done\n\n\n return _extends({}, contextValue, {\n subscription: subscription\n });\n }, [didStoreComeFromProps, contextValue, subscription]); // We need to force this wrapper component to re-render whenever a Redux store update\n // causes a change to the calculated child component props (or we caught an error in mapState)\n\n var _useReducer = useReducer(storeStateUpdatesReducer, EMPTY_ARRAY, initStateUpdates),\n _useReducer$ = _useReducer[0],\n previousStateUpdateResult = _useReducer$[0],\n forceComponentUpdateDispatch = _useReducer[1]; // Propagate any mapState/mapDispatch errors upwards\n\n\n if (previousStateUpdateResult && previousStateUpdateResult.error) {\n throw previousStateUpdateResult.error;\n } // Set up refs to coordinate values between the subscription effect and the render logic\n\n\n var lastChildProps = useRef();\n var lastWrapperProps = useRef(wrapperProps);\n var childPropsFromStoreUpdate = useRef();\n var renderIsScheduled = useRef(false);\n var actualChildProps = usePureOnlyMemo(function () {\n // Tricky logic here:\n // - This render may have been triggered by a Redux store update that produced new child props\n // - However, we may have gotten new wrapper props after that\n // If we have new child props, and the same wrapper props, we know we should use the new child props as-is.\n // But, if we have new wrapper props, those might change the child props, so we have to recalculate things.\n // So, we'll use the child props from store update only if the wrapper props are the same as last time.\n if (childPropsFromStoreUpdate.current && wrapperProps === lastWrapperProps.current) {\n return childPropsFromStoreUpdate.current;\n } // TODO We're reading the store directly in render() here. Bad idea?\n // This will likely cause Bad Things (TM) to happen in Concurrent Mode.\n // Note that we do this because on renders _not_ caused by store updates, we need the latest store state\n // to determine what the child props should be.\n\n\n return childPropsSelector(store.getState(), wrapperProps);\n }, [store, previousStateUpdateResult, wrapperProps]); // We need this to execute synchronously every time we re-render. However, React warns\n // about useLayoutEffect in SSR, so we try to detect environment and fall back to\n // just useEffect instead to avoid the warning, since neither will run anyway.\n\n useIsomorphicLayoutEffectWithArgs(captureWrapperProps, [lastWrapperProps, lastChildProps, renderIsScheduled, wrapperProps, actualChildProps, childPropsFromStoreUpdate, notifyNestedSubs]); // Our re-subscribe logic only runs when the store/subscription setup changes\n\n useIsomorphicLayoutEffectWithArgs(subscribeUpdates, [shouldHandleStateChanges, store, subscription, childPropsSelector, lastWrapperProps, lastChildProps, renderIsScheduled, childPropsFromStoreUpdate, notifyNestedSubs, forceComponentUpdateDispatch], [store, subscription, childPropsSelector]); // Now that all that's done, we can finally try to actually render the child component.\n // We memoize the elements for the rendered child component as an optimization.\n\n var renderedWrappedComponent = useMemo(function () {\n return /*#__PURE__*/React.createElement(WrappedComponent, _extends({}, actualChildProps, {\n ref: reactReduxForwardedRef\n }));\n }, [reactReduxForwardedRef, WrappedComponent, actualChildProps]); // If React sees the exact same element reference as last time, it bails out of re-rendering\n // that child, same as if it was wrapped in React.memo() or returned false from shouldComponentUpdate.\n\n var renderedChild = useMemo(function () {\n if (shouldHandleStateChanges) {\n // If this component is subscribed to store updates, we need to pass its own\n // subscription instance down to our descendants. That means rendering the same\n // Context instance, and putting a different value into the context.\n return /*#__PURE__*/React.createElement(ContextToUse.Provider, {\n value: overriddenContextValue\n }, renderedWrappedComponent);\n }\n\n return renderedWrappedComponent;\n }, [ContextToUse, renderedWrappedComponent, overriddenContextValue]);\n return renderedChild;\n } // If we're in \"pure\" mode, ensure our wrapper component only re-renders when incoming props have changed.\n\n\n var Connect = pure ? React.memo(ConnectFunction) : ConnectFunction;\n Connect.WrappedComponent = WrappedComponent;\n Connect.displayName = ConnectFunction.displayName = displayName;\n\n if (forwardRef) {\n var forwarded = React.forwardRef(function forwardConnectRef(props, ref) {\n return /*#__PURE__*/React.createElement(Connect, _extends({}, props, {\n reactReduxForwardedRef: ref\n }));\n });\n forwarded.displayName = displayName;\n forwarded.WrappedComponent = WrappedComponent;\n return hoistStatics(forwarded, WrappedComponent);\n }\n\n return hoistStatics(Connect, WrappedComponent);\n };\n}","function is(x, y) {\n if (x === y) {\n return x !== 0 || y !== 0 || 1 / x === 1 / y;\n } else {\n return x !== x && y !== y;\n }\n}\n\nexport default function shallowEqual(objA, objB) {\n if (is(objA, objB)) return true;\n\n if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {\n return false;\n }\n\n var keysA = Object.keys(objA);\n var keysB = Object.keys(objB);\n if (keysA.length !== keysB.length) return false;\n\n for (var i = 0; i < keysA.length; i++) {\n if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {\n return false;\n }\n }\n\n return true;\n}","export default function bindActionCreators(actionCreators, dispatch) {\n var boundActionCreators = {};\n\n var _loop = function _loop(key) {\n var actionCreator = actionCreators[key];\n\n if (typeof actionCreator === 'function') {\n boundActionCreators[key] = function () {\n return dispatch(actionCreator.apply(void 0, arguments));\n };\n }\n };\n\n for (var key in actionCreators) {\n _loop(key);\n }\n\n return boundActionCreators;\n}","import verifyPlainObject from '../utils/verifyPlainObject';\nexport function wrapMapToPropsConstant(getConstant) {\n return function initConstantSelector(dispatch, options) {\n var constant = getConstant(dispatch, options);\n\n function constantSelector() {\n return constant;\n }\n\n constantSelector.dependsOnOwnProps = false;\n return constantSelector;\n };\n} // dependsOnOwnProps is used by createMapToPropsProxy to determine whether to pass props as args\n// to the mapToProps function being wrapped. It is also used by makePurePropsSelector to determine\n// whether mapToProps needs to be invoked when props have changed.\n//\n// A length of one signals that mapToProps does not depend on props from the parent component.\n// A length of zero is assumed to mean mapToProps is getting args via arguments or ...args and\n// therefore not reporting its length accurately..\n\nexport function getDependsOnOwnProps(mapToProps) {\n return mapToProps.dependsOnOwnProps !== null && mapToProps.dependsOnOwnProps !== undefined ? Boolean(mapToProps.dependsOnOwnProps) : mapToProps.length !== 1;\n} // Used by whenMapStateToPropsIsFunction and whenMapDispatchToPropsIsFunction,\n// this function wraps mapToProps in a proxy function which does several things:\n//\n// * Detects whether the mapToProps function being called depends on props, which\n// is used by selectorFactory to decide if it should reinvoke on props changes.\n//\n// * On first call, handles mapToProps if returns another function, and treats that\n// new function as the true mapToProps for subsequent calls.\n//\n// * On first call, verifies the first result is a plain object, in order to warn\n// the developer that their mapToProps function is not returning a valid result.\n//\n\nexport function wrapMapToPropsFunc(mapToProps, methodName) {\n return function initProxySelector(dispatch, _ref) {\n var displayName = _ref.displayName;\n\n var proxy = function mapToPropsProxy(stateOrDispatch, ownProps) {\n return proxy.dependsOnOwnProps ? proxy.mapToProps(stateOrDispatch, ownProps) : proxy.mapToProps(stateOrDispatch);\n }; // allow detectFactoryAndVerify to get ownProps\n\n\n proxy.dependsOnOwnProps = true;\n\n proxy.mapToProps = function detectFactoryAndVerify(stateOrDispatch, ownProps) {\n proxy.mapToProps = mapToProps;\n proxy.dependsOnOwnProps = getDependsOnOwnProps(mapToProps);\n var props = proxy(stateOrDispatch, ownProps);\n\n if (typeof props === 'function') {\n proxy.mapToProps = props;\n proxy.dependsOnOwnProps = getDependsOnOwnProps(props);\n props = proxy(stateOrDispatch, ownProps);\n }\n\n if (process.env.NODE_ENV !== 'production') verifyPlainObject(props, displayName, methodName);\n return props;\n };\n\n return proxy;\n };\n}","import bindActionCreators from '../utils/bindActionCreators';\nimport { wrapMapToPropsConstant, wrapMapToPropsFunc } from './wrapMapToProps';\nexport function whenMapDispatchToPropsIsFunction(mapDispatchToProps) {\n return typeof mapDispatchToProps === 'function' ? wrapMapToPropsFunc(mapDispatchToProps, 'mapDispatchToProps') : undefined;\n}\nexport function whenMapDispatchToPropsIsMissing(mapDispatchToProps) {\n return !mapDispatchToProps ? wrapMapToPropsConstant(function (dispatch) {\n return {\n dispatch: dispatch\n };\n }) : undefined;\n}\nexport function whenMapDispatchToPropsIsObject(mapDispatchToProps) {\n return mapDispatchToProps && typeof mapDispatchToProps === 'object' ? wrapMapToPropsConstant(function (dispatch) {\n return bindActionCreators(mapDispatchToProps, dispatch);\n }) : undefined;\n}\nexport default [whenMapDispatchToPropsIsFunction, whenMapDispatchToPropsIsMissing, whenMapDispatchToPropsIsObject];","import { wrapMapToPropsConstant, wrapMapToPropsFunc } from './wrapMapToProps';\nexport function whenMapStateToPropsIsFunction(mapStateToProps) {\n return typeof mapStateToProps === 'function' ? wrapMapToPropsFunc(mapStateToProps, 'mapStateToProps') : undefined;\n}\nexport function whenMapStateToPropsIsMissing(mapStateToProps) {\n return !mapStateToProps ? wrapMapToPropsConstant(function () {\n return {};\n }) : undefined;\n}\nexport default [whenMapStateToPropsIsFunction, whenMapStateToPropsIsMissing];","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport verifyPlainObject from '../utils/verifyPlainObject';\nexport function defaultMergeProps(stateProps, dispatchProps, ownProps) {\n return _extends({}, ownProps, stateProps, dispatchProps);\n}\nexport function wrapMergePropsFunc(mergeProps) {\n return function initMergePropsProxy(dispatch, _ref) {\n var displayName = _ref.displayName,\n pure = _ref.pure,\n areMergedPropsEqual = _ref.areMergedPropsEqual;\n var hasRunOnce = false;\n var mergedProps;\n return function mergePropsProxy(stateProps, dispatchProps, ownProps) {\n var nextMergedProps = mergeProps(stateProps, dispatchProps, ownProps);\n\n if (hasRunOnce) {\n if (!pure || !areMergedPropsEqual(nextMergedProps, mergedProps)) mergedProps = nextMergedProps;\n } else {\n hasRunOnce = true;\n mergedProps = nextMergedProps;\n if (process.env.NODE_ENV !== 'production') verifyPlainObject(mergedProps, displayName, 'mergeProps');\n }\n\n return mergedProps;\n };\n };\n}\nexport function whenMergePropsIsFunction(mergeProps) {\n return typeof mergeProps === 'function' ? wrapMergePropsFunc(mergeProps) : undefined;\n}\nexport function whenMergePropsIsOmitted(mergeProps) {\n return !mergeProps ? function () {\n return defaultMergeProps;\n } : undefined;\n}\nexport default [whenMergePropsIsFunction, whenMergePropsIsOmitted];","import _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nvar _excluded = [\"initMapStateToProps\", \"initMapDispatchToProps\", \"initMergeProps\"];\nimport verifySubselectors from './verifySubselectors';\nexport function impureFinalPropsSelectorFactory(mapStateToProps, mapDispatchToProps, mergeProps, dispatch) {\n return function impureFinalPropsSelector(state, ownProps) {\n return mergeProps(mapStateToProps(state, ownProps), mapDispatchToProps(dispatch, ownProps), ownProps);\n };\n}\nexport function pureFinalPropsSelectorFactory(mapStateToProps, mapDispatchToProps, mergeProps, dispatch, _ref) {\n var areStatesEqual = _ref.areStatesEqual,\n areOwnPropsEqual = _ref.areOwnPropsEqual,\n areStatePropsEqual = _ref.areStatePropsEqual;\n var hasRunAtLeastOnce = false;\n var state;\n var ownProps;\n var stateProps;\n var dispatchProps;\n var mergedProps;\n\n function handleFirstCall(firstState, firstOwnProps) {\n state = firstState;\n ownProps = firstOwnProps;\n stateProps = mapStateToProps(state, ownProps);\n dispatchProps = mapDispatchToProps(dispatch, ownProps);\n mergedProps = mergeProps(stateProps, dispatchProps, ownProps);\n hasRunAtLeastOnce = true;\n return mergedProps;\n }\n\n function handleNewPropsAndNewState() {\n stateProps = mapStateToProps(state, ownProps);\n if (mapDispatchToProps.dependsOnOwnProps) dispatchProps = mapDispatchToProps(dispatch, ownProps);\n mergedProps = mergeProps(stateProps, dispatchProps, ownProps);\n return mergedProps;\n }\n\n function handleNewProps() {\n if (mapStateToProps.dependsOnOwnProps) stateProps = mapStateToProps(state, ownProps);\n if (mapDispatchToProps.dependsOnOwnProps) dispatchProps = mapDispatchToProps(dispatch, ownProps);\n mergedProps = mergeProps(stateProps, dispatchProps, ownProps);\n return mergedProps;\n }\n\n function handleNewState() {\n var nextStateProps = mapStateToProps(state, ownProps);\n var statePropsChanged = !areStatePropsEqual(nextStateProps, stateProps);\n stateProps = nextStateProps;\n if (statePropsChanged) mergedProps = mergeProps(stateProps, dispatchProps, ownProps);\n return mergedProps;\n }\n\n function handleSubsequentCalls(nextState, nextOwnProps) {\n var propsChanged = !areOwnPropsEqual(nextOwnProps, ownProps);\n var stateChanged = !areStatesEqual(nextState, state, nextOwnProps, ownProps);\n state = nextState;\n ownProps = nextOwnProps;\n if (propsChanged && stateChanged) return handleNewPropsAndNewState();\n if (propsChanged) return handleNewProps();\n if (stateChanged) return handleNewState();\n return mergedProps;\n }\n\n return function pureFinalPropsSelector(nextState, nextOwnProps) {\n return hasRunAtLeastOnce ? handleSubsequentCalls(nextState, nextOwnProps) : handleFirstCall(nextState, nextOwnProps);\n };\n} // TODO: Add more comments\n// If pure is true, the selector returned by selectorFactory will memoize its results,\n// allowing connectAdvanced's shouldComponentUpdate to return false if final\n// props have not changed. If false, the selector will always return a new\n// object and shouldComponentUpdate will always return true.\n\nexport default function finalPropsSelectorFactory(dispatch, _ref2) {\n var initMapStateToProps = _ref2.initMapStateToProps,\n initMapDispatchToProps = _ref2.initMapDispatchToProps,\n initMergeProps = _ref2.initMergeProps,\n options = _objectWithoutPropertiesLoose(_ref2, _excluded);\n\n var mapStateToProps = initMapStateToProps(dispatch, options);\n var mapDispatchToProps = initMapDispatchToProps(dispatch, options);\n var mergeProps = initMergeProps(dispatch, options);\n\n if (process.env.NODE_ENV !== 'production') {\n verifySubselectors(mapStateToProps, mapDispatchToProps, mergeProps, options.displayName);\n }\n\n var selectorFactory = options.pure ? pureFinalPropsSelectorFactory : impureFinalPropsSelectorFactory;\n return selectorFactory(mapStateToProps, mapDispatchToProps, mergeProps, dispatch, options);\n}","import _extends from \"@babel/runtime/helpers/esm/extends\";\nimport _objectWithoutPropertiesLoose from \"@babel/runtime/helpers/esm/objectWithoutPropertiesLoose\";\nvar _excluded = [\"pure\", \"areStatesEqual\", \"areOwnPropsEqual\", \"areStatePropsEqual\", \"areMergedPropsEqual\"];\nimport connectAdvanced from '../components/connectAdvanced';\nimport shallowEqual from '../utils/shallowEqual';\nimport defaultMapDispatchToPropsFactories from './mapDispatchToProps';\nimport defaultMapStateToPropsFactories from './mapStateToProps';\nimport defaultMergePropsFactories from './mergeProps';\nimport defaultSelectorFactory from './selectorFactory';\n/*\r\n connect is a facade over connectAdvanced. It turns its args into a compatible\r\n selectorFactory, which has the signature:\r\n\r\n (dispatch, options) => (nextState, nextOwnProps) => nextFinalProps\r\n \r\n connect passes its args to connectAdvanced as options, which will in turn pass them to\r\n selectorFactory each time a Connect component instance is instantiated or hot reloaded.\r\n\r\n selectorFactory returns a final props selector from its mapStateToProps,\r\n mapStateToPropsFactories, mapDispatchToProps, mapDispatchToPropsFactories, mergeProps,\r\n mergePropsFactories, and pure args.\r\n\r\n The resulting final props selector is called by the Connect component instance whenever\r\n it receives new props or store state.\r\n */\n\nfunction match(arg, factories, name) {\n for (var i = factories.length - 1; i >= 0; i--) {\n var result = factories[i](arg);\n if (result) return result;\n }\n\n return function (dispatch, options) {\n throw new Error(\"Invalid value of type \" + typeof arg + \" for \" + name + \" argument when connecting component \" + options.wrappedComponentName + \".\");\n };\n}\n\nfunction strictEqual(a, b) {\n return a === b;\n} // createConnect with default args builds the 'official' connect behavior. Calling it with\n// different options opens up some testing and extensibility scenarios\n\n\nexport function createConnect(_temp) {\n var _ref = _temp === void 0 ? {} : _temp,\n _ref$connectHOC = _ref.connectHOC,\n connectHOC = _ref$connectHOC === void 0 ? connectAdvanced : _ref$connectHOC,\n _ref$mapStateToPropsF = _ref.mapStateToPropsFactories,\n mapStateToPropsFactories = _ref$mapStateToPropsF === void 0 ? defaultMapStateToPropsFactories : _ref$mapStateToPropsF,\n _ref$mapDispatchToPro = _ref.mapDispatchToPropsFactories,\n mapDispatchToPropsFactories = _ref$mapDispatchToPro === void 0 ? defaultMapDispatchToPropsFactories : _ref$mapDispatchToPro,\n _ref$mergePropsFactor = _ref.mergePropsFactories,\n mergePropsFactories = _ref$mergePropsFactor === void 0 ? defaultMergePropsFactories : _ref$mergePropsFactor,\n _ref$selectorFactory = _ref.selectorFactory,\n selectorFactory = _ref$selectorFactory === void 0 ? defaultSelectorFactory : _ref$selectorFactory;\n\n return function connect(mapStateToProps, mapDispatchToProps, mergeProps, _ref2) {\n if (_ref2 === void 0) {\n _ref2 = {};\n }\n\n var _ref3 = _ref2,\n _ref3$pure = _ref3.pure,\n pure = _ref3$pure === void 0 ? true : _ref3$pure,\n _ref3$areStatesEqual = _ref3.areStatesEqual,\n areStatesEqual = _ref3$areStatesEqual === void 0 ? strictEqual : _ref3$areStatesEqual,\n _ref3$areOwnPropsEqua = _ref3.areOwnPropsEqual,\n areOwnPropsEqual = _ref3$areOwnPropsEqua === void 0 ? shallowEqual : _ref3$areOwnPropsEqua,\n _ref3$areStatePropsEq = _ref3.areStatePropsEqual,\n areStatePropsEqual = _ref3$areStatePropsEq === void 0 ? shallowEqual : _ref3$areStatePropsEq,\n _ref3$areMergedPropsE = _ref3.areMergedPropsEqual,\n areMergedPropsEqual = _ref3$areMergedPropsE === void 0 ? shallowEqual : _ref3$areMergedPropsE,\n extraOptions = _objectWithoutPropertiesLoose(_ref3, _excluded);\n\n var initMapStateToProps = match(mapStateToProps, mapStateToPropsFactories, 'mapStateToProps');\n var initMapDispatchToProps = match(mapDispatchToProps, mapDispatchToPropsFactories, 'mapDispatchToProps');\n var initMergeProps = match(mergeProps, mergePropsFactories, 'mergeProps');\n return connectHOC(selectorFactory, _extends({\n // used in error messages\n methodName: 'connect',\n // used to compute Connect's displayName from the wrapped component's displayName.\n getDisplayName: function getDisplayName(name) {\n return \"Connect(\" + name + \")\";\n },\n // if mapStateToProps is falsy, the Connect component doesn't subscribe to store state changes\n shouldHandleStateChanges: Boolean(mapStateToProps),\n // passed through to selectorFactory\n initMapStateToProps: initMapStateToProps,\n initMapDispatchToProps: initMapDispatchToProps,\n initMergeProps: initMergeProps,\n pure: pure,\n areStatesEqual: areStatesEqual,\n areOwnPropsEqual: areOwnPropsEqual,\n areStatePropsEqual: areStatePropsEqual,\n areMergedPropsEqual: areMergedPropsEqual\n }, extraOptions));\n };\n}\nexport default /*#__PURE__*/createConnect();","import { useContext } from 'react';\nimport { ReactReduxContext } from '../components/Context';\n/**\r\n * A hook to access the value of the `ReactReduxContext`. This is a low-level\r\n * hook that you should usually not need to call directly.\r\n *\r\n * @returns {any} the value of the `ReactReduxContext`\r\n *\r\n * @example\r\n *\r\n * import React from 'react'\r\n * import { useReduxContext } from 'react-redux'\r\n *\r\n * export const CounterComponent = ({ value }) => {\r\n * const { store } = useReduxContext()\r\n * return
{store.getState()}
\r\n * }\r\n */\n\nexport function useReduxContext() {\n var contextValue = useContext(ReactReduxContext);\n\n if (process.env.NODE_ENV !== 'production' && !contextValue) {\n throw new Error('could not find react-redux context value; please ensure the component is wrapped in a ');\n }\n\n return contextValue;\n}","import { useContext } from 'react';\nimport { ReactReduxContext } from '../components/Context';\nimport { useReduxContext as useDefaultReduxContext } from './useReduxContext';\n/**\r\n * Hook factory, which creates a `useStore` hook bound to a given context.\r\n *\r\n * @param {React.Context} [context=ReactReduxContext] Context passed to your ``.\r\n * @returns {Function} A `useStore` hook bound to the specified context.\r\n */\n\nexport function createStoreHook(context) {\n if (context === void 0) {\n context = ReactReduxContext;\n }\n\n var useReduxContext = context === ReactReduxContext ? useDefaultReduxContext : function () {\n return useContext(context);\n };\n return function useStore() {\n var _useReduxContext = useReduxContext(),\n store = _useReduxContext.store;\n\n return store;\n };\n}\n/**\r\n * A hook to access the redux store.\r\n *\r\n * @returns {any} the redux store\r\n *\r\n * @example\r\n *\r\n * import React from 'react'\r\n * import { useStore } from 'react-redux'\r\n *\r\n * export const ExampleComponent = () => {\r\n * const store = useStore()\r\n * return
{store.getState()}
\r\n * }\r\n */\n\nexport var useStore = /*#__PURE__*/createStoreHook();","import { ReactReduxContext } from '../components/Context';\nimport { useStore as useDefaultStore, createStoreHook } from './useStore';\n/**\r\n * Hook factory, which creates a `useDispatch` hook bound to a given context.\r\n *\r\n * @param {React.Context} [context=ReactReduxContext] Context passed to your ``.\r\n * @returns {Function} A `useDispatch` hook bound to the specified context.\r\n */\n\nexport function createDispatchHook(context) {\n if (context === void 0) {\n context = ReactReduxContext;\n }\n\n var useStore = context === ReactReduxContext ? useDefaultStore : createStoreHook(context);\n return function useDispatch() {\n var store = useStore();\n return store.dispatch;\n };\n}\n/**\r\n * A hook to access the redux `dispatch` function.\r\n *\r\n * @returns {any|function} redux store's `dispatch` function\r\n *\r\n * @example\r\n *\r\n * import React, { useCallback } from 'react'\r\n * import { useDispatch } from 'react-redux'\r\n *\r\n * export const CounterComponent = ({ value }) => {\r\n * const dispatch = useDispatch()\r\n * const increaseCounter = useCallback(() => dispatch({ type: 'increase-counter' }), [])\r\n * return (\r\n *
\r\n * {value}\r\n * \r\n *
\r\n * )\r\n * }\r\n */\n\nexport var useDispatch = /*#__PURE__*/createDispatchHook();","import { useReducer, useRef, useMemo, useContext, useDebugValue } from 'react';\nimport { useReduxContext as useDefaultReduxContext } from './useReduxContext';\nimport { createSubscription } from '../utils/Subscription';\nimport { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect';\nimport { ReactReduxContext } from '../components/Context';\n\nvar refEquality = function refEquality(a, b) {\n return a === b;\n};\n\nfunction useSelectorWithStoreAndSubscription(selector, equalityFn, store, contextSub) {\n var _useReducer = useReducer(function (s) {\n return s + 1;\n }, 0),\n forceRender = _useReducer[1];\n\n var subscription = useMemo(function () {\n return createSubscription(store, contextSub);\n }, [store, contextSub]);\n var latestSubscriptionCallbackError = useRef();\n var latestSelector = useRef();\n var latestStoreState = useRef();\n var latestSelectedState = useRef();\n var storeState = store.getState();\n var selectedState;\n\n try {\n if (selector !== latestSelector.current || storeState !== latestStoreState.current || latestSubscriptionCallbackError.current) {\n var newSelectedState = selector(storeState); // ensure latest selected state is reused so that a custom equality function can result in identical references\n\n if (latestSelectedState.current === undefined || !equalityFn(newSelectedState, latestSelectedState.current)) {\n selectedState = newSelectedState;\n } else {\n selectedState = latestSelectedState.current;\n }\n } else {\n selectedState = latestSelectedState.current;\n }\n } catch (err) {\n if (latestSubscriptionCallbackError.current) {\n err.message += \"\\nThe error may be correlated with this previous error:\\n\" + latestSubscriptionCallbackError.current.stack + \"\\n\\n\";\n }\n\n throw err;\n }\n\n useIsomorphicLayoutEffect(function () {\n latestSelector.current = selector;\n latestStoreState.current = storeState;\n latestSelectedState.current = selectedState;\n latestSubscriptionCallbackError.current = undefined;\n });\n useIsomorphicLayoutEffect(function () {\n function checkForUpdates() {\n try {\n var newStoreState = store.getState(); // Avoid calling selector multiple times if the store's state has not changed\n\n if (newStoreState === latestStoreState.current) {\n return;\n }\n\n var _newSelectedState = latestSelector.current(newStoreState);\n\n if (equalityFn(_newSelectedState, latestSelectedState.current)) {\n return;\n }\n\n latestSelectedState.current = _newSelectedState;\n latestStoreState.current = newStoreState;\n } catch (err) {\n // we ignore all errors here, since when the component\n // is re-rendered, the selectors are called again, and\n // will throw again, if neither props nor store state\n // changed\n latestSubscriptionCallbackError.current = err;\n }\n\n forceRender();\n }\n\n subscription.onStateChange = checkForUpdates;\n subscription.trySubscribe();\n checkForUpdates();\n return function () {\n return subscription.tryUnsubscribe();\n };\n }, [store, subscription]);\n return selectedState;\n}\n/**\r\n * Hook factory, which creates a `useSelector` hook bound to a given context.\r\n *\r\n * @param {React.Context} [context=ReactReduxContext] Context passed to your ``.\r\n * @returns {Function} A `useSelector` hook bound to the specified context.\r\n */\n\n\nexport function createSelectorHook(context) {\n if (context === void 0) {\n context = ReactReduxContext;\n }\n\n var useReduxContext = context === ReactReduxContext ? useDefaultReduxContext : function () {\n return useContext(context);\n };\n return function useSelector(selector, equalityFn) {\n if (equalityFn === void 0) {\n equalityFn = refEquality;\n }\n\n if (process.env.NODE_ENV !== 'production') {\n if (!selector) {\n throw new Error(\"You must pass a selector to useSelector\");\n }\n\n if (typeof selector !== 'function') {\n throw new Error(\"You must pass a function as a selector to useSelector\");\n }\n\n if (typeof equalityFn !== 'function') {\n throw new Error(\"You must pass a function as an equality function to useSelector\");\n }\n }\n\n var _useReduxContext = useReduxContext(),\n store = _useReduxContext.store,\n contextSub = _useReduxContext.subscription;\n\n var selectedState = useSelectorWithStoreAndSubscription(selector, equalityFn, store, contextSub);\n useDebugValue(selectedState);\n return selectedState;\n };\n}\n/**\r\n * A hook to access the redux store's state. This hook takes a selector function\r\n * as an argument. The selector is called with the store state.\r\n *\r\n * This hook takes an optional equality comparison function as the second parameter\r\n * that allows you to customize the way the selected state is compared to determine\r\n * whether the component needs to be re-rendered.\r\n *\r\n * @param {Function} selector the selector function\r\n * @param {Function=} equalityFn the function that will be used to determine equality\r\n *\r\n * @returns {any} the selected state\r\n *\r\n * @example\r\n *\r\n * import React from 'react'\r\n * import { useSelector } from 'react-redux'\r\n *\r\n * export const CounterComponent = () => {\r\n * const counter = useSelector(state => state.counter)\r\n * return
{counter}
\r\n * }\r\n */\n\nexport var useSelector = /*#__PURE__*/createSelectorHook();","export * from './exports';\nimport { unstable_batchedUpdates as batch } from './utils/reactBatchedUpdates';\nimport { setBatch } from './utils/batch'; // Enable batched updates in our subscriptions for use\n// with standard React renderers (ReactDOM, React Native)\n\nsetBatch(batch);\nexport { batch };","export default function _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n }, _typeof(obj);\n}","import _typeof from \"./typeof.js\";\nexport default function _toPrimitive(input, hint) {\n if (_typeof(input) !== \"object\" || input === null) return input;\n var prim = input[Symbol.toPrimitive];\n if (prim !== undefined) {\n var res = prim.call(input, hint || \"default\");\n if (_typeof(res) !== \"object\") return res;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (hint === \"string\" ? String : Number)(input);\n}","import _typeof from \"./typeof.js\";\nimport toPrimitive from \"./toPrimitive.js\";\nexport default function _toPropertyKey(arg) {\n var key = toPrimitive(arg, \"string\");\n return _typeof(key) === \"symbol\" ? key : String(key);\n}","import toPropertyKey from \"./toPropertyKey.js\";\nexport default function _defineProperty(obj, key, value) {\n key = toPropertyKey(key);\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}","import defineProperty from \"./defineProperty.js\";\nfunction ownKeys(object, enumerableOnly) {\n var keys = Object.keys(object);\n if (Object.getOwnPropertySymbols) {\n var symbols = Object.getOwnPropertySymbols(object);\n enumerableOnly && (symbols = symbols.filter(function (sym) {\n return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n })), keys.push.apply(keys, symbols);\n }\n return keys;\n}\nexport default function _objectSpread2(target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = null != arguments[i] ? arguments[i] : {};\n i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {\n defineProperty(target, key, source[key]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {\n Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n });\n }\n return target;\n}","import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';\n\n/**\n * Adapted from React: https://github.com/facebook/react/blob/master/packages/shared/formatProdErrorMessage.js\n *\n * Do not require this module directly! Use normal throw error calls. These messages will be replaced with error codes\n * during build.\n * @param {number} code\n */\nfunction formatProdErrorMessage(code) {\n return \"Minified Redux error #\" + code + \"; visit https://redux.js.org/Errors?code=\" + code + \" for the full message or \" + 'use the non-minified dev environment for full errors. ';\n}\n\n// Inlined version of the `symbol-observable` polyfill\nvar $$observable = (function () {\n return typeof Symbol === 'function' && Symbol.observable || '@@observable';\n})();\n\n/**\n * These are private action types reserved by Redux.\n * For any unknown actions, you must return the current state.\n * If the current state is undefined, you must return the initial state.\n * Do not reference these action types directly in your code.\n */\nvar randomString = function randomString() {\n return Math.random().toString(36).substring(7).split('').join('.');\n};\n\nvar ActionTypes = {\n INIT: \"@@redux/INIT\" + randomString(),\n REPLACE: \"@@redux/REPLACE\" + randomString(),\n PROBE_UNKNOWN_ACTION: function PROBE_UNKNOWN_ACTION() {\n return \"@@redux/PROBE_UNKNOWN_ACTION\" + randomString();\n }\n};\n\n/**\n * @param {any} obj The object to inspect.\n * @returns {boolean} True if the argument appears to be a plain object.\n */\nfunction isPlainObject(obj) {\n if (typeof obj !== 'object' || obj === null) return false;\n var proto = obj;\n\n while (Object.getPrototypeOf(proto) !== null) {\n proto = Object.getPrototypeOf(proto);\n }\n\n return Object.getPrototypeOf(obj) === proto;\n}\n\nfunction kindOf(val) {\n var typeOfVal = typeof val;\n\n if (process.env.NODE_ENV !== 'production') {\n // Inlined / shortened version of `kindOf` from https://github.com/jonschlinkert/kind-of\n function miniKindOf(val) {\n if (val === void 0) return 'undefined';\n if (val === null) return 'null';\n var type = typeof val;\n\n switch (type) {\n case 'boolean':\n case 'string':\n case 'number':\n case 'symbol':\n case 'function':\n {\n return type;\n }\n }\n\n if (Array.isArray(val)) return 'array';\n if (isDate(val)) return 'date';\n if (isError(val)) return 'error';\n var constructorName = ctorName(val);\n\n switch (constructorName) {\n case 'Symbol':\n case 'Promise':\n case 'WeakMap':\n case 'WeakSet':\n case 'Map':\n case 'Set':\n return constructorName;\n } // other\n\n\n return type.slice(8, -1).toLowerCase().replace(/\\s/g, '');\n }\n\n function ctorName(val) {\n return typeof val.constructor === 'function' ? val.constructor.name : null;\n }\n\n function isError(val) {\n return val instanceof Error || typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number';\n }\n\n function isDate(val) {\n if (val instanceof Date) return true;\n return typeof val.toDateString === 'function' && typeof val.getDate === 'function' && typeof val.setDate === 'function';\n }\n\n typeOfVal = miniKindOf(val);\n }\n\n return typeOfVal;\n}\n\n/**\n * Creates a Redux store that holds the state tree.\n * The only way to change the data in the store is to call `dispatch()` on it.\n *\n * There should only be a single store in your app. To specify how different\n * parts of the state tree respond to actions, you may combine several reducers\n * into a single reducer function by using `combineReducers`.\n *\n * @param {Function} reducer A function that returns the next state tree, given\n * the current state tree and the action to handle.\n *\n * @param {any} [preloadedState] The initial state. You may optionally specify it\n * to hydrate the state from the server in universal apps, or to restore a\n * previously serialized user session.\n * If you use `combineReducers` to produce the root reducer function, this must be\n * an object with the same shape as `combineReducers` keys.\n *\n * @param {Function} [enhancer] The store enhancer. You may optionally specify it\n * to enhance the store with third-party capabilities such as middleware,\n * time travel, persistence, etc. The only store enhancer that ships with Redux\n * is `applyMiddleware()`.\n *\n * @returns {Store} A Redux store that lets you read the state, dispatch actions\n * and subscribe to changes.\n */\n\nfunction createStore(reducer, preloadedState, enhancer) {\n var _ref2;\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'function' || typeof enhancer === 'function' && typeof arguments[3] === 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(0) : 'It looks like you are passing several store enhancers to ' + 'createStore(). This is not supported. Instead, compose them ' + 'together to a single function. See https://redux.js.org/tutorials/fundamentals/part-4-store#creating-a-store-with-enhancers for an example.');\n }\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {\n enhancer = preloadedState;\n preloadedState = undefined;\n }\n\n if (typeof enhancer !== 'undefined') {\n if (typeof enhancer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(1) : \"Expected the enhancer to be a function. Instead, received: '\" + kindOf(enhancer) + \"'\");\n }\n\n return enhancer(createStore)(reducer, preloadedState);\n }\n\n if (typeof reducer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(2) : \"Expected the root reducer to be a function. Instead, received: '\" + kindOf(reducer) + \"'\");\n }\n\n var currentReducer = reducer;\n var currentState = preloadedState;\n var currentListeners = [];\n var nextListeners = currentListeners;\n var isDispatching = false;\n /**\n * This makes a shallow copy of currentListeners so we can use\n * nextListeners as a temporary list while dispatching.\n *\n * This prevents any bugs around consumers calling\n * subscribe/unsubscribe in the middle of a dispatch.\n */\n\n function ensureCanMutateNextListeners() {\n if (nextListeners === currentListeners) {\n nextListeners = currentListeners.slice();\n }\n }\n /**\n * Reads the state tree managed by the store.\n *\n * @returns {any} The current state tree of your application.\n */\n\n\n function getState() {\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(3) : 'You may not call store.getState() while the reducer is executing. ' + 'The reducer has already received the state as an argument. ' + 'Pass it down from the top reducer instead of reading it from the store.');\n }\n\n return currentState;\n }\n /**\n * Adds a change listener. It will be called any time an action is dispatched,\n * and some part of the state tree may potentially have changed. You may then\n * call `getState()` to read the current state tree inside the callback.\n *\n * You may call `dispatch()` from a change listener, with the following\n * caveats:\n *\n * 1. The subscriptions are snapshotted just before every `dispatch()` call.\n * If you subscribe or unsubscribe while the listeners are being invoked, this\n * will not have any effect on the `dispatch()` that is currently in progress.\n * However, the next `dispatch()` call, whether nested or not, will use a more\n * recent snapshot of the subscription list.\n *\n * 2. The listener should not expect to see all state changes, as the state\n * might have been updated multiple times during a nested `dispatch()` before\n * the listener is called. It is, however, guaranteed that all subscribers\n * registered before the `dispatch()` started will be called with the latest\n * state by the time it exits.\n *\n * @param {Function} listener A callback to be invoked on every dispatch.\n * @returns {Function} A function to remove this change listener.\n */\n\n\n function subscribe(listener) {\n if (typeof listener !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(4) : \"Expected the listener to be a function. Instead, received: '\" + kindOf(listener) + \"'\");\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(5) : 'You may not call store.subscribe() while the reducer is executing. ' + 'If you would like to be notified after the store has been updated, subscribe from a ' + 'component and invoke store.getState() in the callback to access the latest state. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.');\n }\n\n var isSubscribed = true;\n ensureCanMutateNextListeners();\n nextListeners.push(listener);\n return function unsubscribe() {\n if (!isSubscribed) {\n return;\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(6) : 'You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.');\n }\n\n isSubscribed = false;\n ensureCanMutateNextListeners();\n var index = nextListeners.indexOf(listener);\n nextListeners.splice(index, 1);\n currentListeners = null;\n };\n }\n /**\n * Dispatches an action. It is the only way to trigger a state change.\n *\n * The `reducer` function, used to create the store, will be called with the\n * current state tree and the given `action`. Its return value will\n * be considered the **next** state of the tree, and the change listeners\n * will be notified.\n *\n * The base implementation only supports plain object actions. If you want to\n * dispatch a Promise, an Observable, a thunk, or something else, you need to\n * wrap your store creating function into the corresponding middleware. For\n * example, see the documentation for the `redux-thunk` package. Even the\n * middleware will eventually dispatch plain object actions using this method.\n *\n * @param {Object} action A plain object representing “what changed”. It is\n * a good idea to keep actions serializable so you can record and replay user\n * sessions, or use the time travelling `redux-devtools`. An action must have\n * a `type` property which may not be `undefined`. It is a good idea to use\n * string constants for action types.\n *\n * @returns {Object} For convenience, the same action object you dispatched.\n *\n * Note that, if you use a custom middleware, it may wrap `dispatch()` to\n * return something else (for example, a Promise you can await).\n */\n\n\n function dispatch(action) {\n if (!isPlainObject(action)) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(7) : \"Actions must be plain objects. Instead, the actual type was: '\" + kindOf(action) + \"'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples.\");\n }\n\n if (typeof action.type === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(8) : 'Actions may not have an undefined \"type\" property. You may have misspelled an action type string constant.');\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(9) : 'Reducers may not dispatch actions.');\n }\n\n try {\n isDispatching = true;\n currentState = currentReducer(currentState, action);\n } finally {\n isDispatching = false;\n }\n\n var listeners = currentListeners = nextListeners;\n\n for (var i = 0; i < listeners.length; i++) {\n var listener = listeners[i];\n listener();\n }\n\n return action;\n }\n /**\n * Replaces the reducer currently used by the store to calculate the state.\n *\n * You might need this if your app implements code splitting and you want to\n * load some of the reducers dynamically. You might also need this if you\n * implement a hot reloading mechanism for Redux.\n *\n * @param {Function} nextReducer The reducer for the store to use instead.\n * @returns {void}\n */\n\n\n function replaceReducer(nextReducer) {\n if (typeof nextReducer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(10) : \"Expected the nextReducer to be a function. Instead, received: '\" + kindOf(nextReducer));\n }\n\n currentReducer = nextReducer; // This action has a similiar effect to ActionTypes.INIT.\n // Any reducers that existed in both the new and old rootReducer\n // will receive the previous state. This effectively populates\n // the new state tree with any relevant data from the old one.\n\n dispatch({\n type: ActionTypes.REPLACE\n });\n }\n /**\n * Interoperability point for observable/reactive libraries.\n * @returns {observable} A minimal observable of state changes.\n * For more information, see the observable proposal:\n * https://github.com/tc39/proposal-observable\n */\n\n\n function observable() {\n var _ref;\n\n var outerSubscribe = subscribe;\n return _ref = {\n /**\n * The minimal observable subscription method.\n * @param {Object} observer Any object that can be used as an observer.\n * The observer object should have a `next` method.\n * @returns {subscription} An object with an `unsubscribe` method that can\n * be used to unsubscribe the observable from the store, and prevent further\n * emission of values from the observable.\n */\n subscribe: function subscribe(observer) {\n if (typeof observer !== 'object' || observer === null) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(11) : \"Expected the observer to be an object. Instead, received: '\" + kindOf(observer) + \"'\");\n }\n\n function observeState() {\n if (observer.next) {\n observer.next(getState());\n }\n }\n\n observeState();\n var unsubscribe = outerSubscribe(observeState);\n return {\n unsubscribe: unsubscribe\n };\n }\n }, _ref[$$observable] = function () {\n return this;\n }, _ref;\n } // When a store is created, an \"INIT\" action is dispatched so that every\n // reducer returns their initial state. This effectively populates\n // the initial state tree.\n\n\n dispatch({\n type: ActionTypes.INIT\n });\n return _ref2 = {\n dispatch: dispatch,\n subscribe: subscribe,\n getState: getState,\n replaceReducer: replaceReducer\n }, _ref2[$$observable] = observable, _ref2;\n}\n\n/**\n * Prints a warning in the console if it exists.\n *\n * @param {String} message The warning message.\n * @returns {void}\n */\nfunction warning(message) {\n /* eslint-disable no-console */\n if (typeof console !== 'undefined' && typeof console.error === 'function') {\n console.error(message);\n }\n /* eslint-enable no-console */\n\n\n try {\n // This error was thrown as a convenience so that if you enable\n // \"break on all exceptions\" in your console,\n // it would pause the execution at this line.\n throw new Error(message);\n } catch (e) {} // eslint-disable-line no-empty\n\n}\n\nfunction getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {\n var reducerKeys = Object.keys(reducers);\n var argumentName = action && action.type === ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer';\n\n if (reducerKeys.length === 0) {\n return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';\n }\n\n if (!isPlainObject(inputState)) {\n return \"The \" + argumentName + \" has unexpected type of \\\"\" + kindOf(inputState) + \"\\\". Expected argument to be an object with the following \" + (\"keys: \\\"\" + reducerKeys.join('\", \"') + \"\\\"\");\n }\n\n var unexpectedKeys = Object.keys(inputState).filter(function (key) {\n return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];\n });\n unexpectedKeys.forEach(function (key) {\n unexpectedKeyCache[key] = true;\n });\n if (action && action.type === ActionTypes.REPLACE) return;\n\n if (unexpectedKeys.length > 0) {\n return \"Unexpected \" + (unexpectedKeys.length > 1 ? 'keys' : 'key') + \" \" + (\"\\\"\" + unexpectedKeys.join('\", \"') + \"\\\" found in \" + argumentName + \". \") + \"Expected to find one of the known reducer keys instead: \" + (\"\\\"\" + reducerKeys.join('\", \"') + \"\\\". Unexpected keys will be ignored.\");\n }\n}\n\nfunction assertReducerShape(reducers) {\n Object.keys(reducers).forEach(function (key) {\n var reducer = reducers[key];\n var initialState = reducer(undefined, {\n type: ActionTypes.INIT\n });\n\n if (typeof initialState === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(12) : \"The slice reducer for key \\\"\" + key + \"\\\" returned undefined during initialization. \" + \"If the state passed to the reducer is undefined, you must \" + \"explicitly return the initial state. The initial state may \" + \"not be undefined. If you don't want to set a value for this reducer, \" + \"you can use null instead of undefined.\");\n }\n\n if (typeof reducer(undefined, {\n type: ActionTypes.PROBE_UNKNOWN_ACTION()\n }) === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(13) : \"The slice reducer for key \\\"\" + key + \"\\\" returned undefined when probed with a random type. \" + (\"Don't try to handle '\" + ActionTypes.INIT + \"' or other actions in \\\"redux/*\\\" \") + \"namespace. They are considered private. Instead, you must return the \" + \"current state for any unknown actions, unless it is undefined, \" + \"in which case you must return the initial state, regardless of the \" + \"action type. The initial state may not be undefined, but can be null.\");\n }\n });\n}\n/**\n * Turns an object whose values are different reducer functions, into a single\n * reducer function. It will call every child reducer, and gather their results\n * into a single state object, whose keys correspond to the keys of the passed\n * reducer functions.\n *\n * @param {Object} reducers An object whose values correspond to different\n * reducer functions that need to be combined into one. One handy way to obtain\n * it is to use ES6 `import * as reducers` syntax. The reducers may never return\n * undefined for any action. Instead, they should return their initial state\n * if the state passed to them was undefined, and the current state for any\n * unrecognized action.\n *\n * @returns {Function} A reducer function that invokes every reducer inside the\n * passed object, and builds a state object with the same shape.\n */\n\n\nfunction combineReducers(reducers) {\n var reducerKeys = Object.keys(reducers);\n var finalReducers = {};\n\n for (var i = 0; i < reducerKeys.length; i++) {\n var key = reducerKeys[i];\n\n if (process.env.NODE_ENV !== 'production') {\n if (typeof reducers[key] === 'undefined') {\n warning(\"No reducer provided for key \\\"\" + key + \"\\\"\");\n }\n }\n\n if (typeof reducers[key] === 'function') {\n finalReducers[key] = reducers[key];\n }\n }\n\n var finalReducerKeys = Object.keys(finalReducers); // This is used to make sure we don't warn about the same\n // keys multiple times.\n\n var unexpectedKeyCache;\n\n if (process.env.NODE_ENV !== 'production') {\n unexpectedKeyCache = {};\n }\n\n var shapeAssertionError;\n\n try {\n assertReducerShape(finalReducers);\n } catch (e) {\n shapeAssertionError = e;\n }\n\n return function combination(state, action) {\n if (state === void 0) {\n state = {};\n }\n\n if (shapeAssertionError) {\n throw shapeAssertionError;\n }\n\n if (process.env.NODE_ENV !== 'production') {\n var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache);\n\n if (warningMessage) {\n warning(warningMessage);\n }\n }\n\n var hasChanged = false;\n var nextState = {};\n\n for (var _i = 0; _i < finalReducerKeys.length; _i++) {\n var _key = finalReducerKeys[_i];\n var reducer = finalReducers[_key];\n var previousStateForKey = state[_key];\n var nextStateForKey = reducer(previousStateForKey, action);\n\n if (typeof nextStateForKey === 'undefined') {\n var actionType = action && action.type;\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(14) : \"When called with an action of type \" + (actionType ? \"\\\"\" + String(actionType) + \"\\\"\" : '(unknown type)') + \", the slice reducer for key \\\"\" + _key + \"\\\" returned undefined. \" + \"To ignore an action, you must explicitly return the previous state. \" + \"If you want this reducer to hold no value, you can return null instead of undefined.\");\n }\n\n nextState[_key] = nextStateForKey;\n hasChanged = hasChanged || nextStateForKey !== previousStateForKey;\n }\n\n hasChanged = hasChanged || finalReducerKeys.length !== Object.keys(state).length;\n return hasChanged ? nextState : state;\n };\n}\n\nfunction bindActionCreator(actionCreator, dispatch) {\n return function () {\n return dispatch(actionCreator.apply(this, arguments));\n };\n}\n/**\n * Turns an object whose values are action creators, into an object with the\n * same keys, but with every function wrapped into a `dispatch` call so they\n * may be invoked directly. This is just a convenience method, as you can call\n * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.\n *\n * For convenience, you can also pass an action creator as the first argument,\n * and get a dispatch wrapped function in return.\n *\n * @param {Function|Object} actionCreators An object whose values are action\n * creator functions. One handy way to obtain it is to use ES6 `import * as`\n * syntax. You may also pass a single function.\n *\n * @param {Function} dispatch The `dispatch` function available on your Redux\n * store.\n *\n * @returns {Function|Object} The object mimicking the original object, but with\n * every action creator wrapped into the `dispatch` call. If you passed a\n * function as `actionCreators`, the return value will also be a single\n * function.\n */\n\n\nfunction bindActionCreators(actionCreators, dispatch) {\n if (typeof actionCreators === 'function') {\n return bindActionCreator(actionCreators, dispatch);\n }\n\n if (typeof actionCreators !== 'object' || actionCreators === null) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(16) : \"bindActionCreators expected an object or a function, but instead received: '\" + kindOf(actionCreators) + \"'. \" + \"Did you write \\\"import ActionCreators from\\\" instead of \\\"import * as ActionCreators from\\\"?\");\n }\n\n var boundActionCreators = {};\n\n for (var key in actionCreators) {\n var actionCreator = actionCreators[key];\n\n if (typeof actionCreator === 'function') {\n boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);\n }\n }\n\n return boundActionCreators;\n}\n\n/**\n * Composes single-argument functions from right to left. The rightmost\n * function can take multiple arguments as it provides the signature for\n * the resulting composite function.\n *\n * @param {...Function} funcs The functions to compose.\n * @returns {Function} A function obtained by composing the argument functions\n * from right to left. For example, compose(f, g, h) is identical to doing\n * (...args) => f(g(h(...args))).\n */\nfunction compose() {\n for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) {\n funcs[_key] = arguments[_key];\n }\n\n if (funcs.length === 0) {\n return function (arg) {\n return arg;\n };\n }\n\n if (funcs.length === 1) {\n return funcs[0];\n }\n\n return funcs.reduce(function (a, b) {\n return function () {\n return a(b.apply(void 0, arguments));\n };\n });\n}\n\n/**\n * Creates a store enhancer that applies middleware to the dispatch method\n * of the Redux store. This is handy for a variety of tasks, such as expressing\n * asynchronous actions in a concise manner, or logging every action payload.\n *\n * See `redux-thunk` package as an example of the Redux middleware.\n *\n * Because middleware is potentially asynchronous, this should be the first\n * store enhancer in the composition chain.\n *\n * Note that each middleware will be given the `dispatch` and `getState` functions\n * as named arguments.\n *\n * @param {...Function} middlewares The middleware chain to be applied.\n * @returns {Function} A store enhancer applying the middleware.\n */\n\nfunction applyMiddleware() {\n for (var _len = arguments.length, middlewares = new Array(_len), _key = 0; _key < _len; _key++) {\n middlewares[_key] = arguments[_key];\n }\n\n return function (createStore) {\n return function () {\n var store = createStore.apply(void 0, arguments);\n\n var _dispatch = function dispatch() {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(15) : 'Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.');\n };\n\n var middlewareAPI = {\n getState: store.getState,\n dispatch: function dispatch() {\n return _dispatch.apply(void 0, arguments);\n }\n };\n var chain = middlewares.map(function (middleware) {\n return middleware(middlewareAPI);\n });\n _dispatch = compose.apply(void 0, chain)(store.dispatch);\n return _objectSpread(_objectSpread({}, store), {}, {\n dispatch: _dispatch\n });\n };\n };\n}\n\n/*\n * This is a dummy function to check if the function name has been altered by minification.\n * If the function has been minified and NODE_ENV !== 'production', warn the user.\n */\n\nfunction isCrushed() {}\n\nif (process.env.NODE_ENV !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') {\n warning('You are currently using minified code outside of NODE_ENV === \"production\". ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or setting mode to production in webpack (https://webpack.js.org/concepts/mode/) ' + 'to ensure you have the correct code for your production build.');\n}\n\nexport { ActionTypes as __DO_NOT_USE__ActionTypes, applyMiddleware, bindActionCreators, combineReducers, compose, createStore };\n","var objectKeys =\n Object.keys ||\n function (obj) {\n var keys = [];\n for (var key in obj) {\n if ({}.hasOwnProperty.call(obj, key)) keys.push(key);\n }\n return keys;\n };\n\nfunction assign(obj, newKey, newValue) {\n var keys = objectKeys(obj);\n var copy = {};\n\n for (var i = 0, l = keys.length; i < l; i++) {\n var key = keys[i];\n copy[key] = obj[key];\n }\n\n copy[newKey] = newValue;\n return copy;\n}\n\nmodule.exports = assign;\n","'use strict';\n\nvar assign = require('./utils/assign');\nvar compose = require('redux').compose;\n\nfunction enhancer() {\n var config = arguments[0] || {};\n config.features = { pause: true, export: true, test: true };\n config.type = 'redux';\n if (config.autoPause === undefined) config.autoPause = true;\n if (config.latency === undefined) config.latency = 500;\n\n return function (createStore) {\n return function (reducer, preloadedState, enhancer) {\n var store = createStore(reducer, preloadedState, enhancer);\n var origDispatch = store.dispatch;\n\n var devTools = window.__REDUX_DEVTOOLS_EXTENSION__.connect(config);\n devTools.init(store.getState());\n\n var dispatch = function (action) {\n var r = origDispatch(action);\n devTools.send(action, store.getState());\n return r;\n };\n\n if (Object.assign) return Object.assign(store, { dispatch: dispatch });\n return assign(store, 'dispatch', dispatch);\n };\n };\n}\n\nfunction composeWithEnhancer(config) {\n return function () {\n return compose(compose.apply(null, arguments), enhancer(config));\n };\n}\n\nexports.__esModule = true;\nexports.composeWithDevTools = function () {\n if (typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION__) {\n if (arguments.length === 0) return enhancer();\n if (typeof arguments[0] === 'object')\n return composeWithEnhancer(arguments[0]);\n return composeWithEnhancer().apply(null, arguments);\n }\n\n if (arguments.length === 0) return undefined;\n if (typeof arguments[0] === 'object') return compose;\n return compose.apply(null, arguments);\n};\n\nexports.devToolsEnhancer =\n typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION__\n ? enhancer\n : function () {\n return function (noop) {\n return noop;\n };\n };\n","'use strict';\n\nvar compose = require('redux').compose;\nvar logOnly = require('./logOnly');\n\nexports.__esModule = true;\nexports.composeWithDevTools =\n process.env.NODE_ENV === 'production'\n ? logOnly.composeWithDevTools\n : typeof window !== 'undefined' &&\n window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__\n ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__\n : function () {\n if (arguments.length === 0) return undefined;\n if (typeof arguments[0] === 'object') return compose;\n return compose.apply(null, arguments);\n };\n\nexports.devToolsEnhancer =\n process.env.NODE_ENV === 'production'\n ? logOnly.devToolsEnhancer\n : typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION__\n ? window.__REDUX_DEVTOOLS_EXTENSION__\n : function () {\n return function (noop) {\n return noop;\n };\n };\n","/** A function that accepts a potential \"extra argument\" value to be injected later,\r\n * and returns an instance of the thunk middleware that uses that value\r\n */\nfunction createThunkMiddleware(extraArgument) {\n // Standard Redux middleware definition pattern:\n // See: https://redux.js.org/tutorials/fundamentals/part-4-store#writing-custom-middleware\n var middleware = function middleware(_ref) {\n var dispatch = _ref.dispatch,\n getState = _ref.getState;\n return function (next) {\n return function (action) {\n // The thunk middleware looks for any functions that were passed to `store.dispatch`.\n // If this \"action\" is really a function, call it and return the result.\n if (typeof action === 'function') {\n // Inject the store's `dispatch` and `getState` methods, as well as any \"extra arg\"\n return action(dispatch, getState, extraArgument);\n } // Otherwise, pass the action down the middleware chain as usual\n\n\n return next(action);\n };\n };\n };\n\n return middleware;\n}\n\nvar thunk = createThunkMiddleware(); // Attach the factory function so users can create a customized version\n// with whatever \"extra arg\" they want to inject into their thunks\n\nthunk.withExtraArgument = createThunkMiddleware;\nexport default thunk;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.ActionCreators = exports.ActionTypes = void 0;\nvar ActionTypes = {\n UNDO: '@@redux-undo/UNDO',\n REDO: '@@redux-undo/REDO',\n JUMP_TO_FUTURE: '@@redux-undo/JUMP_TO_FUTURE',\n JUMP_TO_PAST: '@@redux-undo/JUMP_TO_PAST',\n JUMP: '@@redux-undo/JUMP',\n CLEAR_HISTORY: '@@redux-undo/CLEAR_HISTORY'\n};\nexports.ActionTypes = ActionTypes;\nvar ActionCreators = {\n undo: function undo() {\n return {\n type: ActionTypes.UNDO\n };\n },\n redo: function redo() {\n return {\n type: ActionTypes.REDO\n };\n },\n jumpToFuture: function jumpToFuture(index) {\n return {\n type: ActionTypes.JUMP_TO_FUTURE,\n index: index\n };\n },\n jumpToPast: function jumpToPast(index) {\n return {\n type: ActionTypes.JUMP_TO_PAST,\n index: index\n };\n },\n jump: function jump(index) {\n return {\n type: ActionTypes.JUMP,\n index: index\n };\n },\n clearHistory: function clearHistory() {\n return {\n type: ActionTypes.CLEAR_HISTORY\n };\n }\n};\nexports.ActionCreators = ActionCreators;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.parseActions = parseActions;\nexports.isHistory = isHistory;\nexports.includeAction = includeAction;\nexports.excludeAction = excludeAction;\nexports.combineFilters = combineFilters;\nexports.groupByActionTypes = groupByActionTypes;\nexports.newHistory = newHistory;\n\n// parseActions helper: takes a string (or array)\n// and makes it an array if it isn't yet\nfunction parseActions(rawActions) {\n var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n\n if (Array.isArray(rawActions)) {\n return rawActions;\n } else if (typeof rawActions === 'string') {\n return [rawActions];\n }\n\n return defaultValue;\n} // isHistory helper: check for a valid history object\n\n\nfunction isHistory(history) {\n return typeof history.present !== 'undefined' && typeof history.future !== 'undefined' && typeof history.past !== 'undefined' && Array.isArray(history.future) && Array.isArray(history.past);\n} // includeAction helper: whitelist actions to be added to the history\n\n\nfunction includeAction(rawActions) {\n var actions = parseActions(rawActions);\n return function (action) {\n return actions.indexOf(action.type) >= 0;\n };\n} // excludeAction helper: blacklist actions from being added to the history\n\n\nfunction excludeAction(rawActions) {\n var actions = parseActions(rawActions);\n return function (action) {\n return actions.indexOf(action.type) < 0;\n };\n} // combineFilters helper: combine multiple filters to one\n\n\nfunction combineFilters() {\n for (var _len = arguments.length, filters = new Array(_len), _key = 0; _key < _len; _key++) {\n filters[_key] = arguments[_key];\n }\n\n return filters.reduce(function (prev, curr) {\n return function (action, currentState, previousHistory) {\n return prev(action, currentState, previousHistory) && curr(action, currentState, previousHistory);\n };\n }, function () {\n return true;\n });\n}\n\nfunction groupByActionTypes(rawActions) {\n var actions = parseActions(rawActions);\n return function (action) {\n return actions.indexOf(action.type) >= 0 ? action.type : null;\n };\n}\n\nfunction newHistory(past, present, future) {\n var group = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;\n return {\n past: past,\n present: present,\n future: future,\n group: group,\n _latestUnfiltered: present,\n index: past.length,\n limit: past.length + future.length + 1\n };\n}","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.set = set;\nexports.start = start;\nexports.end = end;\nexports.log = log;\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nvar __DEBUG__;\n\nvar displayBuffer;\nvar colors = {\n prevState: '#9E9E9E',\n action: '#03A9F4',\n nextState: '#4CAF50'\n};\n/* istanbul ignore next: debug messaging is not tested */\n\nfunction initBuffer() {\n displayBuffer = {\n header: [],\n prev: [],\n action: [],\n next: [],\n msgs: []\n };\n}\n/* istanbul ignore next: debug messaging is not tested */\n\n\nfunction printBuffer() {\n var _displayBuffer = displayBuffer,\n header = _displayBuffer.header,\n prev = _displayBuffer.prev,\n next = _displayBuffer.next,\n action = _displayBuffer.action,\n msgs = _displayBuffer.msgs;\n\n if (console.group) {\n var _console, _console2, _console3, _console4, _console5;\n\n (_console = console).groupCollapsed.apply(_console, _toConsumableArray(header));\n\n (_console2 = console).log.apply(_console2, _toConsumableArray(prev));\n\n (_console3 = console).log.apply(_console3, _toConsumableArray(action));\n\n (_console4 = console).log.apply(_console4, _toConsumableArray(next));\n\n (_console5 = console).log.apply(_console5, _toConsumableArray(msgs));\n\n console.groupEnd();\n } else {\n var _console6, _console7, _console8, _console9, _console10;\n\n (_console6 = console).log.apply(_console6, _toConsumableArray(header));\n\n (_console7 = console).log.apply(_console7, _toConsumableArray(prev));\n\n (_console8 = console).log.apply(_console8, _toConsumableArray(action));\n\n (_console9 = console).log.apply(_console9, _toConsumableArray(next));\n\n (_console10 = console).log.apply(_console10, _toConsumableArray(msgs));\n }\n}\n/* istanbul ignore next: debug messaging is not tested */\n\n\nfunction colorFormat(text, color, obj) {\n return [\"%c\".concat(text), \"color: \".concat(color, \"; font-weight: bold\"), obj];\n}\n/* istanbul ignore next: debug messaging is not tested */\n\n\nfunction start(action, state) {\n initBuffer();\n\n if (__DEBUG__) {\n if (console.group) {\n displayBuffer.header = ['%credux-undo', 'font-style: italic', 'action', action.type];\n displayBuffer.action = colorFormat('action', colors.action, action);\n displayBuffer.prev = colorFormat('prev history', colors.prevState, state);\n } else {\n displayBuffer.header = ['redux-undo action', action.type];\n displayBuffer.action = ['action', action];\n displayBuffer.prev = ['prev history', state];\n }\n }\n}\n/* istanbul ignore next: debug messaging is not tested */\n\n\nfunction end(nextState) {\n if (__DEBUG__) {\n if (console.group) {\n displayBuffer.next = colorFormat('next history', colors.nextState, nextState);\n } else {\n displayBuffer.next = ['next history', nextState];\n }\n\n printBuffer();\n }\n}\n/* istanbul ignore next: debug messaging is not tested */\n\n\nfunction log() {\n if (__DEBUG__) {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n displayBuffer.msgs = displayBuffer.msgs.concat([].concat(args, ['\\n']));\n }\n}\n/* istanbul ignore next: debug messaging is not tested */\n\n\nfunction set(debug) {\n __DEBUG__ = debug;\n}","\"use strict\";\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports[\"default\"] = undoable;\n\nvar debug = _interopRequireWildcard(require(\"./debug\"));\n\nvar _actions = require(\"./actions\");\n\nvar _helpers = require(\"./helpers\");\n\nfunction _getRequireWildcardCache() { if (typeof WeakMap !== \"function\") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \"object\" && typeof obj !== \"function\") { return { \"default\": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj[\"default\"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction createHistory(state, ignoreInitialState) {\n // ignoreInitialState essentially prevents the user from undoing to the\n // beginning, in the case that the undoable reducer handles initialization\n // in a way that can't be redone simply\n var history = (0, _helpers.newHistory)([], state, []);\n\n if (ignoreInitialState) {\n history._latestUnfiltered = null;\n }\n\n return history;\n} // insert: insert `state` into history, which means adding the current state\n// into `past`, setting the new `state` as `present` and erasing\n// the `future`.\n\n\nfunction insert(history, state, limit, group) {\n var lengthWithoutFuture = history.past.length + 1;\n debug.log('inserting', state);\n debug.log('new free: ', limit - lengthWithoutFuture);\n var past = history.past,\n _latestUnfiltered = history._latestUnfiltered;\n var isHistoryOverflow = limit && limit <= lengthWithoutFuture;\n var pastSliced = past.slice(isHistoryOverflow ? 1 : 0);\n var newPast = _latestUnfiltered != null ? [].concat(_toConsumableArray(pastSliced), [_latestUnfiltered]) : pastSliced;\n return (0, _helpers.newHistory)(newPast, state, [], group);\n} // jumpToFuture: jump to requested index in future history\n\n\nfunction jumpToFuture(history, index) {\n if (index < 0 || index >= history.future.length) return history;\n var past = history.past,\n future = history.future,\n _latestUnfiltered = history._latestUnfiltered;\n var newPast = [].concat(_toConsumableArray(past), [_latestUnfiltered], _toConsumableArray(future.slice(0, index)));\n var newPresent = future[index];\n var newFuture = future.slice(index + 1);\n return (0, _helpers.newHistory)(newPast, newPresent, newFuture);\n} // jumpToPast: jump to requested index in past history\n\n\nfunction jumpToPast(history, index) {\n if (index < 0 || index >= history.past.length) return history;\n var past = history.past,\n future = history.future,\n _latestUnfiltered = history._latestUnfiltered;\n var newPast = past.slice(0, index);\n var newFuture = [].concat(_toConsumableArray(past.slice(index + 1)), [_latestUnfiltered], _toConsumableArray(future));\n var newPresent = past[index];\n return (0, _helpers.newHistory)(newPast, newPresent, newFuture);\n} // jump: jump n steps in the past or forward\n\n\nfunction jump(history, n) {\n if (n > 0) return jumpToFuture(history, n - 1);\n if (n < 0) return jumpToPast(history, history.past.length + n);\n return history;\n} // helper to dynamically match in the reducer's switch-case\n\n\nfunction actionTypeAmongClearHistoryType(actionType, clearHistoryType) {\n return clearHistoryType.indexOf(actionType) > -1 ? actionType : !actionType;\n} // redux-undo higher order reducer\n\n\nfunction undoable(reducer) {\n var rawConfig = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n debug.set(rawConfig.debug);\n\n var config = _objectSpread({\n limit: undefined,\n filter: function filter() {\n return true;\n },\n groupBy: function groupBy() {\n return null;\n },\n undoType: _actions.ActionTypes.UNDO,\n redoType: _actions.ActionTypes.REDO,\n jumpToPastType: _actions.ActionTypes.JUMP_TO_PAST,\n jumpToFutureType: _actions.ActionTypes.JUMP_TO_FUTURE,\n jumpType: _actions.ActionTypes.JUMP,\n neverSkipReducer: false,\n ignoreInitialState: false,\n syncFilter: false\n }, rawConfig, {\n initTypes: (0, _helpers.parseActions)(rawConfig.initTypes, ['@@redux-undo/INIT']),\n clearHistoryType: (0, _helpers.parseActions)(rawConfig.clearHistoryType, [_actions.ActionTypes.CLEAR_HISTORY])\n }); // Allows the user to call the reducer with redux-undo specific actions\n\n\n var skipReducer = config.neverSkipReducer ? function (res, action) {\n for (var _len = arguments.length, slices = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n slices[_key - 2] = arguments[_key];\n }\n\n return _objectSpread({}, res, {\n present: reducer.apply(void 0, [res.present, action].concat(slices))\n });\n } : function (res) {\n return res;\n };\n var initialState;\n return function () {\n var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;\n var action = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n debug.start(action, state);\n var history = state;\n\n for (var _len2 = arguments.length, slices = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {\n slices[_key2 - 2] = arguments[_key2];\n }\n\n if (!initialState) {\n debug.log('history is uninitialized');\n\n if (state === undefined) {\n var createHistoryAction = {\n type: '@@redux-undo/CREATE_HISTORY'\n };\n var start = reducer.apply(void 0, [state, createHistoryAction].concat(slices));\n history = createHistory(start, config.ignoreInitialState);\n debug.log('do not set initialState on probe actions');\n debug.end(history);\n return history;\n } else if ((0, _helpers.isHistory)(state)) {\n history = initialState = config.ignoreInitialState ? state : (0, _helpers.newHistory)(state.past, state.present, state.future);\n debug.log('initialHistory initialized: initialState is a history', initialState);\n } else {\n history = initialState = createHistory(state, config.ignoreInitialState);\n debug.log('initialHistory initialized: initialState is not a history', initialState);\n }\n }\n\n var res;\n\n switch (action.type) {\n case undefined:\n return history;\n\n case config.undoType:\n res = jump(history, -1);\n debug.log('perform undo');\n debug.end(res);\n return skipReducer.apply(void 0, [res, action].concat(slices));\n\n case config.redoType:\n res = jump(history, 1);\n debug.log('perform redo');\n debug.end(res);\n return skipReducer.apply(void 0, [res, action].concat(slices));\n\n case config.jumpToPastType:\n res = jumpToPast(history, action.index);\n debug.log(\"perform jumpToPast to \".concat(action.index));\n debug.end(res);\n return skipReducer.apply(void 0, [res, action].concat(slices));\n\n case config.jumpToFutureType:\n res = jumpToFuture(history, action.index);\n debug.log(\"perform jumpToFuture to \".concat(action.index));\n debug.end(res);\n return skipReducer.apply(void 0, [res, action].concat(slices));\n\n case config.jumpType:\n res = jump(history, action.index);\n debug.log(\"perform jump to \".concat(action.index));\n debug.end(res);\n return skipReducer.apply(void 0, [res, action].concat(slices));\n\n case actionTypeAmongClearHistoryType(action.type, config.clearHistoryType):\n res = createHistory(history.present, config.ignoreInitialState);\n debug.log('perform clearHistory');\n debug.end(res);\n return skipReducer.apply(void 0, [res, action].concat(slices));\n\n default:\n res = reducer.apply(void 0, [history.present, action].concat(slices));\n\n if (config.initTypes.some(function (actionType) {\n return actionType === action.type;\n })) {\n debug.log('reset history due to init action');\n debug.end(initialState);\n return initialState;\n }\n\n if (history._latestUnfiltered === res) {\n // Don't handle this action. Do not call debug.end here,\n // because this action should not produce side effects to the console\n return history;\n }\n /* eslint-disable-next-line no-case-declarations */\n\n\n var filtered = typeof config.filter === 'function' && !config.filter(action, res, history);\n\n if (filtered) {\n // if filtering an action, merely update the present\n var filteredState = (0, _helpers.newHistory)(history.past, res, history.future, history.group);\n\n if (!config.syncFilter) {\n filteredState._latestUnfiltered = history._latestUnfiltered;\n }\n\n debug.log('filter ignored action, not storing it in past');\n debug.end(filteredState);\n return filteredState;\n }\n /* eslint-disable-next-line no-case-declarations */\n\n\n var group = config.groupBy(action, res, history);\n\n if (group != null && group === history.group) {\n // if grouping with the previous action, only update the present\n var groupedState = (0, _helpers.newHistory)(history.past, res, history.future, history.group);\n debug.log('groupBy grouped the action with the previous action');\n debug.end(groupedState);\n return groupedState;\n } // If the action wasn't filtered or grouped, insert normally\n\n\n history = insert(history, res, config.limit, group);\n debug.log('inserted new state into history');\n debug.end(history);\n return history;\n }\n };\n}","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"ActionTypes\", {\n enumerable: true,\n get: function get() {\n return _actions.ActionTypes;\n }\n});\nObject.defineProperty(exports, \"ActionCreators\", {\n enumerable: true,\n get: function get() {\n return _actions.ActionCreators;\n }\n});\nObject.defineProperty(exports, \"parseActions\", {\n enumerable: true,\n get: function get() {\n return _helpers.parseActions;\n }\n});\nObject.defineProperty(exports, \"isHistory\", {\n enumerable: true,\n get: function get() {\n return _helpers.isHistory;\n }\n});\nObject.defineProperty(exports, \"includeAction\", {\n enumerable: true,\n get: function get() {\n return _helpers.includeAction;\n }\n});\nObject.defineProperty(exports, \"excludeAction\", {\n enumerable: true,\n get: function get() {\n return _helpers.excludeAction;\n }\n});\nObject.defineProperty(exports, \"combineFilters\", {\n enumerable: true,\n get: function get() {\n return _helpers.combineFilters;\n }\n});\nObject.defineProperty(exports, \"groupByActionTypes\", {\n enumerable: true,\n get: function get() {\n return _helpers.groupByActionTypes;\n }\n});\nObject.defineProperty(exports, \"newHistory\", {\n enumerable: true,\n get: function get() {\n return _helpers.newHistory;\n }\n});\nObject.defineProperty(exports, \"default\", {\n enumerable: true,\n get: function get() {\n return _reducer[\"default\"];\n }\n});\n\nvar _actions = require(\"./actions\");\n\nvar _helpers = require(\"./helpers\");\n\nvar _reducer = _interopRequireDefault(require(\"./reducer\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/**\n * Function for interacting with application and module metadata.\n */\nconst MetadataManager = (() => {\n let applicationMetadata = null;\n let moduleMetadata = [];\n /**\n * Register application metadata.\n *\n * @param applicationProps Application metadata to register.\n */\n const registerApplication = (applicationProps) => {\n applicationMetadata = applicationProps;\n };\n /**\n * Register module metadata.\n *\n * @param moduleProps Module metadata to register.\n */\n const registerModule = (moduleProps) => {\n moduleMetadata = [\n ...moduleMetadata.filter(m => m.moduleId !== moduleProps.moduleId),\n moduleProps\n ];\n };\n /**\n * Update and/or add some properties of the application metadata and saves it.\n * The new properties must be a subset of {@link IApplicationMetadata}.\n *\n * @param applicationProps The properties to update.\n */\n const updateApplication = (applicationProps) => {\n applicationMetadata = Object.assign(Object.assign({}, applicationMetadata), applicationProps);\n };\n /**\n * Update and/or add some properties of the module metadata and saves it.\n * The new properties must be a subset of {@link IModuleClient}.\n *\n * @param moduleProps The properties to update.\n * @param moduleId The module id.\n */\n const updateModule = (moduleProps, moduleId) => {\n const currentProps = getModuleMetadata(moduleId);\n moduleMetadata = [\n ...moduleMetadata.filter(m => m.moduleId !== moduleId),\n Object.assign(Object.assign({}, currentProps), moduleProps)\n ];\n };\n /**\n * Get the currently registered application metadata.\n *\n * @returns The registered application metadata if it exists.\n */\n const getApplicationMetadata = () => {\n return applicationMetadata;\n };\n /**\n * Get the registered module metadata for given module id.\n *\n * @param moduleId The module that you want to retrieve the metadata.\n * @returns The registered metadata as an object if it exists.\n */\n const getModuleMetadata = (moduleId) => {\n if (!moduleId) {\n return undefined;\n }\n return moduleMetadata.find(m => m.moduleId == moduleId) || null;\n };\n /**\n * Clear application and module metadata stored.\n */\n const clear = () => {\n applicationMetadata = null;\n moduleMetadata = [];\n };\n return {\n registerApplication,\n registerModule,\n updateApplication,\n updateModule,\n getApplicationMetadata,\n getModuleMetadata,\n clear\n };\n})();\nexports.default = MetadataManager;\n//# sourceMappingURL=MetadataManager.js.map","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst MetadataManager_1 = __importDefault(require(\"./MetadataManager\"));\nconst KEY = 'sequence_number';\n/**\n * Class for handling logic related to the sequence number.\n */\nclass SequenceNumberHandler {\n /**\n * Get the current sequence number.\n *\n * @returns The current sequence number.\n */\n getSequenceNumber() {\n const metadata = MetadataManager_1.default.getApplicationMetadata();\n return (metadata === null || metadata === void 0 ? void 0 : metadata.applicationId)\n ? Number(sessionStorage.getItem(metadata.applicationId.concat('_', KEY)))\n : 0;\n }\n /**\n * Reset sequence number to the default value.\n */\n resetSequenceNumber() {\n this.setSequenceNumber(0);\n }\n /**\n * Increment the current sequence number.\n */\n incrementSequenceNumber() {\n const value = this.getSequenceNumber();\n const updateValue = value + 1;\n this.setSequenceNumber(updateValue);\n }\n /**\n * Set the sequence number.\n *\n * @param value Sequence number to store.\n */\n setSequenceNumber(value) {\n const metadata = MetadataManager_1.default.getApplicationMetadata();\n if (metadata === null || metadata === void 0 ? void 0 : metadata.applicationId) {\n sessionStorage.setItem(metadata.applicationId.concat('_', KEY), String(value));\n }\n }\n}\nexports.default = SequenceNumberHandler;\n//# sourceMappingURL=SequenceNumberHandler.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar TrackingIdEnum;\n(function (TrackingIdEnum) {\n TrackingIdEnum[\"sessionIdKey\"] = \"session_id\";\n TrackingIdEnum[\"longTermIdKey\"] = \"long_term_id\";\n TrackingIdEnum[\"planningIdKey\"] = \"planning_id\";\n TrackingIdEnum[\"ipexIdKey\"] = \"ipex_id\";\n})(TrackingIdEnum || (TrackingIdEnum = {}));\nexports.default = TrackingIdEnum;\n//# sourceMappingURL=TrackingIdEnum.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/**\n * Utility class for random Id generation.\n */\nclass IdGenerator {\n /**\n * Generate a RFC4122 v4 compliant UUID.\n *\n * @returns The newly generated UUID.\n */\n uuidV4() {\n /* Tslint:disable:no-bitwise */\n let d = Date.now(); // Start with now as a seed\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, xy => {\n const r = (d + Math.random() * 16) % 16 | 0; // Generate a new random number\n const c = xy === 'x' ? r : (r & 0x3) | 0x8; // Make sure it's RFC4122 version 4 compliant\n d = Math.floor(d / 16); // Update the seed\n return c.toString(16); // Return the hex digit\n });\n /* Tslint:enable:no-bitwise */\n }\n}\nexports.default = IdGenerator;\n//# sourceMappingURL=IdGenerator.js.map","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst SequenceNumberHandler_1 = __importDefault(require(\"./SequenceNumberHandler\"));\nconst TrackingIdEnum_1 = __importDefault(require(\"../enums/TrackingIdEnum\"));\nconst IdGenerator_1 = __importDefault(require(\"./IdGenerator\"));\nconst MetadataManager_1 = __importDefault(require(\"./MetadataManager\"));\nconst localStorageKeys = [TrackingIdEnum_1.default.longTermIdKey, TrackingIdEnum_1.default.ipexIdKey];\nconst sessionStorageKeys = [TrackingIdEnum_1.default.sessionIdKey, TrackingIdEnum_1.default.planningIdKey];\n/**\n * Utility class for handling data about the session.\n */\nclass SessionManager {\n constructor() {\n this.sequenceNumber = new SequenceNumberHandler_1.default();\n this.idGenerator = new IdGenerator_1.default();\n }\n /**\n * Get the current session Id if one exists, or creates one and returns it if it doesn't.\n *\n * @param key The request session type.\n * @returns The valid tracking Id.\n */\n getValidId(key) {\n const trackingId = this.getId(key);\n if (trackingId) {\n return trackingId;\n }\n return this.createId(key);\n }\n /**\n * Update the time for when the session started to now, and saves it to storage.\n * Will throw an Error if no session exists.\n *\n * @param key The key for the id to update.\n * @returns The new session id object which has been saved.\n */\n updateIdTime(key) {\n const pastId = this.getId(key);\n if (!pastId) {\n throw Error('No session to update');\n }\n const newIdProps = {\n time: Date.now(),\n id: pastId.id\n };\n if (localStorageKeys.includes(key)) {\n localStorage.setItem(key, JSON.stringify(newIdProps));\n }\n else if (sessionStorageKeys.includes(key)) {\n this.safeSessionSet(key, newIdProps);\n }\n return newIdProps;\n }\n /**\n * Ensure the ids in local and session storage exist and are valid. Will create and/or update values if necessary.\n */\n updateIds() {\n const sessionId = this.getId(TrackingIdEnum_1.default.sessionIdKey);\n let longTermId = this.getId(TrackingIdEnum_1.default.longTermIdKey);\n let ipexId = this.getId(TrackingIdEnum_1.default.ipexIdKey);\n if (!longTermId) {\n longTermId = this.createId(TrackingIdEnum_1.default.longTermIdKey);\n }\n if (!ipexId || Date.now() - ipexId.time > 30 * 60 * 1000) {\n ipexId = this.createId(TrackingIdEnum_1.default.ipexIdKey);\n }\n else {\n this.updateIdTime(TrackingIdEnum_1.default.ipexIdKey);\n }\n if (!sessionId) {\n this.createId(TrackingIdEnum_1.default.sessionIdKey);\n this.sequenceNumber.resetSequenceNumber();\n return {\n ['long_term_id_created']: longTermId.time,\n ['ipex_id_created']: ipexId.time\n };\n }\n else if (Date.now() - sessionId.time > 30 * 60 * 1000) {\n // No interaction the past 30 minutes. Create a new session, but leave the long term id as is.\n this.createId(TrackingIdEnum_1.default.sessionIdKey);\n this.sequenceNumber.resetSequenceNumber();\n return {\n ['long_term_id_created']: longTermId.time,\n ['ipex_id_created']: ipexId.time\n };\n }\n else {\n this.updateIdTime(TrackingIdEnum_1.default.sessionIdKey);\n return undefined;\n }\n }\n /**\n * Clear all session related data.\n */\n clearSessions() {\n localStorage.clear();\n sessionStorage.clear();\n }\n /**\n * Create a new id for given key, generates an uuidV4 as id and sets time to now.\n *\n * @param key The key to generate a value for.\n * @param startSource Optional planning start source, which will be saved if the key is for planning ids.\n * @param sourceDesignId Optional design id, which will be saved if the key is for planning ids.\n * @param sourceSpr Optional spr source, which will be saved if the key is for planning ids.\n * @returns The new value object.\n */\n createId(key, startSource, sourceDesignId, sourceSpr) {\n const id = this.idGenerator.uuidV4();\n const newIdProps = {\n time: Date.now(),\n id\n };\n if (key === TrackingIdEnum_1.default.planningIdKey && startSource) {\n newIdProps.startSource = startSource;\n newIdProps.sourceDesignId = sourceDesignId;\n newIdProps.sourceSpr = sourceSpr;\n }\n if (localStorageKeys.includes(key)) {\n localStorage.setItem(key, JSON.stringify(newIdProps));\n }\n else if (sessionStorageKeys.includes(key)) {\n this.safeSessionSet(key, newIdProps);\n }\n return newIdProps;\n }\n /**\n * Get the value for supplied key.\n *\n * @param key The key which to look for.\n * @returns The value for the key. Will be null if no value exists.\n */\n getId(key) {\n if (localStorageKeys.includes(key)) {\n const idProps = localStorage.getItem(key);\n return idProps ? JSON.parse(idProps) : null;\n }\n else if (sessionStorageKeys.includes(key)) {\n return this.safeSessionGet(key);\n }\n return null;\n }\n /**\n * Get user ids.\n *\n * @returns The user ids (sessionId, planningId, longTermId and ipexId).\n */\n getIds() {\n var _a, _b, _c, _d;\n return {\n sessionId: (_a = this.getId(TrackingIdEnum_1.default.sessionIdKey)) === null || _a === void 0 ? void 0 : _a.id,\n planningId: (_b = this.getId(TrackingIdEnum_1.default.planningIdKey)) === null || _b === void 0 ? void 0 : _b.id,\n longTermId: (_c = this.getId(TrackingIdEnum_1.default.longTermIdKey)) === null || _c === void 0 ? void 0 : _c.id,\n ipexId: (_d = this.getId(TrackingIdEnum_1.default.ipexIdKey)) === null || _d === void 0 ? void 0 : _d.id\n };\n }\n /**\n * Save some props to a planner-prepended key, but only if planner name is registered in metadata.\n *\n * @param key The session storage key to save to.\n * @param props The props to save to the key.\n */\n safeSessionSet(key, props) {\n const metadata = MetadataManager_1.default.getApplicationMetadata();\n if ('applicationId' in metadata) {\n const applicationIdKey = metadata.applicationId.concat('_', key);\n sessionStorage.setItem(applicationIdKey, JSON.stringify(props));\n }\n }\n /**\n * Retrieve some props from a planner-prepended key, but only if planner name is registered in metadata.\n *\n * @param key The session storage key to save to.\n * @returns The ITrackingProps saved to the key if it exists, otherwise null.\n */\n safeSessionGet(key) {\n const metadata = MetadataManager_1.default.getApplicationMetadata();\n let idProps;\n if (metadata === null || metadata === void 0 ? void 0 : metadata.applicationId) {\n const applicationIdKey = metadata.applicationId.concat('_', key);\n idProps = sessionStorage.getItem(applicationIdKey);\n }\n return idProps ? JSON.parse(idProps) : null;\n }\n}\nexports.default = SessionManager;\n//# sourceMappingURL=SessionManager.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar IpexMomentEnum;\n(function (IpexMomentEnum) {\n IpexMomentEnum[\"giveMe\"] = \"give_me\";\n IpexMomentEnum[\"whatIsMe\"] = \"what_is_me\";\n IpexMomentEnum[\"showMe\"] = \"show_me\";\n IpexMomentEnum[\"makeItMe\"] = \"make_it_me\";\n IpexMomentEnum[\"helpMe\"] = \"help_me\";\n IpexMomentEnum[\"nonInteraction\"] = \"non_interaction\";\n})(IpexMomentEnum || (IpexMomentEnum = {}));\nexports.default = IpexMomentEnum;\n//# sourceMappingURL=IpexMomentEnum.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/**\n * Utility class for retrieving and handling cookie data.\n */\nclass CookieReader {\n /**\n * Read the Google Analytics clientId from the document cookie.\n *\n * @returns The GA clientId, extracted and trimmed from cookie.\n * @throws If there is no clientId in the cookie, or the cookie is incorrectly formatted.\n */\n getGaId() {\n const cookieSeparated = document.cookie.split('; ').filter(value => value.startsWith('_ga='));\n if (cookieSeparated.length == 0) {\n throw new Error('Unable to retrieve Google Analytics cookie.');\n }\n /* Some markets are setting two cookies with the same name\n * we want to filter out the one that has the following format\n * _ga=GA1.2.XXXXXXXXXX.XXXXXXXXXX\n */\n const gaCookie = cookieSeparated.filter(c => c.split('.').length == 4);\n if (!gaCookie.length) {\n throw new Error('GA cookie is incorrectly constructed.');\n }\n const cookieFields = gaCookie[0].split('.');\n return cookieFields[2] + '.' + cookieFields[3];\n }\n}\nexports.default = CookieReader;\n//# sourceMappingURL=CookieReader.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/**\n * Utility class for retrieving document referrer.\n */\nclass EntryPoint {\n /**\n * Get document referrer.\n *\n * @returns The entry point as an object that contains host, pathname and search.\n */\n getEntryPoint() {\n const entryPoint = document.referrer;\n try {\n const url = new URL(entryPoint);\n return {\n host: url.host,\n pathname: url.pathname,\n search: url.search\n };\n }\n catch (e) {\n return undefined;\n }\n }\n}\nexports.default = EntryPoint;\n//# sourceMappingURL=EntryPoint.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar DesignInteractionEnum;\n(function (DesignInteractionEnum) {\n DesignInteractionEnum[\"getConfiguration\"] = \"get_configuration\";\n DesignInteractionEnum[\"storeConfiguration\"] = \"store_configuration\";\n})(DesignInteractionEnum || (DesignInteractionEnum = {}));\nexports.default = DesignInteractionEnum;\n//# sourceMappingURL=DesignInteractionEnum.js.map","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst DesignInteractionEnum_1 = __importDefault(require(\"./DesignInteractionEnum\"));\nvar OtherEventsEnum;\n(function (OtherEventsEnum) {\n OtherEventsEnum[\"start\"] = \"start\";\n OtherEventsEnum[\"addToCart\"] = \"add_to_cart\";\n OtherEventsEnum[\"addToWishList\"] = \"add_to_wishlist\";\n OtherEventsEnum[\"initiatePlanningSession\"] = \"initiate_planning_session\";\n OtherEventsEnum[\"connectApplication\"] = \"connect_application\";\n OtherEventsEnum[\"pageview\"] = \"pageview\";\n OtherEventsEnum[\"articleAction\"] = \"article_action\";\n OtherEventsEnum[\"userFlow\"] = \"user_flow\";\n})(OtherEventsEnum || (OtherEventsEnum = {}));\nconst InsightsEventEnum = Object.assign(Object.assign({}, OtherEventsEnum), DesignInteractionEnum_1.default);\nexports.default = InsightsEventEnum;\n//# sourceMappingURL=InsightsEventEnum.js.map","\"use strict\";\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst SessionManager_1 = __importDefault(require(\"../utilities/SessionManager\"));\nconst SequenceNumberHandler_1 = __importDefault(require(\"../utilities/SequenceNumberHandler\"));\nconst IpexMomentEnum_1 = __importDefault(require(\"../enums/IpexMomentEnum\"));\nconst TrackingIdEnum_1 = __importDefault(require(\"../enums/TrackingIdEnum\"));\nconst CookieReader_1 = __importDefault(require(\"../utilities/CookieReader\"));\nconst EntryPoint_1 = __importDefault(require(\"../utilities/EntryPoint\"));\nconst InsightsEventEnum_1 = __importDefault(require(\"../enums/InsightsEventEnum\"));\nconst MetadataManager_1 = __importDefault(require(\"../utilities/MetadataManager\"));\n/**\n * Class for handling logic about sending events to Insights.\n */\nclass InsightsTarget {\n constructor() {\n this.sessionManager = new SessionManager_1.default();\n this.sequenceNumberHandler = new SequenceNumberHandler_1.default();\n this.cookie = new CookieReader_1.default();\n }\n /**\n * Sends a given set of data to Ipex Insights.\n *\n * @param ipexMoment The IPEX moment for the event.\n * @param name Name of the event.\n * @param payload Optional payload.\n * @param eventData Event data to send.\n */\n sendInsightsEvent(ipexMoment, name, eventData, payload) {\n return __awaiter(this, void 0, void 0, function* () {\n const applicationMetadata = MetadataManager_1.default.getApplicationMetadata();\n const moduleMetadata = MetadataManager_1.default.getModuleMetadata(this.moduleId);\n this.checkEventSchema(name, ipexMoment, applicationMetadata);\n const eventBody = this.constructEventBody(ipexMoment, name, applicationMetadata, eventData, payload);\n this.sequenceNumberHandler.incrementSequenceNumber();\n const dev = applicationMetadata.dev || (moduleMetadata === null || moduleMetadata === void 0 ? void 0 : moduleMetadata.dev);\n const domain = this.getIpexDomain(dev);\n const key = this.getIpexStreamKey(dev);\n try {\n yield fetch(domain, {\n method: 'POST',\n body: JSON.stringify(eventBody),\n headers: { 'x-api-key': key, 'Content-Type': 'application/json' }\n });\n }\n catch (error) {\n throw new Error(`Failed to send ${name} event, ${error}`);\n }\n });\n }\n /**\n * Create and populate event data object according to IEventSchema.\n *\n * @param ipexMoment Moment for the event.\n * @param name Name of the event.\n * @param applicationMetadata The application metadata.\n * @param eventData Optional eventData.\n * @param payload Optional payload.\n * @returns An event body, conforming to the IEventSchema type.\n */\n constructEventBody(ipexMoment, name, applicationMetadata, eventData, payload) {\n const location = window === null || window === void 0 ? void 0 : window.location;\n const eventBody = {\n event: name,\n moment: ipexMoment,\n ['app_id']: applicationMetadata.applicationId,\n ['session_id']: this.sessionManager.getId(TrackingIdEnum_1.default.sessionIdKey).id,\n ['sequence_nbr']: this.sequenceNumberHandler.getSequenceNumber(),\n ['visitor_timestamp']: Date.now(),\n ['meta']: this.constructMetadata(applicationMetadata),\n page: {\n origin: location === null || location === void 0 ? void 0 : location.origin,\n pathname: location === null || location === void 0 ? void 0 : location.pathname,\n ['query_param']: location === null || location === void 0 ? void 0 : location.search\n }\n };\n if (name == InsightsEventEnum_1.default.start) {\n const entryPoint = new EntryPoint_1.default().getEntryPoint();\n eventBody['meta']['entry_point'] = entryPoint;\n }\n const optionalParams = {\n ['payload']: JSON.stringify(payload),\n ['event_data']: eventData,\n planning: this.constructPlanningData(),\n module: this.constructModuleData()\n };\n for (const [key, value] of Object.entries(optionalParams)) {\n this.addOptionalParameter(eventBody, key, value);\n }\n return eventBody;\n }\n /**\n * Create and populate metatadata, to be added to the object body.\n *\n * @param appData Application metadata.\n * @returns An IMetaDataSchema object, with all relevant parameters set.\n */\n constructMetadata(appData) {\n const pjson = require('../../package.json');\n const metadata = {\n ['ipex_session_id']: this.sessionManager.getId(TrackingIdEnum_1.default.ipexIdKey).id,\n ['long_term_id']: this.sessionManager.getId(TrackingIdEnum_1.default.longTermIdKey).id,\n ['app_version']: appData.applicationVersion,\n ['dpc_version']: pjson.version,\n platform: appData.platform,\n ['country_code']: appData.countryCode,\n ['language_code']: appData.languageCode,\n ['is_planner']: appData.isPlanner\n };\n if (appData.abVersionName || appData.abVersionVariation) {\n metadata['ab_version'] = {\n name: appData.abVersionName || '',\n variation: appData.abVersionVariation || ''\n };\n }\n if (appData.enableGa === true) {\n let clientId;\n try {\n clientId = this.cookie.getGaId();\n }\n catch (error) {\n // eslint-disable-next-line\n console.error(error);\n }\n metadata['ga_client_id'] = clientId || '';\n }\n const optionalParams = {\n ['store_id']: appData.storeId,\n kiosk: appData.kiosk,\n ['kiosk_id']: appData.kioskId\n };\n for (const [key, value] of Object.entries(optionalParams)) {\n this.addOptionalParameter(metadata, key, value);\n }\n return metadata;\n }\n /**\n * Create planning data for the event body, with the appropriate structure.\n * Will set optional parameters only if they are present (i.e. Not undefined).\n *\n * @returns Planning data, as an IPlanning object.\n */\n constructPlanningData() {\n const planningId = this.sessionManager.getId(TrackingIdEnum_1.default.planningIdKey);\n if (planningId == null) {\n return undefined;\n }\n const planningData = {\n ['planning_id']: planningId.id,\n ['start_source']: planningId.startSource\n };\n this.addOptionalParameter(planningData, 'source_design_id', planningId.sourceDesignId);\n this.addOptionalParameter(planningData, 'source_spr', planningId.sourceSpr);\n return planningData;\n }\n /**\n * Create module data for the event body, with the appropriate structure.\n * Will set optional parameters only if they are present (i.e. Not undefined).\n *\n * @returns ModuleData Module data, as an IModuleData object.\n */\n constructModuleData() {\n const metadata = MetadataManager_1.default.getModuleMetadata(this.moduleId);\n if (!metadata) {\n return undefined;\n }\n const moduleData = {\n ['module_id']: metadata.moduleId,\n ['module_version']: metadata.moduleVersion\n };\n if (metadata.abVersionName || metadata.abVersionVariation) {\n moduleData['module_ab_version'] = {\n name: metadata.abVersionName || '',\n variation: metadata.abVersionVariation || ''\n };\n }\n return moduleData;\n }\n /**\n * Helper method to add optional parameters to objects.\n *\n * @param obj The object to add a parameter to.\n * @param key Thge parameter to add.\n * @param val The value of the parameter.\n */\n addOptionalParameter(obj, key, val) {\n if (val !== undefined) {\n obj[key] = val;\n }\n }\n /**\n * Get the domain URL for web events depending on if development or production environment.\n *\n * @param dev True if using the development environment, false if production.\n * @returns The domain URL address.\n */\n getIpexDomain(dev) {\n return dev\n ? 'https://dpc-qa.ipex-insights.com/event/submit'\n : 'https://dpc.ipex-insights.com/event/submit';\n }\n /**\n * Get the stream key for events depending on if development or production.\n *\n * @param dev True if using the development environment, false if production.\n * @returns The x-api-key for the IPEX stream.\n */\n getIpexStreamKey(dev) {\n return dev\n ? 'puIswII0bn2UxyC9IL8KI3aWnYCeIQmv2tya5v7b'\n : 'rZQMCYLyig4uqKOCiRBY78ypyNfCE9Cz7XVh7XdV';\n }\n /**\n * Checks if the event name is valid.\n *\n * @param eventName The event name.\n * @param moment The IPEX moment.\n * @param applicationMetadata The app metadata.\n * @throws An Error if eventName, moment, app_id or module_id are incorrect.\n */\n checkEventSchema(eventName, moment, applicationMetadata) {\n if (typeof eventName !== 'string') {\n throw Error('Insights event name not defined. Will not send event.');\n }\n if (eventName.match(/[^A-Za-z0-9_]/g)) {\n throw Error(`Insights event ${eventName} contains special characters. Only alphanumerics and underscores are allowed.`);\n }\n if (eventName.length <= 3 || eventName.length > 40) {\n throw Error(`Insights event name ${eventName} too long or too short. Please keep it between 3 and 40 characters.`);\n }\n if (!applicationMetadata || Object.keys(applicationMetadata).length === 0) {\n throw Error(`Failed to send ${eventName} event, application metadata not found.`);\n }\n const applicationId = applicationMetadata.applicationId;\n if (applicationId.match(/[^A-Za-z0-9_äÄåÅöÖ]/g)) {\n throw Error(`Application id ${applicationId} contains special characters. Only alphanumerics and underscores are allowed.`);\n }\n const moduleId = this.moduleId || '';\n if (moduleId.match(/[^A-Za-z0-9_äÄåÅöÖ]/g)) {\n throw Error(`Module id ${moduleId} contains special characters. Only alphanumerics and underscores are allowed.`);\n }\n if (!Object.values(IpexMomentEnum_1.default).includes(moment)) {\n throw Error(`Failed to send ${eventName}, moment ${moment} does not exist in IpexMomentEnum.`);\n }\n }\n}\nexports.default = InsightsTarget;\n//# sourceMappingURL=InsightsTarget.js.map","\"use strict\";\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst MetadataManager_1 = __importDefault(require(\"../utilities/MetadataManager\"));\nconst TEAM = 'ipexinsights';\n/**\n * Class for using Google Analytics and sending events.\n */\nclass GoogleAnalyticsTarget {\n /**\n * Set up the Google Analytics integration based on given properties.\n * Will initialize and send the first required event.\n * Requires the Google Analytics script to be loaded in advance.\n *\n * @param props Parameters needed to initiate Google Analytics.\n * @returns A Promise from window.sendEvent.\n */\n setupGoogleAnalytics(props) {\n return __awaiter(this, void 0, void 0, function* () {\n if (this.checkGaEnabled()) {\n try {\n return yield window\n .analyticsInit({\n countryCode: props.countryCode,\n languageCode: props.language,\n platform: props.platform,\n plannerName: props.plannerName,\n dev: props.dev\n })\n .then(() => {\n return this.sendPageViewEvent();\n });\n }\n catch (e) {\n // eslint-disable-next-line\n console.error(e);\n }\n }\n });\n }\n /**\n * Send a given set of data to Google Analytics.\n *\n * @param category The category the event belongs to.\n * @param action The action being performed in the event.\n * @param label Event label, optional.\n * @param custom Parameters to include in the custom dimension.\n */\n sendGoogleAnalyticsEvent(category, action, label, custom) {\n return __awaiter(this, void 0, void 0, function* () {\n if (this.checkGaEnabled()) {\n try {\n return yield window.sendEvent({\n ['event_category']: category,\n ['event_action']: action,\n ['event_label']: label,\n custom: Object.assign({ team: TEAM }, custom)\n });\n }\n catch (e) {\n // eslint-disable-next-line\n console.error(e);\n }\n }\n });\n }\n /**\n * Send an event to Google Analytics with a name and a set of parameters.\n *\n * @param name Name of the event to be sent.\n * @param params Parameters to include in the event.\n * @param custom Parameters to include in the custom dimension.\n */\n sendGoogleAnalyticsEventWithParams(name, params, custom) {\n return __awaiter(this, void 0, void 0, function* () {\n if (this.checkGaEnabled()) {\n try {\n return yield window.sendEvent({\n name: name,\n params: params,\n custom: Object.assign({ team: TEAM }, custom)\n });\n }\n catch (e) {\n // eslint-disable-next-line\n console.error(e);\n }\n }\n });\n }\n /**\n * Check app metadata to see if GA is enabled.\n *\n * @returns True if GA is enabled, false if it's not, or if it's not defined.\n */\n checkGaEnabled() {\n const appMeta = MetadataManager_1.default.getApplicationMetadata();\n if (!('enableGa' in appMeta)) {\n return false;\n }\n if (appMeta.enableGa == null || appMeta.enableGa === false) {\n return false;\n }\n return true;\n }\n /**\n * Send the initial page view event required for Google Analytics to work.\n *\n * @returns A Promise from window.sendEvent.\n */\n sendPageViewEvent() {\n return __awaiter(this, void 0, void 0, function* () {\n if (this.checkGaEnabled()) {\n try {\n return yield window.sendEvent({\n ['event_category']: 'pageview',\n ['page_path']: window.location.pathname,\n ['page_location']: window.location.href,\n custom: {\n team: TEAM\n }\n });\n }\n catch (e) {\n // eslint-disable-next-line\n console.error(e);\n }\n }\n });\n }\n}\nexports.default = GoogleAnalyticsTarget;\n//# sourceMappingURL=GoogleAnalyticsTarget.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar GaEventEnum;\n(function (GaEventEnum) {\n GaEventEnum[\"savePlanner\"] = \"save_planner\";\n GaEventEnum[\"addToWishlist\"] = \"add_to_wishlist\";\n GaEventEnum[\"addToCart\"] = \"add_to_cart\";\n GaEventEnum[\"openPlanner\"] = \"open_planner\";\n})(GaEventEnum || (GaEventEnum = {}));\nexports.default = GaEventEnum;\n//# sourceMappingURL=GaEventEnum.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar GaCategoryEnum;\n(function (GaCategoryEnum) {\n GaCategoryEnum[\"ecommerce\"] = \"ecommerce\";\n GaCategoryEnum[\"planners\"] = \"planners\";\n GaCategoryEnum[\"nonInteraction\"] = \"non_interaction\";\n})(GaCategoryEnum || (GaCategoryEnum = {}));\nexports.default = GaCategoryEnum;\n//# sourceMappingURL=GaCategoryEnum.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar DesignSourceEnum;\n(function (DesignSourceEnum) {\n DesignSourceEnum[\"clipboard\"] = \"clipboard\";\n DesignSourceEnum[\"designSearch\"] = \"design_search\";\n DesignSourceEnum[\"email\"] = \"email\";\n DesignSourceEnum[\"enterCode\"] = \"enter_code\";\n DesignSourceEnum[\"gallery\"] = \"gallery\";\n DesignSourceEnum[\"imageDeeplink\"] = \"image_deeplink\";\n DesignSourceEnum[\"iSell\"] = \"i_sell\";\n DesignSourceEnum[\"planningSupportTool\"] = \"planning_support_tool\";\n DesignSourceEnum[\"qr\"] = \"qr\";\n DesignSourceEnum[\"recommendation\"] = \"recommendation\";\n DesignSourceEnum[\"resumeLastDesign\"] = \"resume_last_design\";\n DesignSourceEnum[\"retailerSystem\"] = \"retailer_system\";\n DesignSourceEnum[\"salesSystem\"] = \"sales_system\";\n DesignSourceEnum[\"searchBar\"] = \"search_bar\";\n DesignSourceEnum[\"skytta\"] = \"skytta\";\n DesignSourceEnum[\"sms\"] = \"sms\";\n DesignSourceEnum[\"spr\"] = \"spr\";\n DesignSourceEnum[\"startFromSaved\"] = \"start_from_saved\";\n DesignSourceEnum[\"startFromScratch\"] = \"start_from_scratch\";\n DesignSourceEnum[\"startFromTemplate\"] = \"start_from_template\";\n})(DesignSourceEnum || (DesignSourceEnum = {}));\nexports.default = DesignSourceEnum;\n//# sourceMappingURL=DesignSourceEnum.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar ArticleActionEnum;\n(function (ArticleActionEnum) {\n ArticleActionEnum[\"add\"] = \"add\";\n ArticleActionEnum[\"delete\"] = \"delete\";\n ArticleActionEnum[\"move\"] = \"move\";\n ArticleActionEnum[\"select\"] = \"select\";\n ArticleActionEnum[\"copy\"] = \"copy\";\n ArticleActionEnum[\"rotate\"] = \"rotate\";\n})(ArticleActionEnum || (ArticleActionEnum = {}));\nexports.default = ArticleActionEnum;\n//# sourceMappingURL=ArticleActionEnum.js.map","\"use strict\";\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst InsightsTarget_1 = __importDefault(require(\"./targets/InsightsTarget\"));\nconst GoogleAnalyticsTarget_1 = __importDefault(require(\"./targets/GoogleAnalyticsTarget\"));\nconst IpexMomentEnum_1 = __importDefault(require(\"./enums/IpexMomentEnum\"));\nconst GaEventEnum_1 = __importDefault(require(\"./enums/GaEventEnum\"));\nconst GaCategoryEnum_1 = __importDefault(require(\"./enums/GaCategoryEnum\"));\nconst DesignSourceEnum_1 = __importDefault(require(\"./enums/DesignSourceEnum\"));\nconst SessionManager_1 = __importDefault(require(\"./utilities/SessionManager\"));\nconst DesignInteractionEnum_1 = __importDefault(require(\"./enums/DesignInteractionEnum\"));\nconst TrackingIdEnum_1 = __importDefault(require(\"./enums/TrackingIdEnum\"));\nconst ArticleActionEnum_1 = __importDefault(require(\"./enums/ArticleActionEnum\"));\nconst InsightsEventEnum_1 = __importDefault(require(\"./enums/InsightsEventEnum\"));\nconst MetadataManager_1 = __importDefault(require(\"./utilities/MetadataManager\"));\n/**\n * Class for sending of events to various sources.\n */\nclass EventSender {\n constructor() {\n this.insights = new InsightsTarget_1.default();\n this.sessionManager = new SessionManager_1.default();\n this.googleAnalytics = new GoogleAnalyticsTarget_1.default();\n }\n /**\n * Set the module id in insights target.\n *\n * @param moduleId The module id.\n */\n setTargetModuleId(moduleId) {\n this.insights.moduleId = moduleId;\n }\n /**\n * Set up Google Analytics, and send open_planner events to Insights and GA.\n *\n * @param props Properties for the init event.\n * @returns The promise for setupGoogleAnalytics.\n */\n setupAndSendInit(props) {\n return __awaiter(this, void 0, void 0, function* () {\n yield this.sendApplicationStartUpEvents();\n return this.googleAnalytics\n .setupGoogleAnalytics({\n countryCode: props.countryCode.toLowerCase(),\n language: props.languageCode.toLowerCase(),\n plannerName: props.applicationId,\n dev: !!props.dev,\n platform: props.platform\n })\n .then(() => __awaiter(this, void 0, void 0, function* () {\n const session = this.sessionManager.getValidId(TrackingIdEnum_1.default.sessionIdKey);\n this.googleAnalytics.sendGoogleAnalyticsEvent(GaCategoryEnum_1.default.planners, GaEventEnum_1.default.openPlanner, session.id);\n }));\n });\n }\n /**\n * Send an add_to_cart event to Insights and GA.\n *\n * @param data Items added to cart.\n */\n sendAddToCart(data) {\n var _a;\n return __awaiter(this, void 0, void 0, function* () {\n yield this.updateLocalIds();\n yield Promise.all([\n this.insights.sendInsightsEvent(IpexMomentEnum_1.default.giveMe, InsightsEventEnum_1.default.addToCart, {\n currency: data.currency,\n ['design_id']: data.designId ? data.designId : null,\n articles: data.items,\n ['unavailable_articles']: data.unavailableItems ? data.unavailableItems : null\n }, data.payload),\n this.googleAnalytics.sendGoogleAnalyticsEventWithParams(GaEventEnum_1.default.addToCart, {\n currency: data.currency,\n items: data.items.map(item => ({\n id: item.id,\n price: item.price,\n quantity: item.qty\n }))\n }, {\n // This is custom dimension 47 and will be renamed to planner_product_combination_id on the server side\n ['planning_id']: (_a = data.designId) !== null && _a !== void 0 ? _a : null\n })\n ]);\n });\n }\n /**\n * Send an add_to_wishlist event to Insights and GA.\n *\n * @param data Items added to wish list.\n */\n sendAddToWishList(data) {\n var _a, _b;\n return __awaiter(this, void 0, void 0, function* () {\n yield this.updateLocalIds();\n yield Promise.all([\n this.insights.sendInsightsEvent(IpexMomentEnum_1.default.giveMe, InsightsEventEnum_1.default.addToWishList, {\n currency: data.currency,\n ['design_id']: (_a = data.designId) !== null && _a !== void 0 ? _a : null,\n articles: data.items\n }, data.payload),\n this.googleAnalytics.sendGoogleAnalyticsEvent(GaCategoryEnum_1.default.ecommerce, GaEventEnum_1.default.addToWishlist, undefined, {\n // Custom dimension 47\n ['planning_id']: (_b = data.designId) !== null && _b !== void 0 ? _b : null\n })\n ]);\n });\n }\n /**\n *\n * @param designId The design id that started the planning session.\n * @param source The source of the planning session.\n * @param payload The payload data.\n * @param spr The SPR that was used as base for the planning if any.\n * @throws If source does not exist in DesignSourceEnum.\n */\n sendInitPlanningSession(designId, source, payload, spr) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!Object.values(DesignSourceEnum_1.default).includes(source)) {\n throw Error(`Failed to send event, design source ${source} is not a valid source. Check DesignSourceEnum.`);\n }\n this.updateDesignId(designId, source);\n this.sessionManager.createId(TrackingIdEnum_1.default.planningIdKey, source, designId, spr);\n yield this.updateLocalIds();\n // Planning data is sent automatically when the event is created.\n yield this.insights.sendInsightsEvent(IpexMomentEnum_1.default.nonInteraction, InsightsEventEnum_1.default.initiatePlanningSession, undefined, payload);\n });\n }\n /**\n * Send a save_planner event to Insights and GA.\n *\n * @param designId The design id to save.\n * @param payload The payload data.\n */\n sendSavePlanner(designId, payload) {\n return __awaiter(this, void 0, void 0, function* () {\n const metadata = MetadataManager_1.default.getApplicationMetadata();\n yield this.updateLocalIds();\n yield Promise.all([\n this.insights.sendInsightsEvent(IpexMomentEnum_1.default.giveMe, 'save_planner', {\n ['design_id']: designId\n }, payload),\n this.googleAnalytics.sendGoogleAnalyticsEvent(GaCategoryEnum_1.default.planners, GaEventEnum_1.default.savePlanner, metadata.applicationId, {\n // Custom dimension 47\n ['planning_id']: designId\n })\n ]);\n });\n }\n /**\n * Send a custom event to Insights. The name of the event is contained in data.event.\n *\n * @param data Data sent with the event.\n */\n sendCustomEvent(data) {\n return __awaiter(this, void 0, void 0, function* () {\n yield this.updateLocalIds();\n yield this.insights.sendInsightsEvent(data.ipexMoment, data.event, undefined, data.payload);\n });\n }\n /**\n * Send a design interaction event to Insights.\n *\n * @param designId The design id which was interacted with.\n * @param interaction The interaction source.\n * @param payload The payload data.\n * @throws An Error if interaction is incorrect.\n */\n sendDesignInteractionEvent(designId, interaction, payload) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!Object.values(DesignInteractionEnum_1.default).includes(interaction)) {\n throw Error(`Failed to send event, interaction ${interaction} is not a valid interaction. Check DesignInteractionEnum.`);\n }\n yield this.updateLocalIds();\n yield this.insights.sendInsightsEvent(IpexMomentEnum_1.default.nonInteraction, interaction, {\n ['design_id']: designId\n }, payload);\n });\n }\n /**\n * Send an article_action event to Insights.\n *\n * @param articleId The article id.\n * @param action The action being performed.\n * @param isGlobal Indicate if article id is global or local.\n * @param [payload] Optional payload data.\n * @throws An Error if action is incorrect.\n */\n sendArticleAction(articleId, action, isGlobal, payload) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!Object.values(ArticleActionEnum_1.default).includes(action)) {\n throw Error(`Failed to send event, action ${action} is not a valid interaction. Check ArticleActionEnum.`);\n }\n yield this.updateLocalIds();\n yield this.insights.sendInsightsEvent(IpexMomentEnum_1.default.makeItMe, InsightsEventEnum_1.default.articleAction, {\n ['article_action']: action,\n ['article_id']: articleId,\n ['is_global']: isGlobal\n }, payload);\n });\n }\n /**\n * Send a flow step event to Insights.\n *\n * @param flowName Name of the flow.\n * @param stepName Name of the step in the flow.\n * @param stepLevel Level of step in the flow.\n */\n sendUserFlowStep(flowName, stepName, stepLevel, payload) {\n return __awaiter(this, void 0, void 0, function* () {\n yield this.updateLocalIds();\n yield this.insights.sendInsightsEvent(IpexMomentEnum_1.default.nonInteraction, InsightsEventEnum_1.default.userFlow, {\n ['flow_name']: flowName,\n ['step_name']: stepName,\n ['step_level']: stepLevel\n }, payload);\n });\n }\n /**\n * Send mandatory startup event for the module client flow.\n */\n sendModuleStartUpEvents() {\n return __awaiter(this, void 0, void 0, function* () {\n yield this.updateLocalIds();\n yield this.insights.sendInsightsEvent(IpexMomentEnum_1.default.nonInteraction, 'connect_module');\n });\n }\n /**\n * Send mandatory startup event for the application startup flow.\n */\n sendApplicationStartUpEvents() {\n return __awaiter(this, void 0, void 0, function* () {\n yield this.updateLocalIds();\n yield this.insights.sendInsightsEvent(IpexMomentEnum_1.default.nonInteraction, InsightsEventEnum_1.default.connectApplication);\n });\n }\n /**\n * Send AB version changed event.\n */\n sendSetAbVersion() {\n return __awaiter(this, void 0, void 0, function* () {\n yield this.updateLocalIds();\n yield this.insights.sendInsightsEvent(IpexMomentEnum_1.default.nonInteraction, 'set_ab_version');\n });\n }\n /**\n * Register a design id in the metadata, or throw an Error if it's empty/undefined and source is incorrect.\n * If the design id is empty/undefined and the source is start_from_scratch, start_from_template,\n * or resume_last_design, design id will be registered as start_from_scratch, start_from_template,\n * or resume_last_design respectively.\n *\n * @param designId The design id to update.\n * @param source The source of the planning session.\n */\n updateDesignId(designId, source) {\n if (!designId &&\n source !== DesignSourceEnum_1.default.startFromScratch &&\n source !== DesignSourceEnum_1.default.startFromTemplate &&\n source !== DesignSourceEnum_1.default.resumeLastDesign) {\n // Will throw an error if no design id is provided (or it's empty), given source is not start_from_scratch\n throw Error('No design id provided');\n }\n else if (!designId && source === DesignSourceEnum_1.default.startFromScratch) {\n MetadataManager_1.default.updateApplication({ designId: 'start_from_scratch' });\n }\n else if (!designId && source === DesignSourceEnum_1.default.startFromTemplate) {\n MetadataManager_1.default.updateApplication({ designId: 'start_from_template' });\n }\n else if (!designId && source === DesignSourceEnum_1.default.resumeLastDesign) {\n MetadataManager_1.default.updateApplication({ designId: 'resume_last_design' });\n }\n else {\n MetadataManager_1.default.updateApplication({ designId });\n }\n }\n /**\n * Update all local Ids through the session manager, then sends a start event if a new Id was generated.\n */\n updateLocalIds() {\n return __awaiter(this, void 0, void 0, function* () {\n const eventData = this.sessionManager.updateIds();\n if (eventData !== undefined) {\n yield this.insights.sendInsightsEvent(IpexMomentEnum_1.default.nonInteraction, InsightsEventEnum_1.default.start, eventData);\n }\n });\n }\n}\nexports.default = EventSender;\n//# sourceMappingURL=EventSender.js.map","\"use strict\";\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst GA_SCRIPT_URL = 'https://www.ikea.com/se/sv/analytics/scripts/analytics-minor.min.js';\nconst TYPE = 'text/javascript';\n/**\n * Utility class for loading the INGKA GA script, necessary for setting up Google Analytics.\n */\nclass GAScriptLoader {\n /**\n * Check if the GA script is already loaded, and constructs and loads it if not.\n *\n * @returns The Promise from {@link constructScriptElement}, or an autoresolved Promise if already loaded.\n */\n loadGoogleAnalyticsScript() {\n return __awaiter(this, void 0, void 0, function* () {\n let scriptLoaded = false;\n const scripts = document.getElementsByTagName('script');\n // Loop through all script tags\n Array.from(scripts).forEach(script => {\n if (script.src && script.src === GA_SCRIPT_URL && script.type && script.type === TYPE) {\n scriptLoaded = true;\n }\n });\n if (!scriptLoaded) {\n try {\n yield this.constructScriptElement();\n return Promise.resolve();\n }\n catch (e) {\n return Promise.reject(e);\n }\n }\n return Promise.resolve();\n });\n }\n /**\n * Construct the script element, and appends it to document.head.\n *\n * @returns A promise for loading the script.\n */\n constructScriptElement() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = GA_SCRIPT_URL;\n script.type = TYPE;\n script.async = true;\n document.head.appendChild(script);\n script.addEventListener('load', () => {\n resolve(script);\n });\n script.addEventListener('error', () => {\n reject(new Error(`${GA_SCRIPT_URL} failed to load.`));\n });\n });\n }\n}\nexports.default = GAScriptLoader;\n//# sourceMappingURL=GAScriptLoader.js.map","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar PlatformEnum;\n(function (PlatformEnum) {\n PlatformEnum[\"owfe\"] = \"owfe\";\n PlatformEnum[\"nonIrw\"] = \"non_irw\";\n PlatformEnum[\"kiosk\"] = \"kiosk\";\n})(PlatformEnum || (PlatformEnum = {}));\nexports.default = PlatformEnum;\n//# sourceMappingURL=PlatformEnum.js.map","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst EventSender_1 = __importDefault(require(\"./EventSender\"));\nconst MetadataManager_1 = __importDefault(require(\"./utilities/MetadataManager\"));\n/**\n * Entrypoint API class for modules.\n */\nclass ModuleClient {\n /**\n * @param moduleMetadata The module metadata.\n * @param insightsApi The insightsApi instance.\n */\n constructor(moduleMetadata, insightsApi) {\n this.insightsApi = null;\n this.insightsApi = insightsApi;\n this.eventSender = new EventSender_1.default();\n MetadataManager_1.default.registerModule(moduleMetadata);\n this.moduleId = moduleMetadata.moduleId;\n this.eventSender.setTargetModuleId(moduleMetadata.moduleId);\n this.eventSender.sendModuleStartUpEvents();\n }\n /**\n * Send an addToCart event, if application is enabled.\n *\n * @param data The included items in the cart.\n */\n addToCart(data) {\n if (this.insightsApi.isEnabled) {\n this.eventSender.sendAddToCart(data);\n }\n }\n /**\n * Send an addToWishList event, if application is enabled.\n *\n * @param data The included items in the wish list.\n */\n addToWishList(data) {\n if (this.insightsApi.isEnabled) {\n this.eventSender.sendAddToWishList(data);\n }\n }\n /**\n * Send a savePlanner event, if application is enabled.\n *\n * @param designId The design id to save, optional.\n * @param [payload] Optional payload data.\n */\n saveDesign(designId, payload) {\n if (this.insightsApi.isEnabled) {\n this.eventSender.sendSavePlanner(designId, payload);\n }\n }\n /**\n * Send a custom event, if application is enabled.\n *\n * @param data The information about the custom event.\n */\n sendEvent(data) {\n if (this.insightsApi.isEnabled) {\n this.eventSender.sendCustomEvent(data);\n }\n }\n /**\n * Send an initPlanningSession event, if application is enabled.\n *\n * @param designId The design id that started the session.\n * @param source The source of the planning session.\n * @param [payload] Optional payload data.\n * @param [spr] Optional The SPR that was used as base for the planning if any.\n */\n initPlanningSession(designId, source, payload, spr) {\n if (this.insightsApi.isEnabled) {\n this.eventSender.sendInitPlanningSession(designId, source, payload, spr);\n }\n }\n /**\n * Send a design interaction event, if application is enabled.\n *\n * @param designId The design id which was interacted with.\n * @param interaction The interaction source.\n * @param [payload] Optional payload data.\n */\n sendDesignInteractionEvent(designId, interaction, payload) {\n if (this.insightsApi.isEnabled) {\n this.eventSender.sendDesignInteractionEvent(designId, interaction, payload);\n }\n }\n /**\n * Send a article action event, if application is enabled.\n *\n * @param articleId The article id.\n * @param action The action being performed.\n * @param isGlobal Indicate if article id is global or local.\n * @param [payload] Optional payload data.\n */\n articleAction(articleId, action, isGlobal, payload) {\n if (this.insightsApi.isEnabled) {\n this.eventSender.sendArticleAction(articleId, action, isGlobal, payload);\n }\n }\n /**\n * Sets the A/B version for the session to facilitate A/B testing, if application is enabled.\n *\n * @param abVersionName Name of the ab version.\n * @param abVersionVariation Optional ab varation.\n */\n setAbVersion(abVersionName, abVersionVariation) {\n if (this.insightsApi.isEnabled) {\n MetadataManager_1.default.updateModule({\n abVersionName,\n abVersionVariation\n }, this.moduleId);\n this.eventSender.sendSetAbVersion();\n }\n }\n /**\n * Send a flow step event, if the component is enabled.\n *\n * @param flowName Name of the flow.\n * @param stepName Name of the step in the flow.\n * @param stepLevel Level of step in the flow.\n */\n sendUserFlowStep(flowName, stepName, stepLevel, payload) {\n if (this.insightsApi.isEnabled) {\n this.eventSender.sendUserFlowStep(flowName, stepName, stepLevel, payload);\n }\n }\n /**\n * Get user ids.\n *\n * @returns The user ids (sessionId, planningId, longTermId and ipexId).\n */\n getIds() {\n if (this.insightsApi.isEnabled) {\n return this.insightsApi.getIds();\n }\n }\n}\nexports.default = ModuleClient;\n//# sourceMappingURL=ModuleClient.js.map","\"use strict\";\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst EventSender_1 = __importDefault(require(\"./EventSender\"));\nconst SessionManager_1 = __importDefault(require(\"./utilities/SessionManager\"));\nconst SequenceNumberHandler_1 = __importDefault(require(\"./utilities/SequenceNumberHandler\"));\nconst GAScriptLoader_1 = __importDefault(require(\"./utilities/GAScriptLoader\"));\nconst PlatformEnum_1 = __importDefault(require(\"./enums/PlatformEnum\"));\nconst ModuleClient_1 = __importDefault(require(\"./ModuleClient\"));\nconst CookieReader_1 = __importDefault(require(\"./utilities/CookieReader\"));\nconst MetadataManager_1 = __importDefault(require(\"./utilities/MetadataManager\"));\n/**\n * Entrypoint API class for applications.\n */\nclass InsightsApi {\n constructor() {\n // eslint-disable-next-line\n this._isEnabled = false;\n this.eventSender = new EventSender_1.default();\n this.session = new SessionManager_1.default();\n this.sequenceNumber = new SequenceNumberHandler_1.default();\n }\n /**\n *\tReturns a boolean that indicates whether or not insights api is enabled.\n */\n get isEnabled() {\n return this._isEnabled;\n }\n /**\n * Connect the component for an application.\n *\n * @param props Initialization data for the application.\n */\n connectApplication(props) {\n return __awaiter(this, void 0, void 0, function* () {\n if (typeof props.applicationId !== 'string') {\n throw new Error('Property applicationId is not a string. DPC Initialization will not proceed.');\n }\n if (!Object.values(PlatformEnum_1.default).includes(props.platform)) {\n throw Error(`Platform ${props.platform} is not valid. Check PlatformEnum. DPC Initialization will not proceed.`);\n }\n if (props.kiosk) {\n props.platform = PlatformEnum_1.default.kiosk;\n }\n MetadataManager_1.default.registerApplication(props);\n if (props.enableGa === true) {\n const cookieReader = new CookieReader_1.default();\n try {\n cookieReader.getGaId();\n const scriptLoader = new GAScriptLoader_1.default();\n yield scriptLoader.loadGoogleAnalyticsScript();\n yield this.eventSender.setupAndSendInit(props);\n }\n catch (error) {\n // Disable GA in case we cannot find the cookie.\n // eslint-disable-next-line\n console.warn(`GA data not found. Disabling GA events.`);\n MetadataManager_1.default.updateApplication({ enableGa: false });\n // Send regular ApplicationStartUpEvents instead.\n yield this.eventSender.sendApplicationStartUpEvents();\n }\n }\n else {\n yield this.eventSender.sendApplicationStartUpEvents();\n }\n this._isEnabled = true;\n });\n }\n /**\n * Receive module initialization data and\n * returns instance of module client.\n *\n * @param moduleMetadata Initialization data for the module.\n * @returns The module client instance.\n */\n moduleClient(moduleMetadata) {\n if (typeof moduleMetadata.moduleId !== 'string') {\n throw new Error('Property moduleId is not a string. Module client initialization will not proceed.');\n }\n if (!this.isEnabled) {\n throw new Error('Application is not enabled. Module client initialization will not proceed.');\n }\n const applicationMetadata = MetadataManager_1.default.getApplicationMetadata();\n if (!applicationMetadata || Object.keys(applicationMetadata).length === 0) {\n throw new Error('Application metadata not found. Module client initialization will not proceed.');\n }\n return new ModuleClient_1.default(moduleMetadata, this);\n }\n /**\n * Disable the component. Will reset session data and metadata, as well as the sequence number.\n */\n disconnect() {\n this._isEnabled = false;\n this.session.clearSessions();\n this.sequenceNumber.resetSequenceNumber();\n MetadataManager_1.default.clear();\n }\n /**\n * Send an addToCart event, if the component is enabled.\n *\n * @param data The included items in the cart.\n */\n addToCart(data) {\n if (this.isEnabled) {\n this.eventSender.sendAddToCart(data);\n }\n }\n /**\n * Send an addToWishList event, if the component is enabled.\n *\n * @param data The included items in the wish list.\n */\n addToWishList(data) {\n if (this.isEnabled) {\n this.eventSender.sendAddToWishList(data);\n }\n }\n /**\n * Send an initPlanningSession event, if the component is enabled.\n *\n * @param designId The design id that started the session.\n * @param source The source of the planning session.\n * @param [payload] Optional payload data.\n * @param [spr] Optional The SPR that was used as base for the planning if any.\n *\n */\n initPlanningSession(designId, source, payload, spr) {\n if (this.isEnabled) {\n this.eventSender.sendInitPlanningSession(designId, source, payload, spr);\n }\n }\n /**\n * Send a savePlanner event, if the component is enabled.\n *\n * @param designId The design id to save, optional.\n * @param [payload] Optional payload data.\n */\n saveDesign(designId, payload) {\n if (this.isEnabled) {\n this.eventSender.sendSavePlanner(designId, payload);\n }\n }\n /**\n * Send a custom event, if the component is enabled.\n *\n * @param data The information about the custom event.\n */\n sendEvent(data) {\n if (this.isEnabled) {\n this.eventSender.sendCustomEvent(data);\n }\n }\n /**\n * Send a design interaction event, if the component is enabled.\n *\n * @param designId The design id which was interacted with.\n * @param interaction The interaction source.\n * @param [payload] Optional payload data.\n */\n sendDesignInteractionEvent(designId, interaction, payload) {\n if (this.isEnabled) {\n this.eventSender.sendDesignInteractionEvent(designId, interaction, payload);\n }\n }\n /**\n * Send a article action event, if the component is enabled.\n *\n * @param articleId The article id.\n * @param action The action being performed.\n * @param isGlobal Indicate if article id is global or local.\n * @param [payload] Optional payload data.\n */\n articleAction(articleId, action, isGlobal, payload) {\n if (this.isEnabled) {\n this.eventSender.sendArticleAction(articleId, action, isGlobal, payload);\n }\n }\n /**\n * Sets the A/B version for the session to facilitate A/B testing, if the component is enabled.\n *\n * @param abVersionName Name of the ab version.\n * @param abVersionVariation Optional ab variation.\n */\n setAbVersion(abVersionName, abVersionVariation) {\n if (this.isEnabled) {\n MetadataManager_1.default.updateApplication({ abVersionName, abVersionVariation });\n this.eventSender.sendSetAbVersion();\n }\n }\n /**\n * Send a flow step event, if the component is enabled.\n *\n * @param flowName Name of the flow.\n * @param stepName Name of the step in the flow.\n * @param stepLevel Level of step in the flow.\n */\n sendUserFlowStep(flowName, stepName, stepLevel, payload) {\n if (this.isEnabled) {\n this.eventSender.sendUserFlowStep(flowName, stepName, stepLevel, payload);\n }\n }\n /**\n * Get user ids.\n *\n * @returns The user ids (sessionId, planningId, longTermId and ipexId).\n */\n getIds() {\n if (this.isEnabled) {\n return this.session.getIds();\n }\n }\n}\nexports.default = InsightsApi;\n//# sourceMappingURL=InsightsApi.js.map","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.PlatformEnum = exports.ModuleClient = exports.IpexMomentEnum = exports.InsightsApi = exports.DesignSourceEnum = exports.DesignInteractionEnum = exports.ArticleActionEnum = void 0;\nconst InsightsApi_1 = __importDefault(require(\"./InsightsApi\"));\nexports.InsightsApi = InsightsApi_1.default;\nconst DesignSourceEnum_1 = __importDefault(require(\"./enums/DesignSourceEnum\"));\nexports.DesignSourceEnum = DesignSourceEnum_1.default;\nconst IpexMomentEnum_1 = __importDefault(require(\"./enums/IpexMomentEnum\"));\nexports.IpexMomentEnum = IpexMomentEnum_1.default;\nconst DesignInteractionEnum_1 = __importDefault(require(\"./enums/DesignInteractionEnum\"));\nexports.DesignInteractionEnum = DesignInteractionEnum_1.default;\nconst PlatformEnum_1 = __importDefault(require(\"./enums/PlatformEnum\"));\nexports.PlatformEnum = PlatformEnum_1.default;\nconst ArticleActionEnum_1 = __importDefault(require(\"./enums/ArticleActionEnum\"));\nexports.ArticleActionEnum = ArticleActionEnum_1.default;\nconst ModuleClient_1 = __importDefault(require(\"./ModuleClient\"));\nexports.ModuleClient = ModuleClient_1.default;\n//# sourceMappingURL=index.js.map","var ABTestNameEnum;\n(function (ABTestNameEnum) {\n ABTestNameEnum[\"qrExitpointTest\"] = \"qrExitpointTest\";\n})(ABTestNameEnum || (ABTestNameEnum = {}));\nexport default ABTestNameEnum;\n//# sourceMappingURL=ABTestNameEnum.js.map","var ABTestVariationEnum;\n(function (ABTestVariationEnum) {\n ABTestVariationEnum[\"A\"] = \"A\";\n ABTestVariationEnum[\"B\"] = \"B\";\n})(ABTestVariationEnum || (ABTestVariationEnum = {}));\nexport default ABTestVariationEnum;\n//# sourceMappingURL=ABTestVariationEnum.js.map","var ApiPlatformEnum;\n(function (ApiPlatformEnum) {\n ApiPlatformEnum[\"irw\"] = \"irw\";\n ApiPlatformEnum[\"roig\"] = \"roig\";\n})(ApiPlatformEnum || (ApiPlatformEnum = {}));\nexport default ApiPlatformEnum;\n//# sourceMappingURL=ApiPlatformEnum.js.map","var AutoCompleteEnum;\n(function (AutoCompleteEnum) {\n // The browser is not permitted to automatically enter or select a value for this field. It is possible that the document or application provides its own autocomplete feature, or that security concerns require that the field's value not be automatically entered.\n AutoCompleteEnum[\"off\"] = \"off\";\n // The browser is allowed to automatically complete the input. No guidance is provided as to the type of data expected in the field, so the browser may use its own judgement.\n AutoCompleteEnum[\"on\"] = \"on\";\n // The field expects the value to be a person's full name. Using \"name\" rather than breaking the name down into its components is generally preferred because it avoids dealing with the wide diversity of human names and how they are structured; however, you can use the following autocomplete values if you do need to break the name down into its components:\n AutoCompleteEnum[\"name\"] = \"name\";\n // The prefix or title, such as \"Mrs.\", \"Mr.\", \"Miss\", \"Ms.\", \"Dr.\", or \"Mlle.\".\n AutoCompleteEnum[\"honorificPrefix\"] = \"honorific-prefix\";\n // The given (or \"first\") name.\n AutoCompleteEnum[\"givenName\"] = \"given-name\";\n // The middle name.\n AutoCompleteEnum[\"additionalName\"] = \"additional-name\";\n // The family (or \"last\") name.\n AutoCompleteEnum[\"familyName\"] = \"family-name\";\n // The suffix, such as \"Jr.\", \"B.Sc.\", \"PhD.\", \"MBASW\", or \"IV\".\n AutoCompleteEnum[\"honorificSuffix\"] = \"honorific-suffix\";\n // A nickname or handle.\n AutoCompleteEnum[\"nickname\"] = \"nickname\";\n // An email address.\n AutoCompleteEnum[\"email\"] = \"email\";\n // A username or account name.\n AutoCompleteEnum[\"username\"] = \"username\";\n // A new password. When creating a new account or changing passwords, this should be used for an \"Enter your new password\" or \"Confirm new password\" field, as opposed to a general \"Enter your current password\" field that might be present. This may be used by the browser both to avoid accidentally filling in an existing password and to offer assistance in creating a secure password (see also Preventing autofilling with autocomplete=\"new-password\").\n AutoCompleteEnum[\"newPassword\"] = \"new-password\";\n // The user's current password.\n AutoCompleteEnum[\"currentPassword\"] = \"current-password\";\n // A one-time code used for verifying user identity.\n AutoCompleteEnum[\"oneTimeCode\"] = \"one-time-code\";\n // A job title, or the title a person has within an organization, such as \"Senior Technical Writer\", \"President\", or \"Assistant Troop Leader\".\n AutoCompleteEnum[\"organizationTitle\"] = \"organization-title\";\n // A company or organization name, such as \"Acme Widget Company\" or \"Girl Scouts of America\".\n AutoCompleteEnum[\"organization\"] = \"organization\";\n // A street address. This can be multiple lines of text, and should fully identify the location of the address within its second administrative level (typically a city or town), but should not include the city name, ZIP or postal code, or country name.\n AutoCompleteEnum[\"streetAddress\"] = \"street-address\";\n // Each individual line of the street address. These should only be present if the \"street-address\" is not present.\n AutoCompleteEnum[\"addressLine1\"] = \"address-line1\";\n // Each individual line of the street address. These should only be present if the \"street-address\" is not present.\n AutoCompleteEnum[\"addressLine2\"] = \"address-line2\";\n // Each individual line of the street address. These should only be present if the \"street-address\" is not present.\n AutoCompleteEnum[\"addressLine3\"] = \"address-line3\";\n // The finest-grained administrative level, in addresses which have four levels.\n AutoCompleteEnum[\"addressLevel4\"] = \"address-level4\";\n // The third administrative level, in addresses with at least three administrative levels.\n AutoCompleteEnum[\"addressLevel3\"] = \"address-level3\";\n // The second administrative level, in addresses with at least two of them. In countries with two administrative levels, this would typically be the city, town, village, or other locality in which the address is located.\n AutoCompleteEnum[\"addressLevel2\"] = \"address-level2\";\n // The first administrative level in the address. This is typically the province in which the address is located. In the United States, this would be the state. In Switzerland, the canton. In the United Kingdom, the post town.\n AutoCompleteEnum[\"addressLevel1\"] = \"address-level1\";\n // A country or territory code.\n AutoCompleteEnum[\"country\"] = \"country\";\n // A country or territory name.\n AutoCompleteEnum[\"countryName\"] = \"country-name\";\n // A postal code (in the United States, this is the ZIP code).\n AutoCompleteEnum[\"postalCode\"] = \"postal-code\";\n // The full name as printed on or associated with a payment instrument such as a credit card. Using a full name field is preferred, typically, over breaking the name into pieces.\n AutoCompleteEnum[\"ccName\"] = \"cc-name\";\n // A given (first) name as given on a payment instrument like a credit card.\n AutoCompleteEnum[\"ccGivenName\"] = \"cc-given-name\";\n // A middle name as given on a payment instrument or credit card.\n AutoCompleteEnum[\"ccAdditionalName\"] = \"cc-additional-name\";\n // A family name, as given on a credit card.\n AutoCompleteEnum[\"ccFamilyName\"] = \"cc-family-name\";\n // A credit card number or other number identifying a payment method, such as an account number.\n AutoCompleteEnum[\"ccNumber\"] = \"cc-number\";\n // A payment method expiration date, typically in the form \"MM/YY\" or \"MM/YYYY\".\n AutoCompleteEnum[\"ccExp\"] = \"cc-exp\";\n // The month in which the payment method expires.\n AutoCompleteEnum[\"ccExpMonth\"] = \"cc-exp-month\";\n // The year in which the payment method expires.\n AutoCompleteEnum[\"ccExpYear\"] = \"cc-exp-year\";\n // The security code for the payment instrument; on credit cards, this is the 3-digit verification number on the back of the card.\n AutoCompleteEnum[\"ccCsc\"] = \"cc-csc\";\n // The type of payment instrument (such as \"Visa\" or \"Master Card\").\n AutoCompleteEnum[\"ccType\"] = \"cc-type\";\n // The currency in which the transaction is to take place.\n AutoCompleteEnum[\"transactionCurrency\"] = \"transaction-currency\";\n // The amount, given in the currency specified by \"transaction-currency\", of the transaction, for a payment form.\n AutoCompleteEnum[\"transactionAmount\"] = \"transaction-amount\";\n // A preferred language, given as a valid BCP 47 language tag.\n AutoCompleteEnum[\"language\"] = \"language\";\n // A birth date, as a full date.\n AutoCompleteEnum[\"bday\"] = \"bday\";\n // The day of the month of a birth date.\n AutoCompleteEnum[\"bdayDay\"] = \"bday-day\";\n // The month of the year of a birth date.\n AutoCompleteEnum[\"bdayMonth\"] = \"bday-month\";\n // The year of a birth date.\n AutoCompleteEnum[\"bdayYear\"] = \"bday-year\";\n // A gender identity (such as \"Female\", \"Fa'afafine\", \"Male\"), as freeform text without newlines.\n AutoCompleteEnum[\"sex\"] = \"sex\";\n // A full telephone number, including the country code. If you need to break the phone number up into its components, you can use these values for those fields:\n AutoCompleteEnum[\"tel\"] = \"tel\";\n // The country code, such as \"1\" for the United States, Canada, and other areas in North America and parts of the Caribbean.\n AutoCompleteEnum[\"telCountryCode\"] = \"tel-country-code\";\n // The entire phone number without the country code component, including a country-internal prefix. For the phone number \"1-855-555-6502\", this field's value would be \"855-555-6502\".\n AutoCompleteEnum[\"telNational\"] = \"tel-national\";\n // The area code, with any country-internal prefix applied if appropriate.\n AutoCompleteEnum[\"telAreaCode\"] = \"tel-area-code\";\n // The phone number without the country or area code. This can be split further into two parts, for phone numbers which have an exchange number and then a number within the exchange. For the phone number \"555-6502\", use \"tel-local-prefix\" for \"555\" and \"tel-local-suffix\" for \"6502\".\n AutoCompleteEnum[\"telLocal\"] = \"tel-local\";\n // A telephone extension code within the phone number, such as a room or suite number in a hotel or an office extension in a company.\n AutoCompleteEnum[\"telExtension\"] = \"tel-extension\";\n // A URL for an instant messaging protocol endpoint, such as \"xmpp:username@example.net\".\n AutoCompleteEnum[\"impp\"] = \"impp\";\n // A URL, such as a home page or company web site address as appropriate given the context of the other fields in the form.\n AutoCompleteEnum[\"url\"] = \"url\";\n // The URL of an image representing the person, company, or contact information given in the other fields in the form.\n AutoCompleteEnum[\"photo\"] = \"photo\";\n})(AutoCompleteEnum || (AutoCompleteEnum = {}));\nexport default AutoCompleteEnum;\n//# sourceMappingURL=AutoCompleteEnum.js.map","var CookieConsentDataSourceEnum;\n(function (CookieConsentDataSourceEnum) {\n CookieConsentDataSourceEnum[\"disabled\"] = \"Disabled\";\n CookieConsentDataSourceEnum[\"oneWeb\"] = \"OneWeb\";\n CookieConsentDataSourceEnum[\"bitbox\"] = \"Bitbox\";\n CookieConsentDataSourceEnum[\"block\"] = \"Block\";\n})(CookieConsentDataSourceEnum || (CookieConsentDataSourceEnum = {}));\nexport default CookieConsentDataSourceEnum;\n//# sourceMappingURL=CookieConsentDataSourceEnum.js.map","var DexfSettingsEnvironmentEnum;\n(function (DexfSettingsEnvironmentEnum) {\n DexfSettingsEnvironmentEnum[\"development\"] = \"development\";\n DexfSettingsEnvironmentEnum[\"production\"] = \"production\";\n})(DexfSettingsEnvironmentEnum || (DexfSettingsEnvironmentEnum = {}));\nexport default DexfSettingsEnvironmentEnum;\n//# sourceMappingURL=DexfSettingsEnvironmentEnum.js.map","var EcommerceCartDataSourceEnum;\n(function (EcommerceCartDataSourceEnum) {\n EcommerceCartDataSourceEnum[\"default\"] = \"default\";\n EcommerceCartDataSourceEnum[\"disabled\"] = \"disabled\";\n EcommerceCartDataSourceEnum[\"iows\"] = \"IOWS\";\n EcommerceCartDataSourceEnum[\"cartApi\"] = \"CartApi\";\n EcommerceCartDataSourceEnum[\"chinaCartApi\"] = \"ChinaCartApi\";\n EcommerceCartDataSourceEnum[\"nifApi\"] = \"NifApi\";\n EcommerceCartDataSourceEnum[\"mvecom\"] = \"MvEcom\";\n EcommerceCartDataSourceEnum[\"iksa\"] = \"IKSA\";\n})(EcommerceCartDataSourceEnum || (EcommerceCartDataSourceEnum = {}));\nexport default EcommerceCartDataSourceEnum;\n//# sourceMappingURL=EcommerceCartDataSourceEnum.js.map","var EcommerceShoppingListDataSourceEnum;\n(function (EcommerceShoppingListDataSourceEnum) {\n EcommerceShoppingListDataSourceEnum[\"default\"] = \"default\";\n EcommerceShoppingListDataSourceEnum[\"disabled\"] = \"disabled\";\n EcommerceShoppingListDataSourceEnum[\"shoppingListApi\"] = \"ShoppingListApi\";\n EcommerceShoppingListDataSourceEnum[\"chinaShoppingListApi\"] = \"ChinaShoppingListApi\";\n EcommerceShoppingListDataSourceEnum[\"iows\"] = \"IOWS\";\n EcommerceShoppingListDataSourceEnum[\"mvecom\"] = \"MvEcom\";\n EcommerceShoppingListDataSourceEnum[\"iksa\"] = \"IKSA\";\n})(EcommerceShoppingListDataSourceEnum || (EcommerceShoppingListDataSourceEnum = {}));\nexport default EcommerceShoppingListDataSourceEnum;\n//# sourceMappingURL=EcommerceShoppingListDataSourceEnum.js.map","var FinancingOptionDataSourceEnum;\n(function (FinancingOptionDataSourceEnum) {\n FinancingOptionDataSourceEnum[\"disabled\"] = \"disabled\";\n FinancingOptionDataSourceEnum[\"oneWeb\"] = \"OneWeb\";\n})(FinancingOptionDataSourceEnum || (FinancingOptionDataSourceEnum = {}));\nexport default FinancingOptionDataSourceEnum;\n//# sourceMappingURL=FinancingOptionDataSourceEnum.js.map","var HeadingsEnum;\n(function (HeadingsEnum) {\n HeadingsEnum[\"h1\"] = \"1\";\n HeadingsEnum[\"h2\"] = \"2\";\n HeadingsEnum[\"h3\"] = \"3\";\n HeadingsEnum[\"h4\"] = \"4\";\n HeadingsEnum[\"h5\"] = \"5\";\n HeadingsEnum[\"h6\"] = \"6\";\n})(HeadingsEnum || (HeadingsEnum = {}));\nexport default HeadingsEnum;\n//# sourceMappingURL=HeadingsEnum.js.map","var IksaShoppingBagTypeEnum;\n(function (IksaShoppingBagTypeEnum) {\n IksaShoppingBagTypeEnum[\"cart\"] = \"onlineshoppingcart\";\n IksaShoppingBagTypeEnum[\"list\"] = \"onlineshoppinglist\";\n})(IksaShoppingBagTypeEnum || (IksaShoppingBagTypeEnum = {}));\nexport default IksaShoppingBagTypeEnum;\n//# sourceMappingURL=IksaShoppingBagTypeEnum.js.map","/**\n * Sizes available on images, where S1 is the smallest and S5 the largest.\n */\nvar ImageSizeTypeEnum;\n(function (ImageSizeTypeEnum) {\n ImageSizeTypeEnum[\"S1\"] = \"S1\";\n ImageSizeTypeEnum[\"S2\"] = \"S2\";\n ImageSizeTypeEnum[\"S3\"] = \"S3\";\n ImageSizeTypeEnum[\"S4\"] = \"S4\";\n ImageSizeTypeEnum[\"S5\"] = \"S5\";\n})(ImageSizeTypeEnum || (ImageSizeTypeEnum = {}));\nexport default ImageSizeTypeEnum;\n//# sourceMappingURL=ImageSizeTypeEnum.js.map","var ImageTypeNameEnum;\n(function (ImageTypeNameEnum) {\n ImageTypeNameEnum[\"mainProductPicture\"] = \"Main Product Picture\";\n ImageTypeNameEnum[\"contextProductPicture\"] = \"Context Product Picture\";\n ImageTypeNameEnum[\"functionalProductPicture\"] = \"Functional Product Picture\";\n ImageTypeNameEnum[\"inspirationalProductPicture\"] = \"Inspirational Product Picture\";\n /**\n * Images that shows measurements.\n *\n * For instance when applied to a Malm bureau, it will show the entire bureau measurements, as well as the drawers measurements.\n */\n ImageTypeNameEnum[\"measurementIllustration\"] = \"Measurement Illustration\";\n})(ImageTypeNameEnum || (ImageTypeNameEnum = {}));\nexport default ImageTypeNameEnum;\n//# sourceMappingURL=ImageTypeNameEnum.js.map","var InvalidProductReasonEnum;\n(function (InvalidProductReasonEnum) {\n // Sell-stopped\n InvalidProductReasonEnum[\"retailItemNotAvailable\"] = \"RETAIL_ITEM_NOT_AVAILABLE\";\n})(InvalidProductReasonEnum || (InvalidProductReasonEnum = {}));\nexport default InvalidProductReasonEnum;\n//# sourceMappingURL=InvalidProductReasonEnum.js.map","var IowsShoppingBagTypeEnum;\n(function (IowsShoppingBagTypeEnum) {\n IowsShoppingBagTypeEnum[\"cart\"] = \"onlineshoppingcart\";\n IowsShoppingBagTypeEnum[\"list\"] = \"onlineshoppinglist\";\n})(IowsShoppingBagTypeEnum || (IowsShoppingBagTypeEnum = {}));\nexport default IowsShoppingBagTypeEnum;\n//# sourceMappingURL=IowsShoppingBagTypeEnum.js.map","/**\n * All different types of items, that are accepted by DEXF.\n *\n * Note: Custom Kompis item types like bundles are not included in this enum.\n */\nvar ItemTypeEnum;\n(function (ItemTypeEnum) {\n ItemTypeEnum[\"art\"] = \"ART\";\n ItemTypeEnum[\"spr\"] = \"SPR\";\n ItemTypeEnum[\"ext\"] = \"EXT\";\n ItemTypeEnum[\"asl\"] = \"ASL\";\n ItemTypeEnum[\"msc\"] = \"MSC\";\n ItemTypeEnum[\"asm\"] = \"ASM\";\n ItemTypeEnum[\"asp\"] = \"ASP\";\n})(ItemTypeEnum || (ItemTypeEnum = {}));\nexport default ItemTypeEnum;\n//# sourceMappingURL=ItemTypeEnum.js.map","/**\n * Enum used by planners when \"showMeasurementSystemSwitch\" is true to allow users to switch between metric and imperial (controlled by planner).\n */\nvar MeasurementSystemEnum;\n(function (MeasurementSystemEnum) {\n MeasurementSystemEnum[\"metric\"] = \"metric\";\n MeasurementSystemEnum[\"imperial\"] = \"imperial\";\n})(MeasurementSystemEnum || (MeasurementSystemEnum = {}));\nexport default MeasurementSystemEnum;\n//# sourceMappingURL=MeasurementSystemEnum.js.map","var MvEcomIrwBagTypeEnum;\n(function (MvEcomIrwBagTypeEnum) {\n MvEcomIrwBagTypeEnum[\"irwCart\"] = \"irw-shopping-cart\";\n MvEcomIrwBagTypeEnum[\"irwList\"] = \"irw-shopping-list\";\n})(MvEcomIrwBagTypeEnum || (MvEcomIrwBagTypeEnum = {}));\nexport default MvEcomIrwBagTypeEnum;\n//# sourceMappingURL=MvEcomIrwBagTypeEnum.js.map","var MvEcomShoppingBagTypeEnum;\n(function (MvEcomShoppingBagTypeEnum) {\n MvEcomShoppingBagTypeEnum[\"cart\"] = \"onlineshoppingcart\";\n MvEcomShoppingBagTypeEnum[\"list\"] = \"onlineshoppinglist\";\n})(MvEcomShoppingBagTypeEnum || (MvEcomShoppingBagTypeEnum = {}));\nexport default MvEcomShoppingBagTypeEnum;\n//# sourceMappingURL=MvEcomShoppingBagTypeEnum.js.map","var NotificationDataSourceEnum;\n(function (NotificationDataSourceEnum) {\n NotificationDataSourceEnum[\"disabled\"] = \"Disabled\";\n NotificationDataSourceEnum[\"dexf\"] = \"DEXF\";\n})(NotificationDataSourceEnum || (NotificationDataSourceEnum = {}));\nexport default NotificationDataSourceEnum;\n//# sourceMappingURL=NotificationDataSourceEnum.js.map","var NotificationLinkTypeEnum;\n(function (NotificationLinkTypeEnum) {\n NotificationLinkTypeEnum[\"deeplink\"] = \"deeplink\";\n NotificationLinkTypeEnum[\"pickinglist\"] = \"pickinglist\";\n})(NotificationLinkTypeEnum || (NotificationLinkTypeEnum = {}));\nexport default NotificationLinkTypeEnum;\n//# sourceMappingURL=NotificationLinkTypeEnum.js.map","var ProductComplianceLabelTypeEnum;\n(function (ProductComplianceLabelTypeEnum) {\n ProductComplianceLabelTypeEnum[\"chileEnergyCompliance\"] = \"ENERGY_LABEL_CL\";\n ProductComplianceLabelTypeEnum[\"chileSecLabel\"] = \"SEC_LABEL_CL\";\n ProductComplianceLabelTypeEnum[\"usEnergy\"] = \"ENERGY_LABEL_US\";\n ProductComplianceLabelTypeEnum[\"euEnergy\"] = \"ENERGY_LABEL_EU\";\n ProductComplianceLabelTypeEnum[\"euUnifiedWaterLabel\"] = \"WATER_LABEL_EU\";\n ProductComplianceLabelTypeEnum[\"repairabilityIndexDocument\"] = \"REPAIR_DOC_FR\";\n ProductComplianceLabelTypeEnum[\"repairabilityIndexImage\"] = \"REPAIR_INDEX_FR\";\n})(ProductComplianceLabelTypeEnum || (ProductComplianceLabelTypeEnum = {}));\nexport default ProductComplianceLabelTypeEnum;\n//# sourceMappingURL=ProductComplianceLabelTypeEnum.js.map","var ProductComplianceTechnicalHeadingTypeEnum;\n(function (ProductComplianceTechnicalHeadingTypeEnum) {\n ProductComplianceTechnicalHeadingTypeEnum[\"energyEfficiencyClass\"] = \"ENERGY_EFFICIENCY_CLASS\";\n ProductComplianceTechnicalHeadingTypeEnum[\"rescaled\"] = \"PRODUCT_INFO_SHEET\";\n ProductComplianceTechnicalHeadingTypeEnum[\"nonRescaled\"] = \"PRODUCT_FICHE\";\n ProductComplianceTechnicalHeadingTypeEnum[\"hyperlink\"] = \"HYPERLINK\";\n ProductComplianceTechnicalHeadingTypeEnum[\"unifiedWaterLabel\"] = \"GRAPHICAL_ELEMENT\";\n ProductComplianceTechnicalHeadingTypeEnum[\"repairabilityIndex\"] = \"REPAIRABILITY_INDEX\";\n ProductComplianceTechnicalHeadingTypeEnum[\"doNotDiy\"] = \"INSTALLATION_TYPE\";\n})(ProductComplianceTechnicalHeadingTypeEnum || (ProductComplianceTechnicalHeadingTypeEnum = {}));\nexport default ProductComplianceTechnicalHeadingTypeEnum;\n//# sourceMappingURL=ProductComplianceTechnicalHeadingTypeEnum.js.map","var ProductOptionalFieldNameEnum;\n(function (ProductOptionalFieldNameEnum) {\n ProductOptionalFieldNameEnum[\"asset\"] = \"asset\";\n ProductOptionalFieldNameEnum[\"careInstruction\"] = \"careInstruction\";\n ProductOptionalFieldNameEnum[\"complementaryItem\"] = \"complementaryItem\";\n ProductOptionalFieldNameEnum[\"customerMaterial\"] = \"customerMaterial\";\n ProductOptionalFieldNameEnum[\"document\"] = \"document\";\n ProductOptionalFieldNameEnum[\"filterAttribute\"] = \"filterAttribute\";\n ProductOptionalFieldNameEnum[\"genericProduct\"] = \"genericProduct\";\n ProductOptionalFieldNameEnum[\"customerBenefitSummary\"] = \"customerBenefitSummary\";\n ProductOptionalFieldNameEnum[\"priceInformation\"] = \"priceInformation\";\n ProductOptionalFieldNameEnum[\"priceUnit\"] = \"priceUnit\";\n ProductOptionalFieldNameEnum[\"child\"] = \"child\";\n ProductOptionalFieldNameEnum[\"measureReference\"] = \"measureReference\";\n ProductOptionalFieldNameEnum[\"measure\"] = \"measure\";\n ProductOptionalFieldNameEnum[\"packageMeasure\"] = \"packageMeasure\";\n ProductOptionalFieldNameEnum[\"customerBenefit\"] = \"customerBenefit\";\n ProductOptionalFieldNameEnum[\"goodToKnow\"] = \"goodToKnow\";\n ProductOptionalFieldNameEnum[\"peopleAndPlanet\"] = \"peopleAndPlanet\";\n ProductOptionalFieldNameEnum[\"image\"] = \"image\";\n ProductOptionalFieldNameEnum[\"video\"] = \"video\";\n ProductOptionalFieldNameEnum[\"technicalInformation\"] = \"technicalInformation\";\n ProductOptionalFieldNameEnum[\"complianceTechnical\"] = \"complianceTechnical\";\n ProductOptionalFieldNameEnum[\"complianceInformation\"] = \"complianceInformation\";\n ProductOptionalFieldNameEnum[\"complianceLabel\"] = \"complianceLabel\";\n ProductOptionalFieldNameEnum[\"validDesignPart\"] = \"validDesignPart\";\n ProductOptionalFieldNameEnum[\"appConfig\"] = \"appConfig\";\n})(ProductOptionalFieldNameEnum || (ProductOptionalFieldNameEnum = {}));\nexport default ProductOptionalFieldNameEnum;\n//# sourceMappingURL=ProductOptionalFieldNameEnum.js.map","var SalesSystemEnum;\n(function (SalesSystemEnum) {\n SalesSystemEnum[\"isell\"] = \"isell\";\n SalesSystemEnum[\"bitboxer\"] = \"bitboxer\";\n SalesSystemEnum[\"navision\"] = \"navision\";\n SalesSystemEnum[\"other\"] = \"other\";\n})(SalesSystemEnum || (SalesSystemEnum = {}));\nexport default SalesSystemEnum;\n//# sourceMappingURL=SalesSystemEnum.js.map","var SalesTypeCodeEnum;\n(function (SalesTypeCodeEnum) {\n SalesTypeCodeEnum[\"aisleAndBin\"] = \"AISLE_AND_BIN\";\n SalesTypeCodeEnum[\"department\"] = \"DEPARTMENT\";\n SalesTypeCodeEnum[\"contactStaff\"] = \"CONTACT_STAFF\"; // WAREHOUSE - Prev full_serve/dds\n})(SalesTypeCodeEnum || (SalesTypeCodeEnum = {}));\nexport default SalesTypeCodeEnum;\n//# sourceMappingURL=SalesTypeCodeEnum.js.map","var SheetAlignmentEnum;\n(function (SheetAlignmentEnum) {\n SheetAlignmentEnum[\"left\"] = \"left\";\n SheetAlignmentEnum[\"right\"] = \"right\";\n})(SheetAlignmentEnum || (SheetAlignmentEnum = {}));\nexport default SheetAlignmentEnum;\n//# sourceMappingURL=SheetAlignmentEnum.js.map","var StoreAvailabilityDataSourceEnum;\n(function (StoreAvailabilityDataSourceEnum) {\n StoreAvailabilityDataSourceEnum[\"disabled\"] = \"disabled\";\n StoreAvailabilityDataSourceEnum[\"DEXF\"] = \"DEXF\";\n})(StoreAvailabilityDataSourceEnum || (StoreAvailabilityDataSourceEnum = {}));\nexport default StoreAvailabilityDataSourceEnum;\n//# sourceMappingURL=StoreAvailabilityDataSourceEnum.js.map","var StoreAvailabilityProbabilityEnum;\n(function (StoreAvailabilityProbabilityEnum) {\n StoreAvailabilityProbabilityEnum[\"highInStock\"] = \"HIGH_IN_STOCK\";\n StoreAvailabilityProbabilityEnum[\"mediumInStock\"] = \"MEDIUM_IN_STOCK\";\n StoreAvailabilityProbabilityEnum[\"lowInStock\"] = \"LOW_IN_STOCK\";\n StoreAvailabilityProbabilityEnum[\"someLowOrOutOfStock\"] = \"SOME_LOW_OR_OUT_OF_STOCK\";\n StoreAvailabilityProbabilityEnum[\"outOfStock\"] = \"OUT_OF_STOCK\";\n StoreAvailabilityProbabilityEnum[\"notSoldAtStore\"] = \"NOT_SOLD_AT_STORE\";\n /** Single product - will show caption text for StoreSelector. */\n StoreAvailabilityProbabilityEnum[\"orderItemSingle\"] = \"ORDER_ITEM_SINGLE\";\n /** Multipe products - caption text for StoreSelector should be hidden. */\n StoreAvailabilityProbabilityEnum[\"orderItemMultiple\"] = \"ORDER_ITEM_MULTIPLE\";\n})(StoreAvailabilityProbabilityEnum || (StoreAvailabilityProbabilityEnum = {}));\nexport default StoreAvailabilityProbabilityEnum;\n//# sourceMappingURL=StoreAvailabilityProbabilityEnum.js.map","var StoreBuTypeEnum;\n(function (StoreBuTypeEnum) {\n StoreBuTypeEnum[\"ecommerce\"] = \"E-commerce\";\n StoreBuTypeEnum[\"store\"] = \"Store\";\n StoreBuTypeEnum[\"office\"] = \"Office\";\n StoreBuTypeEnum[\"smallStore\"] = \"Small Store\";\n StoreBuTypeEnum[\"shop\"] = \"Shop\";\n})(StoreBuTypeEnum || (StoreBuTypeEnum = {}));\nexport default StoreBuTypeEnum;\n//# sourceMappingURL=StoreBuTypeEnum.js.map","var StoreDataSourceEnum;\n(function (StoreDataSourceEnum) {\n StoreDataSourceEnum[\"iows\"] = \"IOWS\";\n StoreDataSourceEnum[\"dexf\"] = \"DEXF\";\n})(StoreDataSourceEnum || (StoreDataSourceEnum = {}));\nexport default StoreDataSourceEnum;\n//# sourceMappingURL=StoreDataSourceEnum.js.map","var TemporaryPricePeriodEnum;\n(function (TemporaryPricePeriodEnum) {\n TemporaryPricePeriodEnum[\"periodStartAndEnd\"] = \"PeriodStartAndEnd\";\n TemporaryPricePeriodEnum[\"periodEnd\"] = \"PeriodEnd\";\n TemporaryPricePeriodEnum[\"periodNone\"] = \"PeriodNone\";\n})(TemporaryPricePeriodEnum || (TemporaryPricePeriodEnum = {}));\nexport default TemporaryPricePeriodEnum;\n//# sourceMappingURL=TemporaryPricePeriodEnum.js.map","var ThemeBreakpointEnum;\n(function (ThemeBreakpointEnum) {\n ThemeBreakpointEnum[\"small\"] = \"small\";\n ThemeBreakpointEnum[\"medium\"] = \"medium\";\n ThemeBreakpointEnum[\"large\"] = \"large\";\n ThemeBreakpointEnum[\"xlarge\"] = \"xlarge\";\n ThemeBreakpointEnum[\"xxlarge\"] = \"xxlarge\";\n})(ThemeBreakpointEnum || (ThemeBreakpointEnum = {}));\nexport default ThemeBreakpointEnum;\n//# sourceMappingURL=ThemeBreakpointEnum.js.map","var ThemeBreakpointIndexEnum;\n(function (ThemeBreakpointIndexEnum) {\n ThemeBreakpointIndexEnum[ThemeBreakpointIndexEnum[\"small\"] = 0] = \"small\";\n ThemeBreakpointIndexEnum[ThemeBreakpointIndexEnum[\"medium\"] = 1] = \"medium\";\n ThemeBreakpointIndexEnum[ThemeBreakpointIndexEnum[\"large\"] = 2] = \"large\";\n ThemeBreakpointIndexEnum[ThemeBreakpointIndexEnum[\"xlarge\"] = 3] = \"xlarge\";\n ThemeBreakpointIndexEnum[ThemeBreakpointIndexEnum[\"xxlarge\"] = 4] = \"xxlarge\"; // Kiosk size\n})(ThemeBreakpointIndexEnum || (ThemeBreakpointIndexEnum = {}));\nexport default ThemeBreakpointIndexEnum;\n//# sourceMappingURL=ThemeBreakpointIndexEnum.js.map","var ThemeFontStyleTypeEnum;\n(function (ThemeFontStyleTypeEnum) {\n ThemeFontStyleTypeEnum[\"bodySmall\"] = \"bodySmall\";\n ThemeFontStyleTypeEnum[\"bodyMedium\"] = \"bodyMedium\";\n ThemeFontStyleTypeEnum[\"bodyLarge\"] = \"bodyLarge\";\n ThemeFontStyleTypeEnum[\"bodyXLarge\"] = \"bodyXLarge\";\n ThemeFontStyleTypeEnum[\"headingXSmall\"] = \"headingXSmall\";\n ThemeFontStyleTypeEnum[\"headingSmall\"] = \"headingSmall\";\n ThemeFontStyleTypeEnum[\"headingMedium\"] = \"headingMedium\";\n ThemeFontStyleTypeEnum[\"headingLarge\"] = \"headingLarge\";\n ThemeFontStyleTypeEnum[\"headingXLarge\"] = \"headingXLarge\";\n ThemeFontStyleTypeEnum[\"priceXSmall\"] = \"priceXSmall\";\n ThemeFontStyleTypeEnum[\"priceSmall\"] = \"priceSmall\";\n ThemeFontStyleTypeEnum[\"priceMedium\"] = \"priceMedium\";\n ThemeFontStyleTypeEnum[\"priceLarge\"] = \"priceLarge\";\n ThemeFontStyleTypeEnum[\"priceXLarge\"] = \"priceXLarge\";\n ThemeFontStyleTypeEnum[\"priceXXLarge\"] = \"priceXXLarge\";\n})(ThemeFontStyleTypeEnum || (ThemeFontStyleTypeEnum = {}));\nexport default ThemeFontStyleTypeEnum;\n//# sourceMappingURL=ThemeFontStyleTypeEnum.js.map","var ZipAvailabilityDataSourceEnum;\n(function (ZipAvailabilityDataSourceEnum) {\n ZipAvailabilityDataSourceEnum[\"disabled\"] = \"disabled\";\n ZipAvailabilityDataSourceEnum[\"DEXF\"] = \"DEXF\";\n})(ZipAvailabilityDataSourceEnum || (ZipAvailabilityDataSourceEnum = {}));\nexport default ZipAvailabilityDataSourceEnum;\n//# sourceMappingURL=ZipAvailabilityDataSourceEnum.js.map","var ZipAvailabilityProbabilityEnum;\n(function (ZipAvailabilityProbabilityEnum) {\n ZipAvailabilityProbabilityEnum[\"highInStock\"] = \"HIGH_IN_STOCK\";\n ZipAvailabilityProbabilityEnum[\"mediumInStock\"] = \"MEDIUM_IN_STOCK\";\n ZipAvailabilityProbabilityEnum[\"lowInStock\"] = \"LOW_IN_STOCK\";\n ZipAvailabilityProbabilityEnum[\"outOfStock\"] = \"OUT_OF_STOCK\";\n ZipAvailabilityProbabilityEnum[\"notInRange\"] = \"NOT_IN_RANGE\";\n ZipAvailabilityProbabilityEnum[\"notSoldTemp\"] = \"NOT_SOLD_TEMP\";\n})(ZipAvailabilityProbabilityEnum || (ZipAvailabilityProbabilityEnum = {}));\nexport default ZipAvailabilityProbabilityEnum;\n//# sourceMappingURL=ZipAvailabilityProbabilityEnum.js.map","var ZipValidationDataSourceEnum;\n(function (ZipValidationDataSourceEnum) {\n ZipValidationDataSourceEnum[\"disabled\"] = \"disabled\";\n ZipValidationDataSourceEnum[\"DEXF\"] = \"DEXF\";\n})(ZipValidationDataSourceEnum || (ZipValidationDataSourceEnum = {}));\nexport default ZipValidationDataSourceEnum;\n//# sourceMappingURL=ZipValidationDataSourceEnum.js.map","export default Object.freeze({\n authentication: 'authentication',\n localization: 'localization',\n translations: 'translations',\n product: 'product',\n storeAvailability: 'storeAvailability',\n store: 'store'\n});\n//# sourceMappingURL=CacheStoreType.js.map","var ExceptionTypeEnum;\n(function (ExceptionTypeEnum) {\n ExceptionTypeEnum[\"platformComponentElement\"] = \"platformComponentElement\";\n ExceptionTypeEnum[\"platform\"] = \"platform\";\n ExceptionTypeEnum[\"componentElement\"] = \"componentElement\";\n ExceptionTypeEnum[\"component\"] = \"component\";\n ExceptionTypeEnum[\"service\"] = \"service\";\n ExceptionTypeEnum[\"generic\"] = \"generic\";\n ExceptionTypeEnum[\"serverErrorResponse\"] = \"serverErrorResponse\";\n ExceptionTypeEnum[\"connectionProblem\"] = \"connectionProblem\";\n ExceptionTypeEnum[\"unableToParseServerResponse\"] = \"unableToParseServerResponse\";\n ExceptionTypeEnum[\"shoppingCart\"] = \"shoppingCart\";\n})(ExceptionTypeEnum || (ExceptionTypeEnum = {}));\nexport default ExceptionTypeEnum;\n//# sourceMappingURL=ExceptionTypeEnum.js.map","/**\n * Custom exception.\n */\nexport default class AbstractException extends Error {\n}\n//# sourceMappingURL=AbstractException.js.map","import AbstractException from '../AbstractException.js';\nimport ExceptionTypeEnum from '../enums/ExceptionTypeEnum.js';\n/**\n * Custom exception.\n */\nexport default class ComponentElementException extends AbstractException {\n /**\n * Class constructor.\n *\n * @param element Element.\n * @param message The error message.\n */\n constructor(element, message) {\n super(element.tagName + ' => ' + message);\n this.exceptionType = ExceptionTypeEnum.componentElement;\n this.name = 'ComponentElementException';\n this.elementTagName = element.tagName;\n }\n}\n//# sourceMappingURL=ComponentElementException.js.map","import AbstractException from '../AbstractException.js';\nimport ExceptionTypeEnum from '../enums/ExceptionTypeEnum.js';\n/**\n * Custom exception.\n */\nexport default class ComponentException extends AbstractException {\n constructor() {\n super(...arguments);\n this.exceptionType = ExceptionTypeEnum.component;\n this.name = 'ComponentException';\n }\n}\n//# sourceMappingURL=ComponentException.js.map","import AbstractException from '../AbstractException.js';\nimport ExceptionTypeEnum from '../enums/ExceptionTypeEnum.js';\n/**\n * Custom exception.\n */\nexport default class ConnectionProblemException extends AbstractException {\n /**\n * Class constructor.\n *\n * @param requestInfo Request info.\n * @param message Message.\n */\n constructor(requestInfo, message) {\n super(`Connection to \"${requestInfo.toString()}\" failed.${message ? ` Error: ${message}` : ''}`);\n this.exceptionType = ExceptionTypeEnum.connectionProblem;\n this.name = 'ConnectionProblemException';\n this.requestInfo = requestInfo;\n }\n}\n//# sourceMappingURL=ConnectionProblemException.js.map","import AbstractException from '../AbstractException.js';\nimport ExceptionTypeEnum from '../enums/ExceptionTypeEnum.js';\n/**\n * Custom exception.\n */\nexport default class Exception extends AbstractException {\n constructor() {\n super(...arguments);\n this.exceptionType = ExceptionTypeEnum.generic;\n this.name = 'Exception';\n }\n}\n//# sourceMappingURL=Exception.js.map","import AbstractException from '../AbstractException.js';\nimport ExceptionTypeEnum from '../enums/ExceptionTypeEnum.js';\n/**\n * Custom exception.\n */\nexport default class ServerErrorResponseException extends AbstractException {\n /**\n * Class constructor.\n *\n * @param response Server response.\n * @param message Message.\n */\n constructor(response, message) {\n super(`Failed to fetch from \"${response.url}\". Server responded with ${response.status} ${response.statusText}.${message ? ` Error: ${message}` : ''}`);\n this.exceptionType = ExceptionTypeEnum.serverErrorResponse;\n this.name = 'ServerErrorResponseException';\n this.serverResponse = response;\n }\n}\n//# sourceMappingURL=ServerErrorResponseException.js.map","import AbstractException from '../AbstractException.js';\nimport ExceptionTypeEnum from '../enums/ExceptionTypeEnum.js';\n/**\n * Custom exception.\n */\nexport default class ServiceException extends AbstractException {\n constructor() {\n super(...arguments);\n this.exceptionType = ExceptionTypeEnum.service;\n this.name = 'ServiceException';\n }\n}\n//# sourceMappingURL=ServiceException.js.map","import AbstractException from '../AbstractException.js';\nimport ExceptionTypeEnum from '../enums/ExceptionTypeEnum.js';\n/**\n * Custom exception.\n */\nexport default class ShoppingCartException extends AbstractException {\n /**\n * Class constructor.\n *\n * @param failedShoppingItems Failed shopping items from the server. Probably from the NifApi when add to cart request fails.\n * @param errorList Expected errors from the Cart API.\n */\n constructor(failedShoppingItems, errorList) {\n super(`Error when trying to add items to cart. ${failedShoppingItems ? 'Article errors: ' + JSON.stringify(failedShoppingItems) : ''}`);\n this.exceptionType = ExceptionTypeEnum.shoppingCart;\n this.name = 'ShoppingCartException';\n this.failedShoppingItems = Array();\n this.errorList = Array();\n this.failedShoppingItems = failedShoppingItems;\n this.errorList = errorList;\n }\n}\n//# sourceMappingURL=ShoppingCartException.js.map","import AbstractException from '../AbstractException.js';\nimport ExceptionTypeEnum from '../enums/ExceptionTypeEnum.js';\n/**\n * Custom exception.\n */\nexport default class UnableToParseServerResponseException extends AbstractException {\n /**\n * Class constructor.\n *\n * @param response Server response.\n * @param message Message.\n */\n constructor(response, message) {\n super(`Unable to parse response from \"${response.url}\". Server responded with ${response.status} ${response.statusText}.${message ? ` Error: ${message}` : ''}`);\n this.exceptionType = ExceptionTypeEnum.unableToParseServerResponse;\n this.name = 'UnableToParseServerResponseException';\n this.serverResponse = response;\n }\n}\n//# sourceMappingURL=UnableToParseServerResponseException.js.map","/**\n *\n */\nexport default class LocalizedInformationAlternateLanguage {\n /**\n * Gets the current alternate languages as an array.\n *\n * @param settings ...\n * @param settings.localisation ...\n * @param settings.localisation.alternateLanguages ...\n * @param locale ...\n * @returns Current language options.\n */\n static getAlternateLanguages(settings, locale) {\n if (settings) {\n const [, country] = locale.split('-');\n const alternateLanguages = 'localisation' in settings\n ? settings.localisation.alternateLanguages\n : settings.localization.alternateLanguages;\n return alternateLanguages\n .split(';')\n .reduce((accumulator, language) => {\n const [value, label] = language.split(':');\n if (label) {\n accumulator.push({ locale: `${value.toLowerCase()}-${country}`, label });\n }\n return accumulator;\n }, []);\n }\n return [];\n }\n}\n//# sourceMappingURL=LocalizedInformationAlternateLanguage.js.map","/**\n * Easings are taken from: https://gist.github.com/gre/1650294.\n */\nconst EASINGS = {\n easeInOutCubic: (t) => {\n return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;\n }\n};\n/**\n * This class is used for creating an animation with an easing.\n */\nexport default class EasingAnimation {\n constructor() {\n this.startValue = 0; // Start value\n this.endValue = 20; // End value\n this.easingType = 'easeInOutCubic'; // Type of easing\n this.animationDuration = 500; // Animation duration in ms\n this.frameInterval = 20; // Min time between frames in ms\n this.isRunning = false;\n this.frames = null;\n this.value = 0;\n this.animationStartTime = 0;\n this.lastFrame = 0;\n this.animationFrameId = null;\n this.events = {\n frame: [],\n end: []\n };\n this.callback = () => {\n // Do nothing\n }; // Callback to be called between each iteration\n }\n /**\n * Adds an event listener.\n *\n * @param eventName Event name (frame, end).\n * @param callback Callback to be called.\n */\n on(eventName, callback) {\n this.events[eventName].push(callback);\n }\n /**\n * Removes an event listener.\n *\n * @param eventName Event name (frame, end).\n * @param callback Callback to be called.\n */\n off(eventName, callback) {\n const index = this.events[eventName].indexOf(callback);\n if (index > -1) {\n this.events[eventName].splice(index, 1);\n }\n }\n /**\n * Triggers an event.\n *\n * @param eventName Event name (frame, end).\n * @param data Data to send to the callback.\n */\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any\n trigger(eventName, data) {\n for (const callback of this.events[eventName]) {\n callback(data);\n }\n }\n /**\n * Starts the animation.\n */\n start() {\n if (this.animationFrameId)\n cancelAnimationFrame(this.animationFrameId);\n this.isRunning = true;\n this.value = this.startValue;\n this.animationStartTime = performance.now();\n this.animationFrameId = requestAnimationFrame(this.animate.bind(this));\n }\n /**\n * Stops the animation.\n */\n stop() {\n if (this.isRunning) {\n this.isRunning = false;\n if (this.animationFrameId)\n cancelAnimationFrame(this.animationFrameId);\n this.trigger('end', this.value);\n }\n }\n /**\n * Calculate eased value, from start value to end value, based on percent of progress.\n *\n * @param startValue Initial value for easing.\n * @param endValue Final value for easing.\n * @param progress Progress of animation [0 to 1].\n * @returns New value based on easing and progress.\n */\n calculateValue(startValue, endValue, progress) {\n let newValue = 0;\n if (startValue < endValue) {\n newValue = startValue + (endValue - startValue) * EASINGS.easeInOutCubic(progress);\n }\n else {\n newValue = startValue - (startValue - endValue) * EASINGS.easeInOutCubic(progress);\n }\n if (startValue === Math.round(startValue) && endValue === Math.round(endValue)) {\n newValue = Math.round(newValue);\n }\n if (progress > 1) {\n newValue = endValue;\n }\n return newValue;\n }\n /**\n * Animation frame - callback passed to rAF.\n *\n * @param now Current time when rAF start to fire callback.\n */\n animate(now) {\n const animationElapsedTime = now - this.animationStartTime;\n const frameElapsedTime = now - this.lastFrame;\n this.value = this.calculateValue(this.startValue, this.endValue, animationElapsedTime / this.animationDuration);\n if (animationElapsedTime > this.animationDuration) {\n this.trigger('frame', this.endValue);\n this.stop();\n }\n else {\n this.animationFrameId = requestAnimationFrame(this.animate.bind(this));\n if (frameElapsedTime > this.frameInterval) {\n this.trigger('frame', this.value);\n this.lastFrame = now - (frameElapsedTime % this.frameInterval);\n }\n }\n }\n}\n//# sourceMappingURL=EasingAnimation.js.map","import { SalesTypeCodeEnum, StoreAvailabilityProbabilityEnum } from '@inter-ikea-kompis/enums';\n/**\n * Availability utility.\n */\nexport default class AvailabilityUtility {\n /**\n * Returns the availability status for the supplied product(s).\n *\n * There are four possible cases for availability.\n * Only one product exists.\n * Several storeAvailabilities exists, where the type of the storeAvailabilities is the same.\n * Several storeAvailabilities exists, where the type of the storeAvailabilities is different.\n * Null, if something unexpected occurs.\n *\n * @param availabilities Store availability information for individual products.\n */\n static getStoreAvailabilityStatus(availabilities) {\n if (availabilities.length === 1) {\n return this.getSingleAvailability(availabilities[0]);\n }\n const storeAvailabilities = this.mapAvailabiltiesToEnum(availabilities);\n if (storeAvailabilities.length === 0) {\n return null;\n }\n const findStoreAvailabilityWithMatchingTypes = this.findStoreAvailabilityWithMatchingTypes(storeAvailabilities);\n if (findStoreAvailabilityWithMatchingTypes) {\n return findStoreAvailabilityWithMatchingTypes;\n }\n const findAnyStoreAvailabilityType = this.findAnyStoreAvailabilityType(storeAvailabilities);\n if (findAnyStoreAvailabilityType) {\n return findAnyStoreAvailabilityType;\n }\n return null;\n }\n /**\n * Returns status indicator color.\n *\n * @param storeAvailability Store availability.\n * @returns Status indicator color.\n */\n static getStoreAvailabilityStatusColor(storeAvailability) {\n const availability = this.getStoreAvailabilty(storeAvailability);\n if (availability) {\n return this.getStoreAvailabilityColor(availability);\n }\n return null;\n }\n /**\n * Returns status indicator color for a given availability status.\n *\n * @param availabilityStatus ...\n * @returns Status indicator color.\n */\n static getStoreAvailabilityColor(availabilityStatus) {\n switch (availabilityStatus) {\n case StoreAvailabilityProbabilityEnum.highInStock:\n return 'green';\n case StoreAvailabilityProbabilityEnum.mediumInStock:\n case StoreAvailabilityProbabilityEnum.lowInStock:\n case StoreAvailabilityProbabilityEnum.someLowOrOutOfStock:\n return 'orange';\n case StoreAvailabilityProbabilityEnum.outOfStock:\n case StoreAvailabilityProbabilityEnum.notSoldAtStore:\n return 'red';\n case StoreAvailabilityProbabilityEnum.orderItemSingle:\n case StoreAvailabilityProbabilityEnum.orderItemMultiple:\n return 'grey';\n default:\n return null;\n }\n }\n static getStoreAvailabilityForProduct(options) {\n const { product, storeAvailabilities } = options;\n if (!product.content || !product.valid || !storeAvailabilities) {\n return null;\n }\n return (storeAvailabilities.find((storeAvailability) => {\n return (product.content?.itemNoLocal === storeAvailability.content.itemNo ||\n product.content?.itemNoGlobal === storeAvailability.content.itemNo);\n }) || null);\n }\n /**\n * Returns status indicator label.\n *\n * @param options Options.\n * @param options.translations Localized information.\n * @param options.storeAvailability Store availability.\n * @returns Status indicator label.\n */\n static getStoreAvailabilityLabel(options) {\n const status = this.getStoreAvailabilty(options.storeAvailability);\n return AvailabilityUtility.getStoreAvailabilityTranslation(status, options.translations);\n }\n /**\n * Returns the store availability translation.\n *\n * @param availabilityStatus ...\n * @param translations ...\n * @returns Store availability translation string.\n */\n static getStoreAvailabilityTranslation(availabilityStatus, translations) {\n switch (availabilityStatus) {\n case StoreAvailabilityProbabilityEnum.highInStock:\n return translations.storeAvailabilityInStock;\n case StoreAvailabilityProbabilityEnum.someLowOrOutOfStock:\n return translations.storeAvailabilitySomeLowOrOutOfStock;\n case StoreAvailabilityProbabilityEnum.mediumInStock:\n case StoreAvailabilityProbabilityEnum.lowInStock:\n return translations.storeAvailabilityLowInStock;\n case StoreAvailabilityProbabilityEnum.outOfStock:\n return translations.storeAvailabilityOutOfStock;\n case StoreAvailabilityProbabilityEnum.notSoldAtStore:\n return translations.storeAvailabilityNotSoldAtStore;\n case StoreAvailabilityProbabilityEnum.orderItemSingle:\n case StoreAvailabilityProbabilityEnum.orderItemMultiple:\n return translations.storeAvailabilityOrderItems;\n default:\n return null;\n }\n }\n /**\n * Returns true if any of the provided availabilities require contacting\n * staff. Otherwise returns false. If an item has multiple sales locations all\n * of them must be \"contactStaff\" for it to be considered full serve.\n *\n * @param availabilities Store availability information for individual\n * products.\n */\n static hasAnyFullServeAvailability(availabilities) {\n return availabilities.some((availability) => availability.content.cashCarry?.salesLocations?.every(this.salesLocationIsFullServe));\n }\n static salesLocationIsFullServe(salesLocation) {\n const isContactStaff = salesLocation.type === SalesTypeCodeEnum.contactStaff;\n const isMissingLocation = salesLocation.type === SalesTypeCodeEnum.department && !salesLocation.departmentName;\n return isContactStaff || isMissingLocation;\n }\n static getSingleAvailability(storeAvailability) {\n if (storeAvailability.content.cashCarry?.inRange === false) {\n if (storeAvailability.content.homeDelivery?.inRange === true) {\n return StoreAvailabilityProbabilityEnum.orderItemSingle;\n }\n return StoreAvailabilityProbabilityEnum.notSoldAtStore;\n }\n return storeAvailability.content?.cashCarry?.messageType ?? null;\n }\n /**\n * Returns status indicator enum.\n *\n * @param storeAvailability Store availability.\n * @returns StoreAvailabilityProbabilityEnum | null.\n */\n static getStoreAvailabilty(storeAvailability // Prop name and type not to introduce a breaking change from originally only supporting one availabiltity\n ) {\n if (Array.isArray(storeAvailability)) {\n return this.getStoreAvailabilityStatus(storeAvailability);\n }\n return this.getStoreAvailabilityStatus([storeAvailability]);\n }\n /**\n * Maps the data returned from DEXF to our StoreAvailabilityProbabilityEnum[].\n * Special business cases are also handled with this function.\n *\n * @param availabilities IStoreAvailability[].\n */\n static mapAvailabiltiesToEnum(availabilities) {\n const { notSoldAtStore } = StoreAvailabilityProbabilityEnum;\n return availabilities\n .map((storeAvailability) => {\n if (storeAvailability.content.cashCarry?.inRange === false) {\n if (storeAvailability.content.homeDelivery?.inRange === true) {\n return StoreAvailabilityProbabilityEnum.orderItemSingle;\n }\n return notSoldAtStore;\n }\n return storeAvailability.content.cashCarry?.messageType;\n })\n .filter((type) => {\n return type !== undefined && Object.values(StoreAvailabilityProbabilityEnum).includes(type);\n });\n }\n /**\n * Returns the matching StoreAvailabilityProbabilityEnum, see StoreAvailability flowchart for a clearer picture.\n * Https://i-p-e-x.atlassian.net/wiki/spaces/KOMPIS/pages/36238426201/Component+flow+charts#Store-Availability.\n *\n * @param storeAvailabilities StoreAvailabilityProbabilityEnum[].\n */\n static findStoreAvailabilityWithMatchingTypes(storeAvailabilities) {\n const { highInStock, mediumInStock, lowInStock, outOfStock, notSoldAtStore, orderItemSingle, orderItemMultiple } = StoreAvailabilityProbabilityEnum;\n if (storeAvailabilities.every((type) => type === orderItemSingle)) {\n return orderItemMultiple;\n }\n else if (storeAvailabilities.every((type) => type === notSoldAtStore)) {\n return notSoldAtStore;\n }\n else if (storeAvailabilities.every((type) => type === outOfStock || type === notSoldAtStore)) {\n return outOfStock;\n }\n else if (storeAvailabilities.some((type) => type === orderItemSingle)) {\n return orderItemMultiple;\n }\n else if (storeAvailabilities.every((type) => type === lowInStock || type === mediumInStock)) {\n return lowInStock;\n }\n else if (storeAvailabilities.every((type) => type === highInStock)) {\n return highInStock;\n }\n return null;\n }\n /**\n * Returns the matching StoreAvailabilityProbabilityEnum, see StoreAvailability flowchart for a clearer picture.\n * Https://i-p-e-x.atlassian.net/wiki/spaces/KOMPIS/pages/36238426201/Component+flow+charts#Store-Availability.\n *\n * @param storeAvailabilities StoreAvailabilityProbabilityEnum[].\n */\n static findAnyStoreAvailabilityType(storeAvailabilities) {\n if (storeAvailabilities.some((type) => type === StoreAvailabilityProbabilityEnum.lowInStock ||\n type === StoreAvailabilityProbabilityEnum.outOfStock ||\n type === StoreAvailabilityProbabilityEnum.notSoldAtStore ||\n type === StoreAvailabilityProbabilityEnum.mediumInStock)) {\n return StoreAvailabilityProbabilityEnum.someLowOrOutOfStock;\n }\n return null;\n }\n}\n//# sourceMappingURL=AvailabilityUtility.js.map","/**\n * Cache store manager.\n */\nexport default class CacheStore {\n constructor() {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.stores = {};\n }\n /**\n * Returns store.\n *\n * @param name Name.\n * @returns Map.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getStore(name) {\n this.stores[name] = this.stores[name] || new Map();\n return this.stores[name];\n }\n}\n//# sourceMappingURL=CacheStore.js.map","import CacheStore from './CacheStore.js';\n/**\n * Cache store manager.\n */\nexport default class GlobalCacheStore extends CacheStore {\n /**\n * Constructor.\n *\n * @param [global] Global/Window object.\n */\n constructor(global) {\n super();\n this.global = global || window;\n }\n /**\n * Returns store.\n *\n * @param name Name.\n * @returns Map.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getStore(name) {\n this.global.$ikeaKompisCacheStores = this.global.$ikeaKompisCacheStores || {};\n this.global.$ikeaKompisCacheStores[name] =\n this.global.$ikeaKompisCacheStores[name] || new Map();\n return this.global.$ikeaKompisCacheStores[name];\n }\n}\n//# sourceMappingURL=GlobalCacheStore.js.map","/**\n * Class that interprets color formats and make operations on them.\n */\nexport default class ColorConverter {\n static multiply(colorA, colorB) {\n return this.convertToHex(this.multiplyColors(this.interpretText(colorA), this.interpretText(colorB)));\n }\n static multiplyOpacity(color, opacity) {\n const opacityColor = {\n red: 1,\n green: 1,\n blue: 1,\n opacity: opacity\n };\n return this.convertToHex(this.multiplyColors(this.interpretText(color), opacityColor));\n }\n static interpretText(str) {\n if (str.startsWith('rgba(')) {\n const results = /rgba\\((.+)\\)/g.exec(str)[1];\n const list = results.split(',');\n return {\n // 0 - 255\n red: this.bitsToNumber(list[0]),\n green: this.bitsToNumber(list[1]),\n blue: this.bitsToNumber(list[2]),\n opacity: list.length === 4 ? Number(list[3]) : 1\n };\n }\n if (str.startsWith('#')) {\n if (str.length === 4) {\n // 0 - 16\n return {\n red: this.hexToNumber(str.substring(1, 2)),\n green: this.hexToNumber(str.substring(2, 3)),\n blue: this.hexToNumber(str.substring(3, 4)),\n opacity: 1\n };\n }\n else if (str.length === 5) {\n // 0 - 16\n return {\n red: this.hexToNumber(str.substring(1, 2)),\n green: this.hexToNumber(str.substring(2, 3)),\n blue: this.hexToNumber(str.substring(3, 4)),\n opacity: this.hexToNumber(str.substring(4, 5))\n };\n }\n else if (str.length === 7) {\n // 0 - 255\n return {\n red: this.hexToNumber(str.substring(1, 3)),\n green: this.hexToNumber(str.substring(3, 5)),\n blue: this.hexToNumber(str.substring(5, 7)),\n opacity: 1\n };\n }\n else if (str.length === 9) {\n // 0 - 255\n return {\n red: this.hexToNumber(str.substring(1, 3)),\n green: this.hexToNumber(str.substring(3, 5)),\n blue: this.hexToNumber(str.substring(5, 7)),\n opacity: this.hexToNumber(str.substring(7, 9))\n };\n }\n }\n throw new Error(\"Color not in rgba or hex format. Color must start with either 'rgba(' or '#'\");\n }\n static convertToHex(color) {\n return ('#' +\n [\n this.numberToHexBits(color.red),\n this.numberToHexBits(color.green),\n this.numberToHexBits(color.blue),\n this.numberToHexBits(color.opacity)\n ].join(''));\n }\n static multiplyColors(a, b) {\n return {\n red: a.red * b.red,\n green: a.green * b.green,\n blue: a.blue * b.blue,\n opacity: a.opacity * b.opacity\n };\n }\n /**\n * E.g. \"cc\" -> 0.8.\n *\n * @param hex ...\n */\n static hexToNumber(hex) {\n if (hex.length === 2) {\n return parseInt(hex, 16) / 255;\n }\n return parseInt(hex, 16) / 15;\n }\n /**\n * 0 - 255 to 0 - 1.\n *\n * @param bits ...\n */\n static bitsToNumber(bits) {\n return Number(bits) / 255;\n }\n /**\n * E.g. 0.8 -> \"cc\".\n *\n * @param number ...\n */\n static numberToHexBits(number) {\n const results = Math.round(number * 255).toString(16);\n if (results.length === 1) {\n return '0' + results;\n }\n return results;\n }\n}\n//# sourceMappingURL=ColorConverter.js.map","const REPLACERS = [\n [/yyyy|YYYY/, (date) => date.getFullYear()],\n [/yy|YY/, (date) => date.getFullYear().toString().slice(2)],\n ['MM', (date) => DateFormatter.addLeadingZeros(date.getMonth() + 1)],\n ['M', (date) => date.getMonth() + 1],\n ['DD', (date) => DateFormatter.addLeadingZeros(date.getDate())],\n ['D', (date) => date.getDate()],\n ['HH', (date) => DateFormatter.addLeadingZeros(date.getHours())],\n ['H', (date) => date.getHours()],\n ['mm', (date) => DateFormatter.addLeadingZeros(date.getMinutes())],\n ['m', (date) => date.getMinutes()],\n ['ss', (date) => DateFormatter.addLeadingZeros(date.getSeconds())],\n ['s', (date) => date.getSeconds()],\n ['SSS', (date) => date.getMilliseconds()],\n ['SS', (date) => Math.floor(date.getMilliseconds() / 10)],\n ['S', (date) => Math.floor(date.getMilliseconds() / 100)]\n];\n/**\n * Handles formatting of dates.\n */\nexport default class DateFormatter {\n /**\n * Formats a date.\n *\n * @param dateString Date string.\n * @returns Formatted date.\n */\n static isoStringToDate(dateString) {\n return new Date(dateString.replace('Z', ''));\n }\n /**\n * Formats a date object to a date string.\n *\n * @param date Date object or string to pass into the Date constructor.\n * @param [format] Format to use. Default is \"YYYY-MM-DD\".\n * @returns Formatted date.\n */\n static dateToString(date, format = 'YYYY-MM-DD') {\n const parsedDate = date instanceof Date ? date : new Date(date);\n if (isNaN(parsedDate.getTime())) {\n return parsedDate.toString();\n }\n return REPLACERS.reduce((str, [pattern, fnc]) => {\n const arr = str.split(pattern);\n if (arr.length === 1) {\n return arr[0];\n }\n return arr.join(fnc(parsedDate));\n }, format);\n }\n /**\n * Adds leading zeross to a number.\n *\n * @param value Number to add leading zeros to.\n * @returns Number with leading zeros converted to a string.\n */\n static addLeadingZeros(value) {\n value = String(value);\n while (value.length < 2) {\n value = '0' + value;\n }\n return value;\n }\n}\n//# sourceMappingURL=DateFormatter.js.map","/**\n * Handles debouncing.\n */\nexport default class DebounceManager {\n constructor() {\n this.debounces = {};\n }\n /**\n * Sets a debounce.\n *\n * @param name Name.\n * @param callback Callback.\n * @param timeout Timeout.\n */\n set(name, callback, timeout = 0) {\n this.clear(name);\n this.debounces[name] = window.setTimeout(callback, timeout);\n }\n /**\n * Checks if a debounce exists.\n *\n * @param name Name of debounce.\n * @returns TRUE if debounce exists.\n */\n exists(name) {\n return typeof this.debounces[name] !== 'undefined';\n }\n /**\n * Clears a debounce.\n *\n * @param name Name of debounce.\n */\n clear(name) {\n clearTimeout(this.debounces[name]);\n delete this.debounces[name];\n }\n /**\n * Clears all debounces.\n */\n clearAll() {\n for (const name of Object.keys(this.debounces)) {\n this.clear(name);\n }\n }\n}\n//# sourceMappingURL=DebounceManager.js.map","import { ProductComplianceTechnicalHeadingTypeEnum } from '@inter-ikea-kompis/enums';\nconst ENERGY_CLASSES = {\n 'A+++': 1,\n 'A++': 1,\n 'A+': 1,\n A: 1,\n B: 1,\n C: 1,\n D: 1,\n E: 1\n};\n/**\n * Energy Class Parser.\n */\nexport default class EnergyClassParser {\n /**\n * Parses product and returns energy class.\n *\n * @param product Product item.\n * @returns EnergyClass.\n */\n static parseProduct(product) {\n const complianceTechnicalEnergyFlag = this.parseProductComplianceTechnical(product);\n return complianceTechnicalEnergyFlag\n ? complianceTechnicalEnergyFlag\n : this.parseProductTechnicalInformation(product);\n }\n /**\n * Parses the technicalInformation object array if there is a Energy Efficiency Class header type available.\n *\n * @param product Product item.\n * @returns EnergyClass.\n */\n static parseProductTechnicalInformation(product) {\n if (!product.content?.technicalInformation?.length) {\n return null;\n }\n for (const item of product.content.technicalInformation) {\n if (typeof item.valueMetric === 'string') {\n if (ENERGY_CLASSES[item.valueMetric]) {\n return item.valueMetric;\n }\n }\n }\n return null;\n }\n /**\n * Parses the complianceTechnical object array if there is a Energy Efficiency Class header type available.\n *\n * @param product Product item.\n * @returns EnergyClass.\n */\n static parseProductComplianceTechnical(product) {\n if (!product.content?.complianceTechnical?.length) {\n return null;\n }\n const item = product.content.complianceTechnical.find((value) => value.headingType === ProductComplianceTechnicalHeadingTypeEnum.energyEfficiencyClass);\n if (typeof item?.text === 'string') {\n if (ENERGY_CLASSES[item.text]) {\n return item.text;\n }\n }\n return null;\n }\n}\n//# sourceMappingURL=EnergyClassParser.js.map","import GlobalCacheStore from '../cache/GlobalCacheStore.js';\n/**\n * Id generator for unique id's.\n */\nexport default class IdGenerator {\n constructor(cache = new GlobalCacheStore()) {\n this.cache = cache;\n }\n /**\n * Generates a unique numeric id from the cache.\n *\n * @returns Unique id.\n */\n generateNumericId() {\n const store = this.cache.getStore('IdGenerator');\n const prevId = store.get('id') ?? 0;\n const id = prevId + 1;\n store.set('id', id);\n return id;\n }\n /**\n * Generates a unique id from the cache.\n *\n * @returns Unique id.\n */\n generateId() {\n const id = this.generateNumericId();\n return 'kompis' + id;\n }\n}\n//# sourceMappingURL=IdGenerator.js.map","export default {\n orientation: {\n landscape: 'landscape',\n portrait: 'portrait'\n },\n maxWidth: 1280,\n maxHeightLandscape: 800,\n minWidthLandscape: 800,\n minHeightLandscape: 560,\n maxRatioLandscape: 2,\n deviceType: {\n desktop: 'desktop',\n tablet: 'tablet',\n mobile: 'mobile'\n },\n preferredRatio: {\n landscape: '16/10',\n portrait: '9/16'\n },\n screenWidthLimits: {\n landscape: {\n mobile: 900,\n tablet: 1280\n },\n portrait: {\n mobile: 480,\n tablet: 800\n }\n },\n nwpHeaders: {\n desktop: 82,\n tablet: 72,\n mobile: 56\n },\n unavailableHeight: {\n desktop: 100,\n tablet: 80,\n mobile: 60\n }\n};\n//# sourceMappingURL=IframeConfig.js.map","import EasingAnimation from '../animation/EasingAnimation.js';\nimport IframeConfig from './IframeConfig.js';\nconst DEFAULT_SCROLL_OPTIONS = {\n element: null,\n animate: true,\n center: true,\n minDistance: 200,\n scrollTopMargin: 10\n};\n/**\n * This class is used for calculating the application size when inside an iframe.\n */\nexport default class IframeUtility {\n /**\n * Calculates the application height based on width.\n *\n * @param width Application width.\n * @returns Calculated height.\n */\n static calculateHeight(width) {\n const screen = this.getScreen(width);\n const orientation = screen.orientation;\n const deviceType = this.calculateDeviceType(screen.width, orientation);\n const appWidth = Math.min(width, IframeConfig.maxWidth);\n const availableHeight = this.getAvailableHeight(screen.height, deviceType);\n let height = appWidth / this.getRatio(orientation);\n height = Math.min(height, availableHeight, IframeConfig.maxHeightLandscape);\n if (screen.orientation === IframeConfig.orientation.landscape) {\n height = Math.max(height, this.getMinHeightLandscape(deviceType, appWidth));\n }\n return Math.floor(height);\n }\n /**\n * Returns the device type based on the application size.\n *\n * @returns Device type (mobile, desktop or tablet).\n */\n static getDeviceType() {\n const minMeasurement = Math.min(window.screen.availWidth, window.screen.availHeight);\n return this.calculateDeviceType(minMeasurement, 'portrait');\n }\n /**\n * Returns the current orientation based on width.\n *\n * @param width Application width.\n * @returns Orientation (landscape or portrait).\n */\n static getOrientation(width) {\n return this.getScreen(width).orientation;\n }\n /**\n * Scrolls the parent window to make the element visible.\n *\n * @param options Options object.\n * @param options.element Element to scroll into view.\n * @param [options.animate] TRUE to animate. Default is TRUE.\n * @param [options.center] TRUE to center the element. Default is TRUE.\n * @param [options.minDistance] Minimal distance before scroll will be activated. Default is \"200\" (px).\n * @param [options.scrollTopMargin] Scroll top margin that will be offset from the top of the element when the element height is greater than the screen height. Default is \"10\" (px);.\n * @returns Returns the easing animation if \"animate\" has been set to \"true\".\n */\n static scrollToElement(options) {\n const optionsWithDefault = { ...DEFAULT_SCROLL_OPTIONS, ...options };\n if (this.isInsideIframe() && this.isParentWindowAccessible()) {\n const screenHeight = window.parent.innerHeight;\n const parentScrollPosition = this.getScrollPosition(window.parent);\n const scrollY = parentScrollPosition.y;\n const iframeTop = (window.frameElement?.getBoundingClientRect().top ?? 0) + scrollY;\n const elementTop = optionsWithDefault.element.getBoundingClientRect().top +\n this.getScrollPosition().y +\n iframeTop;\n const elementHeight = optionsWithDefault.element.offsetHeight;\n const centeredElementScrollY = elementHeight > screenHeight\n ? elementTop - optionsWithDefault.scrollTopMargin\n : elementTop - screenHeight / 2 + elementHeight / 2 - optionsWithDefault.scrollTopMargin;\n const elementScrollY = optionsWithDefault.center\n ? centeredElementScrollY\n : elementTop - optionsWithDefault.scrollTopMargin;\n const newScrollY = elementScrollY > 0 ? elementScrollY : 0;\n const distanceY = newScrollY < scrollY ? scrollY - newScrollY : newScrollY - scrollY;\n if (optionsWithDefault.animate) {\n const frames = Math.floor(distanceY / 10);\n if (distanceY > optionsWithDefault.minDistance || elementHeight > screenHeight) {\n const animation = new EasingAnimation();\n animation.on('frame', (y) => window.parent.scrollTo(parentScrollPosition.x, y));\n animation.startValue = scrollY;\n animation.endValue = newScrollY;\n animation.frames = frames;\n animation.start();\n return animation;\n }\n }\n else {\n window.parent.scrollTo(parentScrollPosition.x, newScrollY);\n }\n }\n return null;\n }\n /**\n * Checks if the application is inside an iframe.\n *\n * @returns TRUE if inside an iframe.\n */\n static isInsideIframe() {\n try {\n if (window.parent === window) {\n return false;\n }\n }\n catch (error) {\n // Ignore error\n }\n return true;\n }\n /**\n * Checks if the parent window is accessible and not subject to cross-origin issues.\n *\n * @returns TRU if the parent window is accessible.\n */\n static isParentWindowAccessible() {\n try {\n window.parent.document;\n }\n catch (error) {\n return false;\n }\n return true;\n }\n /**\n * Returns parent scroll position.\n *\n * @param frame Frame object. Defaults to \"window\".\n * @returns Scroll position.\n */\n static getScrollPosition(frame = window) {\n return {\n y: frame.pageYOffset !== undefined\n ? frame.pageYOffset\n : frame.document.documentElement.scrollTop,\n x: frame.pageXOffset !== undefined\n ? frame.pageXOffset\n : frame.document.documentElement.scrollLeft\n };\n }\n /**\n * Returns the current screen data: width, height and orientation.\n *\n * @param width Application width.\n * @returns Screen setup.\n */\n static getScreen(width) {\n /*\n * Some devices may return same availWidth/availHeight despite rotation\n * using given iframe width and assuming that it will not be greater that the actual screen width,\n * we can assume that we are in portrait if the iframe width is smaller or same as the smallest of the values\n */\n if (width <=\n Math.min(window.screen.availWidth, window.screen.availHeight, IframeConfig.minWidthLandscape)) {\n return {\n width: Math.min(window.screen.availWidth, window.screen.availHeight),\n height: Math.max(window.screen.availWidth, window.screen.availHeight),\n orientation: IframeConfig.orientation.portrait\n };\n }\n else {\n return {\n width: Math.max(window.screen.availWidth, window.screen.availHeight),\n height: Math.min(window.screen.availWidth, window.screen.availHeight),\n orientation: IframeConfig.orientation.landscape\n };\n }\n }\n /**\n * Returns the available height.\n *\n * @param screenHeight The screen height.\n * @param deviceType Device type (mobile, desktop or tablet).\n * @returns Available height.\n */\n static getAvailableHeight(screenHeight, deviceType) {\n return screenHeight - IframeConfig.unavailableHeight[deviceType];\n }\n /**\n * Calculates the device type.\n *\n * @param screenWidth The screen width.\n * @param orientation Orientation (portrait or landscape).\n * @returns Device type (mobile, desktop or tablet).\n */\n static calculateDeviceType(screenWidth, orientation) {\n if (screenWidth < IframeConfig.screenWidthLimits[orientation].mobile) {\n // Largest known phone is 736 (iPhone 6+), smallest known tablet is 1024 (iPad)\n return 'mobile';\n }\n if (screenWidth <= IframeConfig.screenWidthLimits[orientation].tablet) {\n // Tablets larger than this may use full desktop ui\n return 'tablet';\n }\n return 'desktop';\n }\n /**\n * Returns the minimal possible height when in landscape.\n *\n * @param deviceType Device type (mobile, desktop or tablet).\n * @param appWidth Application width.\n * @returns Minimal height for landscape.\n */\n static getMinHeightLandscape(deviceType, appWidth) {\n if (deviceType == IframeConfig.deviceType.mobile) {\n return appWidth / IframeConfig.maxRatioLandscape;\n }\n return IframeConfig.minHeightLandscape;\n }\n /**\n * Returns the current ratio.\n *\n * @param orientation Orientation (portrait or landscape).\n * @returns Ratio.\n */\n static getRatio(orientation) {\n const ratio = IframeConfig.preferredRatio[orientation].split('/');\n return parseInt(ratio[0]) / parseInt(ratio[1]);\n }\n}\n//# sourceMappingURL=IframeUtility.js.map","import IframeUtility from './IframeUtility.js';\n/**\n * IframeVisibleArea.\n */\nclass IframeVisibleArea {\n /**\n * Returns bottom, top, left and right.\n *\n * @param overflow Overflow.\n * @returns Position.\n */\n static getArea(overflow) {\n if (!this.isInsideIframe) {\n throw 'IframeVisibleArea only works when it is called from inside an iframe';\n }\n else if (!this.isParentWindowAccessible) {\n throw 'Could not get visible iframe area. Parent window is not accessible.';\n }\n // TODO: Remove header height as we can't calculate it anymore after we removed uiPlatform from settings.\n const headerHeight = 0;\n const pageHeight = document.body.offsetHeight;\n const screenHeight = window.parent.innerHeight;\n if (!window.frameElement) {\n throw new Error('No frameElement available on window');\n }\n const frameRect = window.frameElement.getBoundingClientRect();\n const positionBottom = pageHeight + frameRect.top - screenHeight;\n const position = {\n top: frameRect.top < headerHeight ? -1 * frameRect.top + headerHeight : 0,\n bottom: positionBottom > 0 ? positionBottom : 0\n };\n if (overflow) {\n const pageBodyHeight = 320;\n position.top = frameRect.top < headerHeight ? -1 * frameRect.top + headerHeight : 0;\n position.bottom = positionBottom > 0 ? positionBottom : 0;\n const topOffset = pageHeight - position.bottom - position.top;\n position.top -= topOffset < pageBodyHeight ? pageBodyHeight - topOffset : 0;\n position.top = position.top > 0 ? position.top : 0;\n const bottomOffset = pageHeight - position.bottom - position.top;\n position.bottom -= bottomOffset < pageBodyHeight ? pageBodyHeight - bottomOffset : 0;\n position.bottom = position.bottom > 0 ? position.bottom : 0;\n return position;\n }\n else {\n return position;\n }\n }\n}\nIframeVisibleArea.isInsideIframe = IframeUtility.isInsideIframe();\nIframeVisibleArea.isParentWindowAccessible = IframeUtility.isParentWindowAccessible();\nexport default IframeVisibleArea;\n//# sourceMappingURL=IframeVisibleArea.js.map","import DebounceManager from '../debounce/DebounceManager.js';\nimport IframeUtility from './IframeUtility.js';\nimport IframeVisibleArea from './IframeVisibleArea.js';\n/**\n * IframeVisibleAreaObserver.\n */\nexport default class IframeVisibleAreaObserver {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.callback ...\n * @param options.overflow ...\n * @param options.debounceTime ...\n */\n constructor(options) {\n this.callback = null;\n this.debounce = new DebounceManager();\n this.debounceTime = null;\n this.overflow = false;\n this.isInsideIframe = IframeUtility.isInsideIframe();\n this.isParentWindowAccessible = IframeUtility.isParentWindowAccessible();\n this.updateListener = () => {\n if (!this.callback) {\n return;\n }\n if (this.debounceTime) {\n this.debounce.set('update', this.callback, this.debounceTime);\n }\n else {\n this.callback();\n }\n };\n this.debounceTime = options ? options.debounceTime : null;\n this.overflow = options ? options.overflow : false;\n this.callback = options\n ? () => options.callback(IframeVisibleArea.getArea(this.overflow))\n : null;\n }\n /**\n * Start dispatching update events.\n */\n observe() {\n if (this.isInsideIframe && this.isParentWindowAccessible) {\n window.parent.addEventListener('scroll', this.updateListener);\n window.parent.addEventListener('resize', this.updateListener);\n window.addEventListener('resize', this.updateListener);\n }\n else {\n throw 'Parent window is not accessible or IframeVisibleAreaObserver will only work from within an iframe. Use position: sticky; instead';\n }\n }\n /**\n * Removes listeners.\n */\n disconnect() {\n if (this.isInsideIframe && this.isParentWindowAccessible) {\n window.parent.removeEventListener('scroll', this.updateListener);\n window.parent.removeEventListener('resize', this.updateListener);\n window.removeEventListener('resize', this.updateListener);\n this.debounce.clearAll();\n }\n }\n /**\n * Returns bottom, top, left and right.\n *\n * @returns Position.\n */\n getArea() {\n return IframeVisibleArea.getArea(false);\n }\n}\n//# sourceMappingURL=IframeVisibleAreaObserver.js.map","const AKAMAI_SIZES = {\n '40': 'xxu',\n '80': 'xu',\n '160': 'u',\n '300': 'xxxs',\n '400': 'xxs',\n '500': 'xs',\n '600': 's',\n '700': 'm',\n '750': 'l',\n '900': 'xl',\n '1100': 'xxl',\n '1400': 'xxxl',\n '1600': 'sg',\n '2000': 'g',\n '3000': 'xg',\n '4000': 'xxg'\n};\nconst SIZE_NUMBERS = Object.keys(AKAMAI_SIZES).map((size) => parseInt(size));\n/**\n * Utility for calculating image src.\n */\nexport default class ImageUtility {\n /**\n * Returns Akamai URL for an image.\n *\n * @param url URL of image.\n * @param width Width in pixels.\n * @param [quality] Quality.\n * @returns Akamai URL.\n */\n static getAkamaiImageUrl(url, width, quality) {\n return url + this.getAkamaiQueryString(width, quality);\n }\n /**\n * Returns an Akamai query string based on size.\n *\n * @param width Width of the image in px.\n * @param [quality] Quality.\n * @returns Query string.\n */\n static getAkamaiQueryString(width, quality) {\n return `?f=${this.getAkamaiSize(width)}${quality ? `&q=${quality}` : ''}`;\n }\n /**\n * Get Akamai formatted size.\n *\n * @param width Image width.\n * @returns Size.\n */\n static getAkamaiSize(width) {\n for (const akamaiSize of SIZE_NUMBERS) {\n if (width <= akamaiSize) {\n return AKAMAI_SIZES[akamaiSize.toString()];\n }\n }\n return AKAMAI_SIZES[SIZE_NUMBERS[SIZE_NUMBERS.length - 1].toString()];\n }\n}\n//# sourceMappingURL=ImageUtility.js.map","/**\n * This utility is used for locales.\n */\nexport default class LocaleUtility {\n /**\n * Converts a locale to country and language.\n *\n * @param locale Locale. Example: en-GB.\n * @returns Country and language.\n */\n static getCountryAndLanguage(locale) {\n const list = locale.split('-');\n if (list.length > 1 && list[0].length === 2 && list[1].length === 2) {\n return {\n country: list[1].toLowerCase(),\n language: list[0].toLowerCase()\n };\n }\n return {\n country: null,\n language: null\n };\n }\n}\n//# sourceMappingURL=LocaleUtility.js.map","/**\n * Handles Measurement utilities.\n *\n * @param millimeter ...\n */\nexport default class MeasurementUtility {\n /**\n * Metric measurements to imperial measurements.\n *\n * @param millimeter Number to convert.\n * @param inFeet If it should contain feet.\n * @param withoutMeasureUnit Return with measurement unit or not.\n * @returns Numbers in imperial.\n */\n static metricToImperial(millimeter, inFeet = false, withoutMeasureUnit = false) {\n const inInch = this.roundToEighths(this.millimeterToInch(millimeter));\n let feet = 0;\n let inches = '0';\n if (inFeet) {\n feet = (inInch / 12) << 0;\n inches = this.decimalsToFractions(inInch % 12);\n }\n else {\n inches = this.decimalsToFractions(inInch);\n }\n if (feet !== 0 && inches !== '0') {\n return `${feet} ft ${inches} in`;\n }\n else if (feet !== 0) {\n return `${feet} ft`;\n }\n return withoutMeasureUnit ? inches : `${inches} in`;\n }\n /**\n * Millimeter to inch.\n *\n * @param millimeter Number to convert.\n * @returns Number in Inches.\n */\n static millimeterToInch(millimeter) {\n return millimeter * 0.0393700787;\n }\n /**\n * Round a number to closest eighths.\n *\n * @param inch Number to convert.\n * @returns Number in Inches rounded to closest eights.\n */\n static roundToEighths(inch) {\n return parseFloat((Math.round(inch * 8) / 8).toFixed(3));\n }\n /**\n * Greatest common divisor.\n *\n * @param a Number.\n * @param b Number.\n * @returns Number the greatest common divisor.\n */\n static greatestCommonDivisor(a, b) {\n if (b === 0) {\n return a;\n }\n return this.greatestCommonDivisor(b, a % b);\n }\n /**\n * Decimals to fractions.\n *\n * @param decimals Number e.g 1.125.\n * @returns String the greatest common divisor.\n */\n static decimalsToFractions(decimals) {\n const decimalArray = decimals.toString().split('.');\n if (decimalArray.length === 1) {\n return decimalArray[0];\n }\n const leftDecimalPart = parseInt(decimalArray[0]);\n const rightDecimalPart = decimalArray[1];\n let numerator = parseInt(rightDecimalPart);\n let denominator = 10 ** rightDecimalPart.length;\n const factor = this.greatestCommonDivisor(numerator, denominator);\n numerator /= factor;\n denominator /= factor;\n return leftDecimalPart !== 0\n ? `${leftDecimalPart} ${numerator}/${denominator}`\n : `${numerator}/${denominator}`;\n }\n}\n//# sourceMappingURL=MeasurementUtility.js.map","import { Exception } from '@inter-ikea-kompis/exceptions';\nconst THOUSAND_SEPERATOR_REGEXP = /(\\d+)(\\d{3})/;\n/**\n * This is an internal utility, not meant to be used by planners.\n *\n * Handles formatting of prices.\n */\nexport default class PriceFormatterUtility {\n /**\n * Formats a price.\n * Make sure that you add a dir=\"ltr\" attribute to the HTML, so that '1 400' wont get reversed in morocco.\n *\n * @param amount Price amount.\n * @param priceSettingsOrDexfPriceSettings Price settings from LocalizationService or DEXF settings.\n * @returns Formatted price with currency and spacing. The price formats are joinable by doing: priceFormat.map(price => price.value).join('').\n */\n static format(amount, priceSettingsOrDexfPriceSettings) {\n const localisation = 'localisation' in priceSettingsOrDexfPriceSettings\n ? priceSettingsOrDexfPriceSettings.localisation\n : priceSettingsOrDexfPriceSettings;\n if (typeof amount !== 'number' || isNaN(amount)) {\n throw new Exception('Failed to format price. Invalid number.');\n }\n const numberOfDecimals = localisation.numberOfDecimals;\n if (isNaN(numberOfDecimals) || numberOfDecimals === null) {\n throw new Exception('priceSettings.numberOfDecimals is not a number.');\n }\n const noValueDecimalsString = localisation.noValueDecimalsString === ' ' ? '' : localisation.noValueDecimalsString;\n const fixedAmount = amount.toFixed(numberOfDecimals).split('.'); // Since the number of trailing zeroes is set with the toFixed, the values cannot be integer\n const fraction = fixedAmount.length === 2 ? fixedAmount[1] : `${0}`;\n // Thousand separator\n let integerString = fixedAmount[0];\n if (localisation.currencyCode === 'INR') {\n integerString = this.formatIndianThousandSeperator(integerString);\n }\n else if (localisation.thousandSeparatorEnabled && integerString.length > 3) {\n integerString = this.formatThousandSeperator(integerString, localisation.thousandSeparator);\n }\n // Decimals\n let decimalArray = [];\n if (localisation.replaceNoValueDecimals &&\n typeof noValueDecimalsString === 'string' &&\n Number(fraction) === 0) {\n decimalArray = [noValueDecimalsString];\n }\n else if (localisation.decimalSeparator && numberOfDecimals !== 0) {\n decimalArray = [localisation.decimalSeparator, fraction];\n }\n // List of parts in order\n const priceWithCurrency = [\n {\n type: 'integerPart',\n value: integerString\n }\n ];\n if (decimalArray.length > 0) {\n priceWithCurrency.push({\n type: 'decimalPart',\n value: decimalArray.join('')\n });\n }\n if (localisation.currencyPosition === 'before') {\n if (localisation.symbolSpacing) {\n priceWithCurrency.unshift({\n type: 'spacing',\n value: ' '\n });\n }\n priceWithCurrency.unshift({\n type: 'currency',\n value: localisation.currencySymbol\n });\n }\n else {\n if (localisation.symbolSpacing) {\n priceWithCurrency.push({\n type: 'spacing',\n value: ' '\n });\n }\n priceWithCurrency.push({\n type: 'currency',\n value: localisation.currencySymbol\n });\n }\n return priceWithCurrency;\n }\n /**\n * Returns Indian price with thousand separator.\n *\n * @param integerString Price integer part (no decimals).\n * @returns Indian price with thousand separator.\n */\n static formatIndianThousandSeperator(integerString) {\n const result = [];\n let thousand = '';\n if (integerString.length > 3) {\n thousand = ',' + integerString.substring(integerString.length - 3);\n integerString = integerString.substring(0, integerString.length - 3);\n while (integerString.length > 2) {\n result.unshift(integerString.substring(integerString.length - 2));\n integerString = integerString.substring(0, integerString.length - 2);\n }\n }\n if (integerString.length > 0) {\n result.unshift(integerString);\n }\n return result.join(',') + thousand;\n }\n /**\n * Returns price with thousand separator.\n *\n * @param integerString Price integer part (no decimals).\n * @param thousandSeparator Thousand separator.\n * @returns Price with thousand separator.\n */\n static formatThousandSeperator(integerString, thousandSeparator) {\n const separator = thousandSeparator || ' ';\n while (THOUSAND_SEPERATOR_REGEXP.test(integerString)) {\n integerString = integerString.replace(THOUSAND_SEPERATOR_REGEXP, '$1' + separator + '$2');\n }\n return integerString;\n }\n}\n//# sourceMappingURL=PriceFormatterUtility.js.map","/**\n * Product price information summary transformer.\n */\nexport default class ProductPriceInformationSummaryTransformer {\n /**\n * Extracts the information from the sales price of a product and puts it into properties that are easier to interpret.\n *\n * @param priceInformation Product price information.\n * @param currency ...\n * @returns Product price information summary.\n */\n static transform(priceInformation, currency) {\n const priceInformationSummary = {\n temporaryFamilyPrice: false,\n newLowerPrice: false,\n hasPreviousPrice: false,\n timeRestrictedOffer: false,\n familyPrice: null,\n price: null,\n regularPrice: null\n };\n if (!priceInformation?.salesPrice) {\n return priceInformationSummary;\n }\n const primaryCurrency = [\n ...new Set(priceInformation.salesPrice.map((price) => price.currencyCode))\n ][0];\n const salesPrices = currency\n ? [...priceInformation.salesPrice]\n .filter((salesPrice) => salesPrice.currencyCode === currency)\n .reverse()\n : [...priceInformation.salesPrice]\n .filter((salesPrice) => salesPrice.currencyCode === primaryCurrency)\n .reverse();\n const isFamilyAndNLP = () => {\n const isFamily = salesPrices.some((salesPrice) => salesPrice.typeCode === 'IKEAFamilySalesUnitPrice');\n const isNLP = salesPrices.some((salesPrice) => salesPrice.typeCode === 'RegularSalesUnitPrice' &&\n salesPrice.changeReason === 'NewLowerPrice');\n return isFamily && isNLP;\n };\n const isFamilyAndNLPPrice = isFamilyAndNLP();\n for (const salesPrice of salesPrices) {\n if (salesPrice.typeCode === 'IKEAFamilySalesUnitPrice') {\n priceInformationSummary.familyPrice = salesPrice;\n if (salesPrice.changeReason === 'Temporary') {\n priceInformationSummary.temporaryFamilyPrice = true;\n }\n }\n else if (salesPrice.changeReason === 'NewLowerPrice') {\n priceInformationSummary.newLowerPrice = true;\n priceInformationSummary.price = salesPrice;\n if (salesPrice.previousSalesPrice) {\n priceInformationSummary.hasPreviousPrice = true;\n if (isFamilyAndNLPPrice) {\n priceInformationSummary.regularPrice = Object.assign({}, salesPrice);\n }\n else {\n priceInformationSummary.regularPrice = Object.assign({}, salesPrice, salesPrice.previousSalesPrice);\n }\n }\n }\n else if (salesPrice.changeReason === 'TimeRestrictedOffer') {\n priceInformationSummary.timeRestrictedOffer = true;\n priceInformationSummary.price = salesPrice;\n if (salesPrice.previousSalesPrice) {\n priceInformationSummary.hasPreviousPrice = true;\n priceInformationSummary.regularPrice = Object.assign({}, salesPrice, salesPrice.previousSalesPrice);\n }\n }\n else if (priceInformation.salesPrice.length > 1) {\n priceInformationSummary.regularPrice = salesPrice;\n }\n else {\n priceInformationSummary.price = salesPrice;\n }\n }\n if (!priceInformationSummary.price && priceInformationSummary.regularPrice) {\n priceInformationSummary.price = priceInformationSummary.regularPrice;\n }\n return priceInformationSummary;\n }\n}\n//# sourceMappingURL=ProductPriceInformationSummaryTransformer.js.map","import { TemporaryPricePeriodEnum } from '@inter-ikea-kompis/enums';\nimport ProductPriceInformationSummaryTransformer from './ProductPriceInformationSummaryTransformer.js';\n/**\n * Price utilities.\n */\nexport default class PriceUtility {\n /**\n * Check if shoppingProducts has a family price.\n *\n * @param shoppingProducts Shopping products.\n * @returns If it is family price.\n */\n static isFamilyPrice(shoppingProducts) {\n return shoppingProducts.some((shoppingProduct) => {\n const priceInformation = shoppingProduct?.product?.content?.priceInformation;\n return priceInformation\n ? ProductPriceInformationSummaryTransformer.transform(priceInformation).familyPrice\n : false;\n });\n }\n /**\n * Returns true if it is just one product.\n *\n * @param shoppingProducts Shopping products.\n * @returns True if just one product.\n */\n static isIndividualProduct(shoppingProducts) {\n return shoppingProducts.length === 1 && shoppingProducts[0].quantity === 1;\n }\n /**\n * Returns \"true\" if TRO (Time Restricted Offer) or family.\n *\n * @param totalPrice Price model.\n * @returns \"true\" if TRO or family.\n */\n static isTroOrFamily(totalPrice) {\n return totalPrice.family || Boolean(totalPrice.temporary && totalPrice.validDateInterval);\n }\n /**\n * Returns \"true\" if TRO (Time Restricted Offer).\n *\n * @param totalPrice Price model.\n * @returns \"true\" if TRO.\n */\n static isTro(totalPrice) {\n return !totalPrice.family && Boolean(totalPrice.temporary && totalPrice.validDateInterval);\n }\n /**\n * Returns \"true\" if family.\n *\n * @param totalPrice Price model.\n * @returns \"true\" if family.\n */\n static isFamily(totalPrice) {\n return totalPrice.family;\n }\n /**\n * Returns \"true\" if new lower price.\n *\n * @param totalPrice Price model.\n * @returns \"true\" if new lower price.\n */\n static isNewLowerPrice(totalPrice) {\n return totalPrice.newLowerPrice;\n }\n /**\n * Returns \"true\" if new lower price which has data for previous price.\n *\n * @param totalPrice Price model.\n * @returns \"true\" if new lower price with previous price data.\n */\n static isNewLowerPriceWithPreviousPrice(totalPrice) {\n return totalPrice.hasPreviousPrice && this.isNewLowerPrice(totalPrice);\n }\n /**\n * Returns \"true\" if an breath taking item.\n *\n * @param totalPrice Price model.\n * @returns \"true\" if breath taking item.\n */\n static isBreathTakingItem(totalPrice) {\n return totalPrice.breathTakingItem;\n }\n /**\n * The price unit.\n *\n * @param shoppingProducts Shopping products.\n * @param useMetricMeasures Metric or imperial values.\n * @returns The price unit.\n */\n static getPriceUnit(shoppingProducts, useMetricMeasures) {\n const product = shoppingProducts[0].product;\n if (!product.content || !product.content.priceUnit || !product.content.priceUnit[0]) {\n return null;\n }\n const priceUnit = product.content.priceUnit[0];\n if (useMetricMeasures) {\n const { factorMetric, textMetric } = priceUnit;\n return this.formatPriceUnit({ factor: factorMetric, text: textMetric });\n }\n else {\n const { factorImperial, textImperial } = priceUnit;\n return this.formatPriceUnit({ factor: factorImperial, text: textImperial });\n }\n }\n /**\n * Returns valid interval.\n *\n * @param totalPrice Price model.\n * @param localizedInformation Deprecated - Use translations and settings instead.\n * @param localizedInformation.translations ...\n * @param localizedInformation.priceSettings ...\n * @param localizedInformation.priceSettings.temporaryPricePeriod ...\n * @param translations The translations retrieved from translations service.\n * @param settings The settings retrieved from settings service.\n * @param settings.kompis ...\n * @param settings.kompis.priceSettings ...\n * @returns Interval.\n */\n static getValidInterval(totalPrice, \n /** @deprecated Use translations and settings instead. */\n localizedInformation, translations, settings) {\n const priceSettings = settings?.kompis.priceSettings ?? localizedInformation?.priceSettings;\n const actualTranslations = translations ?? localizedInformation?.translations;\n if (!priceSettings || !actualTranslations) {\n throw Error('Either translations and settings parameters or localizedInformation parameter must be set.');\n }\n if (!this.isValidInterval(priceSettings, totalPrice.validDateInterval)) {\n return null;\n }\n const validFrom = totalPrice.validDateInterval.validFrom;\n const validTo = totalPrice.validDateInterval.validTo;\n const { priceInfoTemporaryPricePeriodEnd, priceInfoTemporaryPriceDisclaimer, priceInfoTemporaryPriceFullDateRange } = actualTranslations;\n if (TemporaryPricePeriodEnum.periodEnd === priceSettings.temporaryPricePeriod) {\n return [priceInfoTemporaryPricePeriodEnd, validTo, priceInfoTemporaryPriceDisclaimer].join(' ');\n }\n const replacedDateRange = priceInfoTemporaryPriceFullDateRange\n .replace('[[dateFrom]]', validFrom)\n .replace('{{dateFrom}}', validFrom)\n .replace('[[dateTo]]', validTo)\n .replace('{{dateTo}}', validTo);\n return [replacedDateRange, priceInfoTemporaryPriceDisclaimer].join(' ');\n }\n /**\n * Returns price excl tax.\n *\n * @param totalPrice Price model.\n * @returns Price excl tax.\n */\n static getPriceExclTax(totalPrice) {\n return totalPrice.familyExclTax || totalPrice.exclTax;\n }\n /**\n * Returns the product that has the lowest regular price.\n *\n * @param products The products.\n * @returns The product with the lowest price.\n */\n static getLowestRegularPrice(products) {\n const productsOrderedByPrice = products\n .map((product) => ({\n product,\n price: this.getRegularPrice(product)\n }))\n .filter(({ price }) => price !== null)\n .sort((a, b) => (a.price ?? 0) - (b.price ?? 0))\n .map(({ product }) => product);\n return productsOrderedByPrice[0];\n }\n /**\n * Returns the array of shopping products that has the lowest total regular price.\n *\n * @param shoppingProductGroups Array of arrays of shopping products.\n * @returns The array of shopping products with the lowest total regular price.\n */\n static getShoppingProductsWithLowestTotalRegularPrice(shoppingProductGroups) {\n const getTotalPrice = (shoppingProducts) => {\n if (shoppingProducts.some((shoppingProduct) => !shoppingProduct.product.valid || this.getRegularPrice(shoppingProduct.product) === null)) {\n return null;\n }\n return shoppingProducts.reduce((sum, shoppingProduct) => sum + (this.getRegularPrice(shoppingProduct.product) ?? 0) * shoppingProduct.quantity, 0);\n };\n const shoppingProductGroupsOrderedByTotalPrice = shoppingProductGroups\n .map((shoppingProducts) => ({\n shoppingProducts,\n totalPrice: getTotalPrice(shoppingProducts)\n }))\n .filter(({ totalPrice }) => totalPrice !== null)\n .sort((a, b) => {\n return (a.totalPrice ?? 0) - (b.totalPrice ?? 0);\n })\n .map(({ shoppingProducts }) => shoppingProducts);\n if (shoppingProductGroupsOrderedByTotalPrice.length === 0) {\n return null;\n }\n return shoppingProductGroupsOrderedByTotalPrice[0];\n }\n /**\n * Returns price.\n *\n * @param totalPrice Price model.\n * @returns Price.\n */\n static getPrice(totalPrice) {\n return totalPrice.familyInclTax || totalPrice.inclTax;\n }\n /**\n * Returns price.\n *\n * @param totalPrice Price model.\n * @returns Price.\n */\n static getFromPrice(totalPrice) {\n if (this.isNewLowerPrice(totalPrice)) {\n return totalPrice.inclTax;\n }\n return totalPrice.regularInclTax || totalPrice.inclTax;\n }\n /**\n * Returns currency symbol.\n *\n * @param totalPrice Price model.\n * @param localizedInformationOrSettings Either settings retrieved from settings service or localized information fetched from localization service.\n * @returns Currency symbol.\n */\n static getCurrencySymbol(totalPrice, localizedInformationOrSettings) {\n const priceSettings = 'kompis' in localizedInformationOrSettings\n ? {\n currencyCode: localizedInformationOrSettings.localisation.currencyCode,\n currencySymbol: localizedInformationOrSettings.localisation.currencySymbol,\n currencyCodeAlt: localizedInformationOrSettings.kompis.priceSettings.currencyCodeAlt,\n currencySymbolAlt: localizedInformationOrSettings.kompis.priceSettings.currencySymbolAlt\n }\n : localizedInformationOrSettings.priceSettings;\n if (totalPrice.currencyCode === priceSettings.currencyCode) {\n return priceSettings.currencySymbol;\n }\n else if (totalPrice.currencyCode === priceSettings.currencyCodeAlt &&\n priceSettings.currencySymbolAlt) {\n return priceSettings.currencySymbolAlt;\n }\n return null;\n }\n /**\n * If there is a valid interval to show.\n *\n * @param priceSettings ...\n * @param priceSettings.temporaryPricePeriod ...\n * @param totalPriceDateInterval Price date interval.\n * @returns If it is valid interval.\n */\n static isValidInterval(priceSettings, totalPriceDateInterval) {\n return (!!totalPriceDateInterval &&\n priceSettings.temporaryPricePeriod !== TemporaryPricePeriodEnum.periodNone);\n }\n /**\n * @param options Options.\n * @param options.factor Either Metric or imperial.\n * @param options.text Either Metric or imperial.\n */\n static formatPriceUnit(options) {\n const { factor, text } = options;\n if (!factor || !text) {\n return null;\n }\n const formattedFactor = factor === 1.0 ? '' : factor;\n return `${formattedFactor} ${text}`;\n }\n /**\n * @param product The product.\n */\n static getRegularPrice(product) {\n if (!product.content || !product.content.priceInformation) {\n return null;\n }\n return (product.content.priceInformation.salesPrice.find((p) => p.typeCode == 'RegularSalesUnitPrice')\n ?.priceInclTax ?? null // The salesPrice array always contains a RegularSalesUnitPrice so null should never be returned here\n );\n }\n}\n//# sourceMappingURL=PriceUtility.js.map","import { Exception } from '@inter-ikea-kompis/exceptions';\nimport DateFormatter from '../date/DateFormatter.js';\nimport ProductPriceInformationSummaryTransformer from './ProductPriceInformationSummaryTransformer.js';\n/**\n * Handles calculation of total price for a list of products.\n */\nexport default class TotalPriceCalculator {\n /**\n * Calculates total price.\n *\n * @param shoppingProducts Shopping products.\n * @param dateFormat Date format. Example: YYYY-MM-DD.\n * @param currencyCode Currency code to match with.\n * @param isCombinedProduct True if the products should be treated as one.\n * @returns Instance of TotalPriceSummary.\n */\n static calculate(shoppingProducts, dateFormat, currencyCode, isCombinedProduct) {\n if (!dateFormat) {\n throw new Exception('Second parameter \"dateFormat\" was not given.');\n }\n const totalPrice = {\n inclTax: 0,\n exclTax: 0,\n familyInclTax: 0,\n familyExclTax: 0,\n regularInclTax: 0,\n regularExclTax: 0,\n onlineSaleable: false,\n newLowerPrice: false,\n hasPreviousPrice: false,\n breathTakingItem: false,\n family: false,\n temporary: false,\n validDateInterval: null,\n ecoPrice: 0,\n weeePrice: 0,\n currencyCode: currencyCode ?? null\n };\n const shoppingProductsWithQuantity = shoppingProducts.filter(({ quantity }) => quantity > 0);\n if (!shoppingProductsWithQuantity.length) {\n return totalPrice;\n }\n const validDates = [];\n totalPrice.newLowerPrice = isCombinedProduct ? false : true;\n totalPrice.breathTakingItem = true;\n totalPrice.onlineSaleable = true;\n for (const shoppingProduct of shoppingProductsWithQuantity) {\n if (!shoppingProduct.product.valid) {\n throw new Error(`Failed to calculate total price. One of the products (${shoppingProduct.product.itemId}) is not valid.`);\n }\n if (shoppingProduct.product.content) {\n const product = shoppingProduct.product.content;\n if (!product.priceInformation) {\n throw new Exception('Failed to calculate total price, priceInformation was not present in the content object.');\n }\n // Uses the currency provided or only the first currency in the list, if two currencies are present.\n const forcedCurrency = currencyCode\n ? currencyCode\n : product.priceInformation.salesPrice[0].currencyCode;\n const productPriceInformationSummary = ProductPriceInformationSummaryTransformer.transform(product.priceInformation, forcedCurrency);\n const familyValidDate = this.calculateFamilyPrice(shoppingProduct, productPriceInformationSummary, totalPrice);\n const troValidDate = this.calculateTroPrice(productPriceInformationSummary, totalPrice);\n this.calculateNormalPrice(shoppingProduct, productPriceInformationSummary, totalPrice);\n this.calculateRegularPrice(shoppingProduct, productPriceInformationSummary, totalPrice);\n this.calculateFeePrices(shoppingProduct, totalPrice, forcedCurrency);\n totalPrice.onlineSaleable =\n product.priceInformation.onlineSaleable === false ? false : totalPrice.onlineSaleable;\n // If the products are considered a \"combined\" product it is enough that one of the products have NLP to produce a NPL price.\n // Otherwise all products need to have NLP to produce a total NLP price.\n if (isCombinedProduct) {\n totalPrice.newLowerPrice =\n productPriceInformationSummary.newLowerPrice === true ? true : totalPrice.newLowerPrice;\n }\n else {\n totalPrice.newLowerPrice =\n productPriceInformationSummary.newLowerPrice === false\n ? false\n : totalPrice.newLowerPrice;\n }\n totalPrice.hasPreviousPrice = productPriceInformationSummary.hasPreviousPrice\n ? true\n : totalPrice.hasPreviousPrice;\n totalPrice.breathTakingItem =\n product.breathTakingItem === false ? false : totalPrice.breathTakingItem;\n if (familyValidDate) {\n validDates.push(familyValidDate);\n }\n if (troValidDate) {\n validDates.push(troValidDate);\n }\n }\n }\n totalPrice.validDateInterval = this.getValidDateInterval(validDates, dateFormat);\n if (!totalPrice.currencyCode) {\n totalPrice.currencyCode =\n shoppingProducts[0]?.product?.content?.priceInformation?.salesPrice[0]?.currencyCode ??\n null;\n }\n return totalPrice;\n }\n /**\n * Calculates total prices for more than one currency. Used for dual currencies.\n *\n * @param shoppingProducts Shopping products.\n * @param dateFormat Date format. Example: YYYY-MM-DD.\n * @param isCombinedProduct True if the products should be treated as one.\n * @returns Instance of TotalPriceSummary.\n */\n static calculateMultiple(shoppingProducts, dateFormat, isCombinedProduct) {\n if (!dateFormat) {\n throw new Exception('Second parameter \"dateFormat\" was not given.');\n }\n if (shoppingProducts.some((product) => !product.product.content?.priceInformation)) {\n return [];\n }\n const totalPrices = [];\n if (!shoppingProducts.length) {\n totalPrices.push(this.calculate(shoppingProducts, dateFormat, undefined, isCombinedProduct));\n return totalPrices;\n }\n const providedCurrencies = [\n ...new Set(shoppingProducts[0]?.product?.content?.priceInformation?.salesPrice?.map((price) => price.currencyCode))\n ];\n for (const currency in providedCurrencies) {\n totalPrices.push(this.calculate(shoppingProducts, dateFormat, providedCurrencies[currency], isCombinedProduct));\n }\n return totalPrices;\n }\n /**\n * Handles normal price.\n *\n * @param shoppingProduct Shopping product.\n * @param productPriceInformationSummary Sales price information.\n * @param totalPrice Total price model.\n */\n static calculateNormalPrice(shoppingProduct, productPriceInformationSummary, totalPrice) {\n // We should always have a normal price\n if (productPriceInformationSummary.price) {\n totalPrice.inclTax +=\n productPriceInformationSummary.price.priceInclTax * shoppingProduct.quantity;\n totalPrice.exclTax +=\n productPriceInformationSummary.price.priceExclTax * shoppingProduct.quantity;\n }\n else if (productPriceInformationSummary.regularPrice) {\n totalPrice.inclTax +=\n productPriceInformationSummary.regularPrice.priceInclTax * shoppingProduct.quantity;\n totalPrice.exclTax +=\n productPriceInformationSummary.regularPrice.priceExclTax * shoppingProduct.quantity;\n }\n else {\n throw new Exception(`Failed to calculate total price. Missing valid normal price in item: \"${shoppingProduct.product.itemId}\".`);\n }\n }\n /**\n * Handles family price.\n *\n * @param shoppingProduct Shopping product.\n * @param productPriceInformationSummary Sales price information.\n * @param totalPrice Total price model.\n * @returns Valid date.\n */\n static calculateFamilyPrice(shoppingProduct, productPriceInformationSummary, totalPrice) {\n if (productPriceInformationSummary.familyPrice) {\n totalPrice.family = true;\n totalPrice.familyInclTax +=\n productPriceInformationSummary.familyPrice.priceInclTax * shoppingProduct.quantity;\n totalPrice.familyExclTax +=\n productPriceInformationSummary.familyPrice.priceExclTax * shoppingProduct.quantity;\n }\n else {\n // If this was not a family product, family price increases with normal price\n totalPrice.familyInclTax +=\n productPriceInformationSummary.price?.priceInclTax * shoppingProduct.quantity;\n totalPrice.familyExclTax +=\n productPriceInformationSummary.price?.priceExclTax * shoppingProduct.quantity;\n }\n if (productPriceInformationSummary.temporaryFamilyPrice) {\n totalPrice.temporary = true;\n return {\n validFrom: DateFormatter.isoStringToDate(productPriceInformationSummary.familyPrice?.validFromText),\n validTo: DateFormatter.isoStringToDate(productPriceInformationSummary.familyPrice?.validToText)\n };\n }\n return null;\n }\n /**\n * Handles TRO (Time Restricted Offer) price.\n *\n * @param productPriceInformationSummary Sales price information.\n * @param totalPrice Total price model.\n * @returns Valid date.\n */\n static calculateTroPrice(productPriceInformationSummary, totalPrice) {\n if (productPriceInformationSummary.timeRestrictedOffer) {\n totalPrice.temporary = true;\n return {\n validFrom: DateFormatter.isoStringToDate(productPriceInformationSummary.price?.validFromText),\n validTo: DateFormatter.isoStringToDate(productPriceInformationSummary.price?.validToText)\n };\n }\n return null;\n }\n /**\n * Handles Regular price.\n *\n * @param shoppingProduct Shopping product.\n * @param productPriceInformationSummary Sales price information.\n * @param totalPrice Total price model.\n */\n static calculateRegularPrice(shoppingProduct, productPriceInformationSummary, totalPrice) {\n // There was a check here before: if (priceInformation.regularPrice && !priceInformation.newLowerPrice)\n // The check does not make sense, so it has been removed\n if (productPriceInformationSummary.regularPrice) {\n totalPrice.regularInclTax +=\n productPriceInformationSummary.regularPrice.priceInclTax * shoppingProduct.quantity;\n totalPrice.regularExclTax +=\n productPriceInformationSummary.regularPrice.priceExclTax * shoppingProduct.quantity;\n }\n else {\n // If we don't have a special regular price, then the normal is regular\n totalPrice.regularInclTax +=\n productPriceInformationSummary.price?.priceInclTax * shoppingProduct.quantity;\n totalPrice.regularExclTax +=\n productPriceInformationSummary.price?.priceExclTax * shoppingProduct.quantity;\n }\n }\n /**\n * Handles fee price.\n *\n * @param shoppingProduct Shopping product.\n * @param totalPrice Total price model.\n * @param currencyCode To match if there are multiple (dual) currencies in the prices.\n */\n static calculateFeePrices(shoppingProduct, totalPrice, currencyCode) {\n const productFees = shoppingProduct.product.content?.priceInformation?.fees;\n if (productFees) {\n for (const fee of productFees.filter((fee) => fee.currencyCode === currencyCode)) {\n if (fee.typeCode === 'ECO') {\n totalPrice.ecoPrice += fee.amount * shoppingProduct.quantity;\n }\n else if (fee.typeCode === 'WEEE') {\n totalPrice.weeePrice += fee.amount * shoppingProduct.quantity;\n }\n }\n }\n }\n /**\n * Returns the shortest date span of multiple dates.\n *\n * @param validDates Valid dates.\n * @param dateFormat Pattern to use.\n * @returns Date interval.\n */\n static getValidDateInterval(validDates, dateFormat) {\n if (validDates.length > 0) {\n const date = {\n validFrom: validDates[0].validFrom,\n validTo: validDates[0].validTo\n };\n for (const validDate of validDates) {\n if (validDate.validFrom > date.validFrom) {\n date.validFrom = validDate.validFrom;\n }\n if (validDate.validTo < date.validTo) {\n date.validTo = validDate.validTo;\n }\n }\n return {\n validFrom: DateFormatter.dateToString(date.validFrom, dateFormat),\n validTo: DateFormatter.dateToString(date.validTo, dateFormat)\n };\n }\n return null;\n }\n}\n//# sourceMappingURL=TotalPriceCalculator.js.map","/**\n * This allows you to control how descriptive the measurement will be.\n *\n * The total amount of measurements will differ depending on what type of product it is displayed.\n */\nvar ProductDescriptionProductMeasureEnum;\n(function (ProductDescriptionProductMeasureEnum) {\n /**\n * Don't display any measurements for the product.\n */\n ProductDescriptionProductMeasureEnum[\"none\"] = \"none\";\n /**\n * Displays a minimal text describing the measurment for the product.\n *\n * The text comes from the \"measureReference\" available in the products content.\n */\n ProductDescriptionProductMeasureEnum[\"short\"] = \"short\";\n /**\n * Displays a descriptive comma separated text for the product.\n *\n * Measurements for the product comes from the \"measure\" array available in the products content.\n */\n ProductDescriptionProductMeasureEnum[\"long\"] = \"long\";\n /**\n * An array of objects containg the measurement and measurement type.\n *\n * Measurements for the product comes from the \"measure\" array on the displayed product.\n *\n * Should only be used if the intention is to control how the data will be displayed.\n */\n ProductDescriptionProductMeasureEnum[\"array\"] = \"array\";\n})(ProductDescriptionProductMeasureEnum || (ProductDescriptionProductMeasureEnum = {}));\nexport default ProductDescriptionProductMeasureEnum;\n//# sourceMappingURL=ProductDescriptionProductMeasureEnum.js.map","/**\n * Handles string utilities.\n */\nexport default class StringUtility {\n /**\n * Capitalizes first letter.\n *\n * @param text Text to use.\n * @returns String with first letter capitalized.\n */\n static capitalizeFirstLetter(text) {\n return text.charAt(0).toUpperCase() + text.slice(1);\n }\n /**\n * Kebab case to words.\n *\n * @param string String to convert.\n * @returns Text as kebab case.\n */\n static kebabToCamelCase(string) {\n const strings = string.split('-');\n for (let i = 0, max = strings.length; i < max; i++) {\n strings[i] = this.capitalizeFirstLetter(strings[i]);\n }\n return strings.join('');\n }\n /**\n * Function to change camel case to snake case.\n *\n * @param string ...\n */\n static camelToSnake(string) {\n let result = '';\n // Loop through string.\n for (let i = 0; i < string.length; i++) {\n const ch = string.charAt(i);\n // Check if character is upper case and is not the first in index.\n // Append '_' and change character to lower case.\n if (ch === ch.toUpperCase()) {\n if (i > 0) {\n result = result + '_';\n }\n result = result + ch.toLowerCase();\n }\n // If the character is lower case then append to result string.\n else {\n result = result + ch;\n }\n }\n // Return the result\n return result;\n }\n /**\n * Should remove spaces from both sides of string.\n *\n * @param text Text to use.\n * @param [trim] Character to trim. Defaults to \" \".\n * @returns Converted string.\n */\n static trim(text, trim = ' ') {\n while (text.length > 0 && text.charAt(0) === trim) {\n text = text.substring(1);\n }\n while (text.length > 0 && text.charAt(text.length - 1) === trim) {\n text = text.slice(0, -1);\n }\n return text;\n }\n}\n//# sourceMappingURL=StringUtility.js.map","import { ImageTypeNameEnum, ItemTypeEnum, ProductComplianceTechnicalHeadingTypeEnum } from '@inter-ikea-kompis/enums';\nimport IdGenerator from '../generator/IdGenerator.js';\nconst ITEM_NO_NUMBER_OF_CHARACTERS = 3;\nconst ENERGY_CLASS_REGEXP = /^(A\\+{0,3}|B|C|D|E)/;\nconst BUNDLE_ID_TYPE_PREFIX = 'BUN-';\n/**\n * A product utility that can be used for formatting article numbers.\n */\nexport default class ProductUtility {\n /**\n * Formats a product article number to be more readable for the end user. The string \"12535352\" will for example be formatted to \"125.353.52\".\n *\n * @param itemNo Product item number.\n * @returns An item number including dots.\n */\n static formatItemNo(itemNo) {\n const numberOfDots = Math.ceil(itemNo.length / ITEM_NO_NUMBER_OF_CHARACTERS);\n const parts = Array(numberOfDots)\n .fill(null)\n .map((_, index) => itemNo.slice(index * ITEM_NO_NUMBER_OF_CHARACTERS, index * ITEM_NO_NUMBER_OF_CHARACTERS + ITEM_NO_NUMBER_OF_CHARACTERS));\n return parts.join('.');\n }\n /**\n * Returns product information page link.\n *\n * @param product Product.\n * @param localizedInformationOrSettings Either settings retrieved from settings service or localized information fetched from localization service.\n * @returns Product information page link.\n */\n static getProductInformationPageLink(product, localizedInformationOrSettings) {\n const productInformationPageLinkV2 = 'kompis' in localizedInformationOrSettings\n ? localizedInformationOrSettings.kompis.urls.productInformationPageLinkV2\n : localizedInformationOrSettings.urls.productInformationPageLinkV2;\n if (!product.content || !productInformationPageLinkV2) {\n return null;\n }\n const itemNo = product.content.itemNoLocal || product.content.itemNoGlobal;\n if (!itemNo) {\n return null;\n }\n if (this.isProductSPR(product)) {\n return productInformationPageLinkV2\n .replace('{productItemNo}', itemNo)\n .replace('{lowerCaseSprPrefix}', 's')\n .replace('{upperCaseSprPrefix}', 'S');\n }\n return productInformationPageLinkV2\n .replace('{productItemNo}', itemNo)\n .replace('{lowerCaseSprPrefix}', '')\n .replace('{lowerCaseSprPrefix}', '');\n }\n /**\n * Returns main image.\n *\n * @param product Product.\n * @returns Product images.\n */\n static getMainImages(product) {\n return product.content && product.content.image\n ? product.content.image.filter((image) => image.typeName === ImageTypeNameEnum.mainProductPicture)\n : [];\n }\n /**\n * Checks whether itemType is of type SPR or not.\n *\n * @param product IProduct.\n * @returns Boolean.\n */\n static isProductSPR(product) {\n return !this.isBundleProduct(product) && product.content?.itemType === ItemTypeEnum.spr;\n }\n /**\n * Checks whether the product is a bundle product. Can be used to operate on a\n * bundle with type safety.\n *\n * BundleProduct: A custom built product that does not exist in the eyes of\n * PIA but is presented like an SPR with child articles to the user.\n *\n * @param product IProduct.\n * @returns Product is IBundleProduct, boolean.\n */\n static isBundleProduct(product) {\n return product.itemId.startsWith(BUNDLE_ID_TYPE_PREFIX);\n }\n /**\n * Checks whether the shopping product is a bundle shopping product.\n *\n * BundleProduct: A custom built product that has no item number, but is like an SPR, which contains child articles.\n *\n * @param shoppingProduct IProduct.\n * @returns Product is IBundleProduct, boolean.\n */\n static isBundleShoppingProduct(shoppingProduct) {\n return this.isBundleProduct(shoppingProduct.product);\n }\n /**\n * Returns images based on what enum is passed.\n *\n * @param product Product - the product to fetch the image from..\n * @param imageType ImageTypeNameEnum - what type of image to fetch.\n * @returns Product images.\n */\n static getProductImages(product, imageType) {\n const images = product.content && product.content.image\n ? product.content.image.filter((image) => image.typeName === imageType)\n : [];\n return images;\n }\n /**\n * Returns energy class.\n *\n * @param product Product.\n * @returns Energy class.\n */\n static getEnergyClass(product) {\n if (!product.content?.technicalInformation?.length) {\n return null;\n }\n for (const item of product.content.technicalInformation) {\n if (typeof item.valueMetric === 'string') {\n const match = item.valueMetric.match(ENERGY_CLASS_REGEXP);\n if (match) {\n return match[1];\n }\n }\n }\n return null;\n }\n /**\n * Returns the link to EPREL for the product. EPREL stands for \"European Product Registry for Energy Labelling\".\n *\n * @param product ...\n */\n static getProductInformationSheetLink(product) {\n if (product?.content?.complianceTechnical?.length) {\n const productInformationSheetInformation = product.content.complianceTechnical.find((complianceTechnicalItem) => complianceTechnicalItem.headingType === ProductComplianceTechnicalHeadingTypeEnum.rescaled);\n if (productInformationSheetInformation) {\n return {\n text: productInformationSheetInformation.headingText,\n href: productInformationSheetInformation.text\n };\n }\n }\n return null;\n }\n /**\n * Returns energy compliance type (EU/US).\n *\n * @param product ...\n */\n static getProductComplianceType(product) {\n if (product?.content?.complianceTechnical?.length) {\n const complianceType = product.content.complianceTechnical.find((complianceTechnicalItem) => complianceTechnicalItem.headingType ===\n ProductComplianceTechnicalHeadingTypeEnum.energyEfficiencyClass ||\n complianceTechnicalItem.headingType ===\n ProductComplianceTechnicalHeadingTypeEnum.hyperlink ||\n complianceTechnicalItem.headingType ===\n ProductComplianceTechnicalHeadingTypeEnum.unifiedWaterLabel);\n if (complianceType) {\n return complianceType.headingType;\n }\n }\n return null;\n }\n /**\n * Returns IShoppingItem[] from a IShoppingProduct[].\n *\n * @param shoppingProducts ...\n */\n static getShoppingItems(shoppingProducts) {\n const shoppingItems = [];\n for (const shoppingProduct of shoppingProducts) {\n if (shoppingProduct.product.content?.ruItemNo &&\n shoppingProduct.product.content?.ruItemType) {\n shoppingItems.push({\n id: shoppingProduct.product.content.ruItemNo,\n type: shoppingProduct.product.content.ruItemType,\n quantity: shoppingProduct.quantity\n });\n }\n }\n return shoppingItems;\n }\n /**\n * Returns IShoppingProduct[] for child products of the main product.\n *\n * @param options ...\n * @param options.product The \"main\" product (with child products/items).\n * @param options.includedProducts Included products (those not being a main product child will be ignored).\n * @param options.ignoreInvalidProducts Whether or not invalid products in includedProducts should be ignored, i.e. Not be returned as shopping product (false is default).\n */\n static getIncludedShoppingProducts(options) {\n const { product, includedProducts, ignoreInvalidProducts = false } = options;\n const shoppingProducts = [];\n for (const child of product.content?.child ?? []) {\n const itemNo = child.itemId.split('-').reverse()[0];\n const includedProduct = includedProducts.find((p) => itemNo === p.content?.itemNoLocal || itemNo === p.content?.itemNoGlobal);\n if (includedProduct && !(ignoreInvalidProducts && !includedProduct.valid)) {\n shoppingProducts.push({\n product: includedProduct,\n quantity: child.quantity\n });\n }\n }\n return shoppingProducts;\n }\n /**\n * Returns true if product price should be calculated from the child products of the product.\n *\n * @param product The product.\n * @returns True if product have no price information and have child products, otherwise false.\n */\n static shouldCalculatePriceFromChildProducts(product) {\n const hasPriceInformation = !this.isBundleProduct(product) && product.content?.priceInformation;\n const hasChildren = !!product.content?.child;\n return !hasPriceInformation && hasChildren;\n }\n /**\n * Creates a bundle product and adds additional information such as auto\n * generated itemId and sets `valid` to `true`.\n *\n * @param productData Product data to append to the created product.\n */\n static createBundleProduct(productData) {\n const itemId = this.generateBundleId();\n return {\n ...productData,\n itemId,\n valid: true\n };\n }\n /**\n * Generates an ID for a bundle product that follows the PIA pattern (XXX-00000000).\n */\n static generateBundleId() {\n const idGenerator = this.getIdGenerator();\n const idNumber = idGenerator.generateNumericId().toString().padStart(8, '0');\n return BUNDLE_ID_TYPE_PREFIX + idNumber;\n }\n /**\n * Gets a unique IdGenerator for the ProductUtility class.\n */\n static getIdGenerator() {\n if (!this.idGenerator) {\n this.idGenerator = new IdGenerator();\n }\n return this.idGenerator;\n }\n}\n//# sourceMappingURL=ProductUtility.js.map","import { MeasurementSystemEnum } from '@inter-ikea-kompis/enums';\nimport StringUtility from '../string/StringUtility.js';\nimport ProductDescriptionProductMeasureEnum from './ProductDescriptionProductMeasureEnum.js';\nimport ProductUtility from './ProductUtility.js';\n/**\n * Product description utility.\n */\nexport default class ProductDescriptionUtility {\n /**\n * Returns product description.\n *\n * @param options Options.\n * @param options.product Product.\n * @param options.localizedInformation Deprecated - Use translations and settings instead.\n * @param options.include Include in description.\n * @param options.include.designText Design text.\n * @param options.include.packageMeasures Package measures.\n * @param options.include.productMeasures Product measures.\n * @param options.include.weight Weight.\n * @param options.include.measurementSystem ...\n * @param options.exclude.typeName TypeName\n * @param options.settings Settings from DEXF.\n * @param options.translations Translations.\n * @returns Product description.\n */\n static getDescription(options) {\n const { settings, localizedInformation, product, include, exclude, translations } = options;\n const actualTranslations = translations ?? localizedInformation?.translations;\n const isBundleProduct = ProductUtility.isBundleProduct(product);\n const actualSettings = settings ??\n (localizedInformation\n ? {\n localisation: {\n useMetricMeasures: localizedInformation.localization.useMetricMeasures\n }\n }\n : null);\n if (!actualSettings || !actualTranslations) {\n throw Error('Either translations and settings parameters or localizedInformation parameter must be set.');\n }\n const description = [];\n if (product.content?.typeName && !exclude?.typeName) {\n description.push(product.content?.typeName);\n }\n // Design text\n if (include?.designText) {\n const designText = this.getProductDesignText(product);\n if (designText) {\n description.push(designText);\n }\n }\n // Product measures\n if (!isBundleProduct && include?.productMeasures) {\n const productMeasures = this.getProductMeasures({\n settings: actualSettings,\n productMeasures: include.productMeasures,\n product: product,\n measurementSystem: include.measurementSystem\n });\n if (productMeasures && typeof productMeasures === 'string') {\n description.push(productMeasures);\n }\n }\n // Package measures\n if (!isBundleProduct && include?.packageMeasures) {\n const packageMeasures = this.getPackageMeasures({\n settings: actualSettings,\n product: product,\n translations: actualTranslations,\n measurementSystem: include.measurementSystem\n });\n if (packageMeasures) {\n description.push(packageMeasures);\n }\n }\n // Weight\n if (!isBundleProduct && include?.weight) {\n const weight = this.getProductWeight({\n settings: actualSettings,\n product: product,\n translations: actualTranslations,\n include: {\n label: true,\n measurementSystem: include.measurementSystem\n }\n });\n if (weight) {\n description.push(weight);\n }\n }\n // Only capitalize if there actually is any description.\n const capitalizedDescription = description.length\n ? StringUtility.capitalizeFirstLetter(description.filter((part) => part != '').join(', '))\n : '';\n return capitalizedDescription;\n }\n /**\n * Returns product measures.\n *\n * @param options Options.\n * @param options.localizedInformation Deprecated - Use settings instead.\n * @param options.productMeasures Product measure.\n * @param options.product Product.\n * @param options.settings Settings from DEXF.\n * @param options.measurementSystem ...\n * @returns Returns a text with all product measurements.\n */\n static getProductMeasures(options) {\n const { settings, localizedInformation, product, productMeasures, measurementSystem } = options;\n const useMetricMeasures = settings?.localisation.useMetricMeasures ??\n localizedInformation?.localization.useMetricMeasures;\n if (useMetricMeasures === undefined) {\n throw Error('Either options.settings or options.localizedInformation must be set.');\n }\n switch (productMeasures) {\n case ProductDescriptionProductMeasureEnum.short: {\n if (!product.content?.measureReference) {\n return null;\n }\n const { textMetric, textImperial } = product.content.measureReference;\n const shortMeasure = (useMetric) => {\n return useMetric ? textMetric : textImperial;\n };\n if (measurementSystem) {\n return shortMeasure(measurementSystem === MeasurementSystemEnum.metric);\n }\n return shortMeasure(useMetricMeasures);\n }\n case ProductDescriptionProductMeasureEnum.long: {\n if (!product.content?.measure) {\n return null;\n }\n const measure = product.content.measure;\n const longMeasure = (useMetric) => {\n return measure\n .map(({ typeName, textImperial, textMetric }) => `${typeName}: ${useMetric ? textMetric : textImperial}`)\n .join(', ');\n };\n if (measurementSystem) {\n return longMeasure(measurementSystem === MeasurementSystemEnum.metric);\n }\n return longMeasure(useMetricMeasures);\n }\n case ProductDescriptionProductMeasureEnum.array: {\n if (!product.content?.measure) {\n return null;\n }\n const measure = product.content.measure;\n const arrayMeasure = (useMetric) => {\n return measure.map(({ typeName, textMetric, textImperial }) => {\n return {\n typeName: typeName,\n measure: useMetric ? textMetric : textImperial\n };\n });\n };\n if (measurementSystem) {\n return arrayMeasure(measurementSystem === MeasurementSystemEnum.metric);\n }\n return arrayMeasure(useMetricMeasures);\n }\n }\n return null;\n }\n /**\n * Returns weight.\n *\n * @param options Options.\n * @param options.product Product.\n * @param options.settings Settings from DEXF.\n * @param options.translations Translations.\n * @param options.include Extra parameters to include values.\n * @param options.include.label Include label.\n * @returns Template.\n */\n static getProductWeight(options) {\n const { settings, include, product, translations } = options;\n const packageMeasure = product.content?.packageMeasure;\n if (!packageMeasure) {\n return null;\n }\n const useMetricMeasures = settings.localisation.useMetricMeasures;\n const measurementSystem = include?.measurementSystem ?? null;\n const withLabel = include?.label ?? false;\n const packageWeights = (condition, label = false) => {\n const packageLabel = `${label ? `${translations.pickingListSortPackageWeight}: ` : ''}`;\n const packageWeights = `${packageMeasure.package\n .map((p) => (condition ? p.weightGrossMetric : p.weightGrossImperial))\n .join(', ')}`;\n return `${packageLabel}${packageWeights}`;\n };\n if (measurementSystem) {\n return packageWeights(measurementSystem === MeasurementSystemEnum.metric, withLabel);\n }\n return packageWeights(useMetricMeasures, withLabel);\n }\n /**\n * Returns package measures.\n *\n * @param options Options.\n * @param options.product Product.\n * @param options.settings Settings from DEXF.\n * @param options.translations Translations.\n * @param options.measurementSystem ...\n * @returns Returns a text with all package measurements.\n */\n static getPackageMeasures(options) {\n const { settings, product, translations, measurementSystem } = options;\n if (!product.content?.packageMeasure) {\n return null;\n }\n const packages = product.content.packageMeasure.package;\n const useMetricMeasures = settings.localisation.useMetricMeasures;\n const packageMeasures = (useMetric) => {\n return `${translations.pickingListSortPackageSize}: ${packages\n .map((p) => {\n if (!useMetric) {\n return `${p.lengthImperial} x ${p.widthImperial} x ${p.heightImperial}`;\n }\n return `${p.lengthMetric} x ${p.widthMetric} x ${p.heightMetric}`;\n })\n .join(', ')}`;\n };\n if (measurementSystem) {\n return packageMeasures(measurementSystem === MeasurementSystemEnum.metric);\n }\n return packageMeasures(useMetricMeasures);\n }\n /**\n * Returns design text.\n *\n * @param product Product.\n * @returns Design text.\n */\n static getProductDesignText(product) {\n if (!product.content?.validDesignText) {\n return '';\n }\n return product.content.validDesignText;\n }\n}\n//# sourceMappingURL=ProductDescriptionUtility.js.map","/**\n *\n */\nexport default class DexfSettingsUtility {\n /**\n * Parses localized information object from Översätta to DEXF settings object.\n *\n * @param localizedInformation Localized information to parse.\n * @returns Parsed IDexfSettings object.\n */\n static parseLocalizedInformation(localizedInformation) {\n const parsedSettings = {\n kompis: {\n endpoints: localizedInformation.endpoints,\n localization: {\n ...localizedInformation.localization,\n abTest: localizedInformation.userABTest?.ordnaTeam\n },\n serviceSettings: localizedInformation.localization,\n urls: localizedInformation.urls,\n priceSettings: localizedInformation.priceSettings\n },\n localisation: {\n // localization\n useMetricMeasures: localizedInformation.localization.useMetricMeasures,\n usesSubDomain: localizedInformation.localization.usesSubDomain,\n dateFormat: localizedInformation.localization.dateFormat,\n alternateLanguages: localizedInformation.localization.alternateLanguages,\n writeDirection: localizedInformation.localization.writeDirection,\n // priceSettings\n decimalSeparator: localizedInformation.priceSettings.decimalSeparator,\n currencySymbol: localizedInformation.priceSettings.currencySymbol,\n noValueDecimalsString: localizedInformation.priceSettings.noValueDecimalsString,\n thousandSeparatorEnabled: localizedInformation.priceSettings.thousandSeparatorEnabled,\n currencyPosition: localizedInformation.priceSettings.currencyPosition,\n symbolSpacing: localizedInformation.priceSettings.symbolSpacing,\n thousandSeparator: localizedInformation.priceSettings.thousandSeparator,\n replaceNoValueDecimals: localizedInformation.priceSettings.replaceNoValueDecimals,\n numberOfDecimals: localizedInformation.priceSettings.numberOfDecimals,\n currencyCode: localizedInformation.priceSettings.currencyCode\n }\n };\n return parsedSettings;\n }\n}\n//# sourceMappingURL=DexfSettingsUtility.js.map","import { ApiPlatformEnum, EcommerceCartDataSourceEnum, EcommerceShoppingListDataSourceEnum } from '@inter-ikea-kompis/enums';\n/**\n * A utility for checking for shopping cart and list support.\n */\nexport default class ShoppingSupport {\n /**\n * Checks if shopping cart is supported.\n *\n * @param priceSettingsOrDexfPriceSettings ...\n * @returns Returns \"true\" if shopping cart is supported.\n */\n static hasCartSupport(priceSettingsOrDexfPriceSettings) {\n const localization = this.unwrapDexfSettingsObject(priceSettingsOrDexfPriceSettings);\n const eCommerceCartDataSource = localization?.eCommerceCartDataSource;\n const shopOnlineEnabled = localization?.shopOnlineEnabled;\n switch (eCommerceCartDataSource) {\n case EcommerceCartDataSourceEnum.disabled:\n return false;\n case EcommerceCartDataSourceEnum.default:\n return shopOnlineEnabled === true;\n }\n return true;\n }\n /**\n * Checks if shopping list is supported.\n *\n * @param priceSettingsOrDexfPriceSettings ...\n * @returns Returns \"true\" if shopping list is supported.\n */\n static hasListSupport(priceSettingsOrDexfPriceSettings) {\n const localization = this.unwrapDexfSettingsObject(priceSettingsOrDexfPriceSettings);\n const apiPlatform = localization?.apiPlatform;\n const eCommerceShoppingListDataSource = localization?.eCommerceShoppingListDataSource;\n const eCommerceCartDataSource = localization?.eCommerceCartDataSource;\n switch (eCommerceShoppingListDataSource) {\n case EcommerceShoppingListDataSourceEnum.shoppingListApi:\n case EcommerceShoppingListDataSourceEnum.chinaShoppingListApi:\n case EcommerceShoppingListDataSourceEnum.iows:\n case EcommerceShoppingListDataSourceEnum.mvecom:\n case EcommerceShoppingListDataSourceEnum.iksa:\n return true;\n case EcommerceShoppingListDataSourceEnum.default:\n switch (eCommerceCartDataSource) {\n case EcommerceCartDataSourceEnum.iows:\n case EcommerceCartDataSourceEnum.cartApi:\n return true;\n case EcommerceCartDataSourceEnum.default:\n switch (apiPlatform) {\n case ApiPlatformEnum.irw:\n return true;\n }\n }\n }\n return false;\n }\n /**\n * Constructs an object allowing DEXFSettings and LocalizedInformation to be passed into the function.\n *\n * @param priceSettingsOrDexfPriceSettings ...\n * @returns Returns the object with all properties required for ShoppingSupport.\n */\n static unwrapDexfSettingsObject(priceSettingsOrDexfPriceSettings) {\n if ('kompis' in priceSettingsOrDexfPriceSettings) {\n const { serviceSettings, localization } = priceSettingsOrDexfPriceSettings.kompis;\n return {\n eCommerceCartDataSource: serviceSettings.eCommerceCartDataSource,\n apiPlatform: serviceSettings.apiPlatform,\n eCommerceShoppingListDataSource: serviceSettings.eCommerceShoppingListDataSource,\n shopOnlineEnabled: localization.shopOnlineEnabled\n };\n }\n else {\n const localization = priceSettingsOrDexfPriceSettings.localization;\n return {\n eCommerceCartDataSource: localization?.eCommerceCartDataSource,\n apiPlatform: localization?.apiPlatform,\n eCommerceShoppingListDataSource: localization?.eCommerceShoppingListDataSource,\n shopOnlineEnabled: localization?.shopOnlineEnabled\n };\n }\n }\n}\n//# sourceMappingURL=ShoppingSupport.js.map","/**\n * This utility is used for working with Url:s.\n */\nexport default class UrlUtility {\n /**\n * Can handle links without protocol and with wrong order of ancor and query parameters.\n * This property of the link will be kept - if original link had protocol the returned link will too, etc.\n *\n * @param link ...\n * @param paramToAdd Name of the query search parameter to add to link.\n * @param paramValueToAdd Value of the query search parameter to add to link.\n * @returns The link with the query parameter added.\n */\n static addQueryParameter(link, paramToAdd, paramValueToAdd) {\n if (!link || !paramToAdd || !paramValueToAdd) {\n return link;\n }\n const hasProtocol = !!link.match('https?://');\n const url = new URL(hasProtocol ? link : 'http://' + link);\n const hasPath = !!url.pathname && url.pathname !== '/';\n if (url.hash.includes('?')) {\n this.orderHashAndParams(url);\n this.addParamToUrl(url, paramToAdd, paramValueToAdd);\n return this.formattedLink(url, hasProtocol, false, hasPath);\n }\n this.addParamToUrl(url, paramToAdd, paramValueToAdd);\n return this.formattedLink(url, hasProtocol, true, hasPath);\n }\n static getQueryValue(href, key) {\n let url;\n try {\n url = new URL(href);\n }\n catch (error) {\n if (error.code === 'ERR_INVALID_URL')\n return null;\n throw error;\n }\n return url.searchParams.get(key) ?? this.getQueryParameterFromHash(url, key);\n }\n static getQueryParameterFromHash(url, key) {\n const hash = url?.hash?.split('?');\n const queries = hash[1]?.split('&');\n if (!queries)\n return null;\n for (const query of queries) {\n const [k, v] = query.split('=');\n if (k === key)\n return v;\n }\n return null;\n }\n /**\n * Adds the supplied parameters to the url.\n *\n * @param url ...\n * @param paramToAdd ...\n * @param paramValueToAdd ...\n */\n static addParamToUrl(url, paramToAdd, paramValueToAdd) {\n const params = new URLSearchParams(url.search);\n params.append(paramToAdd, paramValueToAdd);\n url.search = '?' + params.toString();\n }\n /**\n * @param url An url following the url standard in order.\n * @param hadProtocolBefore The returned link will contain protocol if it used to have it.\n * @param hadHashAndParamsInCorrectOrder The returned link will have params in the same order it used to have.\n * @param hadPathBefore ...\n */\n static formattedLink(url, hadProtocolBefore, hadHashAndParamsInCorrectOrder, hadPathBefore) {\n const protocolIfHadProtocolBefore = url.protocol && hadProtocolBefore ? url.protocol + '//' : '';\n const portIfHadPortBefore = url.port ? ':' + url.port : '';\n const pathIfHadPathBefore = hadPathBefore\n ? url.pathname && url.pathname.charAt(-1) === '/'\n ? url.pathname.slice(0, -1)\n : url.pathname\n : '';\n const hashAndParams = hadHashAndParamsInCorrectOrder\n ? url.search + url.hash\n : url.hash + url.search;\n return (protocolIfHadProtocolBefore +\n url.hostname +\n portIfHadPortBefore +\n pathIfHadPathBefore +\n hashAndParams);\n }\n /**\n * Reorders the supplied url to follow the standard url format.\n *\n * @param urlUnordered Url with the hash before the query parametes.\n */\n static orderHashAndParams(urlUnordered) {\n const params = new URLSearchParams();\n const [hashWithoutParams, paramsFromHash] = urlUnordered.hash.split('?');\n urlUnordered.hash = hashWithoutParams;\n const paramsList = paramsFromHash.split('&');\n paramsList.forEach((p) => {\n const [name, value] = p.split('=');\n params.append(name, value);\n });\n urlUnordered.search = '?' + params.toString();\n }\n}\n//# sourceMappingURL=UrlUtility.js.map","/**\n * Handles weight utilities.\n *\n */\nexport default class WeightUtility {\n /**\n * Converts weight in kilograms to pounds and ounces.\n *\n * @param weightInKg The weight in kilograms.\n * @returns The weight in pounds and ounces.\n */\n static metricToImperial(weightInKg) {\n const weightInPounds = weightInKg / 0.45359237;\n let lb = Math.floor(weightInPounds);\n let oz = Math.ceil((weightInPounds - lb) * 16);\n if (oz === 16) {\n oz = 0;\n lb++;\n }\n return { lb, oz };\n }\n}\n//# sourceMappingURL=WeightUtility.js.map","/**\n * Utility for getting the write direction in the browser which checks is the browser is Safari.\n */\nexport default class SafariWriteDirectionUtility {\n /**\n * Gets write direction.\n *\n * @returns Write direction.\n * @param element Html element.\n */\n static getWriteDirection(element) {\n if (navigator.userAgent.search('Safari') >= 0 && navigator.userAgent.search('Chrome') < 0) {\n return document.defaultView?.getComputedStyle(element, null).direction || 'ltr';\n }\n return null;\n }\n}\n//# sourceMappingURL=SafariWriteDirectionUtility.js.map","import { ZipAvailabilityProbabilityEnum } from '@inter-ikea-kompis/enums';\n/**\n * Zip availability utility.\n */\nexport default class ZipAvailabilityUtility {\n /**\n * Returns status indicator label for zip.\n *\n * @param options Options.\n * @param options.localizedInformation Deprecated - Use translations instead.\n * @param options.zipAvailability Zip availability.\n * @param options.translations Translations.\n * @returns Status Indicator Label.\n */\n static getLabel(options) {\n const { zipAvailability } = options;\n const actualTranslations = options.translations ?? options.localizedInformation?.translations;\n if (!actualTranslations) {\n throw Error('Either translations or localizedInformation parameter must be set to calculate a label.');\n }\n const { highInStock, lowInStock, mediumInStock, outOfStock, notSoldTemp, notInRange } = ZipAvailabilityProbabilityEnum;\n if (!Array.isArray(zipAvailability)) {\n if (!zipAvailability) {\n return actualTranslations.zipAvailabilityNoDeliveryInfo;\n }\n if (zipAvailability?.content?.availableForHomeDelivery) {\n return actualTranslations.zipAvailabilityAvailable;\n }\n else {\n switch (zipAvailability?.content?.homeDelivery?.messageType) {\n case outOfStock:\n return actualTranslations.zipAvailabilityUnavailable;\n case notSoldTemp:\n return actualTranslations.zipAvailabilityCurrentlyNotSold;\n case notInRange:\n return actualTranslations.zipAvailabilityNotSold;\n default:\n return actualTranslations.zipAvailabilityNoDeliveryInfo;\n }\n }\n }\n else {\n const zipAvailabilities = zipAvailability\n .map((item) => item.content.homeDelivery?.messageType)\n .filter((type) => type !== null);\n if (zipAvailabilities.every((type) => type === highInStock)) {\n return actualTranslations.zipAvailabilityAvailable;\n }\n if (zipAvailabilities.every((type) => type === outOfStock)) {\n return actualTranslations.zipAvailabilityUnavailable;\n }\n else if (zipAvailabilities.some((type) => type === lowInStock || type === mediumInStock || type === outOfStock)) {\n return actualTranslations.homeDeliveryStatusSomeAvailableWithoutZip;\n }\n }\n return '';\n }\n /**\n * Returns status indicator color for zip.\n *\n * @returns Status Indicator Color.\n */\n static getColor(options) {\n const { zipAvailability } = options;\n const { highInStock, lowInStock, mediumInStock, outOfStock } = ZipAvailabilityProbabilityEnum;\n if (!Array.isArray(zipAvailability)) {\n if (!zipAvailability) {\n return 'grey';\n }\n if (zipAvailability?.content?.availableForHomeDelivery) {\n return 'green';\n }\n else {\n switch (zipAvailability.content?.homeDelivery?.messageType) {\n case ZipAvailabilityProbabilityEnum.outOfStock:\n case ZipAvailabilityProbabilityEnum.notSoldTemp:\n return 'red';\n default:\n return 'grey';\n }\n }\n }\n else {\n const zipAvailabilities = zipAvailability\n .map((item) => item.content.homeDelivery?.messageType)\n .filter((type) => !!type);\n // Is it intended that empty zipAvailabilities should return green?\n if (zipAvailabilities.every((type) => type === highInStock)) {\n return 'green';\n }\n if (zipAvailabilities.every((type) => type === outOfStock)) {\n return 'red';\n }\n else if (zipAvailabilities.some((type) => type === lowInStock || type === mediumInStock || type === outOfStock)) {\n return 'orange';\n }\n }\n return null;\n }\n}\n//# sourceMappingURL=ZipAvailabilityUtility.js.map","import { ConnectionProblemException, ServerErrorResponseException, UnableToParseServerResponseException } from '@inter-ikea-kompis/exceptions';\n/**\n * Service fetch utility.\n */\nexport default class ServiceFetch {\n /**\n * Fetches JSON and handles error responses.\n *\n * @param requestInfo Request info.\n * @param [options] Fetch options.\n * @param [options.headers] Fetch options.\n * @param [options.credentials] Fetch options.\n * @param [options.statusHandlers] Object with status handlers for a specific status code. Example: { 419: async () => { return this.__getUser() } }.\n * @returns Promise.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static async json(requestInfo, options) {\n const response = await this.fetch(requestInfo, options);\n if (typeof response.json === 'function') {\n try {\n return await response.json();\n }\n catch (error) {\n throw new UnableToParseServerResponseException(response, error.message);\n }\n }\n return response;\n }\n /**\n * Fetches text and handles error responses.\n *\n * @param requestInfo Request info.\n * @param [options] Fetch options.\n * @param [options.headers] Fetch options.\n * @param [options.credentials] Fetch options.\n * @param [options.statusHandlers] Object with status handlers for a specific status code. Example: { 419: async () => { return this.__getUser() } }.\n * @returns Promise.\n */\n static async text(requestInfo, options) {\n const response = await this.fetch(requestInfo, options);\n if (typeof response.text === 'function') {\n try {\n return await response.text();\n }\n catch (error) {\n throw new UnableToParseServerResponseException(response, error.message);\n }\n }\n return null;\n }\n /**\n * Fetches JSON and handles error responses.\n *\n * @param requestInfo Request info.\n * @param [options] Fetch options.\n * @param [options.headers] Fetch options.\n * @param [options.credentials] Fetch options.\n * @param [options.statusHandlers] Object with status handlers for a specific status code. Example: { 419: async () => { return this.__getUser() } }.\n * @returns Promise.\n */\n static async fetch(requestInfo, options) {\n let response;\n try {\n response = await window.fetch(requestInfo, options);\n }\n catch (error) {\n throw new ConnectionProblemException(requestInfo, error.message);\n }\n if (!response.ok) {\n throw new ServerErrorResponseException(response);\n }\n return response;\n }\n}\n//# sourceMappingURL=ServiceFetch.js.map","import { LocaleUtility } from '@inter-ikea-kompis/utilities';\n/**\n * This class is used for transforming data ÖVERSÄTTA translation tool.\n */\nexport default class OversattaTransformer {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param [options.localizationPrefixApplication] Localization prefix application.\n * @param options.locale Locale.\n */\n constructor(options) {\n this.localizationPrefixApplication = options.localizationPrefixApplication || null;\n this.locale = options.locale;\n }\n /**\n * Transforms data into a LocalizedInformation model.\n *\n * @param data Response data to parse.\n * @returns Localized information model.\n */\n transform(data) {\n const storeId = data.localization && data.localization.storeId ? data.localization.storeId : null;\n const langId = data.localization && data.localization.langId ? data.localization.langId : null;\n const localizedInformation = {\n localization: this.getLocalization(data.localization || {}),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n priceSettings: (data.priceSettings || data.prices || {}),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n urls: this.getUrls(data.urls || data.URLs || {}, storeId, langId),\n endpoints: this.getEndpoints(data.endpoints || {}),\n translations: this.getTranslations(data.translations || {}),\n userABTest: data.UserABTest\n };\n for (const key of Object.keys(data)) {\n if (!localizedInformation[key] &&\n key !== 'iconImages' &&\n key !== 'prices' &&\n key !== 'URLs' &&\n key !== 'UserABTest') {\n localizedInformation[key] = data[key];\n }\n }\n return localizedInformation;\n }\n /**\n * Parses localization.\n *\n * @param localization Localization.\n * @returns Parsed localization.\n */\n getLocalization(localization) {\n const newLocalization = Object.assign({}, localization);\n this.replaceApplicationPrefixedKeys(newLocalization);\n // We should not use these.\n // Instead we should take the locale from the URL, or use endpoints.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n delete newLocalization.locale;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n delete newLocalization.iowsLocalePath;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n delete newLocalization.countryCode;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n delete newLocalization.languageCode;\n return newLocalization;\n }\n /**\n * Parses translations.\n *\n * @param translations Translations.\n * @returns Parsed translations.\n */\n getTranslations(translations) {\n const newTranslations = {};\n this.replaceApplicationPrefixedKeys(translations);\n for (const key of Object.keys(translations)) {\n newTranslations[this.snakeToCamelCase(key)] = translations[key];\n }\n return newTranslations;\n }\n /**\n * Overrides keys with value from key with application prefix.\n *\n * @param keys Object of key/value.\n */\n replaceApplicationPrefixedKeys(keys) {\n const application = this.localizationPrefixApplication;\n if (application) {\n for (const key of Object.keys(keys)) {\n const pairs = key.split('__');\n if (pairs.length > 1 && pairs[0] === application) {\n keys[pairs[1]] = keys[key];\n }\n if (pairs.length > 1) {\n delete keys[key];\n }\n }\n }\n }\n /**\n * Parses URL:s.\n *\n * @param urls URL:s.\n * @param storeId Store id.\n * @param langId Langauge id.\n * @returns Parsed URL:s.\n */\n getUrls(urls, storeId, langId) {\n const { country, language } = LocaleUtility.getCountryAndLanguage(this.locale);\n const newUrls = {};\n for (const key of Object.keys(urls)) {\n newUrls[key] = urls[key]\n .replace('{country}', country)\n .replace('{language}', language)\n .replace('{storeId}', storeId)\n .replace('{langId}', langId);\n }\n return newUrls;\n }\n /**\n * Parses endpoints.\n *\n * @param endpoints Endpoints.\n * @returns Parsed endpoints.\n */\n getEndpoints(endpoints) {\n const { country, language } = LocaleUtility.getCountryAndLanguage(this.locale);\n const newEndpoints = {};\n for (const key of Object.keys(endpoints)) {\n newEndpoints[key] = endpoints[key]\n .replace('{country}', country)\n .replace('{language}', language)\n .replace('{retailUnit}', country?.toUpperCase())\n .replace('{locale}', this.locale);\n }\n return newEndpoints;\n }\n /**\n * Formats a lower camel case string into upper snake case (translation key).\n *\n * @param string String to format.\n * @returns Formatted string.\n */\n snakeToCamelCase(string) {\n if (/[^A-Z0-9_]/.test(string)) {\n return string;\n }\n return string\n .toLowerCase()\n .replace(/([_][a-z0-9])/gi, (chars) => chars.toUpperCase().replace('_', ''));\n }\n}\n//# sourceMappingURL=OversattaTransformer.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport { LocaleUtility } from '@inter-ikea-kompis/utilities';\nimport ServiceFetch from '../../utilities/ServiceFetch.js';\nimport OversattaTransformer from './OversattaTransformer.js';\n/**\n * This service is used for fetching localization information from ÖVERSÄTTA.\n */\nexport default class OversattaService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.localizationPrefixApplication Localization prefix application.\n * @param options.localizationEndpoints Localization endpoints.\n * @param [options.localizationOverrides] Localization overrides.\n * @param options.locale Locale.\n */\n constructor(options) {\n this.localizationPrefixApplication = options.localizationPrefixApplication;\n this.localizationEndpoints = options.localizationEndpoints;\n this.localizationOverrides = options.localizationOverrides;\n this.locale = options.locale;\n }\n /**\n * Fetches and returns translations.\n *\n * @returns Promise object.\n */\n async getLocalizedInformation() {\n const responses = await Promise.all(this.localizationEndpoints.map((url) => this.fetch(url)));\n const transformer = new OversattaTransformer({\n localizationPrefixApplication: this.localizationPrefixApplication,\n locale: this.locale\n });\n const transformed = [];\n for (const response of responses) {\n transformed.push(transformer.transform(response));\n }\n if (this.localizationOverrides) {\n transformed.push(transformer.transform(this.localizationOverrides));\n }\n return this.mergeLocalizedInformation(transformed);\n }\n /**\n * Merges multiple localized information.\n *\n * @param localizedInformations Array of localized informations.\n * @returns Merged localized informations.\n */\n mergeLocalizedInformation(localizedInformations) {\n const merged = Object.assign({}, ...localizedInformations);\n for (const key of Object.keys(merged)) {\n merged[key] = Object.assign({}, ...localizedInformations.map((localizedInformation) => localizedInformation[key]));\n }\n return merged;\n }\n /**\n * Fetches and returns translations.\n *\n * @param url URL.\n * @returns Promise object.\n */\n async fetch(url) {\n const { country, language } = LocaleUtility.getCountryAndLanguage(this.locale);\n if (!country || !language) {\n throw new ServiceException('Country or language is not defined. Format locale correctly, e.g. en-GB');\n }\n const parsedUrl = url.replace('{country}', country).replace('{language}', language);\n return await ServiceFetch.json(parsedUrl, {\n credentials: 'same-origin'\n });\n }\n}\n//# sourceMappingURL=OversattaService.js.map","import { GlobalCacheStore } from '@inter-ikea-kompis/utilities';\nimport CacheStoreType from '../../enums/CacheStoreType.js';\nimport OversattaService from '../../services/localization/OversattaService.js';\n/**\n * @deprecated Use TranslationsService for translations (Phrase) and SettingsService for settings (DEXF).\n * This class is used as a simple interface for translation services.\n */\nexport default class LocalizationService {\n /**\n * Constructor.\n *\n * @param options Options.\n */\n constructor(options) {\n this.localizationPrefixApplication = options.localizationPrefixApplication;\n this.localizationEndpoints = options.localizationEndpoints;\n this.localizationOverrides = options.localizationOverrides;\n this.locale = options.locale;\n this.cache = options.cache || new GlobalCacheStore();\n }\n /**\n * Fetches and returns translations.\n *\n * @returns Promise object.\n */\n async getLocalizedInformation() {\n const cacheStore = this.cache.getStore(CacheStoreType.localization);\n const endpointsCacheKey = JSON.stringify(this.localizationEndpoints);\n const overridesCacheKey = this.localizationOverrides\n ? JSON.stringify(this.localizationOverrides)\n : '';\n const localizedCacheKey = this.locale + endpointsCacheKey + overridesCacheKey;\n const queueCacheKey = this.locale + endpointsCacheKey + overridesCacheKey + 'queue';\n const cachedLocalized = cacheStore.get(localizedCacheKey);\n const cachedQueue = cacheStore.get(queueCacheKey);\n const newQueue = [];\n if (cachedLocalized) {\n return cachedLocalized;\n }\n if (cachedQueue) {\n return new Promise((resolve, reject) => cachedQueue.push({ resolve, reject }));\n }\n cacheStore.set(queueCacheKey, newQueue);\n const service = new OversattaService({\n localizationPrefixApplication: this.localizationPrefixApplication,\n localizationEndpoints: this.localizationEndpoints,\n localizationOverrides: this.localizationOverrides,\n locale: this.locale\n });\n let localizedInformation;\n try {\n localizedInformation = await service.getLocalizedInformation();\n }\n catch (error) {\n for (const item of newQueue) {\n item.reject(error);\n }\n throw error;\n }\n cacheStore.set(localizedCacheKey, localizedInformation);\n cacheStore.delete(queueCacheKey);\n for (const item of newQueue) {\n item.resolve(localizedInformation);\n }\n return localizedInformation;\n }\n}\n//# sourceMappingURL=LocalizationService.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport { DexfSettingsUtility } from '@inter-ikea-kompis/utilities';\nimport LocalizationService from '../facades/localization/LocalizationService.js';\n/**\n *\n */\nexport default class DexfConfiguration {\n constructor(options) {\n this.settingsOptions = options;\n }\n /**\n * Returns the dexf API key that has been set.\n * If no key has been set or can't be fetched an exception will be thrown.\n */\n async getDexfApiKeyOrThrow() {\n if (this.dexfApiKey) {\n return this.dexfApiKey;\n }\n if (this.settingsOptions.dexfApiKey) {\n this.dexfApiKey = this.settingsOptions.dexfApiKey;\n }\n else {\n const localizedInformation = await this.getLocalizedInformation();\n this.dexfApiKey = localizedInformation.localization.dexfApiKey;\n }\n if (!this.dexfApiKey) {\n throw new ServiceException('DEXF API Key not set');\n }\n return this.dexfApiKey;\n }\n /**\n * Get the DEXF settings, either through the already provided DEXF settings object, or by fetching Översätta settings and transforming them to DEXF settings.\n *\n * @returns Promise of DEXF settings.\n */\n async getSettings() {\n if (this.settings) {\n return this.settings;\n }\n if (this.settingsOptions.settings) {\n this.settings = this.settingsOptions.settings;\n }\n else {\n const localizedInformation = await this.getLocalizedInformation();\n this.settings = DexfSettingsUtility.parseLocalizedInformation(localizedInformation);\n }\n return this.settings;\n }\n /**\n *\n */\n async getLocalizedInformation() {\n if (!this.localizedInformation) {\n const { locale, localizationPrefixApplication, localizationEndpoints, localizationOverrides, cache } = this.settingsOptions;\n if (!localizationEndpoints || !locale) {\n throw new ServiceException('Options to fetch localized information not set.');\n }\n const localizationService = new LocalizationService({\n localizationPrefixApplication: localizationPrefixApplication,\n localizationEndpoints: localizationEndpoints,\n localizationOverrides: localizationOverrides,\n locale: locale,\n cache: cache\n });\n this.localizedInformation = await localizationService.getLocalizedInformation();\n }\n return this.localizedInformation;\n }\n}\n//# sourceMappingURL=DexfConfiguration.js.map","var ChinaAuthenticationServiceCookieNameEnum;\n(function (ChinaAuthenticationServiceCookieNameEnum) {\n ChinaAuthenticationServiceCookieNameEnum[\"accessToken\"] = \"accessToken\";\n ChinaAuthenticationServiceCookieNameEnum[\"refreshToken\"] = \"refreshToken\";\n})(ChinaAuthenticationServiceCookieNameEnum || (ChinaAuthenticationServiceCookieNameEnum = {}));\nexport default ChinaAuthenticationServiceCookieNameEnum;\n//# sourceMappingURL=ChinaAuthenticationServiceCookieNameEnum.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport ServiceFetch from '../../../utilities/ServiceFetch.js';\nimport ChinaAuthenticationServiceCookieNameEnum from './ChinaAuthenticationServiceCookieNameEnum.js';\n/**\n * This service is used for handling authentication in China.\n */\nexport default class ChinaAuthenticationService {\n constructor(options) {\n this.loginIntervalTime = 500;\n this.refreshTokenEndpoint = options.refreshTokenEndpoint;\n this.loginPageEndpoint = options.loginPageEndpoint;\n }\n /**\n * Authenticates and returns token.\n *\n * @returns Promise.\n */\n async getToken() {\n const accessToken = this.getCookie(ChinaAuthenticationServiceCookieNameEnum.accessToken);\n const refreshToken = this.getCookie(ChinaAuthenticationServiceCookieNameEnum.refreshToken);\n if (accessToken) {\n return accessToken;\n }\n else if (refreshToken) {\n return await this.refreshAccessToken(refreshToken);\n }\n return await this.login();\n }\n /**\n * Request the user to login.\n *\n * @returns Access token.\n */\n login() {\n return new Promise((resolve, reject) => {\n this.removeCookie(ChinaAuthenticationServiceCookieNameEnum.accessToken);\n this.removeCookie(ChinaAuthenticationServiceCookieNameEnum.refreshToken);\n const popup = window.open(this.loginPageEndpoint);\n let intervalId = null;\n intervalId = setInterval(() => {\n const accessToken = this.getCookie(ChinaAuthenticationServiceCookieNameEnum.accessToken);\n if (accessToken) {\n if (intervalId)\n clearInterval(intervalId);\n popup?.close();\n resolve(accessToken);\n }\n else if (popup?.closed) {\n reject(new ServiceException('Failed to login. The popup was closed.'));\n }\n }, this.loginIntervalTime);\n });\n }\n /**\n * @returns \"true\" if access and/or refresh token cookie exists.\n */\n hasCookie() {\n const accessToken = this.getCookie(ChinaAuthenticationServiceCookieNameEnum.accessToken);\n const refreshToken = this.getCookie(ChinaAuthenticationServiceCookieNameEnum.refreshToken);\n return accessToken !== null || refreshToken !== null;\n }\n /**\n * Refreshes the access token.\n *\n * @param refreshToken Refresh token.\n * @returns Access token.\n */\n async refreshAccessToken(refreshToken) {\n const response = await ServiceFetch.json(this.refreshTokenEndpoint, {\n method: 'post',\n credentials: 'same-origin',\n headers: {\n 'content-type': 'application/json',\n 'x-client-channel': 'WEB',\n 'x-client-platform': 'PcWeb',\n source: 'PLANNER'\n },\n body: JSON.stringify({\n refreshToken\n })\n });\n if (!response.data && response.code) {\n if (response.code === 'InvalidParameter.Refresh.Token.Error') {\n return this.login();\n }\n throw new ServiceException(`Failed to refresh access token. Error: ${response.code}`);\n }\n this.setCookie(ChinaAuthenticationServiceCookieNameEnum.accessToken, response.data.id_token, response.data.expires_in * 1000);\n return response.data.id_token;\n }\n /**\n * Removes a cookie.\n *\n * @param name Name.\n */\n removeCookie(name) {\n this.setCookie(name, '', -1000);\n }\n /**\n * Sets a cookie.\n *\n * @param name Name.\n * @param value Value.\n * @param expiresIn Expires in.\n */\n setCookie(name, value, expiresIn) {\n const date = new Date();\n date.setTime(date.getTime() + expiresIn);\n document.cookie = `${name}=${value}; path=/; expires=${date.toUTCString()};`;\n }\n /**\n * Returns a cookie.\n *\n * @param name Name.\n * @returns Cookie value.\n */\n getCookie(name) {\n const cookie = document.cookie.match('(^|;)\\\\s*' + name + '\\\\s*=\\\\s*([^;]+)');\n return cookie?.pop() ?? null;\n }\n}\n//# sourceMappingURL=ChinaAuthenticationService.js.map","import { ConnectionProblemException, ServiceException, UnableToParseServerResponseException } from '@inter-ikea-kompis/exceptions';\nimport ServiceFetch from '../../../utilities/ServiceFetch.js';\n/**\n * This service handles IOWS authentication.\n */\nexport default class IowsAuthenticationService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.consumer Consumer.\n * @param options.contract Contract.\n * @param options.endpoint Endpoint.\n */\n constructor(options) {\n this.consumer = options.consumer;\n this.contract = options.contract;\n this.endpoint = options.endpoint;\n }\n /**\n * Authenticates and returns an IOWS user.\n *\n * @returns Promise.\n */\n async getUser() {\n let response;\n try {\n response = await window.fetch(this.endpoint, {\n headers: this.getHeaders(),\n credentials: 'include'\n });\n }\n catch (error) {\n throw new ConnectionProblemException(this.endpoint);\n }\n if (response.status === 419) {\n await this.clearUser();\n return await this.getUser();\n }\n let data;\n try {\n data = await response.json();\n }\n catch (error) {\n throw new UnableToParseServerResponseException(response);\n }\n if (!data.SessionContext) {\n throw new ServiceException('Failed to fetch user. Response data did not include SessionContext.');\n }\n return {\n id: String(data.SessionContext.UserId.$)\n };\n }\n /**\n * Clears user session.\n *\n * @returns Promise object.\n */\n async clearUser() {\n await ServiceFetch.json(this.endpoint, {\n method: 'DELETE',\n headers: this.getHeaders(),\n credentials: 'include'\n });\n }\n /**\n * Returns headers.\n *\n * @returns Headers.\n */\n getHeaders() {\n return {\n accept: 'application/vnd.ikea.iows+json;version=2',\n 'auth-token': this.consumer + '-' + this.contract,\n consumer: this.consumer,\n contract: this.contract\n };\n }\n}\n//# sourceMappingURL=IowsAuthenticationService.js.map","import ServiceFetch from '../../../utilities/ServiceFetch.js';\n/**\n * This service handles NIF authentication.\n */\nexport default class NifAuthenticationService {\n constructor(options) {\n this.endpoint = options.endpoint;\n }\n /**\n * Authenticates the user.\n *\n * @returns Promise.\n */\n async authenticate() {\n await ServiceFetch.text(`${this.endpoint}/context`, {\n method: 'GET',\n headers: {\n Accept: 'application/json'\n },\n credentials: 'include'\n });\n }\n}\n//# sourceMappingURL=NifAuthenticationService.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport { GlobalCacheStore } from '@inter-ikea-kompis/utilities';\nconst CONNECTION_TIMEOUT = 15000;\n/**\n * Service fetch utility.\n */\nexport default class IframeManager {\n /**\n * Constructor.\n *\n * @param url Iframe URL.\n * @param cacheStore Cache store.\n */\n constructor(url, cacheStore = new GlobalCacheStore()) {\n this.isConnected = false;\n this.url = url;\n this.cache = cacheStore.getStore('iframeManager');\n }\n /**\n * Connects the iframe.\n *\n * @returns Iframe.\n */\n getIframe() {\n return new Promise((resolve, reject) => {\n const cacheItem = this.cache.get(this.url);\n if (cacheItem) {\n if (!this.isConnected) {\n cacheItem.connectedCount++;\n }\n if (cacheItem.error) {\n reject(cacheItem.error);\n }\n else if (cacheItem.connectionTimeout === null) {\n resolve(cacheItem.iframe);\n }\n else {\n cacheItem.resolves.push(resolve);\n cacheItem.rejects.push(reject);\n }\n }\n else {\n const iframe = document.createElement('iframe');\n const cacheItemDefault = {\n connectedCount: 1,\n iframe,\n connectionTimeout: null,\n resolves: [resolve],\n rejects: [reject],\n error: null\n };\n cacheItemDefault.connectionTimeout = this.getConnectionTimeout(cacheItemDefault);\n this.cache.set(this.url, cacheItemDefault);\n iframe.addEventListener('load', this.onIframeLoad.bind(this, cacheItemDefault));\n iframe.src = this.url;\n iframe.style.display = 'none';\n document.body.appendChild(iframe);\n }\n this.isConnected = true;\n });\n }\n /**\n * Disconnects the iframe.\n */\n disconnect() {\n const cacheItem = this.cache.get(this.url);\n if (cacheItem) {\n cacheItem.connectedCount--;\n if (cacheItem.connectedCount === 0) {\n if (cacheItem.connectionTimeout)\n clearTimeout(cacheItem.connectionTimeout);\n document.body.removeChild(cacheItem.iframe);\n this.cache.delete(this.url);\n }\n }\n this.isConnected = false;\n }\n /**\n * Triggered on iframe load.\n *\n * @param cacheItem Cache item.\n */\n onIframeLoad(cacheItem) {\n if (cacheItem.connectionTimeout)\n clearTimeout(cacheItem.connectionTimeout);\n cacheItem.connectionTimeout = null;\n if (cacheItem.iframe.contentWindow) {\n const resolves = cacheItem.resolves;\n cacheItem.resolves = [];\n for (const resolve of resolves) {\n resolve(cacheItem.iframe);\n }\n }\n else {\n const rejects = cacheItem.rejects;\n cacheItem.error = new ServiceException('Failed to load iframe. Missing access to iframe.contentWindow.');\n cacheItem.rejects = [];\n for (const reject of rejects) {\n reject(cacheItem.error);\n }\n }\n }\n /**\n * Returns a timeout.\n *\n * @param cacheItem Cache item.\n * @returns Timeout.\n */\n getConnectionTimeout(cacheItem) {\n return setTimeout(() => {\n const rejects = cacheItem.rejects;\n cacheItem.error = new ServiceException('Failed to load iframe. Request timed out. Connection problems? Trying to load: ' + this.url);\n cacheItem.rejects = [];\n for (const reject of rejects) {\n reject(cacheItem.error);\n }\n }, CONNECTION_TIMEOUT);\n }\n}\n//# sourceMappingURL=IframeManager.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport IframeManager from '../../../utilities/IframeManager.js';\n/**\n * This class is used for fetching authentication data.\n */\nexport default class OneWebAuthenticationService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.endpoint Endpoint.\n */\n constructor(options) {\n this.endpoint = options.endpoint;\n }\n /**\n * Authenticates and returns token.\n *\n * @returns Promise.\n */\n async getToken() {\n // When the INGKA Javascript API is available on the same page, we can use it to retrieve the token.\n // This is the case when the footer fragment from INGKA is included using ESI include, or if INGKA includes the planner directly on the page using ESI include.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (window.ikea?.authentication?.getTokens) {\n return await this.getTokenFromIngkaApi(window);\n }\n // When a planner is running under /addon-app/, it is not possible to include the footer fragment from INGKA as we are not under a retail unit path (e.g. /gb/en/).\n // It is also not possible to include the necessary Javascript files as the INGKA API will not be able to read the cookies (as they are set under a retail unit path).\n // In this case, we need to use an iframe with a URL that contains a retail unit path to load the INGKA Javascript API and retrieve the token from there.\n // It is only possible to use this method if the planner is running on the same origin as the endpoint for the iframe as it will otherwise not be possible to access the content window.\n // It will for example not work if a subdomain (e.g. \"planner.ikea.com\") includes an iframe URL with the domain \"www.ikea.com\".\n const iframeManager = new IframeManager(this.endpoint);\n const iframe = await iframeManager.getIframe();\n const token = await this.getTokenFromIngkaApi(iframe.contentWindow);\n iframeManager.disconnect();\n return token;\n }\n /**\n * Returns token from INGKA Javascript API.\n *\n * @param targetWindow Window.\n * @returns Token.\n */\n getTokenFromIngkaApi(targetWindow) {\n return new Promise((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (!targetWindow.ikea?.authentication?.getTokens) {\n reject(new ServiceException('Failed to retrieve token from iframe. \"ikea.authentication.getTokens()\" is not defined.'));\n return;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n targetWindow.ikea.authentication.getTokens((error, tokens) => {\n if (error) {\n reject(new ServiceException('Failed to retrieve token from iframe. Error: ' + error));\n return;\n }\n const token = tokens.auth ? tokens.auth : tokens.guest;\n resolve({\n value: token.value,\n isGuest: !tokens.auth\n });\n });\n });\n }\n}\n//# sourceMappingURL=OneWebAuthenticationService.js.map","import { GlobalCacheStore } from '@inter-ikea-kompis/utilities';\nimport CacheStoreType from '../../enums/CacheStoreType.js';\nimport ChinaAuthenticationService from '../../services/authentication/china/ChinaAuthenticationService.js';\nimport IowsAuthenticationService from '../../services/authentication/iows/IowsAuthenticationService.js';\nimport NifAuthenticationService from '../../services/authentication/nif/NifAuthenticationService.js';\nimport OneWebAuthenticationService from '../../services/authentication/one-web/OneWebAuthenticationService.js';\n/**\n * This class is used for storing items in a queue.\n */\nexport default class AuthenticationQueue {\n /**\n * Constructor.\n *\n * @param cache CacheStore.\n */\n constructor(cache) {\n this.cache = cache || new GlobalCacheStore();\n }\n /**\n * Creates user authentication.\n *\n * @param options Options.\n * @param options.consumer Consumer.\n * @param options.contract Contract.\n * @param options.endpoint IOWS authentication endpoint.\n * @returns Promise object.\n */\n async getAuthenticationIows(options) {\n const cacheKey = 'iowsAuthenticationQueue';\n const cacheStore = this.cache.getStore(CacheStoreType.authentication);\n const queuedPromises = cacheStore.get(cacheKey);\n if (queuedPromises) {\n return new Promise((resolve, reject) => queuedPromises.push({ resolve, reject }));\n }\n const promiseQueue = [];\n const authService = new IowsAuthenticationService(options);\n let authentication;\n cacheStore.set(cacheKey, promiseQueue);\n try {\n authentication = await authService.getUser();\n for (const promise of promiseQueue) {\n promise.resolve(authentication);\n }\n }\n catch (error) {\n for (const promise of promiseQueue) {\n promise.reject(error);\n }\n throw error;\n }\n cacheStore.delete(cacheKey);\n return authentication;\n }\n /**\n * Gets or creates user token.\n *\n * @param options Options.\n * @param options.endpoint OneWeb authentication endpoint.\n * @returns Promise object.\n */\n async getAuthTokenOneWeb(options) {\n const cacheKey = 'oneWebAuthenticationQueue';\n const cacheStore = this.cache.getStore(CacheStoreType.authentication);\n const queuedPromises = cacheStore.get(cacheKey);\n if (queuedPromises) {\n return new Promise((resolve, reject) => queuedPromises.push({ resolve, reject }));\n }\n const promiseQueue = [];\n const authService = new OneWebAuthenticationService(options);\n let authentication = undefined;\n cacheStore.set(cacheKey, promiseQueue);\n try {\n authentication = await authService.getToken();\n for (const promise of promiseQueue) {\n promise.resolve(authentication);\n }\n }\n catch (error) {\n for (const promise of promiseQueue) {\n promise.reject(error);\n }\n }\n cacheStore.delete(cacheKey);\n return authentication;\n }\n /**\n * Gets or creates user token.\n *\n * @param options Options.\n * @param options.refreshTokenEndpoint Refresh token endpoint.\n * @param options.loginPageEndpoint Login endpoint.\n * @param options.login Force login. If omitted trye fetch existing token.\n * @returns Promise object.\n */\n async getAuthTokenChina(options) {\n const cacheKey = 'chinaAuthenticationQueue';\n const cacheStore = this.cache.getStore(CacheStoreType.authentication);\n const queuedPromises = cacheStore.get(cacheKey);\n if (queuedPromises) {\n return new Promise((resolve, reject) => queuedPromises.push({ resolve, reject }));\n }\n const promiseQueue = [];\n const authService = new ChinaAuthenticationService({\n refreshTokenEndpoint: options.refreshTokenEndpoint,\n loginPageEndpoint: options.loginPageEndpoint\n });\n let authentication;\n cacheStore.set(cacheKey, promiseQueue);\n try {\n authentication = await (options.login ? authService.login() : authService.getToken());\n for (const promise of promiseQueue) {\n promise.resolve(authentication);\n }\n }\n catch (error) {\n for (const promise of promiseQueue) {\n promise.reject(error);\n }\n }\n cacheStore.delete(cacheKey);\n return authentication;\n }\n /**\n * Creates user authentication.\n *\n * @param options Options.\n * @param options.endpoint Nif authentication endpoint.\n * @returns Promise object.\n */\n async authenticateNif(options) {\n const cacheKey = 'nifAuthenticationQueue';\n const cacheStore = this.cache.getStore(CacheStoreType.authentication);\n const queuedPromises = cacheStore.get(cacheKey);\n if (queuedPromises) {\n return new Promise((resolve, reject) => queuedPromises.push({ resolve, reject }));\n }\n const promiseQueue = [];\n const authService = new NifAuthenticationService(options);\n let authentication;\n cacheStore.set(cacheKey, promiseQueue);\n try {\n authentication = await authService.authenticate();\n for (const promise of promiseQueue) {\n promise.resolve(authentication);\n }\n }\n catch (error) {\n for (const promise of promiseQueue) {\n promise.reject(error);\n }\n }\n cacheStore.delete(cacheKey);\n return authentication;\n }\n}\n//# sourceMappingURL=AuthenticationQueue.js.map","/**\n * Item handling utility.\n */\nexport default class ItemUtility {\n /**\n * Returns an item string to be used in the request URL.\n *\n * @param items Array of items.\n * @returns Item string.\n */\n static getItemsString(items) {\n return items.map((item) => item.type.toUpperCase() + '-' + item.id).join(',');\n }\n /**\n * Returns item sets based on the maximum allowed items per request.\n *\n * @param items Array of items to parse.\n * @param maxItemsPerRequest Maximum items in the request.\n * @returns Product sets.\n */\n static getItemSets(items, maxItemsPerRequest) {\n const sets = [[]];\n let currentSet = sets[0];\n for (let i = 0, max = items.length; i < max; i++) {\n if (currentSet.length === maxItemsPerRequest) {\n currentSet = [];\n sets.push(currentSet);\n }\n if (items[i].id && items[i].type) {\n currentSet.push(items[i]);\n }\n }\n return sets;\n }\n}\n//# sourceMappingURL=ItemUtility.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport ItemUtility from '../../utilities/ItemUtility.js';\nimport ServiceFetch from '../../utilities/ServiceFetch.js';\n/**\n * This class is used for fetching store availability data.\n */\nexport default class DexfStoreAvailabilityService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.endpoint Endpoint.\n * @param options.dexfApiKey DEXF Api key.\n */\n constructor(options) {\n this.maxItemsPerRequest = 50;\n this.maxNumProducts = 150;\n this.endpoint = options.endpoint;\n this.dexfApiKey = options.dexfApiKey;\n }\n /**\n * Authenticates and returns user.\n *\n * @param storeId Store ID.\n * @param items Item.\n * @returns Promise.\n */\n async getStoreAvailabilities(storeId, items) {\n if (items.length > this.maxNumProducts) {\n throw new ServiceException(`Max number of articles exceeded, ${this.maxNumProducts}. Too many products to be handled by this service. Try using the webplanner service instead.`);\n }\n const sets = ItemUtility.getItemSets(items, this.maxItemsPerRequest);\n const options = {\n credentials: 'same-origin',\n headers: {\n 'dexf-api-key': this.dexfApiKey\n }\n };\n const promises = sets.map((set) => {\n const itemId = ItemUtility.getItemsString(set);\n const url = `${this.endpoint.replace('{storeId}', encodeURIComponent(storeId.replace(/ /g, '')))}?filter.itemId=${itemId}`;\n return ServiceFetch.json(url, options);\n });\n const responses = await Promise.all(promises);\n return this.transformResponse(responses);\n }\n /**\n * Transforms the response and returns only valid items.\n *\n * @param responses Responses.\n * @returns Valid items.\n */\n transformResponse(responses) {\n const result = [];\n for (const response of responses) {\n for (const item of response.data) {\n if (item.valid && item.content) {\n const storeAvailability = {\n itemId: item.itemId,\n content: {\n itemType: item.content.itemType,\n itemNo: item.content.itemNo,\n availableForCashCarry: item.content.availableForCashCarry\n }\n };\n if (item.content.cashCarry) {\n storeAvailability.content.cashCarry = {\n messageType: item.content.cashCarry.messageType,\n unitType: item.content.cashCarry.unitType,\n quantity: item.content.cashCarry.quantity,\n restock: item.content.cashCarry.restock,\n salesLocations: item.content.cashCarry.salesLocations\n };\n if ('inRange' in item.content.cashCarry) {\n storeAvailability.content.cashCarry.inRange = item.content.cashCarry.inRange;\n }\n }\n if (item.content.homeDelivery) {\n storeAvailability.content.homeDelivery = item.content.homeDelivery;\n }\n result.push(storeAvailability);\n }\n }\n }\n return result;\n }\n}\n//# sourceMappingURL=DexfStoreAvailabilityService.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport ItemUtility from '../../utilities/ItemUtility.js';\nimport ServiceFetch from '../../utilities/ServiceFetch.js';\n/**\n * This class is used for fetching store availability data.\n */\nexport default class DexfZipAvailabilityService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.endpoint Endpoint.\n * @param options.dexfApiKey DEXF Api key.\n */\n constructor(options) {\n this.maxItemsPerRequest = 50;\n this.maxNumProducts = 150;\n this.endpoint = options.endpoint;\n this.dexfApiKey = options.dexfApiKey;\n }\n /**\n * Authenticates and returns user.\n *\n * @param zipCode Zip Code.\n * @param items Item.\n * @returns Promise.\n */\n async getZipAvailabilities(zipCode, items) {\n if (items.length > this.maxNumProducts) {\n throw new ServiceException(`Max number of articles exceeded, ${this.maxNumProducts}. Too many products to be handled by this service. Try using the webplanner service instead.`);\n }\n const sets = ItemUtility.getItemSets(items, this.maxItemsPerRequest);\n const options = {\n credentials: 'same-origin',\n headers: {\n 'dexf-api-key': this.dexfApiKey\n }\n };\n const promises = sets.map((set) => {\n const itemId = ItemUtility.getItemsString(set);\n const url = `${this.endpoint.replace('{zipCode}', encodeURIComponent(zipCode.replace(/ /g, '')))}?filter.itemId=${itemId}`;\n return ServiceFetch.json(url, options);\n });\n const responses = await Promise.all(promises);\n return this.transformResponse(responses);\n }\n /**\n * Transforms the response and returns only valid items.\n *\n * @returns Valid items.\n */\n transformResponse(responses) {\n const result = [];\n for (const response of responses) {\n for (const item of response.data) {\n if (item.valid && item.content) {\n const zipAvailability = {\n itemId: item.itemId,\n content: {\n itemType: item.content.itemType,\n itemNo: item.content.itemNo,\n availableForHomeDelivery: item.content.availableForHomeDelivery\n }\n };\n if (item.content.homeDelivery) {\n zipAvailability.content.homeDelivery = {\n messageType: item.content.homeDelivery.messageType,\n quantity: item.content.homeDelivery.quantity\n };\n }\n result.push(zipAvailability);\n }\n }\n }\n return result;\n }\n}\n//# sourceMappingURL=DexfZipAvailabilityService.js.map","import { StoreAvailabilityDataSourceEnum, ZipAvailabilityDataSourceEnum } from '@inter-ikea-kompis/enums';\nimport { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport DexfStoreAvailabilityService from '../../services/store-availability/DexfStoreAvailabilityService.js';\nimport DexfZipAvailabilityService from '../../services/zip-availability/DexfZipAvailabilityService.js';\nimport DexfConfiguration from '../../utilities/DexfConfiguration.js';\n/**\n * This class is used as a simple interface for store availability services.\n */\nexport default class CheckoutAvailabilityService {\n /**\n * Constructor.\n *\n * @param options Options.\n */\n constructor(options) {\n this.dexfConfiguration = new DexfConfiguration(options);\n }\n /**\n * Fetches and returns zip code availability.\n *\n * @param zip Zip Code.\n * @param items Items.\n * @returns Promise.\n */\n async getZipAvailabilities(zip, items) {\n const service = await this.getZipAvailabilityService();\n return await service.getZipAvailabilities(zip, items);\n }\n /**\n * Fetches and returns store availability.\n *\n * @param storeId Store id.\n * @param items Items.\n * @returns Promise.\n */\n async getStoreAvailabilities(storeId, items) {\n const service = await this.getStoreAvailabilityService();\n return await service.getStoreAvailabilities(storeId, items);\n }\n /**\n * Returns DEXF service if the zipAvailabilityDataSource setting\n * for the locale is not set to 'disabled'.\n *\n * @returns Service | null.\n */\n async getZipAvailabilityService() {\n const settings = await this.dexfConfiguration.getSettings();\n const dexfApiKey = await this.dexfConfiguration.getDexfApiKeyOrThrow();\n switch (settings.kompis.serviceSettings.zipAvailabilityDataSource) {\n case ZipAvailabilityDataSourceEnum.disabled:\n throw new ServiceException('The zipAvailabilityDataSource is set to \"disabled\" in the localized information. When it is, the ZipAvailabilityService is not available on the market.');\n default:\n return new DexfZipAvailabilityService({\n endpoint: settings.kompis.endpoints.dexfZipAvailabilityService,\n dexfApiKey: dexfApiKey\n });\n }\n }\n /**\n * Returns DEXF service if the storeAvailabilityDataSource setting\n * for the locale is not set to 'disabled'.\n *\n * @returns Service | null.\n */\n async getStoreAvailabilityService() {\n const settings = await this.dexfConfiguration.getSettings();\n const dexfApiKey = await this.dexfConfiguration.getDexfApiKeyOrThrow();\n switch (settings.kompis.serviceSettings.storeAvailabilityDataSource) {\n case StoreAvailabilityDataSourceEnum.disabled:\n throw new ServiceException('The storeAvailabilityDataSource is set to \"disabled\" in the localized information. When it is, the StoreAvailabilityService is not available on the market.');\n default:\n return new DexfStoreAvailabilityService({\n endpoint: settings.kompis.endpoints.dexfStoreAvailabilityService,\n dexfApiKey: dexfApiKey\n });\n }\n }\n}\n//# sourceMappingURL=CheckoutAvailabilityService.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\n/**\n * Utilities related to BitBox.\n */\nexport default class BitBoxUtility {\n static async readIframeContext(iframe) {\n return await new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n window.removeEventListener('message', messageListener);\n reject(new ServiceException('No response from Bitbox iframe script'));\n }, 1000);\n const messageListener = (event) => {\n let parsedData;\n try {\n parsedData = JSON.parse(event.data);\n }\n catch (error) {\n return;\n }\n if (parsedData.action === 'set_context') {\n window.removeEventListener('message', messageListener);\n clearTimeout(timeout);\n resolve(parsedData.value);\n }\n };\n window.addEventListener('message', messageListener);\n iframe.contentWindow?.postMessage(JSON.stringify({ action: 'get_context' }), '*');\n });\n }\n}\n//# sourceMappingURL=BitBoxUtility.js.map","import BitBoxUtility from '../../utilities/BitBoxUtility.js';\nimport IframeManager from '../../utilities/IframeManager.js';\n/**\n * This class is used for checking cookie consent in bitbox markets.\n */\nexport default class BitboxCookieConsentService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.endpoint Endpoint.\n * @param options.cache Cache store.\n */\n constructor(options) {\n this.endpoint = options.endpoint;\n this.cache = options.cache;\n }\n /**\n * Checks if cookie consent meets a provided level.\n *\n * @param consentLevel Consent level (1-4).\n * @returns Promise of boolean.\n */\n async hasCookieConsent(consentLevel) {\n const iframe = await this.createIframe();\n const result = await BitBoxUtility.readIframeContext(iframe);\n const cookieConsent = result.CookieConsent;\n switch (consentLevel) {\n // These numbers mirror the levels used by OneWeb.\n case 1:\n return cookieConsent.necessary;\n case 2:\n return cookieConsent.statistics;\n case 3:\n return cookieConsent.preferences;\n case 4:\n return cookieConsent.marketing;\n }\n }\n /**\n * Creates and returns iframe element.\n *\n * @returns Promise with iframe.\n */\n async createIframe() {\n if (this.iframeManager && this.iframeManager.url !== this.endpoint) {\n this.iframeManager.disconnect();\n this.iframeManager = null;\n }\n if (!this.iframeManager) {\n this.iframeManager = new IframeManager(this.endpoint, this.cache);\n }\n return await this.iframeManager.getIframe();\n }\n}\n//# sourceMappingURL=BitboxCookieConsentService.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport IframeManager from '../../utilities/IframeManager.js';\nconst COOKIE_NAME = 'ikea_cookieconsent_{countryCode}';\n/**\n * This class is used for checking cookie consent.\n */\nexport default class OneWebCookieConsentService {\n constructor(options) {\n this.iframeManager = null;\n this.endpoint = options.endpoint;\n this.cache = options.cache;\n }\n /**\n * Checks if cookie consent meets a provided level.\n *\n * @param consentLevel Consent level (1-4).\n * @param country Country of the cookie.\n * @returns Promise.\n */\n async hasCookieConsent(consentLevel, country) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (typeof window.ikea?.cookieConsent?.hasConsent === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return window.ikea.cookieConsent.hasConsent(consentLevel);\n }\n const cookie = this.getCookie(country);\n if (cookie) {\n return !!Object.values(cookie)[Object.keys(cookie).indexOf(consentLevel.toString())];\n }\n if (this.iframeManager && this.iframeManager.url !== this.endpoint) {\n this.iframeManager.disconnect();\n this.iframeManager = null;\n }\n if (!this.iframeManager) {\n this.iframeManager = new IframeManager(this.endpoint, this.cache);\n }\n const iframe = await this.iframeManager.getIframe();\n if (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n !iframe.contentWindow?.ikea ||\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n !iframe.contentWindow.ikea.cookieConsent ||\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n !iframe.contentWindow.ikea.cookieConsent.hasConsent) {\n throw new ServiceException('Failed to retrieve cookie consent from iframe. \"ikea.cookieConsent.hasConsent()\" is not defined.');\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return iframe.contentWindow.ikea.cookieConsent.hasConsent(consentLevel);\n }\n /**\n * @param country Country.\n */\n getCookie(country) {\n const cookieName = COOKIE_NAME.replace('{countryCode}', country.toLowerCase()) + '=';\n const decodedCookie = decodeURIComponent(document.cookie);\n const existingCookies = decodedCookie.split(';');\n for (let cookie of existingCookies) {\n while (cookie.charAt(0) == ' ') {\n cookie = cookie.substring(1);\n }\n if (cookie.indexOf(cookieName) == 0) {\n return JSON.parse(cookie.substring(cookieName.length, cookie.length));\n }\n }\n return null;\n }\n}\n//# sourceMappingURL=OneWebCookieConsentService.js.map","import { CookieConsentDataSourceEnum } from '@inter-ikea-kompis/enums';\nimport { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport { GlobalCacheStore, LocaleUtility } from '@inter-ikea-kompis/utilities';\nimport BitboxCookieConsentService from '../../services/cookie-consent/BitboxCookieConsentService.js';\nimport OneWebCookieConsentService from '../../services/cookie-consent/OneWebCookieConsentService.js';\nimport DexfConfiguration from '../../utilities/DexfConfiguration.js';\n/**\n * This class is used as a simple interface for cookie consent services.\n */\nexport default class CookieConsentService {\n /**\n * Constructor.\n *\n * @param options Localization service options or a localized information object.\n */\n constructor(options) {\n this.localizedInformation = null;\n if ('localizedServiceOptions' in options) {\n this.localizedInformation = options.localizedServiceOptions ?? null;\n }\n else {\n this.dexfConfiguration = new DexfConfiguration(options);\n }\n if ('cache' in options && options.cache) {\n this.cache = options.cache;\n }\n else {\n this.cache = new GlobalCacheStore();\n }\n this.locale = options.locale;\n }\n /**\n * Checks if cookie consent meets a provided level.\n *\n * @param consentLevel Consent level (1-4).\n * @returns Promise.\n */\n async hasCookieConsent(consentLevel) {\n const localizedInformation = await this.getLocalizedInformation();\n const cookieConsentDataSource = localizedInformation.localization.cookieConsentDataSource;\n switch (cookieConsentDataSource) {\n case CookieConsentDataSourceEnum.disabled:\n return true;\n case CookieConsentDataSourceEnum.block:\n return false;\n case CookieConsentDataSourceEnum.bitbox:\n return await this.hasCookieConsentBitbox(consentLevel, localizedInformation);\n case CookieConsentDataSourceEnum.oneWeb:\n return await this.hasCookieConsentOneWeb(consentLevel, localizedInformation);\n default:\n return false;\n }\n }\n async hasCookieConsentBitbox(consentLevel, localizedInformation) {\n return await new BitboxCookieConsentService({\n endpoint: localizedInformation.endpoints.bitboxCookieConsentService,\n cache: this.cache\n }).hasCookieConsent(consentLevel);\n }\n async hasCookieConsentOneWeb(consentLevel, localizedInformation) {\n const country = LocaleUtility.getCountryAndLanguage(this.locale).country;\n if (!country) {\n throw new ServiceException(`Locale does not contain country. Bad format: ${this.locale}`);\n }\n return await new OneWebCookieConsentService({\n endpoint: localizedInformation.endpoints.oneWebCookieConsentService,\n cache: this.cache\n }).hasCookieConsent(consentLevel, country);\n }\n /**\n *\n * @returns Get either the provided localized information or fetch a new/cached one using localization service options.\n */\n async getLocalizedInformation() {\n if (this.localizedInformation) {\n return this.localizedInformation;\n }\n const settings = await this.dexfConfiguration.getSettings();\n return {\n localization: {\n cookieConsentDataSource: settings.kompis.serviceSettings.cookieConsentDataSource\n },\n endpoints: {\n oneWebCookieConsentService: settings.kompis.endpoints.oneWebCookieConsentService,\n bitboxCookieConsentService: settings.kompis.endpoints.bitboxCookieConsentService\n }\n };\n }\n}\n//# sourceMappingURL=CookieConsentService.js.map","import { ServerErrorResponseException, ServiceException } from '@inter-ikea-kompis/exceptions';\nimport ServiceFetch from '../../utilities/ServiceFetch.js';\n/**\n * OneWeb financing service.\n */\nexport default class OneWebFinancingService {\n /**\n * @param endpoint The endpoint to the API.\n * @param fragmentLocationBaseUrl The base URL of the fragment content location, needed for proxy server.\n * @param price The price of the solution.\n * @returns Promise of financing option.\n * @throws ServiceException if price is negative or if any part of the fetched financing option data is invalid.\n * @throws ServerErrorResponseException if API endpoint is not found or if fetch to API endpoint fails.\n */\n async getFinancingOption(endpoint, fragmentLocationBaseUrl, price) {\n if (price < 0) {\n throw new ServiceException('Negative price.');\n }\n const priceWithTwoDecimals = price.toFixed(2);\n const endpointWithPrice = `${endpoint.replace('{totalPrice}', priceWithTwoDecimals)}`;\n const response = await fetch(endpointWithPrice);\n this.validateResponse(response);\n const data = await response.json();\n const { anchor, anchorLink, fragmentLocation, moreInfoAnchor, moreInfoLink } = this.getValidFinancingOptionData(data);\n const content = await this.fetchFragmentContent(fragmentLocation, fragmentLocationBaseUrl);\n const financingOption = {\n anchor,\n anchorLink,\n content,\n moreInfoAnchor,\n moreInfoLink\n };\n return financingOption;\n }\n /**\n * Validate the reponse.\n *\n * @param response The response from INGKA financing service API.\n */\n validateResponse(response) {\n if (response.status === 404) {\n throw new ServerErrorResponseException(response, 'There was no financing option available for the market.');\n }\n if (!response.ok) {\n throw new ServerErrorResponseException(response, 'Something went wrong when fetching from Ingka financing service.');\n }\n }\n /**\n * Get the validated financing option data.\n *\n * @param data Unvalidated JSON data from the external API, in camel case format.\n * @param data.anchor Anchor text used for button/link.\n * @param data.anchor_link Optional anchor link for anchor.\n * @param data.fragment_location URL to fragment.\n * @param data.read_more_anchor Anchor text for \"read more\" link.\n * @param data.read_more_link Link used as href when read_more_anchor is clicked.\n */\n getValidFinancingOptionData(data) {\n return {\n anchor: this.getValidatedPropWithLength(data.anchor, 'anchor'),\n anchorLink: data.anchor_link ?? null,\n fragmentLocation: this.getValidatedPropWithLength(data.fragment_location, 'fragment_location'),\n moreInfoAnchor: this.getValidatedPropWithLength(data.read_more_anchor, 'read_more_anchor'),\n moreInfoLink: this.getValidatedPropWithLength(data.read_more_link, 'read_more_link')\n };\n }\n /**\n * @param prop The prop to validate.\n * @param propName The name of the property.\n * @returns The validated prop if valid.\n * @throws ServiceException if invalid prop.\n */\n getValidatedPropWithLength(prop, propName) {\n if (prop?.length) {\n return prop;\n }\n throw new ServiceException(`Invalid financing option. Missing ${propName} or it is empty.`);\n }\n /**\n * @param fragmentLocation The fragment location.\n * @param fragmentLocationBaseUrl The base URL of the fragment content location, needed for proxy server.\n * @returns The HTML content of the fragment as text.\n */\n async fetchFragmentContent(fragmentLocation, fragmentLocationBaseUrl) {\n const updatedFragmentLocation = fragmentLocation.replace('https://www.ikea.com', fragmentLocationBaseUrl);\n const content = await ServiceFetch.text(updatedFragmentLocation);\n if (!content?.length) {\n throw new ServiceException('No fragment content found.');\n }\n return content;\n }\n}\n//# sourceMappingURL=OneWebFinancingService.js.map","import { FinancingOptionDataSourceEnum } from '@inter-ikea-kompis/enums';\nimport { PriceUtility, TotalPriceCalculator } from '@inter-ikea-kompis/utilities';\nimport OneWebFinancingService from '../../services/financing/OneWebFinancingService.js';\nimport DexfConfiguration from '../../utilities/DexfConfiguration.js';\n/**\n * Financing service used to fetch a financing option for a customer's solution.\n */\nexport default class FinancingService {\n /**\n * Constructor.\n *\n * @param options IFinancingServiceOptions.\n */\n constructor(options) {\n this.dexfConfiguration = new DexfConfiguration(options);\n }\n /**\n * Fetches and returns financial services data.\n *\n * @param shoppingProducts The shopping products of the current solution.\n * @returns Promise of financing option, or null if not supported by the market.\n * @throws Different errors if fetching financing option fails in some way (see {@link OneWebFinancingService.getFinancingOption}).\n */\n async getFinancingOption(shoppingProducts) {\n const settings = await this.dexfConfiguration.getSettings();\n if (settings.kompis.serviceSettings.financingOptionDataSource ===\n FinancingOptionDataSourceEnum.disabled) {\n return null;\n }\n const price = TotalPriceCalculator.calculate(shoppingProducts, settings.localisation.dateFormat);\n return await new OneWebFinancingService().getFinancingOption(settings.kompis.endpoints.oneWebFinancingService, settings.kompis.endpoints.oneWebFinancingServiceFragmentBaseUrl ?? '', PriceUtility.getPrice(price));\n }\n}\n//# sourceMappingURL=FinancingService.js.map","import { LocaleUtility } from '@inter-ikea-kompis/utilities';\n/**\n * This class is used for transforming data from DEXF Settings.\n */\nexport default class DexfSettingsTransformer {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.locale Locale.\n */\n constructor(options) {\n this.locale = options.locale;\n }\n /**\n * Transforms data into a DexfSettings model.\n *\n * @param data Response data to parse.\n * @returns IDexfSettings model.\n */\n transform(data) {\n const storeId = data.kompis?.localization?.storeId ? data.kompis.localization.storeId : null;\n const langId = data.kompis?.localization?.langId ? data.kompis.localization.langId : null;\n const dexfSettings = {\n kompis: {\n endpoints: this.getEndpoints(data.kompis?.endpoints || {}),\n urls: this.getUrls(data.kompis?.urls || {}, storeId, langId),\n serviceSettings: (data.kompis?.serviceSettings || {}),\n localization: (data.kompis?.localization || {}),\n priceSettings: (data.kompis?.priceSettings || {})\n },\n localisation: (data.localisation || {})\n };\n // Include all custom settings which the teams could have\n for (const key of Object.keys(data)) {\n if (!dexfSettings[key]) {\n dexfSettings[key] = data[key];\n }\n }\n return dexfSettings;\n }\n /**\n * Parses URL:s.\n *\n * @param urls URL:s.\n * @param storeId Store id.\n * @param langId Language id.\n * @returns Parsed URL:s.\n */\n getUrls(urls, storeId, langId) {\n const { country, language } = LocaleUtility.getCountryAndLanguage(this.locale);\n const newUrls = {};\n for (const key of Object.keys(urls)) {\n newUrls[key] = urls[key]\n .replace('{country}', country)\n .replace('{language}', language)\n .replace('{storeId}', storeId)\n .replace('{langId}', langId);\n }\n return newUrls;\n }\n /**\n * Parses endpoints.\n *\n * @param endpoints Endpoints.\n * @returns Parsed endpoints.\n */\n getEndpoints(endpoints) {\n const { country, language } = LocaleUtility.getCountryAndLanguage(this.locale);\n const newEndpoints = {};\n for (const key of Object.keys(endpoints)) {\n newEndpoints[key] = endpoints[key]\n .replace('{country}', country)\n .replace('{language}', language)\n .replace('{retailUnit}', country?.toUpperCase())\n .replace('{locale}', this.locale);\n }\n return newEndpoints;\n }\n}\n//# sourceMappingURL=DexfSettingsTransformer.js.map","import { DexfSettingsEnvironmentEnum } from '@inter-ikea-kompis/enums';\nimport { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport { LocaleUtility } from '@inter-ikea-kompis/utilities';\nimport ServiceFetch from '../../utilities/ServiceFetch.js';\nimport DexfSettingsTransformer from './DexfSettingsTransformer.js';\nconst DEXF_QA = 'https://api.dexf.qa.ikeadt.com';\nconst DEXF_PROD = 'https://api.dexf.ikea.com';\n/**\n * This service is used for fetching setting configuration from DEXF.\n */\nexport default class DexfSettingsService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.dexfApiKey DEXF API key.\n * @param options.environment ...\n */\n constructor(options) {\n this.dexfApiKey = options.dexfApiKey;\n this.endpoint = `${options.environment === DexfSettingsEnvironmentEnum.development ? DEXF_QA : DEXF_PROD}/setting/v1/data/apps/{appId}/retail-units/{retailUnit}/locales/{language}-{country}`;\n }\n /**\n * Fetches setting configuration assigned to an application in DEXF.\n *\n * @param dexfApplicationId ...\n * @param locale ...\n * @param filterSegment ...\n * @returns Promise.\n */\n async getApplicationSettings(dexfApplicationId, locale, filterSegment) {\n const { country, language } = LocaleUtility.getCountryAndLanguage(locale);\n if (!country || !language) {\n throw new ServiceException('Country or language is not defined. Format locale correctly, e.g. en-GB');\n }\n const url = `${this.endpoint}${filterSegment ? `?filter.segment=${filterSegment}` : ''}`\n .replace('{appId}', dexfApplicationId)\n .replace('{retailUnit}', country.toUpperCase())\n .replace('{language}', language)\n .replace('{country}', country.toUpperCase());\n const response = await ServiceFetch.json(url, {\n credentials: 'same-origin',\n headers: {\n 'dexf-api-key': this.dexfApiKey\n }\n });\n const transformer = new DexfSettingsTransformer({ locale });\n const transformedResponse = transformer.transform(response);\n return transformedResponse;\n }\n}\n//# sourceMappingURL=DexfSettingsService.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport DexfSettingsService from '../../services/localization/DexfSettingsService.js';\n/**\n * This class is used as a simple interface for settings configuration services.\n */\nexport default class SettingsService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.dexfApiKey ...\n * @param options.dexfApplicationId ...\n * @param options.locale ...\n */\n constructor(options) {\n this.dexfApiKey = options.dexfApiKey;\n this.dexfEnvironment = options.dexfEnvironment;\n this.dexfApplicationId = options.dexfApplicationId;\n this.locale = options.locale;\n }\n /**\n * Fetches and returns configuration settings from DEXF.\n *\n * @param filterSegment ...\n * @returns Promise object.\n */\n async getApplicationSettings(filterSegment) {\n if (!this.dexfApiKey) {\n throw new ServiceException('Failed to fetch application settings. The configuration \"dexfApiKey\" has not been defined. Send it in to the constructor of SettingsService.');\n }\n if (!this.dexfApplicationId) {\n throw new ServiceException('Failed to fetch application settings. The configuration \"dexfApplicationId\" has not been defined. Send it in to the constructor of SettingsService.');\n }\n if (!this.locale) {\n throw new ServiceException('Failed to fetch application settings. The configuration \"locale\" has not been defined. Send it in to the constructor of SettingsService.');\n }\n const service = new DexfSettingsService({\n dexfApiKey: this.dexfApiKey,\n environment: this.dexfEnvironment\n });\n const configurationSettings = await service.getApplicationSettings(this.dexfApplicationId, this.locale, filterSegment);\n return configurationSettings;\n }\n}\n//# sourceMappingURL=SettingsService.js.map","/**\n * This class is used for transforming translations data.\n */\nexport default class TranslationsTransformer {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.translationPrefixApplication Translation prefix application.\n */\n constructor(options) {\n this.translationPrefixApplication = options?.translationPrefixApplication || null;\n }\n /**\n * Transforms data into a ITranslations model.\n *\n * @param data Response data to parse.\n * @returns Localized information model.\n */\n transform(data) {\n return this.replaceApplicationPrefixInKeys(data);\n }\n /**\n * Recursively replaces application prefix in all keys in the object.\n *\n * @param objectOrString Object or string.\n */\n replaceApplicationPrefixInKeys(objectOrString) {\n if (!objectOrString || typeof objectOrString === 'string') {\n return objectOrString;\n }\n const objectWithUpdatedKeys = {};\n for (const key in objectOrString) {\n const updatedKey = this.replaceApplicationPrefixInKey(key);\n if (updatedKey) {\n objectWithUpdatedKeys[updatedKey] = this.replaceApplicationPrefixInKeys(objectOrString[key]);\n }\n }\n return objectWithUpdatedKeys;\n }\n /**\n * @param key The key to replace application prefix in.\n */\n replaceApplicationPrefixInKey(key) {\n const application = this.translationPrefixApplication;\n if (!application) {\n return key;\n }\n const pairs = key.split('__');\n if (pairs.length > 1 && pairs[0] === application) {\n return pairs[1];\n }\n // We should remove other application prefixed keys that don't match the application.\n if (pairs.length > 1) {\n return null;\n }\n return key;\n }\n}\n//# sourceMappingURL=TranslationsTransformer.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport { LocaleUtility } from '@inter-ikea-kompis/utilities';\nimport ServiceFetch from '../../utilities/ServiceFetch.js';\nimport TranslationsTransformer from './TranslationsTransformer.js';\n/**\n * This service is used for fetching and transforming translations.\n */\nexport default class InternalTranslationsService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.translationPrefixApplication Translation prefix application.\n * @param options.translationEndpoints Translation endpoints.\n * @param options.locale Locale.\n */\n constructor(options) {\n this.translationPrefixApplication = options.translationPrefixApplication;\n this.translationEndpoints = options.translationEndpoints;\n this.locale = options.locale;\n }\n /**\n * Fetches and returns translations.\n *\n * @returns Promise object.\n */\n async getTranslations() {\n const responses = await Promise.all(this.translationEndpoints.map((url) => this.fetch(url)));\n const transformer = new TranslationsTransformer({\n translationPrefixApplication: this.translationPrefixApplication\n });\n const transformed = responses.map((response) => transformer.transform(response));\n return this.mergeTranslations(transformed);\n }\n /**\n * Merges multiple translations.\n *\n * @param translations Array of translations.\n * @returns Merged translations.\n */\n mergeTranslations(translations) {\n const merged = Object.assign({}, ...translations);\n for (const key of Object.keys(merged)) {\n merged[key] = Object.assign({}, ...translations.map((translations) => translations[key]));\n }\n return merged;\n }\n /**\n * Fetches and returns translations.\n *\n * @param url URL.\n * @returns Promise object.\n */\n async fetch(url) {\n const { country, language } = LocaleUtility.getCountryAndLanguage(this.locale);\n if (!country || !language) {\n throw new ServiceException('Country or language is not defined. Format locale correctly, e.g. en-GB');\n }\n const parsedUrl = url\n .replace('{country}', country.toUpperCase())\n .replace('{language}', language);\n return await ServiceFetch.json(parsedUrl, {\n credentials: 'same-origin'\n });\n }\n}\n//# sourceMappingURL=InternalTranslationsService.js.map","import { GlobalCacheStore } from '@inter-ikea-kompis/utilities';\nimport CacheStoreType from '../../enums/CacheStoreType.js';\nimport InternalTranslationsService from '../../services/localization/InternalTranslationsService.js';\n/**\n * This class is used as a simple interface for translation services.\n */\nexport default class TranslationsService {\n /**\n * Constructor.\n *\n * @param options Options.\n */\n constructor(options) {\n this.translationPrefixApplication = options.translationPrefixApplication;\n this.translationEndpoints = options.translationEndpoints;\n this.locale = options.locale;\n this.cache = options.cache || new GlobalCacheStore();\n }\n /**\n * Fetches and returns translations.\n *\n * @returns Promise object.\n */\n async getTranslations() {\n const cacheStore = this.cache.getStore(CacheStoreType.translations);\n const endpointsCacheKey = JSON.stringify(this.translationEndpoints);\n const translationsCacheKey = this.locale + endpointsCacheKey;\n const queueCacheKey = this.locale + endpointsCacheKey + 'queue';\n const cachedTranslations = cacheStore.get(translationsCacheKey);\n if (cachedTranslations) {\n return cachedTranslations;\n }\n const cachedQueue = cacheStore.get(queueCacheKey);\n if (cachedQueue) {\n return new Promise((resolve, reject) => cachedQueue.push({ resolve, reject }));\n }\n const newQueue = [];\n cacheStore.set(queueCacheKey, newQueue);\n const service = new InternalTranslationsService({\n translationPrefixApplication: this.translationPrefixApplication,\n translationEndpoints: this.translationEndpoints,\n locale: this.locale\n });\n let translations;\n try {\n translations = await service.getTranslations();\n }\n catch (error) {\n for (const item of newQueue) {\n item.reject(error);\n }\n throw error;\n }\n cacheStore.set(translationsCacheKey, translations);\n cacheStore.delete(queueCacheKey);\n for (const item of newQueue) {\n item.resolve(translations);\n }\n return translations;\n }\n}\n//# sourceMappingURL=TranslationsService.js.map","import { NotificationLinkTypeEnum } from '@inter-ikea-kompis/enums';\nimport { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport ServiceFetch from '../../utilities/ServiceFetch.js';\n/**\n * This class is used for sending a saved planner configuration to a user through email.\n */\nexport default class DexfNotificationService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.endpoint Endpoint.\n * @param options.dexfApiKey DEXF API key.\n */\n constructor(options) {\n this.endpoint = options.endpoint;\n this.dexfApiKey = options.dexfApiKey;\n }\n /**\n * Sends an email with a configuration to a user.\n *\n * @param options Options.\n * @param options.vpcCode Vpc code.\n * @param options.emailAddress Email address.\n * @param options.linkType Destination for the link. Planner or pickinglist.\n * @param options.storeId Store ID. Configurable for pickinglist.\n * @returns Sent notification status.\n */\n async sendNotification(options) {\n const preparedMessageUrl = await this.prepareMessage(options.vpcCode, options.linkType, options.storeId);\n if (!preparedMessageUrl) {\n throw new ServiceException('Failed to get preparedMessageUrl. Service did not return url.');\n }\n const response = await ServiceFetch.json(preparedMessageUrl, {\n credentials: 'same-origin',\n method: 'POST',\n headers: this.getHeaders(),\n body: this.getBody(options.emailAddress)\n });\n if (response.jobId === undefined) {\n throw new ServiceException('Failed to get jobId. Service did not return jobID.');\n }\n }\n /**\n * Prepares message template and returns prepared reference object.\n *\n * @param vpcCode VpcCode ex '34WY5'.\n * @param linkType Destination for the link. Planner or pickinglist.\n * @param storeId Store ID. Configurable for pickinglist.\n * @returns Prepared message url.\n */\n async prepareMessage(vpcCode, linkType, storeId) {\n const baseUrl = this.endpoint;\n let url = `${baseUrl}/${vpcCode}/prepare?type=email&linkType=${linkType}`;\n if (storeId && NotificationLinkTypeEnum.pickinglist === linkType) {\n url += `&storeCode=${storeId}`;\n }\n const response = await ServiceFetch.json(url, {\n credentials: 'same-origin',\n method: 'GET',\n headers: this.getHeaders()\n });\n if (response._links) {\n return decodeURI(response._links.send.href);\n }\n return null;\n }\n /**\n * Returns body for notification.\n *\n * @param emailAddress Email address.\n * @returns Stringified body.\n */\n getBody(emailAddress) {\n return JSON.stringify({\n to: emailAddress\n });\n }\n /**\n * Returns headers.\n *\n * @returns Headers.\n */\n getHeaders() {\n return {\n 'dexf-api-key': this.dexfApiKey,\n 'content-type': 'application/json'\n };\n }\n}\n//# sourceMappingURL=DexfNotificationService.js.map","import { NotificationDataSourceEnum } from '@inter-ikea-kompis/enums';\nimport { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport DexfNotificationService from '../../services/notification/DexfNotificationService.js';\nimport DexfConfiguration from '../../utilities/DexfConfiguration.js';\n/**\n * This class is used as an interface for Dexf notification service.\n */\nexport default class NotificationService {\n /**\n * Constructor.\n *\n * @param options Options.\n */\n constructor(options) {\n this.dexfConfiguration = new DexfConfiguration(options);\n }\n /**\n * Send planner configuration to user via Email.\n *\n * @param options Notification Options.\n * @param options.vpcCode Vpc code.\n * @param options.email Email address.\n * @param options.linkType Link type.\n * @param options.storeId Store ID. Configurable for pickinglist.\n * @returns True if sent.\n */\n async sendEmail(options) {\n const service = await this.getService();\n const { vpcCode, email, linkType, storeId } = options;\n return await service.sendNotification({\n vpcCode,\n emailAddress: email,\n linkType,\n storeId\n });\n }\n /**\n * Returns service.\n *\n * @returns Service.\n */\n async getService() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const dexfApiKey = await this.dexfConfiguration.getDexfApiKeyOrThrow();\n switch (kompis.serviceSettings.notificationDataSource) {\n case NotificationDataSourceEnum.disabled:\n throw new ServiceException(`The notificationDataSource is set to \"Disabled\". When it is, the notification functionality should be disabled in the planner.`);\n default:\n return new DexfNotificationService({\n endpoint: kompis.endpoints.dexfNotificationService,\n dexfApiKey: dexfApiKey\n });\n }\n }\n}\n//# sourceMappingURL=NotificationService.js.map","import { IframeUtility } from '@inter-ikea-kompis/utilities';\n/**\n * This class handles communication with the IRW application through post message.\n */\nexport default class IrwPlatformCommunication {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.applicationName Application name.\n */\n constructor(options) {\n this.applicationName = options.applicationName;\n }\n /**\n * Sets the iframe container height.\n *\n * @param height Height to set.\n */\n setIframeHeight(height) {\n if (IframeUtility.isInsideIframe()) {\n window.parent.postMessage({\n header: {\n name: 'setContainerSize'\n },\n body: {\n height: height,\n containerName: this.getContainerName()\n }\n }, '*');\n }\n }\n /**\n * Sets the cart count.\n *\n * @param cartCount Cart count to set.\n */\n setCartCount(cartCount) {\n if (IframeUtility.isInsideIframe()) {\n window.parent.postMessage({\n header: {\n name: 'shoppingcartCount'\n },\n body: {\n count: cartCount,\n containerName: this.getContainerName()\n }\n }, '*');\n }\n }\n /**\n * Returns the iframe container name.\n *\n * @returns Iframe container name.\n */\n getContainerName() {\n return '#' + this.applicationName + '-application';\n }\n}\n//# sourceMappingURL=IrwPlatformCommunication.js.map","import { IframeUtility } from '@inter-ikea-kompis/utilities';\n/**\n * This class handles communication with the ROIG application through post message.\n */\nexport default class RoigPlatformCommunication {\n /**\n * Sets the iframe container height.\n *\n * @param height Height to set.\n */\n setIframeHeight(height) {\n if (IframeUtility.isInsideIframe()) {\n window.parent.postMessage({\n method: 'setHeight',\n parameters: {\n height\n }\n }, '*');\n }\n }\n /**\n * Adds items to shopping bag.\n *\n * @param items List of items.\n * @param vpcCode VPC code.\n */\n addToCart(items, vpcCode) {\n if (IframeUtility.isInsideIframe()) {\n window.parent.postMessage({\n method: 'addToShoppingBag',\n parameters: {\n items: items.map((item) => {\n return { ID: item.id, Type: item.type, Qty: item.quantity };\n }),\n vpcCode\n }\n }, '*');\n }\n }\n /**\n * Sets the cart count.\n *\n * @param cartCount Cart count to set.\n */\n setCartCount(cartCount) {\n if (IframeUtility.isInsideIframe()) {\n window.parent.postMessage({\n method: 'setCartCount',\n parameters: {\n cartCount: cartCount\n }\n }, '*');\n }\n }\n}\n//# sourceMappingURL=RoigPlatformCommunication.js.map","import { ApiPlatformEnum } from '@inter-ikea-kompis/enums';\nimport DexfConfiguration from '../../utilities/DexfConfiguration.js';\nimport IrwPlatformCommunication from '../../utilities/platform-communication/IrwPlatformCommunication.js';\nimport RoigPlatformCommunication from '../../utilities/platform-communication/RoigPlatformCommunication.js';\n/**\n * This class is used as a interface for platform services.\n */\nexport default class PlatformService {\n /**\n * Constructor.\n *\n * @param options Options.\n */\n constructor(options) {\n this.applicationName = options.applicationName;\n this.dexfConfiguration = new DexfConfiguration(options);\n }\n /**\n * Sets the iframe container height.\n *\n * @param height Height in pixels.\n * @returns Promise object.\n */\n async setIframeHeight(height) {\n const { kompis } = await this.dexfConfiguration.getSettings();\n switch (kompis.serviceSettings.apiPlatform) {\n case ApiPlatformEnum.roig:\n new RoigPlatformCommunication().setIframeHeight(height);\n break;\n }\n /*\n Communicate via the standard API no matter what since we don't know if a\n NIF/ROIG market has implemented the new one or not.\n */\n new IrwPlatformCommunication({ applicationName: this.applicationName }).setIframeHeight(height);\n }\n}\n//# sourceMappingURL=PlatformService.js.map","import { ProductOptionalFieldNameEnum } from '@inter-ikea-kompis/enums';\nconst KompisDefaultFields = [\n ProductOptionalFieldNameEnum.priceInformation,\n ProductOptionalFieldNameEnum.priceUnit,\n ProductOptionalFieldNameEnum.child,\n ProductOptionalFieldNameEnum.measureReference,\n ProductOptionalFieldNameEnum.measure,\n ProductOptionalFieldNameEnum.packageMeasure,\n ProductOptionalFieldNameEnum.customerBenefit,\n ProductOptionalFieldNameEnum.customerBenefitSummary,\n ProductOptionalFieldNameEnum.goodToKnow,\n ProductOptionalFieldNameEnum.peopleAndPlanet,\n ProductOptionalFieldNameEnum.image,\n ProductOptionalFieldNameEnum.video,\n ProductOptionalFieldNameEnum.technicalInformation,\n ProductOptionalFieldNameEnum.complianceTechnical,\n ProductOptionalFieldNameEnum.complianceInformation,\n ProductOptionalFieldNameEnum.complianceLabel,\n ProductOptionalFieldNameEnum.careInstruction,\n ProductOptionalFieldNameEnum.customerMaterial\n];\nexport default KompisDefaultFields;\n//# sourceMappingURL=KompisDefaultFields.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport { GlobalCacheStore } from '@inter-ikea-kompis/utilities';\nimport CacheStoreType from '../../enums/CacheStoreType.js';\n/**\n * This class is used for storing and loading products from cache.\n */\nexport default class ProductCache {\n /**\n * Constructor.\n *\n * @param [locale] Locale.\n * @param [cache] Cache store.\n */\n constructor(locale, cache = null) {\n this.products = new Map();\n if (cache && !cache.getStore) {\n throw new ServiceException('Failed to instanciate facade. Expected second parameter to be of type CacheStore.');\n }\n this.locale = locale;\n this.cache = cache || new GlobalCacheStore();\n }\n /**\n * Returns multiple cached products.\n *\n * @param items Array of items.\n * @param fields Fields.\n * @returns Products and missing items.\n */\n getProducts(items, fields) {\n const searchableProductMap = this.getSearchableProductMap(fields);\n const products = [];\n const missing = [];\n for (const item of items) {\n const product = searchableProductMap[this.getProductCacheKey(item)];\n if (product) {\n products.push(product);\n }\n else {\n missing.push(item);\n }\n }\n return { products, missing };\n }\n /**\n * Adds multiple products.\n *\n * @param products Products.\n * @param fields Fields.\n */\n addProducts(products, fields) {\n for (const product of products) {\n this.addProduct(product, fields);\n }\n }\n /**\n * Removes products that has been added to this instance from cache.\n \n */\n removeProducts(products) {\n for (const product of products) {\n this.removeProduct(product);\n }\n }\n /**\n * Clears all products that has been added to this instance from cache.\n */\n clear() {\n for (const product of Array.from(this.products.values())) {\n this.removeProduct(product);\n }\n }\n /**\n * Returns map that can be used for when searching for a product item.\n *\n * @param fields Fields.\n * @returns Product items.\n */\n getSearchableProductMap(fields) {\n const store = this.cache.getStore(CacheStoreType.product);\n let merged = {};\n for (const key of Array.from(store.keys())) {\n if (key.startsWith('items-' + this.locale)) {\n const cachedFields = key.replace('items-' + this.locale + '-', '').split('_');\n let hasMatch = true;\n for (let i = 0, max = fields.length; i < max; i++) {\n if (!cachedFields.includes(fields[i])) {\n hasMatch = false;\n break;\n }\n }\n if (hasMatch) {\n merged = Object.assign(merged, store.get(key));\n }\n }\n }\n return merged;\n }\n /**\n * Returns map that can be used for storing products.\n *\n * @param fields Fields.\n * @returns Product items.\n */\n getStorableProductMap(fields) {\n const store = this.cache.getStore(CacheStoreType.product);\n const cacheKey = this.getFieldsCacheKey(fields);\n const productMap = store.get(cacheKey);\n if (productMap) {\n return productMap;\n }\n const newProductMap = {};\n store.set(cacheKey, newProductMap);\n return newProductMap;\n }\n /**\n * Returns fields cache key.\n *\n * @param fields Fields.\n * @returns Cache key.\n */\n getFieldsCacheKey(fields) {\n return 'items-' + this.locale + '-' + fields.sort().join('_');\n }\n /**\n * Returns cache key for an item.\n *\n * @param item Product item.\n * @returns Cache key.\n */\n getProductCacheKey(item) {\n return item.type.toLowerCase() + item.id;\n }\n /**\n * Removes a product that has been added to this instance from cache.\n */\n removeProduct(product) {\n const store = this.cache.getStore(CacheStoreType.product);\n const [type, id] = product.itemId.split('-');\n const cacheKey = this.getProductCacheKey({ id, type });\n if (this.products.get(cacheKey)) {\n this.products.delete(cacheKey);\n }\n for (const items of Array.from(store.values())) {\n if (items[cacheKey]) {\n delete items[cacheKey];\n }\n }\n }\n /**\n * Adds a product to cache.\n *\n * @param product Product.\n * @param fields Fields.\n */\n addProduct(product, fields) {\n const productMap = this.getStorableProductMap(fields);\n const [type, id] = product.itemId.split('-');\n const cacheKey = this.getProductCacheKey({ id, type });\n this.products.set(cacheKey, product);\n productMap[cacheKey] = product;\n }\n}\n//# sourceMappingURL=ProductCache.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport ItemUtility from '../../utilities/ItemUtility.js';\nimport ServiceFetch from '../../utilities/ServiceFetch.js';\n/**\n * This class is used for fetching product data.\n */\nexport default class DexfWebplannerService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.endpoint Endpoint.\n * @param options.dexfApiKey DEXF API key.\n */\n constructor(options) {\n this.maxItemsPerRequest = 50;\n this.endpoint = options.endpoint;\n this.dexfApiKey = options.dexfApiKey;\n }\n /**\n * Fetches items from DEXF.\n *\n * @param items Array of items.\n * @param fields Fields.\n * @param params Optional params.\n * @returns Promise.\n */\n async getProducts(items, fields, params = {}) {\n if (!fields) {\n throw new ServiceException('You have to specify fields to fetch product information.');\n }\n const sortedFields = fields.slice();\n const sets = ItemUtility.getItemSets(items, this.maxItemsPerRequest);\n const options = {\n credentials: 'same-origin',\n headers: {\n 'dexf-api-key': this.dexfApiKey\n }\n };\n sortedFields.sort();\n const promises = sets.map((set) => {\n const itemId = ItemUtility.getItemsString(set);\n const url = `${this.endpoint}?filter.itemId=${itemId}&fields=${sortedFields.join(',')}${this.getOptionalQueryString(params)}`;\n return ServiceFetch.json(url, options);\n });\n const parts = await Promise.all(promises);\n const products = [];\n for (const part of parts) {\n for (const item of part.data) {\n products.push(this.parseProduct(item));\n }\n }\n return products;\n }\n /**\n * Fetches all items assigned to an application from DEXF.\n *\n * @param dexfApplicationId DEXF application ID.\n * @param fields Fields.\n * @param params Optional params.\n * @returns Promise.\n */\n async getApplicationProducts(dexfApplicationId, fields, params = {}) {\n if (!fields) {\n throw new ServiceException('You have to specify fields to fetch product information.');\n }\n const sortedFields = fields.slice();\n sortedFields.sort();\n const url = `${this.endpoint}?filter.appId=${dexfApplicationId}&fields=${sortedFields.join(',')}${this.getOptionalQueryString(params)}`;\n const response = await ServiceFetch.json(url, {\n credentials: 'same-origin',\n headers: {\n 'dexf-api-key': this.dexfApiKey\n }\n });\n const products = [];\n for (const item of response.data) {\n products.push(this.parseProduct(item));\n }\n return products;\n }\n /**\n * Get optional query string.\n *\n * @param params Optional params.\n * @returns Query string.\n */\n getOptionalQueryString(params) {\n let qs = '';\n if (params.tags && params.tags.length > 0) {\n qs += `&filter.tags=${params.tags.join(',')}`;\n }\n if (params.valid !== undefined) {\n qs += `&filter.valid=${params.valid}`;\n }\n if (params.customParams) {\n for (const param in params.customParams) {\n qs += `&${param}=${params.customParams[param]}`;\n }\n }\n return qs;\n }\n /**\n * Parses product data.\n *\n * @param data Data.\n * @returns Item string.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parseProduct(data) {\n return {\n reason: data.reason || [],\n valid: data.valid || false,\n itemId: data.itemId || null,\n content: data.content ? this.parseProductContent(data.content) : null\n };\n }\n /**\n * Parses product content data.\n *\n * @param data Data.\n * @returns Item string.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parseProductContent(data) {\n return {\n itemType: data.itemType || null,\n itemNoGlobal: data.itemNoGlobal || null,\n itemNoLocal: data.itemNoLocal || null,\n ruItemType: data.ruItemType || null,\n ruItemNo: data.ruItemNo || null,\n breathTakingItem: data.breathTakingItem || false,\n name: data.name || null,\n mainTypeCode: data.mainTypeCode || null,\n mainTypeName: data.mainTypeName || null,\n typeCode: data.typeCode || null,\n typeName: data.typeName || null,\n validDesignText: data.validDesignText || null,\n colourDotCode: data.colourDotCode || null,\n colourDotUrl: data.colourDotUrl || null,\n requiresAssembly: data.requiresAssembly || null,\n appConfig: data.appConfig || null,\n measure: data.measure || null,\n packageMeasure: data.packageMeasure || null,\n priceInformation: data.priceInformation || null,\n image: data.image || null,\n video: data.video || null,\n goodToKnow: data.goodToKnow || null,\n customerBenefit: data.customerBenefit || null,\n customerBenefitSummary: data.customerBenefitSummary || null,\n complianceTechnical: data.complianceTechnical || null,\n complianceLabel: data.complianceLabel || null,\n complianceInformation: data.complianceInformation || null,\n technicalInformation: data.technicalInformation || null,\n peopleAndPlanet: data.peopleAndPlanet || null,\n careInstruction: data.careInstruction || null,\n customerMaterial: data.customerMaterial || null,\n filterAttribute: data.filterAttribute || null,\n validDesignPart: data.validDesignPart || null,\n priceUnit: data.priceUnit || null,\n child: data.child || null,\n fullyLocalized: data.fullyLocalized || null,\n presentationGroupCode: data.presentationGroupCode || null,\n assemblyTime: data.assemblyTime || null,\n genericProduct: data.genericProduct || null,\n measureReference: data.measureReference || null,\n reason: data.reason || null,\n document: data.document || null,\n complementaryItem: data.complementaryItem || null,\n asset: data.asset || null,\n saleEndDateTime: data.saleEndDateTime || null,\n saleEndDateText: data.saleEndDateText || null\n };\n }\n}\n//# sourceMappingURL=DexfWebplannerService.js.map","/**\n * This class is used for storing items in a queue.\n */\nexport default class ProductItemQueue {\n constructor() {\n this.items = {};\n this.timeout = null;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n this.callbacks = [];\n }\n /**\n * Releases waiting in queue.\n *\n * @param callbacks Callbacks.\n */\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n releaseWaiting(callbacks) {\n for (const callback of callbacks) {\n callback({ items: [], callbacks: [] });\n }\n }\n /**\n * Retrieves items in queue.\n *\n * @param items Array of items.\n * @returns Promise.\n */\n async retrieveItems(items\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n ) {\n this.addItems(items);\n return new Promise((resolve) => {\n if (this.timeout !== null) {\n this.callbacks.push(resolve);\n }\n else {\n this.timeout = window.setTimeout(() => {\n const items = Object.values(this.items);\n const callbacks = this.callbacks;\n this.callbacks = [];\n this.timeout = null;\n this.items = {};\n resolve({ items, callbacks });\n });\n }\n });\n }\n /**\n * Adds items to queue.\n *\n * @param items Array of items.\n */\n addItems(items) {\n for (const item of items) {\n this.items[item.type.toLowerCase() + item.id] = item;\n }\n }\n}\n//# sourceMappingURL=ProductItemQueue.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport { GlobalCacheStore } from '@inter-ikea-kompis/utilities';\nimport CacheStoreType from '../../enums/CacheStoreType.js';\nimport DexfWebplannerService from '../../services/product/DexfWebplannerService.js';\nimport DexfConfiguration from '../../utilities/DexfConfiguration.js';\nimport ProductCache from './ProductCache.js';\nimport ProductItemQueue from './ProductItemQueue.js';\n/**\n * This class is used as a simple interface for product services.\n */\nexport default class ProductService {\n /**\n * Constructor.\n *\n * @param options Options.\n */\n constructor(options) {\n this.locale = options.locale;\n this.dexfApplicationId = options.dexfApplicationId || null;\n this.cache = options.cache || new GlobalCacheStore();\n this.cacheStore = this.cache.getStore(CacheStoreType.product);\n this.productCache = new ProductCache(options.locale, this.cache);\n this.dexfConfiguration = new DexfConfiguration(options);\n }\n /**\n * Fetches and returns products.\n *\n * @param items Array of items.\n * @param fields Fields.\n * @param params Optional params.\n * @returns Promise.\n */\n async getProducts(items, fields, params) {\n const cached = this.productCache.getProducts(items, fields);\n if (cached.missing.length === 0) {\n return cached.products;\n }\n const productItemQueueKey = 'queue-' + this.locale + '-' + fields.sort().join('_');\n let productItemQueue = this.cacheStore.get(productItemQueueKey);\n if (!productItemQueue) {\n productItemQueue = new ProductItemQueue();\n this.cacheStore.set(productItemQueueKey, productItemQueue);\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n const callbacks = [];\n let itemsAndCallbacks = { items, callbacks };\n itemsAndCallbacks = await productItemQueue.retrieveItems(cached.missing);\n if (itemsAndCallbacks.items.length > 0) {\n const service = await this.getService();\n const products = await service.getProducts(itemsAndCallbacks.items, fields, params);\n this.productCache.addProducts(products, fields);\n productItemQueue.releaseWaiting(itemsAndCallbacks.callbacks);\n }\n return this.productCache.getProducts(items, fields).products;\n }\n /**\n * Returns an Array of fetched ShoppingProduct objects.\n *\n * @param shoppingItems Array of ShoppingItem.\n * @param fields Fields.\n * @returns Array of ShoppingProduct objects.\n */\n async getShoppingProducts(shoppingItems, fields) {\n const products = await this.getProducts(shoppingItems, fields);\n const shoppingItemsMap = {};\n for (const shoppingItem of shoppingItems) {\n const type = shoppingItem.type.toLowerCase();\n shoppingItemsMap[type + '-' + shoppingItem.id] = shoppingItem;\n }\n return products.map((product) => {\n if (!product.content) {\n return {\n product,\n quantity: shoppingItemsMap[product.itemId.toLowerCase()].quantity\n };\n }\n const itemType = product.content.itemType?.toLowerCase();\n const item = shoppingItemsMap[itemType + '-' + product.content.itemNoLocal] ||\n shoppingItemsMap[itemType + '-' + product.content.itemNoGlobal];\n return {\n product,\n quantity: item.quantity\n };\n });\n }\n /**\n * Fetches and returns all products for a planner.\n *\n * @param fields Fields.\n * @param params Optional params.\n * @returns Promise.\n */\n async getApplicationProducts(fields, params) {\n if (!this.dexfApplicationId) {\n throw new ServiceException('Failed to fetch application products. The configuration \"dexfApplicationId\" has not been defined. Send it in to the constructor of ProductService.');\n }\n const service = await this.getService();\n const products = await service.getApplicationProducts(this.dexfApplicationId, fields, params);\n this.productCache.addProducts(products, fields);\n return products;\n }\n /**\n * Returns service.\n *\n * @returns Service.\n */\n async getService() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const dexfApiKey = await this.dexfConfiguration.getDexfApiKeyOrThrow();\n return new DexfWebplannerService({\n endpoint: kompis.endpoints.dexfWebplannerService,\n dexfApiKey\n });\n }\n}\n//# sourceMappingURL=ProductService.js.map","import ServiceFetch from '../../../../utilities/ServiceFetch.js';\n/**\n * This class handles adding items to the China cart.\n */\nexport default class ChinaCartService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.endpoint Endpoint.\n */\n constructor(options) {\n this.endpoint = options.endpoint;\n }\n /**\n * Adds items to shopping cart in IRW.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @param options.token Token.\n * @param options.designCode VPC/design code to group articles in checkout.\n * @returns Promise object.\n */\n async addToCart(options) {\n await ServiceFetch.json(`${this.endpoint}/add-planner-design-to-cart`, {\n method: 'post',\n credentials: 'same-origin',\n headers: this.getHeaders(options.token),\n body: this.getAddToCartBody(options.items, options.designCode)\n });\n const cartCount = await this.getCartCount(options);\n return {\n cartCount,\n errorList: []\n };\n }\n /**\n * Returns cart count for a shopping cart.\n *\n * @param options Options.\n * @param options.token Token.\n * @returns Promise object.\n */\n async getCartCount(options) {\n const response = await ServiceFetch.json(this.endpoint, {\n method: 'get',\n credentials: 'same-origin',\n headers: this.getHeaders(options.token)\n });\n let quantity = 0;\n for (const item of response.items) {\n quantity += item.quantity;\n }\n return quantity;\n }\n /**\n * Returns the body.\n *\n * @param items Items.\n * @param designCode VPC Code to group articles with.\n * @returns Add to cart body.\n */\n getAddToCartBody(items, designCode) {\n return JSON.stringify({\n products: items.map((item) => ({\n productFullId: (item.type.toUpperCase() === 'SPR' ? 's' : '') + item.id,\n quantity: item.quantity\n })),\n designCode\n });\n }\n /**\n * Returns headers.\n *\n * @param token Token.\n * @returns Headers.\n */\n getHeaders(token) {\n return {\n 'content-type': 'application/json',\n 'x-client-channel': 'WEB',\n 'x-client-platform': 'PcWeb',\n authorization: `Bearer ${token}`\n };\n }\n}\n//# sourceMappingURL=ChinaCartService.js.map","export default {\n 10001: 'INVALID_ITEM_NUMBER'\n};\n//# sourceMappingURL=IksaShoppingBagErrorCodes.js.map","import { IksaShoppingBagTypeEnum } from '@inter-ikea-kompis/enums';\nimport { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport ServiceFetch from '../../../utilities/ServiceFetch.js';\nimport IksaShoppingBagErrorCodes from './IksaShoppingBagErrorCodes.js';\n/**\n * This class handles CRUD operations for IKSA shopping cart API.\n */\nexport default class IksaShoppingBagService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.consumer Consumer.\n * @param options.contract Contract.\n * @param options.endpoint Endpoint.\n */\n constructor(options) {\n this.consumer = options.consumer;\n this.contract = options.contract;\n this.endpoint = options.endpoint;\n }\n /**\n * Adds items to shopping cart.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.items Array of shopping items.\n * @returns Promise object.\n */\n async addToCart(options) {\n return await this.addToBag({\n userId: options.userId,\n items: options.items,\n shoppingBagType: IksaShoppingBagTypeEnum.cart\n });\n }\n /**\n * Adds items to shopping list.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.items Array of shopping items.\n * @param options.shoppingListName List name.\n * @returns Promise object.\n */\n async addToList(options) {\n const cart = await this.addToBag({\n userId: options.userId,\n items: options.items,\n shoppingBagType: IksaShoppingBagTypeEnum.list,\n shoppingListName: options.shoppingListName\n });\n return { listCount: cart.cartCount, errorList: cart.errorList };\n }\n /**\n * Returns cart count for a shopping cart.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @returns Promise object.\n */\n async getCartCount(options) {\n const cartInfo = await this.getCartInfo({\n userId: options.userId,\n shoppingBagType: IksaShoppingBagTypeEnum.cart\n });\n return cartInfo\n ? (await this.getCart({\n userId: options.userId,\n shoppingBagType: IksaShoppingBagTypeEnum.cart,\n cartId: cartInfo.id\n })).cartCount\n : 0;\n }\n /**\n * Returns list count from a shopping list.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.shoppingListName List name.\n * @returns Promise object.\n */\n async getListCount(options) {\n const cartInfo = await this.getCartInfo({\n userId: options.userId,\n shoppingBagType: IksaShoppingBagTypeEnum.list,\n shoppingListName: options.shoppingListName\n });\n return cartInfo\n ? (await this.getCart({\n userId: options.userId,\n shoppingBagType: IksaShoppingBagTypeEnum.list,\n cartId: cartInfo.id\n })).cartCount\n : 0;\n }\n /**\n * Adds items to shopping bag.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.items Array of shopping items.\n * @param options.shoppingBagType Cart type.\n * @param options.shoppingListName List name.\n * @returns Promise of ICart.\n */\n async addToBag(options) {\n const cartInfo = await this.getCartInfo({\n userId: options.userId,\n shoppingBagType: options.shoppingBagType\n });\n if (cartInfo !== null) {\n return await this.updateShoppingBagItems({ ...options, cartId: cartInfo.id });\n }\n return await this.createBag({\n items: options.items,\n userId: options.userId,\n shoppingBagType: options.shoppingBagType,\n shoppingListName: options.shoppingListName\n });\n }\n /**\n * Returns cart information (name and id) if a cart exists.\n * Returns null if the cart doesn't exist.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.shoppingBagType Cart type.\n * @param options.shoppingListName List name.\n * @returns Promise of IIksaShoppingBagCartInfo or null.\n */\n async getCartInfo(options) {\n const response = await ServiceFetch.json(this.getEndpointUrl(options.userId, options.shoppingBagType), {\n headers: this.getHeaders(),\n credentials: 'include'\n });\n const iksaResponse = response;\n if (iksaResponse.length === 0) {\n return null;\n }\n const cart = iksaResponse[0];\n return {\n id: cart.bagId,\n type: cart.bagType,\n name: options.shoppingListName ?? null\n };\n }\n /**\n * Returns a shopping cart.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.cartId Cart id.\n * @param options.shoppingBagType Cart type.\n * @returns Promise object.\n */\n async getCart(options) {\n const endpointUrl = this.getEndpointUrl(options.userId, options.shoppingBagType);\n const url = `${endpointUrl}/${options.cartId}`;\n const response = await ServiceFetch.json(url, {\n headers: this.getHeaders(),\n credentials: 'include'\n });\n return this.parseShoppingBagResponse(response);\n }\n /**\n * @param response The response to parse.\n * @returns ICart parsed from response.\n */\n parseShoppingBagResponse(response) {\n if ('errorList' in response) {\n return this.parseShoppingBagErrorResponse(response);\n }\n return this.parseShoppingBagSuccessResponse(response);\n }\n /**\n * @param response The error response to parse.\n * @returns ICart parsed from error response.\n */\n parseShoppingBagErrorResponse(response) {\n const errorList = [];\n for (const error of response.errorList) {\n const items = [];\n for (const attributes of error.errorAttributeList ?? []) {\n items.push(attributes.value);\n }\n const code = error.errorCode ? IksaShoppingBagErrorCodes[error.errorCode] : null;\n errorList.push({\n message: error.errorMessage ?? '',\n code: code ?? '',\n items\n });\n }\n return {\n cartCount: null,\n errorList\n };\n }\n /**\n * @param response The success response to parse.\n * @returns ICart parsed from success response.\n */\n parseShoppingBagSuccessResponse(response) {\n const itemList = response.shoppingBagSectionList?.[0];\n if (!itemList || !itemList.shoppingBagItemList) {\n throw new ServiceException('Unexpected shopping bag response!');\n }\n let cartCount = 0;\n const items = itemList.shoppingBagItemList;\n for (const item of items) {\n cartCount += Number(item.itemQty);\n }\n return { cartCount, errorList: [] };\n }\n /**\n * Updates shopping bag items.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.shoppingBagType Cart type.\n * @param options.cartId Cart id.\n * @param options.items Items to use.\n * @returns Promise object.\n */\n async updateShoppingBagItems(options) {\n const endpointUrl = this.getEndpointUrl(options.userId, options.shoppingBagType);\n const url = `${endpointUrl}/${options.cartId}/items`;\n const response = await ServiceFetch.text(url, {\n method: 'PUT',\n headers: this.getHeaders(),\n credentials: 'include',\n body: JSON.stringify(this.createUpdateShoppingBagItemsRequestBody(options.items))\n });\n if (typeof response === 'string' && response.startsWith('{\"errorList\"')) {\n return this.parseShoppingBagErrorResponse(JSON.parse(response));\n }\n return await this.getCart(options);\n }\n /**\n * @param items The shopping items to add to shopping bag.\n * @returns Request body including the shopping items.\n */\n createUpdateShoppingBagItemsRequestBody(items) {\n const itemList = [];\n for (const item of items) {\n this.validateItem(item);\n itemList.push({\n itemType: item.type,\n itemNo: item.id,\n itemQty: item.quantity\n });\n }\n return itemList;\n }\n /**\n * Creates a shopping bag.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.shoppingBagType Cart type.\n * @param options.items Items to use.\n * @param options.shoppingListName List name.\n * @returns Promise of ICart.\n */\n async createBag(options) {\n const url = this.getEndpointUrl(options.userId, options.shoppingBagType);\n const modelOptions = {\n userId: options.userId,\n items: options.items,\n shoppingBagType: options.shoppingBagType,\n shoppingListName: options.shoppingListName\n };\n const response = await ServiceFetch.json(url, {\n method: 'POST',\n headers: this.getHeaders(),\n credentials: 'include',\n body: JSON.stringify(this.createShoppingCartRequestBody(modelOptions))\n });\n return this.parseShoppingBagResponse(response);\n }\n /**\n * Generates a shopping cart request body.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.shoppingBagType Cart type.\n * @param options.items Items to use.\n * @param options.shoppingListName List name.\n * @returns Shopping cart request body.\n */\n createShoppingCartRequestBody(options) {\n const shoppingListName = options.shoppingListName || options.shoppingBagType;\n return {\n bagType: options.shoppingBagType.toUpperCase(),\n bagSource: 'IRW',\n bagName: shoppingListName,\n customerSource: 'IRW',\n customerId: options.userId,\n createdDateTime: this.getCreatedTime(),\n shoppingBagSectionList: [\n {\n shoppingBagItemList: options.items.map((item) => {\n this.validateItem(item);\n return {\n itemType: item.type.toUpperCase(),\n itemNo: item.id,\n itemQty: item.quantity.toString()\n };\n })\n }\n ]\n };\n }\n /**\n * @param item A shopping item.\n * @throws ServiceException if item is invalid.\n */\n validateItem(item) {\n if (typeof item.id !== 'string' ||\n typeof item.type !== 'string' ||\n typeof item.quantity !== 'number') {\n throw new ServiceException('Item was not in a valid format. Please use this format: { id: \"123456\", type: \"ART\", quantity: 1 }');\n }\n }\n /**\n * Returns headers to be used by requests.\n *\n * @returns Object as key value pairs of headers.\n */\n getHeaders() {\n return {\n accept: 'application/vnd.middleware-v1+json',\n contract: this.contract,\n consumer: this.consumer,\n 'content-type': 'application/json'\n };\n }\n /**\n * Returns endpoint URL.\n *\n * @param userId User id.\n * @param shoppingBagType Bag type.\n * @returns Endpoint url.\n */\n getEndpointUrl(userId, shoppingBagType) {\n return this.endpoint.replace('{userId}', userId).replace('{bagType}', shoppingBagType);\n }\n /**\n * Returns a date ISO string of the current time.\n *\n * @returns Date ISO string.\n */\n getCreatedTime() {\n return new Date().toISOString();\n }\n}\n//# sourceMappingURL=IksaShoppingBagService.js.map","var IngkaCartErrorCodeEnum;\n(function (IngkaCartErrorCodeEnum) {\n IngkaCartErrorCodeEnum[\"cartNotFound\"] = \"CART_NOT_FOUND\";\n})(IngkaCartErrorCodeEnum || (IngkaCartErrorCodeEnum = {}));\nexport default IngkaCartErrorCodeEnum;\n//# sourceMappingURL=IngkaCartErrorCodeEnum.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport ServiceFetch from '../../../../utilities/ServiceFetch.js';\nimport IngkaCartErrorCodeEnum from './enums/IngkaCartErrorCodeEnum.js';\n/**\n * This class handles adding items to the One Web cart.\n */\nexport default class IngkaCartService {\n get endpointLowerCase() {\n return this.endpoint.toLowerCase();\n }\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.endpoint Endpoint.\n * @param options.consumerName Consumer used to communicate with one web cart.\n * @param options.itemGroupingInBagEnabled Setting if grouping in bag is enabled on the market.\n */\n constructor(options) {\n this.endpoint = options.endpoint;\n this.itemGroupingInBagEnabled = options.itemGroupingInBagEnabled;\n this.consumerName = options.consumerName;\n }\n /**\n * Adds items to the shopping cart.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @param options.token One web token.\n * @param options.designCode Design code (VPC-code) to group articles in checkout and assembly services.\n * @param options.addDesignCodeAsGroup Boolean to group the articles or not in cart.\n * @param options.singleItems Single items to be added individually outside the group.\n * @returns Promise object.\n */\n async addToCart(options) {\n const { designCode, addDesignCodeAsGroup, items, token, singleItems } = options;\n if (!designCode && addDesignCodeAsGroup) {\n throw new ServiceException(\"Can't add as a group to cart when no design code has been provided.\");\n }\n const addItemsAsGroup = !!designCode && !!addDesignCodeAsGroup && this.itemGroupingInBagEnabled;\n let response;\n if (addItemsAsGroup) {\n /**\n * If the design code is already in cart, don't do anything.\n * TODO: This logic should be removed when the INGKA front-end team has implemented support for quantity for design codes.\n */\n const inCart = await this.checkIfInCart({ token: options.token, designCode });\n if (inCart.isInCart) {\n return {\n cartCount: inCart.cartQuantity ?? null,\n errorList: []\n };\n }\n response = await this.addDesignCodeToCart(designCode, token);\n if (singleItems && singleItems.length > 0) {\n response = await this.addItemsToCart(singleItems, token);\n }\n }\n else {\n response = await this.addItemsToCart(items, token);\n }\n return {\n cartCount: response.cart?.quantity ?? null,\n // The request is always expected to throw an error if the request fails. Therefore, when returning here the errorList will always be empty.\n errorList: []\n };\n }\n async addItemsToCart(items, token) {\n const requestBody = {\n items: items.map((item) => {\n return {\n itemNo: item.id,\n quantity: item.quantity\n };\n }),\n populateCart: {\n fetchCartContext: true,\n fetchItemInfo: true\n }\n };\n return await ServiceFetch.json(this.endpointLowerCase + '/items', {\n body: JSON.stringify(requestBody),\n method: 'POST',\n headers: this.getHeaders(token)\n });\n }\n async addDesignCodeToCart(designCode, token) {\n const requestBody = {\n plans: [{ code: designCode, quantity: 1 }],\n populateCart: {\n fetchCartContext: true,\n // Needed to be able to add plans to cart, for some reason.\n fetchItemInfo: true\n }\n };\n return await ServiceFetch.json(this.endpointLowerCase + '/plans', {\n body: JSON.stringify(requestBody),\n method: 'POST',\n headers: this.getHeaders(token)\n });\n }\n /**\n * Returns cart count for a shopping cart.\n *\n * @param options Options.\n * @param options.token One web token.\n * @returns Promise object.\n */\n async getCartCount(options) {\n const cart = await this.getCart(options);\n return cart ? cart.quantity : 0;\n }\n async checkIfInCart(options) {\n const cart = await this.getCart(options);\n if (!cart) {\n return { isInCart: false };\n }\n for (const group of cart.groups) {\n for (const plan of group.plans) {\n if (plan.code.toUpperCase() === options.designCode.toUpperCase()) {\n return { isInCart: true, cartQuantity: cart.quantity };\n }\n }\n }\n return { isInCart: false };\n }\n async getCart(options) {\n try {\n const response = await ServiceFetch.json(this.endpointLowerCase + '?fetchItemInfo=true', {\n method: 'GET',\n headers: this.getHeaders(options.token)\n });\n return response;\n }\n catch (error) {\n const errorResponse = await error.serverResponse?.json();\n if (errorResponse?.errors) {\n const ingkaServerResponse = errorResponse;\n for (const error of ingkaServerResponse.errors) {\n if (error.code === IngkaCartErrorCodeEnum.cartNotFound) {\n return null;\n }\n }\n }\n throw error;\n }\n }\n /**\n * Returns headers.\n *\n * @param token Token.\n * @returns Headers.\n */\n getHeaders(token) {\n const headers = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'Accept-Language': 'en',\n Authorization: 'Bearer ' + token.value,\n 'X-Consumer-Name': this.consumerName\n };\n return headers;\n }\n}\n//# sourceMappingURL=IngkaCartService.js.map","export default {\n 10001: 'INVALID_ITEM_NUMBER'\n};\n//# sourceMappingURL=IowsShoppingBagErrorCodes.js.map","import { IowsShoppingBagTypeEnum } from '@inter-ikea-kompis/enums';\nimport { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport ServiceFetch from '../../../utilities/ServiceFetch.js';\nimport IowsShoppingBagErrorCodes from './IowsShoppingBagErrorCodes.js';\n/**\n * This class handles CRUD operations for IOWS shopping cart API.\n */\nexport default class IowsShoppingBagService {\n constructor(options) {\n this.consumer = options.consumer;\n this.contract = options.contract;\n this.endpoint = options.endpoint;\n }\n /**\n * Adds items to shopping cart in IRW.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.items Array of shopping items.\n * @returns Promise object.\n */\n async addToCart(options) {\n return this.addToBag({\n userId: options.userId,\n items: options.items,\n shoppingBagType: IowsShoppingBagTypeEnum.cart\n });\n }\n /**\n * Adds items to shopping list in IRW.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.items Array of shopping items.\n * @param options.shoppingListName List name.\n * @returns Promise object.\n */\n async addToList(options) {\n const cart = await this.addToBag({\n userId: options.userId,\n items: options.items,\n shoppingBagType: IowsShoppingBagTypeEnum.list,\n shoppingListName: options.shoppingListName\n });\n return {\n errorList: cart.errorList,\n listCount: cart.cartCount\n };\n }\n /**\n * Returns cart count for a shopping cart.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @returns Promise object.\n */\n async getCartCount(options) {\n const cartInfo = await this.getCartInfo({\n userId: options.userId,\n shoppingBagType: IowsShoppingBagTypeEnum.cart\n });\n if (cartInfo === null) {\n return 0;\n }\n return this.getCartCountFromCart({\n userId: options.userId,\n shoppingBagType: IowsShoppingBagTypeEnum.cart,\n cartId: cartInfo.id\n });\n }\n /**\n * Returns list count from a shopping list.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.shoppingListName List name.\n * @returns Promise object.\n */\n async getListCount(options) {\n const cartInfo = await this.getCartInfo({\n userId: options.userId,\n shoppingBagType: IowsShoppingBagTypeEnum.list,\n shoppingListName: options.shoppingListName\n });\n if (cartInfo === null) {\n return 0;\n }\n return this.getCartCountFromCart({\n userId: options.userId,\n shoppingBagType: IowsShoppingBagTypeEnum.list,\n cartId: cartInfo.id\n });\n }\n /**\n * Adds items to shopping cart in IRW.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.items Array of shopping items.\n * @param options.shoppingBagType Cart type. Valid values: \"cart\", \"list\".\n * @param options.shoppingListName List name.\n * @returns Promise object.\n */\n async addToBag(options) {\n const cartInfo = await this.getCartInfo(options);\n if (cartInfo !== null) {\n const updateOptions = Object.assign({}, options, { cartId: cartInfo.id });\n const updateInfo = await this.updateCartItems(updateOptions);\n if (updateInfo.cartCount === null) {\n updateInfo.cartCount = await this.getCartCountFromCart(updateOptions);\n }\n return updateInfo;\n }\n return await this.createCart(options);\n }\n /**\n * Returns cart count for a shopping cart.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.cartId Cart id.\n * @param options.shoppingBagType Cart type.\n * @returns Promise object.\n */\n async getCartCountFromCart(options) {\n const cart = await this.getCart(options);\n return cart.cartCount;\n }\n /**\n * Returns cart information (name and id) if a cart exists.\n * Returns null if the cart doesn't exist.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.shoppingBagType Cart type.\n * @param [options.shoppingListName] List name.\n * @returns Promise object.\n */\n async getCartInfo(options) {\n const response = await ServiceFetch.json(this.getEndpointUrl(options.userId, options.shoppingBagType), {\n headers: this.getHeaders(),\n credentials: 'include'\n });\n return this.parseCartInfo({\n response: response,\n shoppingListName: options.shoppingListName\n });\n }\n /**\n * Returns a shopping cart.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.cartId Cart id.\n * @param options.shoppingBagType Cart type.\n * @returns Promise object.\n */\n async getCart(options) {\n const url = this.getEndpointUrl(options.userId, options.shoppingBagType) + '/' + options.cartId;\n const response = await ServiceFetch.json(url, {\n headers: this.getHeaders(),\n credentials: 'include'\n });\n return {\n errorList: [],\n cartCount: this.calculateCartCountFromResponse(response)\n };\n }\n /**\n * Creates a shopping cart.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.shoppingBagType Cart type.\n * @param options.items Items to use.\n * @param [options.shoppingListName] List name.\n * @returns Promise object.\n */\n async createCart(options) {\n const url = this.getEndpointUrl(options.userId, options.shoppingBagType);\n const modelOptions = {\n userId: options.userId,\n items: options.items,\n shoppingBagType: options.shoppingBagType,\n shoppingListName: options.shoppingListName\n };\n const response = await ServiceFetch.json(url, {\n method: 'POST',\n headers: this.getHeaders(),\n credentials: 'include',\n body: 'list=' + JSON.stringify(this.createShoppingCartModel(modelOptions))\n });\n return this.parseResponse(response);\n }\n /**\n * Updates shopping cart items.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.shoppingBagType Cart type.\n * @param options.cartId Cart id.\n * @param options.items Items to use.\n * @returns Promise object.\n */\n async updateCartItems(options) {\n const endpointUrl = this.getEndpointUrl(options.userId, options.shoppingBagType);\n const url = endpointUrl + '/' + options.cartId + '/items';\n const response = await ServiceFetch.text(url, {\n method: 'PUT',\n headers: this.getHeaders(),\n credentials: 'include',\n body: 'list=' + JSON.stringify(this.createItemsAdjustmentListModel(options.items))\n });\n if (typeof response === 'string' && response.startsWith('{')) {\n return this.parseResponse(JSON.parse(response));\n }\n return {\n cartCount: null,\n errorList: []\n };\n }\n /**\n * Parses response.\n *\n * @param response Response.\n * @returns Promise object.\n */\n parseResponse(response) {\n const cartCount = this.calculateCartCountFromResponse(response);\n const parsed = {\n cartCount,\n errorList: []\n };\n if (typeof response === 'object' && response !== null && response.ErrorList) {\n const errorObject = response.ErrorList.Error;\n const errorList = Array.isArray(errorObject) ? errorObject : [errorObject];\n for (const error of errorList) {\n const errorMessage = error.ErrorMessage || {};\n const errorCode = error.ErrorCode || {};\n const message = errorMessage.$ ? errorMessage.$ : null;\n const code = errorCode.$ ? errorCode.$ : null;\n const items = [];\n if (error.ErrorAttributeList && Array.isArray(error.ErrorAttributeList.ErrorAttribute)) {\n for (const attribute of error.ErrorAttributeList.ErrorAttribute) {\n if (attribute.Value && attribute.Value.$) {\n items.push(String(attribute.Value.$));\n }\n }\n }\n parsed.errorList.push({\n code: IowsShoppingBagErrorCodes[code] || String(code),\n message,\n items\n });\n }\n }\n return parsed;\n }\n /**\n * Calculates cart count from data.\n *\n * @param response Data returned from the response.\n * @returns Cart count or error object.\n */\n calculateCartCountFromResponse(response) {\n const bag = response.ShoppingBag || {};\n bag.ShoppingBagSectionList = bag.ShoppingBagSectionList || {};\n bag.ShoppingBagSectionList.ShoppingBagSection =\n bag.ShoppingBagSectionList.ShoppingBagSection || {};\n bag.BagType = bag.BagType || { $: '' };\n const isCart = bag.BagType.$ === 'ONLINESHOPPINGCART';\n const isList = bag.BagType.$ === 'ONLINESHOPPINGLIST';\n const itemList = bag.ShoppingBagSectionList.ShoppingBagSection.ShoppingBagItemList;\n let cartCount = null;\n if ((isCart || isList) && itemList) {\n const items = itemList.ShoppingBagItem;\n if (!items) {\n return null;\n }\n const array = Array.isArray(items) ? items : [items];\n cartCount = 0;\n for (const item of array) {\n if (item.ItemQty) {\n cartCount += item.ItemQty.$;\n }\n }\n }\n return cartCount;\n }\n /**\n * Parses cart data and returns cart info.\n *\n * @param options Options.\n * @param options.response Response.\n * @param [options.shoppingListName] List name.\n * @returns Parsed data.\n */\n parseCartInfo(options) {\n const { response, shoppingListName } = options;\n let cartInfo = null;\n if (response.ShoppingBag && response.ShoppingBag.BagId) {\n cartInfo = {\n id: response.ShoppingBag.BagId.$,\n name: response.ShoppingBag.BagName && response.ShoppingBag.BagName.$\n ? response.ShoppingBag.BagName.$\n : null,\n type: response.ShoppingBag.BagType && response.ShoppingBag.BagType.$\n ? response.ShoppingBag.BagType.$.toLowerCase()\n : null\n };\n }\n else if (response.ShoppingBagRefList && response.ShoppingBagRefList.ShoppingBagRef) {\n if (Array.isArray(response.ShoppingBagRefList.ShoppingBagRef)) {\n for (const ref of response.ShoppingBagRefList.ShoppingBagRef) {\n if (ref.BagId &&\n (!ref.BagName ||\n !ref.BagName.$ ||\n !ref.BagType ||\n !ref.BagType.$ ||\n ref.BagName.$ === shoppingListName)) {\n cartInfo = {\n id: ref.BagId.$,\n name: ref.BagName && ref.BagName.$ ? ref.BagName.$ : null,\n type: ref.BagType && ref.BagType.$ ? ref.BagType.$.toLowerCase() : null\n };\n break;\n }\n }\n }\n else if (response.ShoppingBagRefList.ShoppingBagRef.BagId) {\n const ref = response.ShoppingBagRefList.ShoppingBagRef;\n cartInfo = {\n id: ref.BagId?.$ ?? null,\n name: ref.BagName && ref.BagName.$ ? ref.BagName.$ : null,\n type: ref.BagType && ref.BagType.$ ? ref.BagType.$.toLowerCase() : null\n };\n }\n }\n if (cartInfo?.type && cartInfo?.name && cartInfo?.name !== shoppingListName) {\n return null;\n }\n return cartInfo;\n }\n /**\n * Generates a shopping cart model to be used as JSON.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.items Items to use.\n * @param options.shoppingBagType Cart type.\n * @param [options.shoppingListName] List name.\n * @param [options.cartId] Cart id.\n * @param options.bagId ...\n * @returns Shopping cart model.\n */\n createShoppingCartModel(options) {\n const shoppingListName = options.shoppingListName || options.shoppingBagType;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const json = {\n ShoppingBag: {\n BagType: {\n $: options.shoppingBagType\n },\n BagSource: {\n $: 'IRW'\n },\n BagName: {\n $: shoppingListName\n },\n CustomerSource: {\n $: 'IRW'\n },\n CustomerId: {\n $: options.userId\n },\n CreatedDateTime: {\n $: this.getCreatedTime()\n },\n ShoppingBagSectionList: [\n {\n ShoppingBagSection: {\n ShoppingBagItemList: {\n ShoppingBagItem: []\n }\n }\n }\n ],\n '@xmlns': {\n $: 'ikea.com/cem/iows/ShoppingBagService/2.0/'\n }\n }\n };\n const list = json.ShoppingBag.ShoppingBagSectionList[0].ShoppingBagSection.ShoppingBagItemList\n .ShoppingBagItem;\n for (const item of options.items) {\n if (typeof item.id !== 'string' ||\n typeof item.type !== 'string' ||\n typeof item.quantity !== 'number') {\n throw new ServiceException('Item was not in a valid format. Please use this format: { id: 123456, type: \"ART\", quantity: 1 }');\n }\n list.push({\n ItemType: {\n $: item.type.toUpperCase()\n },\n ItemNo: {\n $: item.id\n },\n ItemQty: {\n $: item.quantity\n }\n });\n }\n if (options.bagId) {\n json.BagId = {\n $: options.bagId\n };\n }\n return json;\n }\n /**\n * Generates a shopping cart adjustment list model to be used as JSON.\n *\n * @param items Items to use.\n * @returns Shopping cart model.\n */\n createItemsAdjustmentListModel(items) {\n const json = {\n ShoppingBagAdjustmentItemList: {\n ShoppingBagAdjustmentItem: [],\n '@xmlns': {\n $: 'ikea.com/cem/iows/ShoppingBagService/2.0/'\n }\n }\n };\n const list = json.ShoppingBagAdjustmentItemList.ShoppingBagAdjustmentItem;\n for (const item of items) {\n if (typeof item.id !== 'string' ||\n typeof item.type !== 'string' ||\n typeof item.quantity !== 'number') {\n throw new ServiceException('Item was not in a valid format. Please use this format: { id: 123456, type: \"ART\", quantity: 1 }');\n }\n list.push({\n ItemType: {\n $: item.type.toUpperCase()\n },\n ItemNo: {\n $: item.id\n },\n ItemQty: {\n $: item.quantity\n },\n SectionId: {\n $: 0\n }\n });\n }\n return json;\n }\n /**\n * Returns headers to be used by requests.\n *\n * @returns Object as key value pairs of headers.\n */\n getHeaders() {\n return {\n accept: 'application/vnd.ikea.iows+json; version=2.0',\n 'auth-token': this.consumer + '-' + this.contract,\n contract: this.contract,\n consumer: this.consumer,\n 'content-type': 'application/x-www-form-urlencoded'\n };\n }\n /**\n * Returns endpoint URL.\n *\n * @param userId User id.\n * @param shoppingBagType Cart type. Valid values: \"cart\", \"list\".\n * @returns Endpoint url.\n */\n getEndpointUrl(userId, shoppingBagType) {\n return this.endpoint\n .replace('{userId}', userId)\n .replace('{bagType}', shoppingBagType.toLowerCase());\n }\n /**\n * Returns a date ISO string of the current time.\n *\n * @returns Date ISO string.\n */\n getCreatedTime() {\n return new Date().toISOString();\n }\n}\n//# sourceMappingURL=IowsShoppingBagService.js.map","export default {\n 10001: 'INVALID_ITEM_NUMBER'\n};\n//# sourceMappingURL=MvEcomShoppingBagErrorCodes.js.map","import { MvEcomIrwBagTypeEnum, MvEcomShoppingBagTypeEnum } from '@inter-ikea-kompis/enums';\nimport { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport ServiceFetch from '../../../utilities/ServiceFetch.js';\nimport MvEcomShoppingBagErrorCodes from './MvEcomShoppingBagErrorCodes.js';\n/**\n * This class handles CRUD operations for MvEcom shopping cart API.\n */\nexport default class MvEcomShoppingBagService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.endpoint Endpoint.\n * @param options.mvEcomApiKey ...\n */\n constructor(options) {\n this.endpoint = options.endpoint;\n this.mvEcomApiKey = options.mvEcomApiKey;\n }\n /**\n * Adds items to shopping cart in IRW.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.items Array of shopping items.\n * @returns Promise object.\n */\n async addToCart(options) {\n return this.addToBag({\n irwBagType: MvEcomIrwBagTypeEnum.irwCart,\n userId: options.userId,\n items: options.items,\n shoppingBagType: MvEcomShoppingBagTypeEnum.cart\n });\n }\n /**\n * Adds items to shopping list in IRW.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.items Array of shopping items.\n * @param options.shoppingListName List name.\n * @returns Promise object.\n */\n async addToList(options) {\n const cart = await this.addToBag({\n irwBagType: MvEcomIrwBagTypeEnum.irwList,\n userId: options.userId,\n items: options.items,\n shoppingBagType: MvEcomShoppingBagTypeEnum.list,\n shoppingListName: options.shoppingListName\n });\n return {\n errorList: cart.errorList,\n listCount: cart.cartCount\n };\n }\n /**\n * Returns cart count for a shopping cart.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @returns Promise object.\n */\n async getCartCount(options) {\n const cartInfo = await this.getCartInfo({\n irwBagType: MvEcomIrwBagTypeEnum.irwCart,\n userId: options.userId,\n shoppingBagType: MvEcomShoppingBagTypeEnum.cart\n });\n if (cartInfo === null) {\n return 0;\n }\n return this.getCartCountFromCart({\n irwBagType: MvEcomIrwBagTypeEnum.irwCart,\n userId: options.userId,\n shoppingBagType: MvEcomShoppingBagTypeEnum.cart,\n cartId: cartInfo.id\n });\n }\n /**\n * Returns list count from a shopping list.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.shoppingListName List name.\n * @returns Promise object.\n */\n async getListCount(options) {\n const cartInfo = await this.getCartInfo({\n irwBagType: MvEcomIrwBagTypeEnum.irwList,\n userId: options.userId,\n shoppingBagType: MvEcomShoppingBagTypeEnum.list,\n shoppingListName: options.shoppingListName\n });\n if (cartInfo === null) {\n return 0;\n }\n return this.getCartCountFromCart({\n irwBagType: MvEcomIrwBagTypeEnum.irwList,\n userId: options.userId,\n shoppingBagType: MvEcomShoppingBagTypeEnum.list,\n cartId: cartInfo.id\n });\n }\n /**\n * Adds items to shopping cart in IRW.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.items Array of shopping items.\n * @param options.shoppingBagType Cart type. Valid values: \"cart\", \"list\".\n * @param options.shoppingListName List name.\n * @param options.irwBagType ...\n * @returns Promise object.\n */\n async addToBag(options) {\n const cartInfo = await this.getCartInfo(options);\n if (cartInfo !== null) {\n const updateOptions = Object.assign({}, options, { cartId: cartInfo.id });\n const updateInfo = await this.updateCartItems(updateOptions);\n if (updateInfo.cartCount === null) {\n updateInfo.cartCount = await this.getCartCountFromCart(updateOptions);\n }\n return updateInfo;\n }\n return await this.createCart(options);\n }\n /**\n * Returns cart count for a shopping cart.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.cartId Cart id.\n * @param options.shoppingBagType Cart type.\n * @param options.irwBagType ...\n * @returns Promise object.\n */\n async getCartCountFromCart(options) {\n const cart = await this.getCart(options);\n return cart.cartCount;\n }\n /**\n * Returns cart information (name and id) if a cart exists.\n * Returns null if the cart does not exist.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.shoppingBagType Cart type.\n * @param [options.shoppingListName] List name.\n * @param options.irwBagType ...\n * @returns Promise object.\n */\n async getCartInfo(options) {\n const response = await ServiceFetch.json(this.getEndpointUrl(options.irwBagType, options.userId, options.shoppingBagType), {\n headers: this.getHeaders({ mvEcomApiKey: this.mvEcomApiKey }),\n credentials: 'include'\n });\n if (Object.keys(response).length === 0) {\n return null;\n }\n return {\n id: response[0].bagId,\n name: options.shoppingListName,\n type: response[0].bagType\n };\n }\n /**\n * Returns a shopping cart.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.cartId Cart id.\n * @param options.shoppingBagType Cart type.\n * @param options.irwBagType ...\n * @returns Promise object.\n */\n async getCart(options) {\n const url = this.getEndpointUrl(options.irwBagType, options.userId, options.shoppingBagType) +\n '/' +\n options.cartId;\n const response = await ServiceFetch.json(url, {\n headers: this.getHeaders({ mvEcomApiKey: this.mvEcomApiKey }),\n credentials: 'include'\n });\n return {\n errorList: [],\n cartCount: this.calculateCartCountFromResponse(response)\n };\n }\n /**\n * Creates a shopping cart.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.shoppingBagType Cart type.\n * @param options.items Items to use.\n * @param [options.shoppingListName] List name.\n * @param options.irwBagType ...\n * @returns Promise object.\n */\n async createCart(options) {\n const url = this.getEndpointUrl(options.irwBagType, options.userId, options.shoppingBagType);\n const modelOptions = {\n customerId: options.userId,\n items: options.items,\n bagType: options.shoppingBagType,\n bagName: options.shoppingListName\n };\n const response = await ServiceFetch.json(url, {\n method: 'POST',\n headers: this.getHeaders({ mvEcomApiKey: this.mvEcomApiKey }),\n credentials: 'include',\n body: JSON.stringify(this.createShoppingCartModel(modelOptions))\n });\n return this.parseResponse(response);\n }\n /**\n * Updates shopping cart items.\n *\n * @param options Options.\n * @param options.userId User ID.\n * @param options.shoppingBagType Cart type.\n * @param options.cartId Cart id.\n * @param options.items Items to use.\n * @param options.irwBagType ...\n * @returns Promise object.\n */\n async updateCartItems(options) {\n const endpointUrl = this.getEndpointUrl(options.irwBagType, options.userId, options.shoppingBagType);\n const url = endpointUrl + '/' + options.cartId + '/items';\n // TODO: Change this to a json service fetch in the future if we (or MvEcom) redoes this API.\n const response = await ServiceFetch.text(url, {\n method: 'PUT',\n headers: this.getHeaders({ mvEcomApiKey: this.mvEcomApiKey }),\n credentials: 'include',\n body: JSON.stringify(this.createItemsAdjustmentListModel(options.items))\n });\n if (!response) {\n throw new ServiceException('Could not update cart items. Make sure all parameters are correct.');\n }\n const isError = typeof response === 'string' && response.startsWith('[');\n const isValidResponse = typeof response === 'string' && response.startsWith('{');\n if (isError || isValidResponse) {\n return this.parseResponse(JSON.parse(response));\n }\n return {\n cartCount: null,\n errorList: []\n };\n }\n /**\n * Parses response.\n *\n * @param response Response.\n * @returns Promise object.\n */\n parseResponse(response) {\n const cartCount = this.calculateCartCountFromResponse(response);\n const errorList = this.getErrorsFromResponse(response);\n return {\n cartCount,\n errorList\n };\n }\n /**\n * Checks if the response contains errors.\n *\n * @param response Response.\n * @returns Array of error objects.\n */\n getErrorsFromResponse(response) {\n const errors = [];\n if (typeof response === 'object' && response !== null && response[0]?.errorCode) {\n const errorObjectList = Array.isArray(response) ? response : [response];\n for (const error of errorObjectList) {\n const errorMessage = error.errorMessage || {};\n const errorCode = error.errorCode || {};\n const message = errorMessage ? errorMessage : null;\n const code = errorCode ? errorCode : null;\n const items = [];\n if (error.errorAttributeList && Array.isArray(error.errorAttributeList)) {\n for (const attribute of error.errorAttributeList) {\n if (attribute.value) {\n items.push(String(attribute.value));\n }\n }\n }\n errors.push({\n code: MvEcomShoppingBagErrorCodes[code] || String(code),\n message,\n items\n });\n }\n }\n return errors;\n }\n /**\n * Calculates cart count from data.\n *\n * @param response Data returned from the response.\n * @returns Cart count or error object.\n */\n calculateCartCountFromResponse(response) {\n const bag = response || {};\n bag.shoppingBagSectionList = bag.shoppingBagSectionList || [{}];\n bag.bagType = bag.bagType || '';\n const isCart = response.bagType === 'ONLINESHOPPINGCART';\n const isList = response.bagType === 'ONLINESHOPPINGLIST';\n const itemList = bag.shoppingBagSectionList[0];\n let cartCount = null;\n if ((isCart || isList) && itemList) {\n const items = itemList.shoppingBagItemList;\n if (!items) {\n return null;\n }\n cartCount = 0;\n for (const item of items) {\n if (item.itemQty) {\n cartCount += Number(item.itemQty);\n }\n }\n }\n return cartCount;\n }\n /**\n * Generates a shopping cart model to be used as JSON.\n *\n * @param options Options.\n * @param options.bagId Bag Id.\n * @param options.customerId User id.\n * @param options.bagType Bag type.\n * @param options.bagName Bag name.\n * @param options.items Shopping items.\n * @param options.cartId Cart id.\n * @returns Shopping cart model.\n */\n createShoppingCartModel(options) {\n const shoppingListName = options.bagName || options.bagType;\n const json = {\n bagType: options.bagType,\n bagSource: 'IRW',\n bagName: shoppingListName,\n customerSource: 'IRW',\n customerId: options.customerId,\n shoppingBagSectionList: [\n {\n shoppingBagItemList: []\n }\n ]\n };\n for (const item of options.items) {\n if (typeof item.id !== 'string' ||\n typeof item.type !== 'string' ||\n typeof item.quantity !== 'number') {\n throw new ServiceException('Item was not in a valid format. Please use this format: { id: 123456, type: \"ART\", quantity: 1 }');\n }\n json.shoppingBagSectionList?.[0].shoppingBagItemList?.push({\n itemType: item.type.toUpperCase(),\n itemNo: item.id,\n itemQty: item.quantity\n });\n }\n return json;\n }\n /**\n * Generates a shopping cart adjustment list model to be used as JSON.\n *\n * @param items Items to use.\n * @returns Shopping cart model.\n */\n createItemsAdjustmentListModel(items) {\n const list = [];\n for (const item of items) {\n if (typeof item.id !== 'string' ||\n typeof item.type !== 'string' ||\n typeof item.quantity !== 'number') {\n throw new ServiceException('Item was not in a valid format. Please use this format: { id: 123456, type: \"ART\", quantity: 1 }');\n }\n list.push({\n itemType: item.type,\n itemNo: item.id,\n itemQty: item.quantity\n });\n }\n return list;\n }\n /**\n * Returns headers to be used by requests.\n *\n * @param options Options.\n * @param options.mvEcomApiKey X-client-id.\n * @returns Object as key value pairs of headers.\n */\n getHeaders(options) {\n return {\n accept: 'application/vnd.ikea.api+json; version=2',\n 'content-type': 'application/json',\n 'x-client-id': options.mvEcomApiKey\n };\n }\n /**\n * Returns endpoint URL.\n *\n * @param irwBagType ...\n * @param userId User id.\n * @param shoppingBagType Cart type. Valid values: \"cart\", \"list\".\n * @returns Endpoint url.\n */\n getEndpointUrl(irwBagType, userId, shoppingBagType) {\n return this.endpoint\n .replace('{irwBagType}', irwBagType)\n .replace('{userId}', userId)\n .replace('{bagType}', shoppingBagType.toLowerCase());\n }\n}\n//# sourceMappingURL=MvEcomShoppingBagService.js.map","var NifUnitTypeEnum;\n(function (NifUnitTypeEnum) {\n NifUnitTypeEnum[\"retailUnit\"] = \"ru\";\n NifUnitTypeEnum[\"store\"] = \"sto\";\n})(NifUnitTypeEnum || (NifUnitTypeEnum = {}));\nexport default NifUnitTypeEnum;\n//# sourceMappingURL=NifUnitTypeEnum.js.map","import { ServiceException, ShoppingCartException } from '@inter-ikea-kompis/exceptions';\nimport { LocaleUtility } from '@inter-ikea-kompis/utilities';\nimport BitBoxUtility from '../../../utilities/BitBoxUtility.js';\nimport IframeManager from '../../../utilities/IframeManager.js';\nimport ServiceFetch from '../../../utilities/ServiceFetch.js';\nimport NifUnitTypeEnum from './enums/NifUnitTypeEnum.js';\n/**\n * This class is used for CRUD operations for NIF eCommerce API.\n */\nexport default class NifCartService {\n constructor(options) {\n this.locale = options.locale;\n this.endpoint = options.endpoint;\n this.frameContextEndpoint = options.frameContextEndpoint;\n this.nifCartUseBearerToken = options.nifCartUseBearerToken;\n this.cache = options.cache;\n }\n /**\n * Adds items to shopping cart.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n */\n async addToCart(options) {\n const carts = await this.getCarts();\n const cart = carts.length > 0 ? carts[0] : await this.createCart(NifUnitTypeEnum.retailUnit);\n try {\n await this.addCartItems({ items: options.items, cartId: cart.id });\n }\n catch (error) {\n const { serverResponse } = error;\n if (serverResponse?.status === 406) {\n const failedShoppingItems = await this.getFailedShoppingItems(serverResponse);\n if (failedShoppingItems.length > 0) {\n throw new ShoppingCartException(failedShoppingItems, []);\n }\n }\n }\n const cartCount = await this.getCartCountById(cart.id);\n return {\n errorList: [],\n cartCount\n };\n }\n /**\n * Fetches and returns the cart count.\n *\n */\n async getCartCount() {\n const carts = await this.getCarts();\n if (carts.length > 0) {\n return this.getCartCountById(carts[0].id);\n }\n return 0;\n }\n /**\n * Parses Error ServerResponse and returns array of failed shopping items.\n *\n * @param serverResponse ...\n */\n async getFailedShoppingItems(serverResponse) {\n const response = await serverResponse.json();\n const items = Array();\n if (response) {\n for (const item of response) {\n if (item.itemNo && item.message) {\n items.push(item);\n }\n }\n }\n return items;\n }\n /**\n * Fetches and returns the cart count.\n *\n * @param cartId Cart id.\n */\n async getCartCountById(cartId) {\n const response = await ServiceFetch.json(`${this.endpoint}/carts/${cartId}`, {\n method: 'GET',\n credentials: 'include',\n headers: {\n Accept: 'application/json',\n ...(await this.getAuthorizationHeaders())\n }\n });\n return response.quantity || 0;\n }\n /**\n * Fetches all carts and returns them. Returns an empty array if 0 (zero) carts.\n */\n async getCarts() {\n return await ServiceFetch.json(`${this.endpoint}/carts`, {\n method: 'GET',\n credentials: 'include',\n headers: {\n Accept: 'application/json',\n ...(await this.getAuthorizationHeaders())\n }\n });\n }\n /**\n * Creates a cart and returns the created cart.\n *\n * @param retailUnitType The type of unit (ru = Retail Unit/Market or sto = Store).\n */\n async createCart(retailUnitType) {\n const { country, language } = LocaleUtility.getCountryAndLanguage(this.locale);\n return await ServiceFetch.json(`${this.endpoint}/carts`, {\n method: 'POST',\n credentials: 'include',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n ...(await this.getAuthorizationHeaders())\n },\n body: JSON.stringify({\n context: {\n id: country,\n type: retailUnitType\n },\n countryCode: country,\n languageCode: language\n })\n });\n }\n /**\n * Add cart items to cart.\n *\n * @param options Configuration.\n * @param options.items Array of shopping items.\n * @param options.cartId Cart id.\n */\n async addCartItems(options) {\n await ServiceFetch.text(`${this.endpoint}/carts/${options.cartId}/items`, {\n method: 'POST',\n credentials: 'include',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n ...(await this.getAuthorizationHeaders())\n },\n body: JSON.stringify({\n items: options.items.map((item) => {\n return {\n itemNo: item.id,\n type: item.type,\n quantity: item.quantity\n };\n })\n })\n });\n }\n /**\n * Retrieves authorization token from iframe and returns it as an\n * authorization header. If third party domain token retrieval is not enabled\n * this method will return an empty header object. This should cause the\n * calling function to fall back to using cookies.\n *\n * We need to use an iframe to get context information because sometimes the\n * application is hosted on a domain other than the one of the primary market\n * site. When this is the case sometimes cookies can't be read cross-site\n * because of privacy settings in some users browsers, especially in private\n * browsing mode. This causes a cart to be created separate from the cart used\n * on the primary site.\n */\n async getAuthorizationHeaders() {\n if (!this.nifCartUseBearerToken)\n return {};\n const token = await this.getToken();\n return {\n Authorization: `Bearer ${token}`\n };\n }\n /**\n * Retrieves authorization token from iframe. The iframe instance will be\n * cached so calling this multiple times will not create multiple iframes.\n */\n async getToken() {\n const iframe = await this.createIframe();\n const context = await BitBoxUtility.readIframeContext(iframe);\n // Context is a union type of v1 and v2 context. TypeScript isn't happy if\n // we just check thuthiness.\n if (!('token' in context)) {\n throw new ServiceException('Token not returned from iframe.');\n }\n return context.token;\n }\n /**\n * Creates and returns iframe element.\n *\n * @returns Promise with iframe.\n */\n async createIframe() {\n if (this.iframeManager && this.iframeManager.url !== this.frameContextEndpoint) {\n this.iframeManager.disconnect();\n this.iframeManager = null;\n }\n if (!this.iframeManager) {\n this.iframeManager = new IframeManager(this.frameContextEndpoint, this.cache);\n }\n return await this.iframeManager.getIframe();\n }\n}\n//# sourceMappingURL=NifCartService.js.map","import { ApiPlatformEnum, EcommerceCartDataSourceEnum } from '@inter-ikea-kompis/enums';\nimport { ExceptionTypeEnum, ServiceException } from '@inter-ikea-kompis/exceptions';\nimport { GlobalCacheStore } from '@inter-ikea-kompis/utilities';\nimport ChinaAuthenticationService from '../../services/authentication/china/ChinaAuthenticationService.js';\nimport ChinaCartService from '../../services/shopping/china/cart/ChinaCartService.js';\nimport IksaShoppingBagService from '../../services/shopping/iksa/IksaShoppingBagService.js';\nimport IngkaCartService from '../../services/shopping/ingka/cart/IngkaCartService.js';\nimport IowsShoppingBagService from '../../services/shopping/iows/IowsShoppingBagService.js';\nimport MvEcomShoppingBagService from '../../services/shopping/mvecom/MvEcomShoppingBagService.js';\nimport NifCartService from '../../services/shopping/nif/NifCartService.js';\nimport DexfConfiguration from '../../utilities/DexfConfiguration.js';\nimport IrwPlatformCommunication from '../../utilities/platform-communication/IrwPlatformCommunication.js';\nimport RoigPlatformCommunication from '../../utilities/platform-communication/RoigPlatformCommunication.js';\nimport AuthenticationQueue from './AuthenticationQueue.js';\n/**\n * This class is used as a simple interface for shopping services.\n */\nexport default class ShoppingCartService {\n /**\n * Constructor.\n *\n * @param options Options.\n */\n constructor(options) {\n this.consumer = options.consumer;\n this.contract = options.contract;\n this.applicationName = options.applicationName;\n this.locale = options.locale;\n this.cache = options.cache || new GlobalCacheStore();\n this.dexfConfiguration = new DexfConfiguration(options);\n }\n /**\n * Adds items to shopping cart.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @param options.designCode VPC code used to group articles as a planner purchase.\n * @param options.addDesignCodeAsGroup If true the articles will be added as a group in the markets where this is possible. This requires designCode to be set.\n * @param options.singleItems Single items to be added individually outside the group.\n * @returns Promise object containing ICart.\n */\n async addToCart(options) {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const eCommerceCartDataSource = kompis.serviceSettings.eCommerceCartDataSource;\n const apiPlatform = kompis.serviceSettings.apiPlatform;\n switch (eCommerceCartDataSource) {\n case EcommerceCartDataSourceEnum.cartApi:\n return await this.addToCartOneWeb({\n items: options.items,\n designCode: options.designCode,\n addDesignCodeAsGroup: options.addDesignCodeAsGroup,\n singleItems: options.singleItems\n });\n case EcommerceCartDataSourceEnum.chinaCartApi:\n return await this.addToCartChina({\n items: options.items,\n designCode: options.designCode\n });\n case EcommerceCartDataSourceEnum.iows:\n return await this.addToCartIows({\n items: options.items\n });\n case EcommerceCartDataSourceEnum.mvecom:\n return await this.addToCartMvEcom({\n items: options.items\n });\n case EcommerceCartDataSourceEnum.nifApi:\n return await this.addToCartNif({\n items: options.items\n });\n case EcommerceCartDataSourceEnum.iksa:\n return await this.addToCartIksa({\n items: options.items\n });\n case EcommerceCartDataSourceEnum.default:\n switch (apiPlatform) {\n case ApiPlatformEnum.irw:\n return await this.addToCartIows({\n items: options.items\n });\n case ApiPlatformEnum.roig:\n return await this.addToCartNif({\n items: options.items\n });\n default:\n throw new ServiceException(`Failed to add items to cart. Unknown api platform \"${apiPlatform}\".`);\n }\n default:\n throw new ServiceException(`Failed to add items to cart. Unknown cart data source \"${eCommerceCartDataSource}\".`);\n }\n }\n /**\n * Returns total amount of items in a shopping cart.\n *\n * @returns Promise object.\n */\n async getCartCount() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const eCommerceCartDataSource = kompis.serviceSettings.eCommerceCartDataSource;\n const apiPlatform = kompis.serviceSettings.apiPlatform;\n switch (eCommerceCartDataSource) {\n case EcommerceCartDataSourceEnum.cartApi:\n return await this.getCartCountOneWeb();\n case EcommerceCartDataSourceEnum.chinaCartApi:\n return await this.getCartCountChina();\n case EcommerceCartDataSourceEnum.iows:\n return await this.getCartCountIows();\n case EcommerceCartDataSourceEnum.mvecom:\n return await this.getCartCountMvEcom();\n case EcommerceCartDataSourceEnum.nifApi:\n return await this.getCartCountNif();\n case EcommerceCartDataSourceEnum.iksa:\n return await this.getCartCountIksa();\n case EcommerceCartDataSourceEnum.default:\n switch (apiPlatform) {\n case ApiPlatformEnum.irw:\n return await this.getCartCountIows();\n default:\n throw new ServiceException(`Failed to get cart count. Unknown api platform \"${apiPlatform}\".`);\n }\n default:\n throw new ServiceException(`Failed to get cart count. Unknown cart data source \"${eCommerceCartDataSource}\".`);\n }\n }\n /**\n * Adds items to shopping cart.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @returns Promise object.\n */\n async addToCartIows(options) {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new IowsShoppingBagService({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iowsShoppingBagService\n });\n const userId = await this.getIowsUserId();\n const cart = await shoppingService.addToCart({\n items: options.items,\n userId\n });\n const platform = new IrwPlatformCommunication({ applicationName: this.applicationName });\n platform.setCartCount(cart.cartCount);\n return cart;\n }\n /**\n * Returns cart count for IOWS.\n *\n * @returns Promise object.\n */\n async getCartCountIows() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new IowsShoppingBagService({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iowsShoppingBagService\n });\n const userId = await this.getIowsUserId();\n return await shoppingService.getCartCount({\n userId\n });\n }\n /**\n * Adds items to shopping cart.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @returns Promise object.\n */\n async addToCartMvEcom(options) {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new MvEcomShoppingBagService({\n mvEcomApiKey: kompis.serviceSettings.mvEcomApiKey,\n endpoint: kompis.endpoints.mvEcomShoppingBagService\n });\n const userId = await this.getIowsUserId();\n const cart = await shoppingService.addToCart({\n items: options.items,\n userId\n });\n const platform = new IrwPlatformCommunication({ applicationName: this.applicationName });\n platform.setCartCount(cart.cartCount);\n return cart;\n }\n /**\n * Returns cart count for MvEcom.\n *\n * @returns Promise object.\n */\n async getCartCountMvEcom() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new MvEcomShoppingBagService({\n mvEcomApiKey: kompis.serviceSettings.mvEcomApiKey,\n endpoint: kompis.endpoints.mvEcomShoppingBagService\n });\n const userId = await this.getIowsUserId();\n return await shoppingService.getCartCount({\n userId\n });\n }\n /**\n * Adds items to shopping cart.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @param options.designCode Design code (VPC-code) to group articles in checkout and assembly services.\n * @param options.addDesignCodeAsGroup Boolean to group the articles or not in cart.\n * @param options.singleItems Single items to be added individually outside the group.\n * @returns Promise object.\n */\n async addToCartOneWeb(options) {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new IngkaCartService({\n endpoint: kompis.endpoints.ingkaCartServiceV2,\n itemGroupingInBagEnabled: kompis.serviceSettings.itemGroupingInBagEnabled,\n consumerName: kompis.serviceSettings.oneWebShoppingCartConsumerName\n });\n const authQueue = new AuthenticationQueue(this.cache);\n const token = await authQueue.getAuthTokenOneWeb({\n endpoint: kompis.endpoints.oneWebAuthenticationToken\n });\n if (!token) {\n throw new ServiceException('Token is not valid.');\n }\n const cart = await shoppingService.addToCart({\n items: options.items,\n token,\n designCode: options.designCode,\n addDesignCodeAsGroup: options.addDesignCodeAsGroup,\n singleItems: options.singleItems\n });\n const platform = new IrwPlatformCommunication({ applicationName: this.applicationName });\n platform.setCartCount(cart.cartCount);\n return cart;\n }\n /**\n * Returns cart count for one web.\n *\n * @returns Promise object.\n */\n async getCartCountOneWeb() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new IngkaCartService({\n endpoint: kompis.endpoints.ingkaCartServiceV2,\n itemGroupingInBagEnabled: kompis.serviceSettings.itemGroupingInBagEnabled,\n consumerName: kompis.serviceSettings.oneWebShoppingCartConsumerName\n });\n const authQueue = new AuthenticationQueue(this.cache);\n const token = await authQueue.getAuthTokenOneWeb({\n endpoint: kompis.endpoints.oneWebAuthenticationToken\n });\n if (!token) {\n throw new ServiceException('Token is not valid.');\n }\n return await shoppingService.getCartCount({\n token\n });\n }\n /**\n * Adds items to shopping cart.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @param options.designCode VPC/design code to group articles in checkout.\n * @returns Promise object.\n */\n async addToCartChina(options) {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new ChinaCartService({\n endpoint: kompis.endpoints.chinaCartService\n });\n const authQueue = new AuthenticationQueue(this.cache);\n const token = await authQueue.getAuthTokenChina({\n refreshTokenEndpoint: kompis.endpoints.chinaAuthenticationRefreshToken,\n loginPageEndpoint: kompis.endpoints.chinaAuthenticationLoginPage\n });\n if (!token) {\n throw new ServiceException('Token is not valid.');\n }\n try {\n return await shoppingService.addToCart({\n items: options.items,\n token,\n designCode: options.designCode\n });\n }\n catch (error) {\n if (error.exceptionType === ExceptionTypeEnum.serverErrorResponse &&\n error.serverResponse.status === 401) {\n const token = await authQueue.getAuthTokenChina({\n refreshTokenEndpoint: kompis.endpoints.chinaAuthenticationRefreshToken,\n loginPageEndpoint: kompis.endpoints.chinaAuthenticationLoginPage,\n login: true\n });\n if (!token) {\n throw new ServiceException('Token is not valid.');\n }\n return await shoppingService.addToCart({\n items: options.items,\n token,\n designCode: options.designCode\n });\n }\n throw error;\n }\n }\n /**\n * Returns cart count for china.\n *\n * @returns Promise object.\n */\n async getCartCountChina() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n if (!new ChinaAuthenticationService({\n refreshTokenEndpoint: kompis.endpoints.chinaAuthenticationRefreshToken,\n loginPageEndpoint: kompis.endpoints.chinaAuthenticationLoginPage\n }).hasCookie()) {\n return 0;\n }\n const shoppingService = new ChinaCartService({\n endpoint: kompis.endpoints.chinaCartService\n });\n const authQueue = new AuthenticationQueue(this.cache);\n const token = await authQueue.getAuthTokenChina({\n refreshTokenEndpoint: kompis.endpoints.chinaAuthenticationRefreshToken,\n loginPageEndpoint: kompis.endpoints.chinaAuthenticationLoginPage\n });\n if (!token) {\n throw new ServiceException('Token is not valid.');\n }\n try {\n return await shoppingService.getCartCount({\n token\n });\n }\n catch (error) {\n if (error.exceptionType === ExceptionTypeEnum.serverErrorResponse &&\n error.serverResponse.status === 401) {\n const token = await authQueue.getAuthTokenChina({\n refreshTokenEndpoint: kompis.endpoints.chinaAuthenticationRefreshToken,\n loginPageEndpoint: kompis.endpoints.chinaAuthenticationLoginPage,\n login: true\n });\n if (!token) {\n throw new ServiceException('Token is not valid.');\n }\n return await shoppingService.getCartCount({\n token\n });\n }\n throw error;\n }\n }\n /**\n * Adds items to shopping cart.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @returns Promise object.\n */\n async addToCartNif(options) {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new NifCartService({\n endpoint: kompis.endpoints.nifECommerceApiEndpoint,\n frameContextEndpoint: kompis.endpoints.bitboxCookieConsentService,\n locale: this.locale,\n nifCartUseBearerToken: kompis.serviceSettings.nifCartUseBearerToken,\n cache: this.cache\n });\n const platform = new RoigPlatformCommunication();\n if (!kompis.serviceSettings.nifCartUseBearerToken) {\n const authQueue = new AuthenticationQueue(this.cache);\n await authQueue.authenticateNif({\n endpoint: kompis.endpoints.nifECommerceApiEndpoint\n });\n }\n const cart = await shoppingService.addToCart({\n items: options.items\n });\n if (cart.cartCount) {\n platform.setCartCount(cart.cartCount);\n }\n else {\n console.warn('No cartCount returned from shoppingService.addToCart.');\n }\n return cart;\n }\n /**\n * Returns cart count for NIF.\n *\n * @returns Promise object.\n */\n async getCartCountNif() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new NifCartService({\n endpoint: kompis.endpoints.nifECommerceApiEndpoint,\n frameContextEndpoint: kompis.endpoints.bitboxCookieConsentService,\n locale: this.locale,\n nifCartUseBearerToken: kompis.serviceSettings.nifCartUseBearerToken,\n cache: this.cache\n });\n if (!kompis.serviceSettings.nifCartUseBearerToken) {\n const authQueue = new AuthenticationQueue(this.cache);\n await authQueue.authenticateNif({\n endpoint: kompis.endpoints.nifECommerceApiEndpoint\n });\n }\n return await shoppingService.getCartCount();\n }\n /**\n * Adds items to shopping cart.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @returns Promise object.\n */\n async addToCartIksa(options) {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new IksaShoppingBagService({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iksaShoppingBagService\n });\n const userId = await this.getIowsUserId();\n const cart = await shoppingService.addToCart({\n items: options.items,\n userId\n });\n const platform = new IrwPlatformCommunication({ applicationName: this.applicationName });\n platform.setCartCount(cart.cartCount);\n return cart;\n }\n /**\n * Returns cart count for IKSA.\n *\n * @returns Promise object.\n */\n async getCartCountIksa() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new IksaShoppingBagService({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iksaShoppingBagService\n });\n const userId = await this.getIowsUserId();\n return await shoppingService.getCartCount({\n userId\n });\n }\n /**\n * Returns authenticated IOWS user id.\n *\n * @returns Promise of user id as string.\n */\n async getIowsUserId() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const authQueue = new AuthenticationQueue(this.cache);\n const user = await authQueue.getAuthenticationIows({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iowsAuthenticationServiceV2\n });\n return user.id;\n }\n}\n//# sourceMappingURL=ShoppingCartService.js.map","import ServiceFetch from '../../../../utilities/ServiceFetch.js';\n/**\n * This class handles adding items to the China shopping list.\n */\nexport default class ChinaShoppingListService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.endpoint Endpoint.\n */\n constructor(options) {\n this.endpoint = options.endpoint;\n }\n /**\n * Adds items to shopping list.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @param options.token Token.\n * @returns Promise object.\n */\n async addToList(options) {\n await ServiceFetch.text(`${this.endpoint}/add-products-with-quantity`, {\n method: 'post',\n credentials: 'same-origin',\n headers: this.getHeaders(options.token),\n body: this.getAddToListBody(options.items)\n });\n const listCount = await this.getListCount(options);\n return {\n listCount,\n errorList: []\n };\n }\n /**\n * Returns list count for a shopping list.\n *\n * @param options Options.\n * @param options.token Token.\n * @returns Promise object.\n */\n async getListCount(options) {\n const response = await ServiceFetch.json(this.endpoint, {\n method: 'get',\n credentials: 'same-origin',\n headers: this.getHeaders(options.token)\n });\n return response.length || 0;\n }\n /**\n * Returns the body.\n *\n * @param items Items.\n * @returns Add to cart body.\n */\n getAddToListBody(items) {\n return JSON.stringify({\n products: items.map((item) => ({\n productFullId: (item.type.toUpperCase() === 'SPR' ? 's' : '') + item.id,\n quantity: item.quantity\n }))\n });\n }\n /**\n * Returns headers.\n *\n * @param token Token.\n * @returns Headers.\n */\n getHeaders(token) {\n const headers = {\n 'content-type': 'application/json',\n 'x-client-channel': 'WEB',\n 'x-client-platform': 'PcWeb',\n authorization: 'Bearer ' + token\n };\n return headers;\n }\n}\n//# sourceMappingURL=ChinaShoppingListService.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport ServiceFetch from '../../../../utilities/ServiceFetch.js';\n/**\n * This class handles adding items to the One Web cart.\n *\n * GraphQL Playground: https://dev.favs.oneweb.ingkadt.com/playground.\n */\nexport default class IngkaShoppingListService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.endpoint Endpoint.\n * @param options.clientId Client ID.\n * @param options.clientSecret Client secret.\n * @param options.itemGroupingInBagEnabled Setting if grouping in bag is enabled on the market.\n */\n constructor(options) {\n this.endpoint = options.endpoint;\n this.clientId = options.clientId;\n this.clientSecret = options.clientSecret;\n this.itemGroupingInBagEnabled = options.itemGroupingInBagEnabled;\n }\n /**\n * Adds items to shopping list.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @param options.token One web token.\n * @param options.shoppingListName List name.\n * @param options.designCode Design code (VPC-code) to group articles in checkout and assembly services.\n * @param options.singleItems Single items to be added individually outside the group.\n * @returns Promise object.\n */\n async addToList(options) {\n let listId = await this.getListId({\n token: options.token,\n shoppingListName: options.shoppingListName\n });\n if (!listId) {\n listId = await this.createList({\n token: options.token,\n shoppingListName: options.shoppingListName\n });\n }\n await this.setSelectedList({ token: options.token, listId });\n return await this.addItemsToList({\n items: options.items,\n token: options.token,\n listId,\n shoppingListName: options.shoppingListName,\n designCode: options.designCode,\n singleItems: options.singleItems\n });\n }\n /**\n * Returns list count.\n *\n * @param options Options..\n * @param options.token One web token.\n * @param options.shoppingListName List name.\n * @returns Promise object.\n */\n async getListCount(options) {\n const response = await ServiceFetch.json(this.endpoint, {\n credentials: 'same-origin',\n method: 'POST',\n headers: this.getHeaders(options.token),\n body: this.getListQuantityBody()\n });\n const data = response.data;\n if (!data || !Array.isArray(data.lists)) {\n throw new ServiceException('Failed to get list count. No lists in response.');\n }\n const list = data.lists.find((list) => list.name === options.shoppingListName);\n return list ? list.quantity : 0;\n }\n /**\n * Sets the shopping list which the latest item was added to as selected.\n *\n * @param options ...\n * @param options.token One web token.\n * @param options.listId List id.\n * @returns Promise object.\n */\n async setSelectedList(options) {\n await ServiceFetch.json(this.endpoint, {\n credentials: 'same-origin',\n method: 'POST',\n headers: this.getHeaders(options.token),\n body: this.getSelectedListBody(options.listId)\n });\n }\n /**\n * Returns list id.\n *\n * @param options Options.\n * @param options.token One web token.\n * @param options.shoppingListName List name.\n * @returns Promise object.\n */\n async getListId(options) {\n const response = await ServiceFetch.json(this.endpoint, {\n credentials: 'same-origin',\n method: 'POST',\n headers: this.getHeaders(options.token),\n body: this.getListIdBody()\n });\n const data = response.data;\n if (!data || !Array.isArray(data.lists)) {\n throw new ServiceException('Failed to get list id. No lists in response.');\n }\n const list = data.lists.find((list) => list.name === options.shoppingListName);\n return list ? list.listId : null;\n }\n /**\n * Creates a list and returns the ID.\n *\n * @param options Options.\n * @param options.token One web token.\n * @param options.shoppingListName List name.\n * @returns Promise object.\n */\n async createList(options) {\n const response = await ServiceFetch.json(this.endpoint, {\n credentials: 'same-origin',\n method: 'POST',\n headers: this.getHeaders(options.token),\n body: this.getCreateListBody(options.shoppingListName)\n });\n const data = response.data;\n if (!data || !data.createList || !data.createList.listId) {\n throw new ServiceException('Failed to create list. Missing \"listId\" in response.');\n }\n return data.createList.listId;\n }\n /**\n * Adds item to a shopping list.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @param options.token One web token.\n * @param options.listId List name.\n * @param options.designCode Design Code.\n * @param options.singleItems Single items to be added.\n * @param options.shoppingListName Name to fetch list count.\n * @returns Promise object.\n */\n async addItemsToList(options) {\n const response = await ServiceFetch.json(this.endpoint, {\n credentials: 'same-origin',\n method: 'POST',\n headers: this.getHeaders(options.token),\n body: this.getAddItemsBody(options.listId, options.items, options.designCode, options.singleItems)\n });\n const listCount = (await this.getListCount({\n token: options.token,\n shoppingListName: options.shoppingListName\n })) ?? null;\n return {\n listCount,\n errorList: this.getErrorList(response)\n };\n }\n getListIdBody() {\n return JSON.stringify({\n operationName: null,\n variables: {},\n query: '{ lists {name, listId} }'\n });\n }\n getListQuantityBody() {\n return JSON.stringify({\n operationName: null,\n variables: {},\n query: '{ lists {name, quantity} }'\n });\n }\n getAddItemsBody(listId, items, designCode, singleItems) {\n let mutation = '';\n const addItemsAsGroup = !!designCode && this.itemGroupingInBagEnabled;\n if (!addItemsAsGroup) {\n mutation = this.getAddItemsMutation(items, listId);\n }\n else {\n if (singleItems) {\n mutation = this.getAddItemsMutation(singleItems, listId);\n }\n const addDesignsMutation = `addDesigns(designs: [{configurationId: \"${designCode}\", quantity: 1}], listId: \"${listId}\") { listId, name }`;\n mutation = mutation\n ? `${mutation}\n\t\t\t\t${addDesignsMutation}`\n : addDesignsMutation;\n }\n return JSON.stringify({\n operationName: null,\n variables: {},\n query: `mutation {${mutation}}`\n });\n }\n getAddItemsMutation(items, listId) {\n const itemsString = `[${items.map((item) => {\n return `{ itemNo: \"${item.id}\", quantity: ${item.quantity} }`;\n })}]`;\n return `addItems(items: ${itemsString}, listId: \"${listId}\" ) { quantity }`;\n }\n getSelectedListBody(id) {\n return JSON.stringify({\n operationName: null,\n variables: {},\n query: `mutation { setSelected(listId: \"${id}\" ) { context { userId } } }`\n });\n }\n getCreateListBody(name) {\n return JSON.stringify({\n operationName: null,\n variables: {},\n query: `mutation { createList(name: \"${name}\") { listId } }`\n });\n }\n /**\n * Returns an error list.\n *\n * @param response Response.\n * @returns Error list.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getErrorList(response) {\n const errors = response.errors;\n if (errors) {\n return errors.map((error) => {\n return {\n code: error.extensions ? error.extensions.code : null,\n message: error.message,\n items: error.extensions && error.extensions.data && error.extensions.data.itemNos\n ? error.extensions.data.itemNos\n : null\n };\n });\n }\n return [];\n }\n getHeaders(token) {\n const headers = {\n 'Content-Type': 'application/json',\n Authorization: 'Bearer ' + token.value,\n Accept: 'application/json',\n 'x-client-id': this.clientId,\n 'x-client-secret': this.clientSecret\n // The below can be used for accessing GraphQL Playground:\n // 'x-user-id': '2008c852-8b33-48f6-b5ef-45add754cdf5',\n // 'x-is-anonymous': true,\n };\n return headers;\n }\n}\n//# sourceMappingURL=IngkaShoppingListService.js.map","import { ApiPlatformEnum, EcommerceCartDataSourceEnum, EcommerceShoppingListDataSourceEnum } from '@inter-ikea-kompis/enums';\nimport { ExceptionTypeEnum, ServiceException } from '@inter-ikea-kompis/exceptions';\nimport { GlobalCacheStore } from '@inter-ikea-kompis/utilities';\nimport ChinaAuthenticationService from '../../services/authentication/china/ChinaAuthenticationService.js';\nimport ChinaShoppingListService from '../../services/shopping/china/shopping-list/ChinaShoppingListService.js';\nimport IksaShoppingBagService from '../../services/shopping/iksa/IksaShoppingBagService.js';\nimport IngkaShoppingListService from '../../services/shopping/ingka/shopping-list/IngkaShoppingListService.js';\nimport IowsShoppingBagService from '../../services/shopping/iows/IowsShoppingBagService.js';\nimport MvEcomShoppingBagService from '../../services/shopping/mvecom/MvEcomShoppingBagService.js';\nimport DexfConfiguration from '../../utilities/DexfConfiguration.js';\nimport LocalizationService from '../localization/LocalizationService.js';\nimport AuthenticationQueue from './AuthenticationQueue.js';\n/**\n * This class is used as a simple interface for shopping services.\n */\nexport default class ShoppingListService {\n /**\n * Constructor.\n *\n * @param options Options.\n */\n constructor(options) {\n this.consumer = options.consumer;\n this.contract = options.contract;\n this.localizationPrefixApplication = options.localizationPrefixApplication;\n this.localizationEndpoints = options.localizationEndpoints;\n this.localizationOverrides = options.localizationOverrides;\n this.locale = options.locale;\n this.shoppingListName = options.shoppingListName;\n this.cache = options.cache || new GlobalCacheStore();\n this.dexfConfiguration = new DexfConfiguration(options);\n this.translations = options.translations;\n }\n /**\n * Adds items to shopping cart in IRW.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @param options.designCode VPC code used to group articles in the shopping list.\n * @param options.singleItems Single items to be added individually outside the group. Only applicable when a designCode has been set.\n * @returns Promise object.\n */\n async addToList(options) {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const eCommerceCartDataSource = kompis.serviceSettings.eCommerceCartDataSource;\n const eCommerceShoppingListDataSource = kompis.serviceSettings.eCommerceShoppingListDataSource;\n const apiPlatform = kompis.serviceSettings.apiPlatform;\n switch (eCommerceShoppingListDataSource) {\n case EcommerceShoppingListDataSourceEnum.shoppingListApi:\n return await this.addToListOneWeb({\n items: options.items,\n designCode: options.designCode,\n singleItems: options.singleItems\n });\n case EcommerceShoppingListDataSourceEnum.chinaShoppingListApi:\n return await this.addToListChina({\n items: options.items\n });\n case EcommerceShoppingListDataSourceEnum.iows:\n return await this.addToListIows({\n items: options.items\n });\n case EcommerceShoppingListDataSourceEnum.mvecom:\n return await this.addToListMvEcom({\n items: options.items\n });\n case EcommerceShoppingListDataSourceEnum.iksa:\n return await this.addToListIksa({\n items: options.items\n });\n case EcommerceShoppingListDataSourceEnum.default:\n switch (eCommerceCartDataSource) {\n case EcommerceCartDataSourceEnum.iows:\n case EcommerceCartDataSourceEnum.cartApi:\n return await this.addToListIows({\n items: options.items\n });\n case EcommerceCartDataSourceEnum.default:\n switch (apiPlatform) {\n case ApiPlatformEnum.irw:\n return await this.addToListIows({\n items: options.items\n });\n default:\n throw new ServiceException(`Failed to add items to shopping list. Unknown api platform \"${apiPlatform}\".`);\n }\n default:\n throw new ServiceException(`Failed to add items to shopping list. Unknown shopping cart data source \"${eCommerceCartDataSource}\".`);\n }\n default:\n throw new ServiceException(`Failed to add items to shopping list. Unknown shopping list data source \"${eCommerceShoppingListDataSource}\".`);\n }\n }\n /**\n * Returns total amount of items in a shopping list.\n *\n * @returns Promise object.\n */\n async getListCount() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const eCommerceCartDataSource = kompis.serviceSettings.eCommerceCartDataSource;\n const eCommerceShoppingListDataSource = kompis.serviceSettings.eCommerceShoppingListDataSource;\n const apiPlatform = kompis.serviceSettings.apiPlatform;\n switch (eCommerceShoppingListDataSource) {\n case EcommerceShoppingListDataSourceEnum.shoppingListApi:\n return await this.getListCountOneWeb();\n case EcommerceShoppingListDataSourceEnum.iows:\n return await this.getListCountIows();\n case EcommerceShoppingListDataSourceEnum.mvecom:\n return await this.getListCountMvEcom();\n case EcommerceShoppingListDataSourceEnum.chinaShoppingListApi:\n return await this.getListCountChina();\n case EcommerceShoppingListDataSourceEnum.iksa:\n return await this.getListCountIksa();\n case EcommerceShoppingListDataSourceEnum.default:\n switch (eCommerceCartDataSource) {\n case EcommerceCartDataSourceEnum.iows:\n case EcommerceCartDataSourceEnum.cartApi:\n return await this.getListCountIows();\n case EcommerceCartDataSourceEnum.default:\n switch (apiPlatform) {\n case ApiPlatformEnum.irw:\n return await this.getListCountIows();\n default:\n throw new ServiceException(`Failed to get list count. Unknown api platform \"${apiPlatform}\".`);\n }\n default:\n throw new ServiceException(`Failed to get list count. Unknown shopping cart data source \"${eCommerceCartDataSource}\".`);\n }\n default:\n throw new ServiceException(`Failed to get list count. Unknown shopping list data source \"${eCommerceShoppingListDataSource}\".`);\n }\n }\n /**\n * Returns shopping list name.\n */\n async getShoppingListName() {\n if (this.shoppingListName) {\n return this.shoppingListName;\n }\n else if (this.translations) {\n return this.translations.plannerShoppingListName;\n }\n else if (this.localizationEndpoints && this.locale) {\n const localizationService = new LocalizationService({\n localizationPrefixApplication: this.localizationPrefixApplication,\n localizationEndpoints: this.localizationEndpoints,\n localizationOverrides: this.localizationOverrides,\n locale: this.locale,\n cache: this.cache\n });\n const localizedInformation = await localizationService.getLocalizedInformation();\n return localizedInformation.translations.plannerShoppingListName;\n }\n throw new Error('Shopping list name must be defined either through the \"shoppingListName\", \"translations\" option or \"localizedInformation\" props.');\n }\n /**\n * Adds items to shopping cart.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @returns Promise object.\n */\n async addToListIows(options) {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new IowsShoppingBagService({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iowsShoppingBagService\n });\n const authQueue = new AuthenticationQueue(this.cache);\n const user = await authQueue.getAuthenticationIows({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iowsAuthenticationServiceV2\n });\n const shoppingList = await shoppingService.addToList({\n items: options.items,\n userId: user.id,\n shoppingListName: await this.getShoppingListName()\n });\n return shoppingList;\n }\n /**\n * Returns list count for IOWS.\n *\n * @returns Promise object.\n */\n async getListCountIows() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new IowsShoppingBagService({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iowsShoppingBagService\n });\n const authQueue = new AuthenticationQueue(this.cache);\n const user = await authQueue.getAuthenticationIows({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iowsAuthenticationServiceV2\n });\n return await shoppingService.getListCount({\n userId: user.id,\n shoppingListName: await this.getShoppingListName()\n });\n }\n /**\n * Adds items to shopping list for MvEcom.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @returns Promise object.\n */\n async addToListMvEcom(options) {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new MvEcomShoppingBagService({\n mvEcomApiKey: kompis.serviceSettings.mvEcomApiKey,\n endpoint: kompis.endpoints.mvEcomShoppingBagService\n });\n const authQueue = new AuthenticationQueue(this.cache);\n const user = await authQueue.getAuthenticationIows({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iowsAuthenticationServiceV2\n });\n const shoppingList = await shoppingService.addToList({\n items: options.items,\n userId: user.id,\n shoppingListName: await this.getShoppingListName()\n });\n return shoppingList;\n }\n /**\n * Returns list count for MvEcom.\n *\n * @returns Promise object.\n */\n async getListCountMvEcom() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new MvEcomShoppingBagService({\n mvEcomApiKey: kompis.serviceSettings.mvEcomApiKey,\n endpoint: kompis.endpoints.mvEcomShoppingBagService\n });\n const authQueue = new AuthenticationQueue(this.cache);\n const user = await authQueue.getAuthenticationIows({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iowsAuthenticationServiceV2\n });\n return await shoppingService.getListCount({\n userId: user.id,\n shoppingListName: await this.getShoppingListName()\n });\n }\n /**\n * Adds items to shopping list.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @param options.designCode ...\n * @param options.singleItems ...\n * @returns Promise object.\n */\n async addToListOneWeb(options) {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new IngkaShoppingListService({\n endpoint: kompis.endpoints.ingkaShoppingListService,\n clientId: kompis.serviceSettings.ingkaShoppingListClientId,\n clientSecret: kompis.serviceSettings.ingkaShoppingListClientSecret,\n itemGroupingInBagEnabled: kompis.serviceSettings.itemGroupingInBagEnabled\n });\n const authQueue = new AuthenticationQueue(this.cache);\n const token = await authQueue.getAuthTokenOneWeb({\n endpoint: kompis.endpoints.oneWebAuthenticationToken\n });\n if (!token) {\n throw new ServiceException('Token is not valid.');\n }\n const shoppingList = await shoppingService.addToList({\n items: options.items,\n token,\n shoppingListName: await this.getShoppingListName(),\n designCode: options.designCode,\n singleItems: options.singleItems\n });\n return shoppingList;\n }\n /**\n * Returns list count for One Web.\n *\n * @returns Promise object.\n */\n async getListCountOneWeb() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new IngkaShoppingListService({\n endpoint: kompis.endpoints.ingkaShoppingListService,\n clientId: kompis.serviceSettings.ingkaShoppingListClientId,\n clientSecret: kompis.serviceSettings.ingkaShoppingListClientSecret,\n itemGroupingInBagEnabled: kompis.serviceSettings.itemGroupingInBagEnabled\n });\n const authQueue = new AuthenticationQueue(this.cache);\n const token = await authQueue.getAuthTokenOneWeb({\n endpoint: kompis.endpoints.oneWebAuthenticationToken\n });\n if (!token) {\n throw new ServiceException('Token is not valid.');\n }\n return await shoppingService.getListCount({\n token,\n shoppingListName: await this.getShoppingListName()\n });\n }\n /**\n * Adds items to shopping list.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @returns Promise object.\n */\n async addToListChina(options) {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new ChinaShoppingListService({\n endpoint: kompis.endpoints.chinaShoppingListService\n });\n const authQueue = new AuthenticationQueue(this.cache);\n const token = await authQueue.getAuthTokenChina({\n refreshTokenEndpoint: kompis.endpoints.chinaAuthenticationRefreshToken,\n loginPageEndpoint: kompis.endpoints.chinaAuthenticationLoginPage\n });\n if (!token) {\n throw new ServiceException('Token is not valid.');\n }\n try {\n return await shoppingService.addToList({\n items: options.items,\n token\n });\n }\n catch (error) {\n if (error.exceptionType === ExceptionTypeEnum.serverErrorResponse &&\n error.serverResponse.status === 401) {\n const token = await authQueue.getAuthTokenChina({\n refreshTokenEndpoint: kompis.endpoints.chinaAuthenticationRefreshToken,\n loginPageEndpoint: kompis.endpoints.chinaAuthenticationLoginPage,\n login: true\n });\n if (!token) {\n throw new ServiceException('Token is not valid.');\n }\n return await shoppingService.addToList({\n items: options.items,\n token\n });\n }\n throw error;\n }\n }\n /**\n * Returns list count for China.\n *\n * @returns Promise object.\n */\n async getListCountChina() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n if (!new ChinaAuthenticationService({\n refreshTokenEndpoint: kompis.endpoints.chinaAuthenticationRefreshToken,\n loginPageEndpoint: kompis.endpoints.chinaAuthenticationLoginPage\n }).hasCookie()) {\n return 0;\n }\n const shoppingService = new ChinaShoppingListService({\n endpoint: kompis.endpoints.chinaShoppingListService\n });\n const authQueue = new AuthenticationQueue(this.cache);\n const token = await authQueue.getAuthTokenChina({\n refreshTokenEndpoint: kompis.endpoints.chinaAuthenticationRefreshToken,\n loginPageEndpoint: kompis.endpoints.chinaAuthenticationLoginPage\n });\n if (!token) {\n throw new ServiceException('Token is not valid.');\n }\n try {\n return await shoppingService.getListCount({\n token\n });\n }\n catch (error) {\n if (error.exceptionType === ExceptionTypeEnum.serverErrorResponse &&\n error.serverResponse.status === 401) {\n const token = await authQueue.getAuthTokenChina({\n refreshTokenEndpoint: kompis.endpoints.chinaAuthenticationRefreshToken,\n loginPageEndpoint: kompis.endpoints.chinaAuthenticationLoginPage,\n login: true\n });\n if (!token) {\n throw new ServiceException('Token is not valid.');\n }\n return await shoppingService.getListCount({\n token\n });\n }\n throw error;\n }\n }\n /**\n * Adds items to shopping cart.\n *\n * @param options Options.\n * @param options.items Array of shopping items.\n * @returns Promise object.\n */\n async addToListIksa(options) {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new IksaShoppingBagService({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iksaShoppingBagService\n });\n const authQueue = new AuthenticationQueue(this.cache);\n const user = await authQueue.getAuthenticationIows({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iowsAuthenticationServiceV2\n });\n const shoppingList = await shoppingService.addToList({\n items: options.items,\n userId: user.id,\n shoppingListName: await this.getShoppingListName()\n });\n return shoppingList;\n }\n /**\n * Returns list count for IKSA.\n *\n * @returns Promise object.\n */\n async getListCountIksa() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const shoppingService = new IksaShoppingBagService({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iksaShoppingBagService\n });\n const authQueue = new AuthenticationQueue(this.cache);\n const user = await authQueue.getAuthenticationIows({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iowsAuthenticationServiceV2\n });\n return await shoppingService.getListCount({\n userId: user.id,\n shoppingListName: await this.getShoppingListName()\n });\n }\n}\n//# sourceMappingURL=ShoppingListService.js.map","import { GlobalCacheStore } from '@inter-ikea-kompis/utilities';\nimport CacheStoreType from '../../enums/CacheStoreType.js';\n/**\n * This class is used for storing and loading stores from cache.\n */\nexport default class StoreCache {\n /**\n * Constructor.\n *\n * @param locale Locale.\n * @param cache Cache store.\n */\n constructor(locale, cache) {\n this.locale = locale;\n this.cache = cache || new GlobalCacheStore();\n }\n /**\n * Returns stores.\n *\n * @returns Stores.\n */\n getStores() {\n return this.cache.getStore(CacheStoreType.store).get(this.getCacheKey()) || null;\n }\n /**\n * Sets stores.\n *\n * @param stores Stores.\n */\n addStores(stores) {\n this.cache.getStore(CacheStoreType.store).set(this.getCacheKey(), stores);\n }\n /**\n * Removes stores.\n */\n clear() {\n this.cache.getStore(CacheStoreType.store).delete(this.getCacheKey());\n }\n /**\n * Returns cache key.\n *\n * @returns Cache key.\n */\n getCacheKey() {\n return this.locale + 'stores';\n }\n}\n//# sourceMappingURL=StoreCache.js.map","import { StoreBuTypeEnum } from '@inter-ikea-kompis/enums';\nimport ServiceFetch from '../../utilities/ServiceFetch.js';\n/**\n * This class is used for fetching a list of stores for a market.\n */\nexport default class DexfStoreService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.endpoint Endpoint.\n * @param options.dexfApiKey DEXF Api ket.\n */\n constructor(options) {\n this.endpoint = options.endpoint;\n this.dexfApiKey = options.dexfApiKey;\n }\n /**\n * Returns stores from a retail unit/market.\n *\n * @returns Promise.\n */\n async getStores() {\n const options = {\n credentials: 'same-origin',\n headers: {\n 'dexf-api-key': this.dexfApiKey\n }\n };\n const response = await ServiceFetch.json(this.endpoint, options);\n if (!response) {\n return [];\n }\n const stores = [];\n for (const store of response.stores) {\n // Filtering the store types.\n if (store.buType === StoreBuTypeEnum.store ||\n store.buType === StoreBuTypeEnum.office ||\n store.buType === StoreBuTypeEnum.smallStore ||\n store.buType === StoreBuTypeEnum.shop) {\n stores.push(this.parseStoreItem(store));\n }\n }\n return stores;\n }\n /**\n * Parses store data.\n *\n * @param store Response store.\n * @returns Item string.\n */\n parseStoreItem(store) {\n return {\n id: store.code,\n name: store.storeText,\n location: {\n latitude: store.latitude,\n longitude: store.longitude\n }\n };\n }\n}\n//# sourceMappingURL=DexfStoreService.js.map","/**\n * This class is used for transforming data from IRW into the format of the Store model.\n */\nexport default class IowsStoreTransformer {\n /**\n * Transforms data into format of StoreAvailability model.\n *\n * @param data Data to parse.\n * @returns Parsed data.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types\n transform(data) {\n const stores = [];\n if (data.StoreRefList && data.StoreRefList.StoreRef) {\n const items = Array.isArray(data.StoreRefList.StoreRef)\n ? data.StoreRefList.StoreRef\n : [data.StoreRefList.StoreRef];\n for (const item of items) {\n stores.push({\n location: this.getLocation(item),\n name: item.StoreName && item.StoreName.$ ? item.StoreName.$ : null,\n id: item.StoreNo && item.StoreNo.$ ? String(item.StoreNo.$) : null,\n url: item.StoreUrl && item.StoreUrl.$ ? item.StoreUrl.$ : null\n });\n }\n }\n return stores;\n }\n /**\n * Returns location.\n *\n * @param item Store item.\n * @returns Parsed data.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getLocation(item) {\n if (item.StoreLocation && item.StoreLocation.Latitude && item.StoreLocation.Latitude.$) {\n return {\n latitude: item.StoreLocation.Latitude.$,\n longitude: item.StoreLocation.Longitude.$\n };\n }\n return null;\n }\n}\n//# sourceMappingURL=IowsStoreTransformer.js.map","import ServiceFetch from '../../utilities/ServiceFetch.js';\nimport IowsStoreTransformer from './IowsStoreTransformer.js';\n/**\n * This class is used for fetching and parsing store data for IRW.\n */\nexport default class IowsStoreService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.consumer Consumer.\n * @param options.contract Contract.\n * @param options.endpoint Endpoint.\n */\n constructor(options) {\n this.consumer = options.consumer;\n this.contract = options.contract;\n this.endpoint = options.endpoint;\n }\n /**\n * Fetches and returns stores.\n *\n * @returns Promise object.\n */\n async getStores() {\n const transformer = new IowsStoreTransformer();\n const response = await ServiceFetch.json(this.endpoint, {\n credentials: 'same-origin',\n headers: {\n accept: 'application/vnd.ikea.irms+json; version=2',\n 'auth-token': this.consumer + '-' + this.contract,\n contract: this.contract,\n consumer: this.consumer\n }\n });\n return transformer.transform(response);\n }\n}\n//# sourceMappingURL=IowsStoreService.js.map","import { StoreDataSourceEnum } from '@inter-ikea-kompis/enums';\nimport { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport { GlobalCacheStore } from '@inter-ikea-kompis/utilities';\nimport CacheStoreType from '../../enums/CacheStoreType.js';\nimport DexfStoreService from '../../services/store/DexfStoreService.js';\nimport IowsStoreService from '../../services/store/IowsStoreService.js';\nimport DexfConfiguration from '../../utilities/DexfConfiguration.js';\nimport StoreCache from './StoreCache.js';\n/**\n * This class is used as a simple interface for store services.\n */\nexport default class StoreService {\n /**\n * Constructor.\n *\n * @param options Options.\n */\n constructor(options) {\n this.dexfConfiguration = new DexfConfiguration(options);\n this.locale = options.locale;\n this.consumer = options.consumer;\n this.contract = options.contract;\n this.cache = options.cache || new GlobalCacheStore();\n }\n /**\n * Fetches and returns translations.\n *\n * @returns Promise object.\n */\n async getStores() {\n const cacheStore = this.cache.getStore(CacheStoreType.store);\n const storeCache = new StoreCache(this.locale, this.cache);\n const queueCacheKey = this.locale + 'queue';\n const cachedStores = storeCache.getStores();\n if (cachedStores) {\n return cachedStores;\n }\n const cachedQueue = cacheStore.get(queueCacheKey);\n if (cachedQueue) {\n return new Promise((resolve) => cachedQueue.push(resolve));\n }\n const newQueue = [];\n cacheStore.set(queueCacheKey, newQueue);\n const service = await this.getService();\n const stores = await service.getStores();\n storeCache.addStores(stores);\n cacheStore.delete(queueCacheKey);\n for (const callback of newQueue) {\n callback(stores);\n }\n return stores;\n }\n /**\n * Returns service.\n *\n * @returns Service.\n */\n async getService() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n switch (kompis.serviceSettings.storeDataSource) {\n case StoreDataSourceEnum.dexf: {\n const dexfApiKey = await this.dexfConfiguration.getDexfApiKeyOrThrow();\n return new DexfStoreService({\n endpoint: kompis.endpoints.dexfStoreService,\n dexfApiKey: dexfApiKey\n });\n }\n default:\n if (!this.consumer || !this.contract) {\n throw new ServiceException('Consumer and contract must be defined.');\n }\n return new IowsStoreService({\n consumer: this.consumer,\n contract: this.contract,\n endpoint: kompis.endpoints.iowsStoreService\n });\n }\n }\n}\n//# sourceMappingURL=StoreService.js.map","import { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport ServiceFetch from '../../../utilities/ServiceFetch.js';\nconst DEFAULT_CONFIGURATION_VERSION = '1.0';\nconst DEFAULT_ICF_VERSION = '1.0';\n/**\n * This class is used for saving planner configurations to the IKEA VPC service.\n */\nexport default class DexfVpcService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.dexfApplicationId DEXF application ID.\n * @param options.endpoint Endpoint.\n * @param options.dexfApiKey DEXF API key.\n * @param [options.dexfConfigurationVersion] Configuration version. Defaults to \"1.0\".\n * @param [options.dexfIcfVersion] Icf version. Defaults to \"1.0\".\n */\n constructor(options) {\n this.dexfConfigurationVersion = '1.0';\n this.dexfIcfVersion = '1.0';\n this.dexfApplicationId = options.dexfApplicationId;\n this.endpoint = options.endpoint;\n this.dexfApiKey = options.dexfApiKey;\n this.dexfConfigurationVersion =\n options.dexfConfigurationVersion || DEFAULT_CONFIGURATION_VERSION;\n this.dexfIcfVersion = options.dexfIcfVersion || DEFAULT_ICF_VERSION;\n }\n /**\n * Saves a planner configuration.\n *\n * @param configuration Configuration to save.\n * @param shoppingItems Product items.\n * @param [configurationImage] Configuration image as a base 64 string (e.g. \"data:image/jpeg;base64,abc..\").\n * @param insightsCombinationFormat Insights Combination Format.\n * @returns Promise object.\n */\n async saveConfiguration(configuration, shoppingItems, configurationImage, insightsCombinationFormat) {\n const response = await ServiceFetch.json(this.endpoint, {\n method: 'POST',\n body: this.getRequestBody(configuration, shoppingItems, insightsCombinationFormat),\n credentials: 'same-origin',\n headers: {\n 'dexf-api-key': this.dexfApiKey,\n 'content-type': 'application/json'\n }\n });\n if (response && response.configurationId) {\n const configurationResponse = {\n configurationId: response.configurationId,\n configurationVersion: this.dexfConfigurationVersion,\n application: this.dexfApplicationId,\n configuration\n };\n if (configurationImage) {\n const images = [];\n if (typeof configurationImage === 'string') {\n images.push({\n typeCode: 'main-design-image',\n image: configurationImage\n });\n }\n else if (Array.isArray(configurationImage)) {\n images.push(...configurationImage);\n }\n const imageResponse = await Promise.all(images.map((image) => this.saveImage(response._links, image.image, image.typeCode)));\n return { ...configurationResponse, imageUrl: imageResponse };\n }\n return configurationResponse;\n }\n return null;\n }\n /**\n * Save image to vpc dexf.\n *\n * @param links Links.\n * @param configurationImage Configuration image.\n * @param typeCode Type code.\n * @returns Promise object.\n */\n async saveImage(links, configurationImage, typeCode) {\n try {\n // eslint-disable-next-line dot-notation\n const response = await ServiceFetch.json(links[typeCode]['href'], {\n method: 'POST',\n body: configurationImage,\n credentials: 'same-origin',\n headers: {\n 'dexf-api-key': this.dexfApiKey,\n 'content-type': 'text/plain;charset=UTF-8'\n }\n });\n return {\n typeCode,\n url: response.url\n };\n }\n catch (error) {\n throw new ServiceException('Failed to save image. Error: ' + error);\n }\n }\n /**\n * Fetches and returns a planner configuration.\n *\n * @param id Configuration ID (VPC Code).\n * @param options ...\n * @param options.includeIcfData Whether to include ICF data in the response or not.\n * @returns Promise object.\n */\n async getConfiguration(id, options) {\n const url = this.endpoint + '/' + id.toUpperCase();\n const response = await ServiceFetch.json(url, {\n credentials: 'same-origin',\n headers: {\n 'dexf-api-key': this.dexfApiKey\n }\n });\n if (response && response.configurationId) {\n return {\n configurationId: response.configurationId,\n configurationVersion: response.configuration.version,\n application: response.application.toUpperCase(),\n configuration: response.configuration.content,\n imageUrl: response.image,\n itemList: response.itemList?.item ? this.getItemList(response.itemList.item) : null,\n ...(options?.includeIcfData && { icf: response.icf })\n };\n }\n return null;\n }\n /**\n * Return a list of shopping items.\n *\n * @param itemList ItemList.\n * @param itemList.itemType ItemType.\n * @param itemList.itemNo ItemNo.\n * @param itemList.quantity Quantity.\n */\n getItemList(itemList) {\n return itemList.map((item) => ({\n id: item.itemNo,\n type: item.itemType,\n quantity: item.quantity\n }));\n }\n /**\n * Returns payload to be used when saving a configuration.\n *\n * @param configuration Configuration to save.\n * @param shoppingItems Product items.\n * @param insightsCombinationFormat Insights Combination Format.\n * @returns Parsed data.\n */\n getRequestBody(configuration, shoppingItems, insightsCombinationFormat) {\n const body = {\n application: this.dexfApplicationId,\n itemList: {\n item: shoppingItems.map((item) => {\n return { itemType: item.type, itemNo: item.id, quantity: item.quantity };\n })\n },\n configuration: {\n version: this.dexfConfigurationVersion,\n content: configuration\n }\n };\n if (insightsCombinationFormat) {\n Object.assign(body, {\n icf: {\n version: this.dexfIcfVersion,\n content: insightsCombinationFormat\n }\n });\n }\n return JSON.stringify(body);\n }\n}\n//# sourceMappingURL=DexfVpcService.js.map","import DexfVpcService from '../../services/vpc/dexf/DexfVpcService.js';\nimport DexfConfiguration from '../../utilities/DexfConfiguration.js';\n/**\n * This class is used as a simple interface for VPC services.\n */\nexport default class VpcService {\n /**\n * Constructor.\n *\n * @param options Options.\n */\n constructor(options) {\n this.applicationName = options.applicationName;\n this.dexfApplicationId = options.dexfApplicationId || null;\n this.dexfConfigurationVersion = options.dexfConfigurationVersion;\n this.dexfIcfVersion = options.dexfIcfVersion;\n this.dexfConfiguration = new DexfConfiguration(options);\n }\n /**\n * Saves a planner configuration.\n *\n * @param configuration Configuration to save.\n * @param shoppingItems Product items.\n * @param [configurationImage] Configuration image as a base 64 string (e.g. \"data:image/jpeg;base64,abc..\").\n * @param insightsCombinationFormat Insights Combination Format.\n * @returns Promise object.\n */\n async saveConfiguration(configuration, shoppingItems, configurationImage, insightsCombinationFormat) {\n const service = await this.getService();\n return await service.saveConfiguration(configuration, shoppingItems, configurationImage, insightsCombinationFormat);\n }\n /**\n * Fetches and returns a planner configuration.\n *\n * @param id Configuration ID (VPC Code).\n * @param options ...\n * @param options.includeIcfData Whether to include ICF data in the response or not.\n * @returns Promise object.\n */\n async getConfiguration(id, options) {\n const service = await this.getService();\n return await service.getConfiguration(id, options);\n }\n /**\n * Returns service.\n *\n * @returns Service.\n */\n async getService() {\n const { kompis } = await this.dexfConfiguration.getSettings();\n const dexfApiKey = await this.dexfConfiguration.getDexfApiKeyOrThrow();\n return new DexfVpcService({\n endpoint: kompis.endpoints.dexfVpcService,\n dexfApplicationId: this.dexfApplicationId || this.applicationName,\n dexfApiKey,\n dexfConfigurationVersion: this.dexfConfigurationVersion,\n dexfIcfVersion: this.dexfIcfVersion\n });\n }\n}\n//# sourceMappingURL=VpcService.js.map","import ServiceFetch from '../../utilities/ServiceFetch.js';\n/**\n * This class is used for validating zip code .\n */\nexport default class DexfZipValidationService {\n /**\n * Constructor.\n *\n * @param options Options.\n * @param options.endpoint Endpoint.\n * @param options.dexfApiKey DEXF Api key.\n */\n constructor(options) {\n this.endpoint = options.endpoint;\n this.dexfApiKey = options.dexfApiKey;\n }\n /**\n * Fetches the validity of a given zip code.\n *\n * @param zipCode ...\n */\n async getZipValidation(zipCode) {\n const options = {\n credentials: 'same-origin',\n headers: {\n 'dexf-api-key': this.dexfApiKey\n }\n };\n const url = `${this.endpoint.replace('{zipCode}', encodeURIComponent(zipCode.replace(/ /g, '')))}`;\n const response = await ServiceFetch.json(url, options);\n return response;\n }\n}\n//# sourceMappingURL=DexfZipValidationService.js.map","import { ZipValidationDataSourceEnum } from '@inter-ikea-kompis/enums';\nimport { ServiceException } from '@inter-ikea-kompis/exceptions';\nimport DexfZipValidationService from '../../services/zip-availability/DexfZipValidationService.js';\nimport DexfConfiguration from '../../utilities/DexfConfiguration.js';\n/**\n * This class is used as a simple interface for zip code validation services.\n */\nexport default class ZipValidationService {\n /**\n * @param options Options.\n */\n constructor(options) {\n this.dexfConfiguration = new DexfConfiguration(options);\n }\n /**\n * Fetches and returns zip code validity.\n *\n * @param zipCode Zip Code.\n * @returns Promise IZipValidation.\n */\n async getZipValidation(zipCode) {\n const service = await this.getService();\n return await service.getZipValidation(zipCode);\n }\n /**\n * Returns DEXF service if the zipValidationDataSource setting for the locale is not set to 'disabled'.\n *\n * @returns Service | null.\n */\n async getService() {\n const settings = await this.dexfConfiguration.getSettings();\n const dexfApiKey = await this.dexfConfiguration.getDexfApiKeyOrThrow();\n switch (settings.kompis.serviceSettings.zipValidationDataSource) {\n case ZipValidationDataSourceEnum.disabled:\n throw new ServiceException('The zipValidationDataSource is set to \"disabled\". When it is, the ZipValidationService is not available on the market.');\n default:\n return new DexfZipValidationService({\n endpoint: settings.kompis.endpoints.dexfZipValidationService,\n dexfApiKey\n });\n }\n }\n}\n//# sourceMappingURL=ZipValidationService.js.map","var NavigationToEnum;\n(function (NavigationToEnum) {\n NavigationToEnum[\"ikeaMainPage\"] = \"ikea web main page\";\n NavigationToEnum[\"ikeaFavorites\"] = \"ikea web favorites\";\n NavigationToEnum[\"ikeaCart\"] = \"ikea web shopping cart\";\n NavigationToEnum[\"ikeaAssembly\"] = \"ikea assembly services info\";\n})(NavigationToEnum || (NavigationToEnum = {}));\nexport default NavigationToEnum;\n//# sourceMappingURL=NavigationToEnum.js.map","import { ABTestVariationEnum } from '@inter-ikea-kompis/enums';\n/**\n * A/B test variation utility for kiosk.\n *\n * Kiosk A/B tests have a separate way of calculating variations, based on the assumption that kiosks can be used for several days without being restarted. In order not to skew the amount of users being exposed to the A vs the B version too much by a popular kiosk not being restarted for a long time, a new A/B version will be generated each day.\n *\n * The variation is based on is based on the kiosk ID and the current date using a seeded random number generator. In that way the same kiosk will have the same variation through the whole day, but the following day will have a newly generated variation with a 50/50 chance between each alternative.\n */\nexport default class KioskABTestVariation {\n static getVariation(kioskLongTermId) {\n return this.getAB(kioskLongTermId);\n }\n /**\n * Generates a hash consisting of 4 32 bit integers from a string.\n *\n * Inspired by https://stackoverflow.com/a/47593316.\n */\n static cyrb128(str) {\n let h1 = 1779033703;\n let h2 = 3144134277;\n let h3 = 1013904242;\n let h4 = 2773480762;\n for (let i = 0, k; i < str.length; i++) {\n k = str.charCodeAt(i);\n h1 = h2 ^ Math.imul(h1 ^ k, 597399067);\n h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);\n h3 = h4 ^ Math.imul(h3 ^ k, 951274213);\n h4 = h1 ^ Math.imul(h4 ^ k, 2716044179);\n }\n h1 = Math.imul(h3 ^ (h1 >>> 18), 597399067);\n h2 = Math.imul(h4 ^ (h2 >>> 22), 2869860233);\n h3 = Math.imul(h1 ^ (h3 >>> 17), 951274213);\n h4 = Math.imul(h2 ^ (h4 >>> 19), 2716044179);\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n (h1 ^= h2 ^ h3 ^ h4), (h2 ^= h1), (h3 ^= h1), (h4 ^= h1);\n return [h1 >>> 0, h2 >>> 0, h3 >>> 0, h4 >>> 0];\n }\n /**\n * Takes a 128 bit seed consisting of 4 32 bit integers and returns a function\n * that generates pseudo random deterministic 32 bit integers.\n *\n * @returns A function that generates pseudo random deterministic 32 bit integers.\n *\n * Inspired by https://stackoverflow.com/a/47593316.\n * See test made https://i-p-e-x.atlassian.net/browse/KOMPIS-5901?focusedCommentId=202004.\n */\n static sfc32(a, b, c, d) {\n return function () {\n a |= 0;\n b |= 0;\n c |= 0;\n d |= 0;\n const t = (((a + b) | 0) + d) | 0;\n d = (d + 1) | 0;\n a = b ^ (b >>> 9);\n b = (c + (c << 3)) | 0;\n c = (c << 21) | (c >>> 11);\n c = (c + t) | 0;\n return (t >>> 0) / 4294967296;\n };\n }\n static getAB(longTermId) {\n const currentDate = new Date();\n const seed = this.cyrb128(longTermId + currentDate.getDate() + currentDate.getMonth() + currentDate.getFullYear());\n const rand = this.sfc32(...seed);\n if (rand() > 0.5) {\n return ABTestVariationEnum.A;\n }\n return ABTestVariationEnum.B;\n }\n}\n//# sourceMappingURL=KioskABTestVariation.js.map","import { ABTestNameEnum, ABTestVariationEnum } from '@inter-ikea-kompis/enums';\nimport KioskABTestVariation from './KioskABTestVariation.js';\nconst KOMPIS_AB_TEST_KEY = 'kompisABTest';\n/**\n * A/B test variation utility.\n */\nexport default class ABTestUtility {\n /**\n * Returns AB test name and variation if there is an active test available in DEXF settings.\n * If no test is enabled it will return null.\n *\n * If the AB test is ran exclusively on kiosk, supply the kioskLongTermId for a variation generation more suitable for that use case.\n */\n static initializeABTests(settings, kioskLongTermId) {\n const { abTest } = settings.kompis.localization;\n if (!(abTest && abTest in ABTestNameEnum)) {\n return null;\n }\n const name = abTest;\n const variation = ABTestUtility.getVariation(name, kioskLongTermId);\n return { name, variation };\n }\n static getVariation(abTestId, kioskLongTermId) {\n if (kioskLongTermId) {\n return KioskABTestVariation.getVariation(kioskLongTermId);\n }\n return this.getLocalStorageTestVariation(abTestId) ?? this.setNewTestVariation(abTestId);\n }\n static getLocalStorageTestVariation(abTestId) {\n const localStorageABTest = localStorage.getItem(KOMPIS_AB_TEST_KEY);\n const localStorageABTestKeys = localStorageABTest && JSON.parse(localStorageABTest);\n if (localStorageABTestKeys) {\n const currentABTest = localStorageABTestKeys[abTestId];\n if (currentABTest && currentABTest in ABTestVariationEnum) {\n return currentABTest;\n }\n }\n return null;\n }\n static setNewTestVariation(abTestId) {\n const variation = Math.random() < 0.5 ? ABTestVariationEnum.A : ABTestVariationEnum.B;\n const localStorageABTest = localStorage.getItem(KOMPIS_AB_TEST_KEY);\n const value = {\n ...(localStorageABTest && JSON.parse(localStorageABTest)),\n [abTestId]: variation\n };\n localStorage.setItem(KOMPIS_AB_TEST_KEY, JSON.stringify(value));\n return variation;\n }\n}\n//# sourceMappingURL=ABTestUtility.js.map","/**\n * Used for setting the instance of InsightsApi, so that components\n * with automatic analytics can access it, and send events through it.\n */\nclass AnalyticsManager {\n /**\n * Returns the set insightsApi instance, or null if it wasn't set.\n */\n static getInsightsApi() {\n return this.insightsApi;\n }\n /**\n * Planners should call this method as early as possible, before rendering\n * any components which have automatic analytics enabled.\n *\n * @param insightsApi The insightsApi instance created by the planner.\n */\n static setInsightsApi(insightsApi) {\n this.insightsApi = insightsApi;\n }\n}\nAnalyticsManager.insightsApi = null;\nexport default AnalyticsManager;\n//# sourceMappingURL=AnalyticsManager.js.map","import { CookieConsentService } from '@inter-ikea-kompis/services';\nimport ReporterManager from '../utilities/ReporterManager.js';\n/**\n * Provides the connection between a tracker and the Insights DPC.\n */\nexport default class InsightsReporter {\n constructor() {\n this.moduleClient = null;\n this.cookieConsentService = null;\n }\n /**\n * Connects the reporter to the Insights DPC.\n *\n * @param insightsApi ...\n * @param moduleMetaData ...\n * @param cookieConsentServiceOptions ...\n */\n async connect(insightsApi, moduleMetaData, cookieConsentServiceOptions) {\n // We consider the reporter connected regardless of if the module client was created or not.\n // We connect first, before any async stuff, to allow disconnecting while any async stuff is ongoing.\n ReporterManager.connect(this);\n this.cookieConsentService = new CookieConsentService(cookieConsentServiceOptions);\n let hasCookieConsent;\n try {\n hasCookieConsent = await this.cookieConsentService?.hasCookieConsent(2);\n }\n catch (error) {\n console.error('hasCookieConsent error thrown when trying to connect InsightsReporter');\n return;\n }\n if (hasCookieConsent) {\n if (!insightsApi) {\n throw Error(`InsightsApi is not found, did you forget to run AnalyticsManager.setInsightsApi before rendering ${moduleMetaData.moduleId}?`);\n }\n if (!insightsApi.isEnabled) {\n throw Error(`InsightsApi is not enabled, did you forget to run insightsApi.connectApplication before rendering ${moduleMetaData.moduleId}?`);\n }\n this.moduleClient = insightsApi.moduleClient(moduleMetaData);\n }\n }\n /**\n * Returns whether the reporter has been connected or not.\n * It is still considered connected even if no module client could be created when trying to connect.\n *\n * @returns Whether the reporter has been connected or not.\n */\n isConnected() {\n return ReporterManager.isConnected(this);\n }\n /**\n * Disconnects the reporter.\n */\n disconnect() {\n ReporterManager.disconnect(this);\n }\n /**\n * Get the id of the the reporter, if connected. See {@link ReporterManager.getConnectedId}.\n */\n getConnectedId() {\n return ReporterManager.getConnectedId(this);\n }\n /**\n * Report a custom event to InsightsApi.\n *\n * @param event ...\n */\n report(event) {\n return this.reportIfCookieConsent(() => this.moduleClient?.sendEvent(event));\n }\n addToCart(data) {\n return this.reportIfCookieConsent(() => this.moduleClient?.addToCart(data));\n }\n addToWishList(data) {\n return this.reportIfCookieConsent(() => this.moduleClient?.addToWishList(data));\n }\n saveDesign(options, context) {\n const { type } = options;\n const vpcCode = 'vpcCode' in options ? options.vpcCode : undefined;\n const payload = {\n type,\n context\n };\n return this.reportIfCookieConsent(() => this.moduleClient?.saveDesign(vpcCode, payload));\n }\n /**\n * @param sendFunction Function to perform if the user has cookie consent.\n */\n async reportIfCookieConsent(sendFunction) {\n const hasCookieConsent = await this.cookieConsentService?.hasCookieConsent(2);\n if (hasCookieConsent) {\n sendFunction();\n }\n }\n}\n//# sourceMappingURL=InsightsReporter.js.map","import { IdGenerator } from '@inter-ikea-kompis/utilities';\nimport InsightsReporter from '../reporters/InsightsReporter.js';\n/**\n * Used internally in Kompis for managing of {@link IAnalyticsReporter}s which are used to send analytics.\n *\n * Should NOT be used by planners.\n */\nclass ReporterManager {\n /**\n * Returns an existing connected reporter based on optional id, or creates a new one, or uses the platform reporter set from outside (only in the Kompis platform).\n *\n * @param id The id of an existing reporter, if any. Used to share the same instance of reporter across mutliple trackers.\n */\n static getReporter(id) {\n if (id) {\n const reporter = this.reporterMap.get(id);\n if (!reporter) {\n throw Error(`Expected to find reporter based on id ${id}, but found none.`);\n }\n return reporter;\n }\n return this.platformReporter ?? new InsightsReporter();\n }\n /**\n * Store the reporter instance.\n * This makes it possible to access the same instance of the reporter across multiple components by passing an id to the reporter between components.\n *\n * @param reporter The reporter.\n */\n static connect(reporter) {\n const id = this.idGenerator.generateId();\n this.reporterMap.set(id, reporter);\n }\n /**\n * Attempts to remove the provided reporter from the reporter cache.\n * This will only have an effect if the reporter has been connected earlier.\n *\n * @param reporter The reporter.\n */\n static disconnect(reporter) {\n const id = this.getConnectedId(reporter);\n if (id) {\n this.reporterMap.delete(id);\n }\n }\n /**\n * Returns whether the reporter has been connected or not.\n *\n * @param reporter The reporter.\n */\n static isConnected(reporter) {\n return !!this.getConnectedId(reporter);\n }\n /**\n * Get the id of the provided reporter.\n * The id can only be found if the reporter is connected.\n *\n * @param reporter The reporter.\n */\n static getConnectedId(reporter) {\n for (const [id, reporterEntry] of this.reporterMap.entries()) {\n if (reporterEntry === reporter) {\n return id;\n }\n }\n return null;\n }\n /**\n * Used internally to make tracking in the platform work. Is always PlatformReporter.\n *\n * @param platformReporter ...\n */\n static setPlatformReporter(platformReporter) {\n this.platformReporter = platformReporter;\n }\n}\nReporterManager.platformReporter = null;\nReporterManager.reporterMap = new Map();\nReporterManager.idGenerator = new IdGenerator();\nexport default ReporterManager;\n//# sourceMappingURL=ReporterManager.js.map","export default { version: '142.6.2' }","import ABTestUtility from '../utilities/ABTestUtility.js';\nimport AnalyticsManager from '../utilities/AnalyticsManager.js';\nimport ReporterManager from '../utilities/ReporterManager.js';\nimport Version from '../version.js';\n/**\n * Base class for analytics trackers.\n * Handles the common connect / disconnect logic.\n */\nexport default class AbstractAnalyticsTracker {\n /**\n * @param options ...\n * @param options.moduleId The id of the module (for identification of events).\n * @param options.dev Should be true if application is in development mode, defaults to false.\n * @param options.ab If ab tests should be enabled or not.\n * @param options.settings DEXF settings needed for Cookie Consent service and AB tests.\n * @param options.locale Locale needed for Cookie Consent service.\n * @param options.reporterId The id of an already connected reporter instance which should be used by this tracker.\n * @param kioskLongTermId Should be supplied when an A/B test is run exclusively on kiosk.\n */\n constructor(options, kioskLongTermId) {\n this.reporter = ReporterManager.getReporter(options.reporterId);\n this.options = options;\n const { ab, settings } = options;\n this.abTest = ab ? ABTestUtility.initializeABTests(settings, kioskLongTermId) : null;\n this.managesReporterLifecycle = !this.reporter.isConnected();\n }\n /**\n * Connects the reporter used by the tracker.\n * If the reporter is managed by another tracker, nothing will happen. The reporter is already connected and can be reused by this tracker.\n *\n * The trackers are responsible for the reporters' lifecycles, that is connecting and disconnecting them.\n * A reporter can be used by several trackers, but it should only be connected and disconnected once. This is the responsibility of the tracker of top level component.\n *\n * Example:\n * - Component_A has support for analytics.\n * - Component_B has support for analytics.\n * - Component_B can be rendered both from within Component_A and can be used stand alone.\n *\n * Scenarios:\n * - Component_A calls Tracker_A.connect. Tracker_A manages the reporter lifecycle, the reporter will be connected.\n * - Component_B (as stand alone) calls Tracker_B.connect. Tracker_B manages the reporter lifecycle, the reporter will be connected.\n * - Component_B (within Component_A) calls Tracker_B.connect. Tracker_A manages the reporter lifecycle, nothing will happen, the reporter is already connected.\n *\n */\n async connect() {\n if (!this.managesReporterLifecycle) {\n return;\n }\n const insightsApi = AnalyticsManager.getInsightsApi();\n const { moduleId, dev, locale, settings } = this.options;\n const cookieConsentServiceOptions = { locale, settings: settings };\n return this.reporter.connect(insightsApi, {\n moduleId,\n moduleVersion: Version.version,\n dev,\n abVersionName: this.abTest?.name,\n abVersionVariation: this.abTest?.variation\n }, cookieConsentServiceOptions);\n }\n /**\n * Disconnects the reporter used by tracker.\n * If the reporter is managed by another tracker, nothing will happen. The reporter can be used by several trackers and it should not be disconnected while still in use by another tracker.\n *\n * See {@link connect} for more information.\n */\n disconnect() {\n if (this.managesReporterLifecycle) {\n this.reporter.disconnect();\n }\n }\n /**\n * Get the id used to retrieve the connected reporter or null if the reporter is not connected yet.\n *\n * @returns The id or null.\n */\n getConnectedReporterId() {\n return this.reporter.getConnectedId();\n }\n /**\n * @returns AB test name and variation if there is an active test available in Översätta.\n */\n getABTest() {\n return this.abTest ?? null;\n }\n /**\n * Returns the reporter.\n */\n getReporter() {\n return this.reporter;\n }\n}\n//# sourceMappingURL=AbstractAnalyticsTracker.js.map","// eslint-disable-next-line @typescript-eslint/unbound-method\nconst objectToString = Object.prototype.toString;\n\n/**\n * Checks whether given value's type is one of a few Error or Error-like\n * {@link isError}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nfunction isError(wat) {\n switch (objectToString.call(wat)) {\n case '[object Error]':\n case '[object Exception]':\n case '[object DOMException]':\n case '[object WebAssembly.Exception]':\n return true;\n default:\n return isInstanceOf(wat, Error);\n }\n}\n/**\n * Checks whether given value is an instance of the given built-in class.\n *\n * @param wat The value to be checked\n * @param className\n * @returns A boolean representing the result.\n */\nfunction isBuiltin(wat, className) {\n return objectToString.call(wat) === `[object ${className}]`;\n}\n\n/**\n * Checks whether given value's type is ErrorEvent\n * {@link isErrorEvent}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nfunction isErrorEvent(wat) {\n return isBuiltin(wat, 'ErrorEvent');\n}\n\n/**\n * Checks whether given value's type is DOMError\n * {@link isDOMError}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nfunction isDOMError(wat) {\n return isBuiltin(wat, 'DOMError');\n}\n\n/**\n * Checks whether given value's type is DOMException\n * {@link isDOMException}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nfunction isDOMException(wat) {\n return isBuiltin(wat, 'DOMException');\n}\n\n/**\n * Checks whether given value's type is a string\n * {@link isString}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nfunction isString(wat) {\n return isBuiltin(wat, 'String');\n}\n\n/**\n * Checks whether given string is parameterized\n * {@link isParameterizedString}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nfunction isParameterizedString(wat) {\n return (\n typeof wat === 'object' &&\n wat !== null &&\n '__sentry_template_string__' in wat &&\n '__sentry_template_values__' in wat\n );\n}\n\n/**\n * Checks whether given value is a primitive (undefined, null, number, boolean, string, bigint, symbol)\n * {@link isPrimitive}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nfunction isPrimitive(wat) {\n return wat === null || isParameterizedString(wat) || (typeof wat !== 'object' && typeof wat !== 'function');\n}\n\n/**\n * Checks whether given value's type is an object literal, or a class instance.\n * {@link isPlainObject}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nfunction isPlainObject(wat) {\n return isBuiltin(wat, 'Object');\n}\n\n/**\n * Checks whether given value's type is an Event instance\n * {@link isEvent}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nfunction isEvent(wat) {\n return typeof Event !== 'undefined' && isInstanceOf(wat, Event);\n}\n\n/**\n * Checks whether given value's type is an Element instance\n * {@link isElement}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nfunction isElement(wat) {\n return typeof Element !== 'undefined' && isInstanceOf(wat, Element);\n}\n\n/**\n * Checks whether given value's type is an regexp\n * {@link isRegExp}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nfunction isRegExp(wat) {\n return isBuiltin(wat, 'RegExp');\n}\n\n/**\n * Checks whether given value has a then function.\n * @param wat A value to be checked.\n */\nfunction isThenable(wat) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n return Boolean(wat && wat.then && typeof wat.then === 'function');\n}\n\n/**\n * Checks whether given value's type is a SyntheticEvent\n * {@link isSyntheticEvent}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nfunction isSyntheticEvent(wat) {\n return isPlainObject(wat) && 'nativeEvent' in wat && 'preventDefault' in wat && 'stopPropagation' in wat;\n}\n\n/**\n * Checks whether given value's type is an instance of provided constructor.\n * {@link isInstanceOf}.\n *\n * @param wat A value to be checked.\n * @param base A constructor to be used in a check.\n * @returns A boolean representing the result.\n */\nfunction isInstanceOf(wat, base) {\n try {\n return wat instanceof base;\n } catch (_e) {\n return false;\n }\n}\n\n/**\n * Checks whether given value's type is a Vue ViewModel.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nfunction isVueViewModel(wat) {\n // Not using Object.prototype.toString because in Vue 3 it would read the instance's Symbol(Symbol.toStringTag) property.\n return !!(typeof wat === 'object' && wat !== null && ((wat ).__isVue || (wat )._isVue));\n}\n\nexport { isDOMError, isDOMException, isElement, isError, isErrorEvent, isEvent, isInstanceOf, isParameterizedString, isPlainObject, isPrimitive, isRegExp, isString, isSyntheticEvent, isThenable, isVueViewModel };\n//# sourceMappingURL=is.js.map\n","import { isVueViewModel, isString, isRegExp } from './is.js';\n\n/**\n * Truncates given string to the maximum characters count\n *\n * @param str An object that contains serializable values\n * @param max Maximum number of characters in truncated string (0 = unlimited)\n * @returns string Encoded\n */\nfunction truncate(str, max = 0) {\n if (typeof str !== 'string' || max === 0) {\n return str;\n }\n return str.length <= max ? str : `${str.slice(0, max)}...`;\n}\n\n/**\n * This is basically just `trim_line` from\n * https://github.com/getsentry/sentry/blob/master/src/sentry/lang/javascript/processor.py#L67\n *\n * @param str An object that contains serializable values\n * @param max Maximum number of characters in truncated string\n * @returns string Encoded\n */\nfunction snipLine(line, colno) {\n let newLine = line;\n const lineLength = newLine.length;\n if (lineLength <= 150) {\n return newLine;\n }\n if (colno > lineLength) {\n // eslint-disable-next-line no-param-reassign\n colno = lineLength;\n }\n\n let start = Math.max(colno - 60, 0);\n if (start < 5) {\n start = 0;\n }\n\n let end = Math.min(start + 140, lineLength);\n if (end > lineLength - 5) {\n end = lineLength;\n }\n if (end === lineLength) {\n start = Math.max(end - 140, 0);\n }\n\n newLine = newLine.slice(start, end);\n if (start > 0) {\n newLine = `'{snip} ${newLine}`;\n }\n if (end < lineLength) {\n newLine += ' {snip}';\n }\n\n return newLine;\n}\n\n/**\n * Join values in array\n * @param input array of values to be joined together\n * @param delimiter string to be placed in-between values\n * @returns Joined values\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction safeJoin(input, delimiter) {\n if (!Array.isArray(input)) {\n return '';\n }\n\n const output = [];\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let i = 0; i < input.length; i++) {\n const value = input[i];\n try {\n // This is a hack to fix a Vue3-specific bug that causes an infinite loop of\n // console warnings. This happens when a Vue template is rendered with\n // an undeclared variable, which we try to stringify, ultimately causing\n // Vue to issue another warning which repeats indefinitely.\n // see: https://github.com/getsentry/sentry-javascript/pull/8981\n if (isVueViewModel(value)) {\n output.push('[VueViewModel]');\n } else {\n output.push(String(value));\n }\n } catch (e) {\n output.push('[value cannot be serialized]');\n }\n }\n\n return output.join(delimiter);\n}\n\n/**\n * Checks if the given value matches a regex or string\n *\n * @param value The string to test\n * @param pattern Either a regex or a string against which `value` will be matched\n * @param requireExactStringMatch If true, `value` must match `pattern` exactly. If false, `value` will match\n * `pattern` if it contains `pattern`. Only applies to string-type patterns.\n */\nfunction isMatchingPattern(\n value,\n pattern,\n requireExactStringMatch = false,\n) {\n if (!isString(value)) {\n return false;\n }\n\n if (isRegExp(pattern)) {\n return pattern.test(value);\n }\n if (isString(pattern)) {\n return requireExactStringMatch ? value === pattern : value.includes(pattern);\n }\n\n return false;\n}\n\n/**\n * Test the given string against an array of strings and regexes. By default, string matching is done on a\n * substring-inclusion basis rather than a strict equality basis\n *\n * @param testString The string to test\n * @param patterns The patterns against which to test the string\n * @param requireExactStringMatch If true, `testString` must match one of the given string patterns exactly in order to\n * count. If false, `testString` will match a string pattern if it contains that pattern.\n * @returns\n */\nfunction stringMatchesSomePattern(\n testString,\n patterns = [],\n requireExactStringMatch = false,\n) {\n return patterns.some(pattern => isMatchingPattern(testString, pattern, requireExactStringMatch));\n}\n\nexport { isMatchingPattern, safeJoin, snipLine, stringMatchesSomePattern, truncate };\n//# sourceMappingURL=string.js.map\n","import { isInstanceOf } from './is.js';\nimport { truncate } from './string.js';\n\n/**\n * Creates exceptions inside `event.exception.values` for errors that are nested on properties based on the `key` parameter.\n */\nfunction applyAggregateErrorsToEvent(\n exceptionFromErrorImplementation,\n parser,\n maxValueLimit = 250,\n key,\n limit,\n event,\n hint,\n) {\n if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) {\n return;\n }\n\n // Generally speaking the last item in `event.exception.values` is the exception originating from the original Error\n const originalException =\n event.exception.values.length > 0 ? event.exception.values[event.exception.values.length - 1] : undefined;\n\n // We only create exception grouping if there is an exception in the event.\n if (originalException) {\n event.exception.values = truncateAggregateExceptions(\n aggregateExceptionsFromError(\n exceptionFromErrorImplementation,\n parser,\n limit,\n hint.originalException ,\n key,\n event.exception.values,\n originalException,\n 0,\n ),\n maxValueLimit,\n );\n }\n}\n\nfunction aggregateExceptionsFromError(\n exceptionFromErrorImplementation,\n parser,\n limit,\n error,\n key,\n prevExceptions,\n exception,\n exceptionId,\n) {\n if (prevExceptions.length >= limit + 1) {\n return prevExceptions;\n }\n\n let newExceptions = [...prevExceptions];\n\n // Recursively call this function in order to walk down a chain of errors\n if (isInstanceOf(error[key], Error)) {\n applyExceptionGroupFieldsForParentException(exception, exceptionId);\n const newException = exceptionFromErrorImplementation(parser, error[key]);\n const newExceptionId = newExceptions.length;\n applyExceptionGroupFieldsForChildException(newException, key, newExceptionId, exceptionId);\n newExceptions = aggregateExceptionsFromError(\n exceptionFromErrorImplementation,\n parser,\n limit,\n error[key],\n key,\n [newException, ...newExceptions],\n newException,\n newExceptionId,\n );\n }\n\n // This will create exception grouping for AggregateErrors\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError\n if (Array.isArray(error.errors)) {\n error.errors.forEach((childError, i) => {\n if (isInstanceOf(childError, Error)) {\n applyExceptionGroupFieldsForParentException(exception, exceptionId);\n const newException = exceptionFromErrorImplementation(parser, childError);\n const newExceptionId = newExceptions.length;\n applyExceptionGroupFieldsForChildException(newException, `errors[${i}]`, newExceptionId, exceptionId);\n newExceptions = aggregateExceptionsFromError(\n exceptionFromErrorImplementation,\n parser,\n limit,\n childError,\n key,\n [newException, ...newExceptions],\n newException,\n newExceptionId,\n );\n }\n });\n }\n\n return newExceptions;\n}\n\nfunction applyExceptionGroupFieldsForParentException(exception, exceptionId) {\n // Don't know if this default makes sense. The protocol requires us to set these values so we pick *some* default.\n exception.mechanism = exception.mechanism || { type: 'generic', handled: true };\n\n exception.mechanism = {\n ...exception.mechanism,\n ...(exception.type === 'AggregateError' && { is_exception_group: true }),\n exception_id: exceptionId,\n };\n}\n\nfunction applyExceptionGroupFieldsForChildException(\n exception,\n source,\n exceptionId,\n parentId,\n) {\n // Don't know if this default makes sense. The protocol requires us to set these values so we pick *some* default.\n exception.mechanism = exception.mechanism || { type: 'generic', handled: true };\n\n exception.mechanism = {\n ...exception.mechanism,\n type: 'chained',\n source,\n exception_id: exceptionId,\n parent_id: parentId,\n };\n}\n\n/**\n * Truncate the message (exception.value) of all exceptions in the event.\n * Because this event processor is ran after `applyClientOptions`,\n * we need to truncate the message of the added exceptions here.\n */\nfunction truncateAggregateExceptions(exceptions, maxValueLength) {\n return exceptions.map(exception => {\n if (exception.value) {\n exception.value = truncate(exception.value, maxValueLength);\n }\n return exception;\n });\n}\n\nexport { applyAggregateErrorsToEvent };\n//# sourceMappingURL=aggregate-errors.js.map\n","/**\n * Determine a breadcrumb's log level (only `warning` or `error`) based on an HTTP status code.\n */\nfunction getBreadcrumbLogLevelFromHttpStatusCode(statusCode) {\n // NOTE: undefined defaults to 'info' in Sentry\n if (statusCode === undefined) {\n return undefined;\n } else if (statusCode >= 400 && statusCode < 500) {\n return 'warning';\n } else if (statusCode >= 500) {\n return 'error';\n } else {\n return undefined;\n }\n}\n\nexport { getBreadcrumbLogLevelFromHttpStatusCode };\n//# sourceMappingURL=breadcrumb-log-level.js.map\n","// This is a magic string replaced by rollup\n\nconst SDK_VERSION = \"8.39.0\" ;\n\nexport { SDK_VERSION };\n//# sourceMappingURL=version.js.map\n","import { SDK_VERSION } from './version.js';\n\n/** Get's the global object for the current JavaScript runtime */\nconst GLOBAL_OBJ = globalThis ;\n\n/**\n * Returns a global singleton contained in the global `__SENTRY__[]` object.\n *\n * If the singleton doesn't already exist in `__SENTRY__`, it will be created using the given factory\n * function and added to the `__SENTRY__` object.\n *\n * @param name name of the global singleton on __SENTRY__\n * @param creator creator Factory function to create the singleton if it doesn't already exist on `__SENTRY__`\n * @param obj (Optional) The global object on which to look for `__SENTRY__`, if not `GLOBAL_OBJ`'s return value\n * @returns the singleton\n */\nfunction getGlobalSingleton(name, creator, obj) {\n const gbl = (obj || GLOBAL_OBJ) ;\n const __SENTRY__ = (gbl.__SENTRY__ = gbl.__SENTRY__ || {});\n const versionedCarrier = (__SENTRY__[SDK_VERSION] = __SENTRY__[SDK_VERSION] || {});\n return versionedCarrier[name] || (versionedCarrier[name] = creator());\n}\n\nexport { GLOBAL_OBJ, getGlobalSingleton };\n//# sourceMappingURL=worldwide.js.map\n","import { isString } from './is.js';\nimport { GLOBAL_OBJ } from './worldwide.js';\n\nconst WINDOW = GLOBAL_OBJ ;\n\nconst DEFAULT_MAX_STRING_LENGTH = 80;\n\n/**\n * Given a child DOM element, returns a query-selector statement describing that\n * and its ancestors\n * e.g. [HTMLElement] => body > div > input#foo.btn[name=baz]\n * @returns generated DOM path\n */\nfunction htmlTreeAsString(\n elem,\n options = {},\n) {\n if (!elem) {\n return '';\n }\n\n // try/catch both:\n // - accessing event.target (see getsentry/raven-js#838, #768)\n // - `htmlTreeAsString` because it's complex, and just accessing the DOM incorrectly\n // - can throw an exception in some circumstances.\n try {\n let currentElem = elem ;\n const MAX_TRAVERSE_HEIGHT = 5;\n const out = [];\n let height = 0;\n let len = 0;\n const separator = ' > ';\n const sepLength = separator.length;\n let nextStr;\n const keyAttrs = Array.isArray(options) ? options : options.keyAttrs;\n const maxStringLength = (!Array.isArray(options) && options.maxStringLength) || DEFAULT_MAX_STRING_LENGTH;\n\n while (currentElem && height++ < MAX_TRAVERSE_HEIGHT) {\n nextStr = _htmlElementAsString(currentElem, keyAttrs);\n // bail out if\n // - nextStr is the 'html' element\n // - the length of the string that would be created exceeds maxStringLength\n // (ignore this limit if we are on the first iteration)\n if (nextStr === 'html' || (height > 1 && len + out.length * sepLength + nextStr.length >= maxStringLength)) {\n break;\n }\n\n out.push(nextStr);\n\n len += nextStr.length;\n currentElem = currentElem.parentNode;\n }\n\n return out.reverse().join(separator);\n } catch (_oO) {\n return '';\n }\n}\n\n/**\n * Returns a simple, query-selector representation of a DOM element\n * e.g. [HTMLElement] => input#foo.btn[name=baz]\n * @returns generated DOM path\n */\nfunction _htmlElementAsString(el, keyAttrs) {\n const elem = el\n\n;\n\n const out = [];\n\n if (!elem || !elem.tagName) {\n return '';\n }\n\n // @ts-expect-error WINDOW has HTMLElement\n if (WINDOW.HTMLElement) {\n // If using the component name annotation plugin, this value may be available on the DOM node\n if (elem instanceof HTMLElement && elem.dataset) {\n if (elem.dataset['sentryComponent']) {\n return elem.dataset['sentryComponent'];\n }\n if (elem.dataset['sentryElement']) {\n return elem.dataset['sentryElement'];\n }\n }\n }\n\n out.push(elem.tagName.toLowerCase());\n\n // Pairs of attribute keys defined in `serializeAttribute` and their values on element.\n const keyAttrPairs =\n keyAttrs && keyAttrs.length\n ? keyAttrs.filter(keyAttr => elem.getAttribute(keyAttr)).map(keyAttr => [keyAttr, elem.getAttribute(keyAttr)])\n : null;\n\n if (keyAttrPairs && keyAttrPairs.length) {\n keyAttrPairs.forEach(keyAttrPair => {\n out.push(`[${keyAttrPair[0]}=\"${keyAttrPair[1]}\"]`);\n });\n } else {\n if (elem.id) {\n out.push(`#${elem.id}`);\n }\n\n const className = elem.className;\n if (className && isString(className)) {\n const classes = className.split(/\\s+/);\n for (const c of classes) {\n out.push(`.${c}`);\n }\n }\n }\n const allowedAttrs = ['aria-label', 'type', 'name', 'title', 'alt'];\n for (const k of allowedAttrs) {\n const attr = elem.getAttribute(k);\n if (attr) {\n out.push(`[${k}=\"${attr}\"]`);\n }\n }\n\n return out.join('');\n}\n\n/**\n * A safe form of location.href\n */\nfunction getLocationHref() {\n try {\n return WINDOW.document.location.href;\n } catch (oO) {\n return '';\n }\n}\n\n/**\n * Gets a DOM element by using document.querySelector.\n *\n * This wrapper will first check for the existence of the function before\n * actually calling it so that we don't have to take care of this check,\n * every time we want to access the DOM.\n *\n * Reason: DOM/querySelector is not available in all environments.\n *\n * We have to cast to any because utils can be consumed by a variety of environments,\n * and we don't want to break TS users. If you know what element will be selected by\n * `document.querySelector`, specify it as part of the generic call. For example,\n * `const element = getDomElement('selector');`\n *\n * @param selector the selector string passed on to document.querySelector\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction getDomElement(selector) {\n if (WINDOW.document && WINDOW.document.querySelector) {\n return WINDOW.document.querySelector(selector) ;\n }\n return null;\n}\n\n/**\n * Given a DOM element, traverses up the tree until it finds the first ancestor node\n * that has the `data-sentry-component` or `data-sentry-element` attribute with `data-sentry-component` taking\n * precedence. This attribute is added at build-time by projects that have the component name annotation plugin installed.\n *\n * @returns a string representation of the component for the provided DOM element, or `null` if not found\n */\nfunction getComponentName(elem) {\n // @ts-expect-error WINDOW has HTMLElement\n if (!WINDOW.HTMLElement) {\n return null;\n }\n\n let currentElem = elem ;\n const MAX_TRAVERSE_HEIGHT = 5;\n for (let i = 0; i < MAX_TRAVERSE_HEIGHT; i++) {\n if (!currentElem) {\n return null;\n }\n\n if (currentElem instanceof HTMLElement) {\n if (currentElem.dataset['sentryComponent']) {\n return currentElem.dataset['sentryComponent'];\n }\n if (currentElem.dataset['sentryElement']) {\n return currentElem.dataset['sentryElement'];\n }\n }\n\n currentElem = currentElem.parentNode;\n }\n\n return null;\n}\n\nexport { getComponentName, getDomElement, getLocationHref, htmlTreeAsString };\n//# sourceMappingURL=browser.js.map\n","/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nconst DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);\n\nexport { DEBUG_BUILD };\n//# sourceMappingURL=debug-build.js.map\n","import { DEBUG_BUILD } from './debug-build.js';\nimport { getGlobalSingleton, GLOBAL_OBJ } from './worldwide.js';\n\n/** Prefix for logging strings */\nconst PREFIX = 'Sentry Logger ';\n\nconst CONSOLE_LEVELS = [\n 'debug',\n 'info',\n 'warn',\n 'error',\n 'log',\n 'assert',\n 'trace',\n] ;\n\n/** This may be mutated by the console instrumentation. */\nconst originalConsoleMethods\n\n = {};\n\n/** JSDoc */\n\n/**\n * Temporarily disable sentry console instrumentations.\n *\n * @param callback The function to run against the original `console` messages\n * @returns The results of the callback\n */\nfunction consoleSandbox(callback) {\n if (!('console' in GLOBAL_OBJ)) {\n return callback();\n }\n\n const console = GLOBAL_OBJ.console ;\n const wrappedFuncs = {};\n\n const wrappedLevels = Object.keys(originalConsoleMethods) ;\n\n // Restore all wrapped console methods\n wrappedLevels.forEach(level => {\n const originalConsoleMethod = originalConsoleMethods[level] ;\n wrappedFuncs[level] = console[level] ;\n console[level] = originalConsoleMethod;\n });\n\n try {\n return callback();\n } finally {\n // Revert restoration to wrapped state\n wrappedLevels.forEach(level => {\n console[level] = wrappedFuncs[level] ;\n });\n }\n}\n\nfunction makeLogger() {\n let enabled = false;\n const logger = {\n enable: () => {\n enabled = true;\n },\n disable: () => {\n enabled = false;\n },\n isEnabled: () => enabled,\n };\n\n if (DEBUG_BUILD) {\n CONSOLE_LEVELS.forEach(name => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n logger[name] = (...args) => {\n if (enabled) {\n consoleSandbox(() => {\n GLOBAL_OBJ.console[name](`${PREFIX}[${name}]:`, ...args);\n });\n }\n };\n });\n } else {\n CONSOLE_LEVELS.forEach(name => {\n logger[name] = () => undefined;\n });\n }\n\n return logger ;\n}\n\n/**\n * This is a logger singleton which either logs things or no-ops if logging is not enabled.\n * The logger is a singleton on the carrier, to ensure that a consistent logger is used throughout the SDK.\n */\nconst logger = getGlobalSingleton('logger', makeLogger);\n\nexport { CONSOLE_LEVELS, consoleSandbox, logger, originalConsoleMethods };\n//# sourceMappingURL=logger.js.map\n","import { DEBUG_BUILD } from './debug-build.js';\nimport { consoleSandbox, logger } from './logger.js';\n\n/** Regular expression used to parse a Dsn. */\nconst DSN_REGEX = /^(?:(\\w+):)\\/\\/(?:(\\w+)(?::(\\w+)?)?@)([\\w.-]+)(?::(\\d+))?\\/(.+)/;\n\nfunction isValidProtocol(protocol) {\n return protocol === 'http' || protocol === 'https';\n}\n\n/**\n * Renders the string representation of this Dsn.\n *\n * By default, this will render the public representation without the password\n * component. To get the deprecated private representation, set `withPassword`\n * to true.\n *\n * @param withPassword When set to true, the password will be included.\n */\nfunction dsnToString(dsn, withPassword = false) {\n const { host, path, pass, port, projectId, protocol, publicKey } = dsn;\n return (\n `${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ''}` +\n `@${host}${port ? `:${port}` : ''}/${path ? `${path}/` : path}${projectId}`\n );\n}\n\n/**\n * Parses a Dsn from a given string.\n *\n * @param str A Dsn as string\n * @returns Dsn as DsnComponents or undefined if @param str is not a valid DSN string\n */\nfunction dsnFromString(str) {\n const match = DSN_REGEX.exec(str);\n\n if (!match) {\n // This should be logged to the console\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.error(`Invalid Sentry Dsn: ${str}`);\n });\n return undefined;\n }\n\n const [protocol, publicKey, pass = '', host = '', port = '', lastPath = ''] = match.slice(1);\n let path = '';\n let projectId = lastPath;\n\n const split = projectId.split('/');\n if (split.length > 1) {\n path = split.slice(0, -1).join('/');\n projectId = split.pop() ;\n }\n\n if (projectId) {\n const projectMatch = projectId.match(/^\\d+/);\n if (projectMatch) {\n projectId = projectMatch[0];\n }\n }\n\n return dsnFromComponents({ host, pass, path, projectId, port, protocol: protocol , publicKey });\n}\n\nfunction dsnFromComponents(components) {\n return {\n protocol: components.protocol,\n publicKey: components.publicKey || '',\n pass: components.pass || '',\n host: components.host,\n port: components.port || '',\n path: components.path || '',\n projectId: components.projectId,\n };\n}\n\nfunction validateDsn(dsn) {\n if (!DEBUG_BUILD) {\n return true;\n }\n\n const { port, projectId, protocol } = dsn;\n\n const requiredComponents = ['protocol', 'publicKey', 'host', 'projectId'];\n const hasMissingRequiredComponent = requiredComponents.find(component => {\n if (!dsn[component]) {\n logger.error(`Invalid Sentry Dsn: ${component} missing`);\n return true;\n }\n return false;\n });\n\n if (hasMissingRequiredComponent) {\n return false;\n }\n\n if (!projectId.match(/^\\d+$/)) {\n logger.error(`Invalid Sentry Dsn: Invalid projectId ${projectId}`);\n return false;\n }\n\n if (!isValidProtocol(protocol)) {\n logger.error(`Invalid Sentry Dsn: Invalid protocol ${protocol}`);\n return false;\n }\n\n if (port && isNaN(parseInt(port, 10))) {\n logger.error(`Invalid Sentry Dsn: Invalid port ${port}`);\n return false;\n }\n\n return true;\n}\n\n/**\n * Creates a valid Sentry Dsn object, identifying a Sentry instance and project.\n * @returns a valid DsnComponents object or `undefined` if @param from is an invalid DSN source\n */\nfunction makeDsn(from) {\n const components = typeof from === 'string' ? dsnFromString(from) : dsnFromComponents(from);\n if (!components || !validateDsn(components)) {\n return undefined;\n }\n return components;\n}\n\nexport { dsnFromString, dsnToString, makeDsn };\n//# sourceMappingURL=dsn.js.map\n","/** An error emitted by Sentry SDKs and related utilities. */\nclass SentryError extends Error {\n /** Display name of this error instance. */\n\n constructor( message, logLevel = 'warn') {\n super(message);this.message = message;\n this.name = new.target.prototype.constructor.name;\n // This sets the prototype to be `Error`, not `SentryError`. It's unclear why we do this, but commenting this line\n // out causes various (seemingly totally unrelated) playwright tests consistently time out. FYI, this makes\n // instances of `SentryError` fail `obj instanceof SentryError` checks.\n Object.setPrototypeOf(this, new.target.prototype);\n this.logLevel = logLevel;\n }\n}\n\nexport { SentryError };\n//# sourceMappingURL=error.js.map\n","import { htmlTreeAsString } from './browser.js';\nimport { DEBUG_BUILD } from './debug-build.js';\nimport { isError, isEvent, isInstanceOf, isElement, isPlainObject, isPrimitive } from './is.js';\nimport { logger } from './logger.js';\nimport { truncate } from './string.js';\n\n/**\n * Replace a method in an object with a wrapped version of itself.\n *\n * @param source An object that contains a method to be wrapped.\n * @param name The name of the method to be wrapped.\n * @param replacementFactory A higher-order function that takes the original version of the given method and returns a\n * wrapped version. Note: The function returned by `replacementFactory` needs to be a non-arrow function, in order to\n * preserve the correct value of `this`, and the original method must be called using `origMethod.call(this, )` or `origMethod.apply(this, [])` (rather than being called directly), again to preserve `this`.\n * @returns void\n */\nfunction fill(source, name, replacementFactory) {\n if (!(name in source)) {\n return;\n }\n\n const original = source[name] ;\n const wrapped = replacementFactory(original) ;\n\n // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work\n // otherwise it'll throw \"TypeError: Object.defineProperties called on non-object\"\n if (typeof wrapped === 'function') {\n markFunctionWrapped(wrapped, original);\n }\n\n source[name] = wrapped;\n}\n\n/**\n * Defines a non-enumerable property on the given object.\n *\n * @param obj The object on which to set the property\n * @param name The name of the property to be set\n * @param value The value to which to set the property\n */\nfunction addNonEnumerableProperty(obj, name, value) {\n try {\n Object.defineProperty(obj, name, {\n // enumerable: false, // the default, so we can save on bundle size by not explicitly setting it\n value: value,\n writable: true,\n configurable: true,\n });\n } catch (o_O) {\n DEBUG_BUILD && logger.log(`Failed to add non-enumerable property \"${name}\" to object`, obj);\n }\n}\n\n/**\n * Remembers the original function on the wrapped function and\n * patches up the prototype.\n *\n * @param wrapped the wrapper function\n * @param original the original function that gets wrapped\n */\nfunction markFunctionWrapped(wrapped, original) {\n try {\n const proto = original.prototype || {};\n wrapped.prototype = original.prototype = proto;\n addNonEnumerableProperty(wrapped, '__sentry_original__', original);\n } catch (o_O) {} // eslint-disable-line no-empty\n}\n\n/**\n * This extracts the original function if available. See\n * `markFunctionWrapped` for more information.\n *\n * @param func the function to unwrap\n * @returns the unwrapped version of the function if available.\n */\nfunction getOriginalFunction(func) {\n return func.__sentry_original__;\n}\n\n/**\n * Encodes given object into url-friendly format\n *\n * @param object An object that contains serializable values\n * @returns string Encoded\n */\nfunction urlEncode(object) {\n return Object.keys(object)\n .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(object[key])}`)\n .join('&');\n}\n\n/**\n * Transforms any `Error` or `Event` into a plain object with all of their enumerable properties, and some of their\n * non-enumerable properties attached.\n *\n * @param value Initial source that we have to transform in order for it to be usable by the serializer\n * @returns An Event or Error turned into an object - or the value argument itself, when value is neither an Event nor\n * an Error.\n */\nfunction convertToPlainObject(\n value,\n)\n\n {\n if (isError(value)) {\n return {\n message: value.message,\n name: value.name,\n stack: value.stack,\n ...getOwnProperties(value),\n };\n } else if (isEvent(value)) {\n const newObj\n\n = {\n type: value.type,\n target: serializeEventTarget(value.target),\n currentTarget: serializeEventTarget(value.currentTarget),\n ...getOwnProperties(value),\n };\n\n if (typeof CustomEvent !== 'undefined' && isInstanceOf(value, CustomEvent)) {\n newObj.detail = value.detail;\n }\n\n return newObj;\n } else {\n return value;\n }\n}\n\n/** Creates a string representation of the target of an `Event` object */\nfunction serializeEventTarget(target) {\n try {\n return isElement(target) ? htmlTreeAsString(target) : Object.prototype.toString.call(target);\n } catch (_oO) {\n return '';\n }\n}\n\n/** Filters out all but an object's own properties */\nfunction getOwnProperties(obj) {\n if (typeof obj === 'object' && obj !== null) {\n const extractedProps = {};\n for (const property in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, property)) {\n extractedProps[property] = (obj )[property];\n }\n }\n return extractedProps;\n } else {\n return {};\n }\n}\n\n/**\n * Given any captured exception, extract its keys and create a sorted\n * and truncated list that will be used inside the event message.\n * eg. `Non-error exception captured with keys: foo, bar, baz`\n */\nfunction extractExceptionKeysForMessage(exception, maxLength = 40) {\n const keys = Object.keys(convertToPlainObject(exception));\n keys.sort();\n\n const firstKey = keys[0];\n\n if (!firstKey) {\n return '[object has no keys]';\n }\n\n if (firstKey.length >= maxLength) {\n return truncate(firstKey, maxLength);\n }\n\n for (let includedKeys = keys.length; includedKeys > 0; includedKeys--) {\n const serialized = keys.slice(0, includedKeys).join(', ');\n if (serialized.length > maxLength) {\n continue;\n }\n if (includedKeys === keys.length) {\n return serialized;\n }\n return truncate(serialized, maxLength);\n }\n\n return '';\n}\n\n/**\n * Given any object, return a new object having removed all fields whose value was `undefined`.\n * Works recursively on objects and arrays.\n *\n * Attention: This function keeps circular references in the returned object.\n */\nfunction dropUndefinedKeys(inputValue) {\n // This map keeps track of what already visited nodes map to.\n // Our Set - based memoBuilder doesn't work here because we want to the output object to have the same circular\n // references as the input object.\n const memoizationMap = new Map();\n\n // This function just proxies `_dropUndefinedKeys` to keep the `memoBuilder` out of this function's API\n return _dropUndefinedKeys(inputValue, memoizationMap);\n}\n\nfunction _dropUndefinedKeys(inputValue, memoizationMap) {\n if (isPojo(inputValue)) {\n // If this node has already been visited due to a circular reference, return the object it was mapped to in the new object\n const memoVal = memoizationMap.get(inputValue);\n if (memoVal !== undefined) {\n return memoVal ;\n }\n\n const returnValue = {};\n // Store the mapping of this value in case we visit it again, in case of circular data\n memoizationMap.set(inputValue, returnValue);\n\n for (const key of Object.getOwnPropertyNames(inputValue)) {\n if (typeof inputValue[key] !== 'undefined') {\n returnValue[key] = _dropUndefinedKeys(inputValue[key], memoizationMap);\n }\n }\n\n return returnValue ;\n }\n\n if (Array.isArray(inputValue)) {\n // If this node has already been visited due to a circular reference, return the array it was mapped to in the new object\n const memoVal = memoizationMap.get(inputValue);\n if (memoVal !== undefined) {\n return memoVal ;\n }\n\n const returnValue = [];\n // Store the mapping of this value in case we visit it again, in case of circular data\n memoizationMap.set(inputValue, returnValue);\n\n inputValue.forEach((item) => {\n returnValue.push(_dropUndefinedKeys(item, memoizationMap));\n });\n\n return returnValue ;\n }\n\n return inputValue;\n}\n\nfunction isPojo(input) {\n if (!isPlainObject(input)) {\n return false;\n }\n\n try {\n const name = (Object.getPrototypeOf(input) ).constructor.name;\n return !name || name === 'Object';\n } catch (e) {\n return true;\n }\n}\n\n/**\n * Ensure that something is an object.\n *\n * Turns `undefined` and `null` into `String`s and all other primitives into instances of their respective wrapper\n * classes (String, Boolean, Number, etc.). Acts as the identity function on non-primitives.\n *\n * @param wat The subject of the objectification\n * @returns A version of `wat` which can safely be used with `Object` class methods\n */\nfunction objectify(wat) {\n let objectified;\n switch (true) {\n case wat === undefined || wat === null:\n objectified = new String(wat);\n break;\n\n // Though symbols and bigints do have wrapper classes (`Symbol` and `BigInt`, respectively), for whatever reason\n // those classes don't have constructors which can be used with the `new` keyword. We therefore need to cast each as\n // an object in order to wrap it.\n case typeof wat === 'symbol' || typeof wat === 'bigint':\n objectified = Object(wat);\n break;\n\n // this will catch the remaining primitives: `String`, `Number`, and `Boolean`\n case isPrimitive(wat):\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n objectified = new (wat ).constructor(wat);\n break;\n\n // by process of elimination, at this point we know that `wat` must already be an object\n default:\n objectified = wat;\n break;\n }\n return objectified;\n}\n\nexport { addNonEnumerableProperty, convertToPlainObject, dropUndefinedKeys, extractExceptionKeysForMessage, fill, getOriginalFunction, markFunctionWrapped, objectify, urlEncode };\n//# sourceMappingURL=object.js.map\n","const STACKTRACE_FRAME_LIMIT = 50;\nconst UNKNOWN_FUNCTION = '?';\n// Used to sanitize webpack (error: *) wrapped stack errors\nconst WEBPACK_ERROR_REGEXP = /\\(error: (.*)\\)/;\nconst STRIP_FRAME_REGEXP = /captureMessage|captureException/;\n\n/**\n * Creates a stack parser with the supplied line parsers\n *\n * StackFrames are returned in the correct order for Sentry Exception\n * frames and with Sentry SDK internal frames removed from the top and bottom\n *\n */\nfunction createStackParser(...parsers) {\n const sortedParsers = parsers.sort((a, b) => a[0] - b[0]).map(p => p[1]);\n\n return (stack, skipFirstLines = 0, framesToPop = 0) => {\n const frames = [];\n const lines = stack.split('\\n');\n\n for (let i = skipFirstLines; i < lines.length; i++) {\n const line = lines[i] ;\n // Ignore lines over 1kb as they are unlikely to be stack frames.\n // Many of the regular expressions use backtracking which results in run time that increases exponentially with\n // input size. Huge strings can result in hangs/Denial of Service:\n // https://github.com/getsentry/sentry-javascript/issues/2286\n if (line.length > 1024) {\n continue;\n }\n\n // https://github.com/getsentry/sentry-javascript/issues/5459\n // Remove webpack (error: *) wrappers\n const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, '$1') : line;\n\n // https://github.com/getsentry/sentry-javascript/issues/7813\n // Skip Error: lines\n if (cleanedLine.match(/\\S*Error: /)) {\n continue;\n }\n\n for (const parser of sortedParsers) {\n const frame = parser(cleanedLine);\n\n if (frame) {\n frames.push(frame);\n break;\n }\n }\n\n if (frames.length >= STACKTRACE_FRAME_LIMIT + framesToPop) {\n break;\n }\n }\n\n return stripSentryFramesAndReverse(frames.slice(framesToPop));\n };\n}\n\n/**\n * Gets a stack parser implementation from Options.stackParser\n * @see Options\n *\n * If options contains an array of line parsers, it is converted into a parser\n */\nfunction stackParserFromStackParserOptions(stackParser) {\n if (Array.isArray(stackParser)) {\n return createStackParser(...stackParser);\n }\n return stackParser;\n}\n\n/**\n * Removes Sentry frames from the top and bottom of the stack if present and enforces a limit of max number of frames.\n * Assumes stack input is ordered from top to bottom and returns the reverse representation so call site of the\n * function that caused the crash is the last frame in the array.\n * @hidden\n */\nfunction stripSentryFramesAndReverse(stack) {\n if (!stack.length) {\n return [];\n }\n\n const localStack = Array.from(stack);\n\n // If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call)\n if (/sentryWrapped/.test(getLastStackFrame(localStack).function || '')) {\n localStack.pop();\n }\n\n // Reversing in the middle of the procedure allows us to just pop the values off the stack\n localStack.reverse();\n\n // If stack ends with one of our internal API calls, remove it (ends, meaning it's the bottom of the stack - aka top-most call)\n if (STRIP_FRAME_REGEXP.test(getLastStackFrame(localStack).function || '')) {\n localStack.pop();\n\n // When using synthetic events, we will have a 2 levels deep stack, as `new Error('Sentry syntheticException')`\n // is produced within the hub itself, making it:\n //\n // Sentry.captureException()\n // getCurrentHub().captureException()\n //\n // instead of just the top `Sentry` call itself.\n // This forces us to possibly strip an additional frame in the exact same was as above.\n if (STRIP_FRAME_REGEXP.test(getLastStackFrame(localStack).function || '')) {\n localStack.pop();\n }\n }\n\n return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map(frame => ({\n ...frame,\n filename: frame.filename || getLastStackFrame(localStack).filename,\n function: frame.function || UNKNOWN_FUNCTION,\n }));\n}\n\nfunction getLastStackFrame(arr) {\n return arr[arr.length - 1] || {};\n}\n\nconst defaultFunctionName = '';\n\n/**\n * Safely extract function name from itself\n */\nfunction getFunctionName(fn) {\n try {\n if (!fn || typeof fn !== 'function') {\n return defaultFunctionName;\n }\n return fn.name || defaultFunctionName;\n } catch (e) {\n // Just accessing custom props in some Selenium environments\n // can cause a \"Permission denied\" exception (see raven-js#495).\n return defaultFunctionName;\n }\n}\n\n/**\n * Get's stack frames from an event without needing to check for undefined properties.\n */\nfunction getFramesFromEvent(event) {\n const exception = event.exception;\n\n if (exception) {\n const frames = [];\n try {\n // @ts-expect-error Object could be undefined\n exception.values.forEach(value => {\n // @ts-expect-error Value could be undefined\n if (value.stacktrace.frames) {\n // @ts-expect-error Value could be undefined\n frames.push(...value.stacktrace.frames);\n }\n });\n return frames;\n } catch (_oO) {\n return undefined;\n }\n }\n return undefined;\n}\n\nexport { UNKNOWN_FUNCTION, createStackParser, getFramesFromEvent, getFunctionName, stackParserFromStackParserOptions, stripSentryFramesAndReverse };\n//# sourceMappingURL=stacktrace.js.map\n","import { DEBUG_BUILD } from '../debug-build.js';\nimport { logger } from '../logger.js';\nimport { getFunctionName } from '../stacktrace.js';\n\n// We keep the handlers globally\nconst handlers = {};\nconst instrumented = {};\n\n/** Add a handler function. */\nfunction addHandler(type, handler) {\n handlers[type] = handlers[type] || [];\n (handlers[type] ).push(handler);\n}\n\n/**\n * Reset all instrumentation handlers.\n * This can be used by tests to ensure we have a clean slate of instrumentation handlers.\n */\nfunction resetInstrumentationHandlers() {\n Object.keys(handlers).forEach(key => {\n handlers[key ] = undefined;\n });\n}\n\n/** Maybe run an instrumentation function, unless it was already called. */\nfunction maybeInstrument(type, instrumentFn) {\n if (!instrumented[type]) {\n instrumented[type] = true;\n try {\n instrumentFn();\n } catch (e) {\n DEBUG_BUILD && logger.error(`Error while instrumenting ${type}`, e);\n }\n }\n}\n\n/** Trigger handlers for a given instrumentation type. */\nfunction triggerHandlers(type, data) {\n const typeHandlers = type && handlers[type];\n if (!typeHandlers) {\n return;\n }\n\n for (const handler of typeHandlers) {\n try {\n handler(data);\n } catch (e) {\n DEBUG_BUILD &&\n logger.error(\n `Error while triggering instrumentation handler.\\nType: ${type}\\nName: ${getFunctionName(handler)}\\nError:`,\n e,\n );\n }\n }\n}\n\nexport { addHandler, maybeInstrument, resetInstrumentationHandlers, triggerHandlers };\n//# sourceMappingURL=handlers.js.map\n","import { CONSOLE_LEVELS, originalConsoleMethods } from '../logger.js';\nimport { fill } from '../object.js';\nimport { GLOBAL_OBJ } from '../worldwide.js';\nimport { addHandler, maybeInstrument, triggerHandlers } from './handlers.js';\n\n/**\n * Add an instrumentation handler for when a console.xxx method is called.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nfunction addConsoleInstrumentationHandler(handler) {\n const type = 'console';\n addHandler(type, handler);\n maybeInstrument(type, instrumentConsole);\n}\n\nfunction instrumentConsole() {\n if (!('console' in GLOBAL_OBJ)) {\n return;\n }\n\n CONSOLE_LEVELS.forEach(function (level) {\n if (!(level in GLOBAL_OBJ.console)) {\n return;\n }\n\n fill(GLOBAL_OBJ.console, level, function (originalConsoleMethod) {\n originalConsoleMethods[level] = originalConsoleMethod;\n\n return function (...args) {\n const handlerData = { args, level };\n triggerHandlers('console', handlerData);\n\n const log = originalConsoleMethods[level];\n log && log.apply(GLOBAL_OBJ.console, args);\n };\n });\n });\n}\n\nexport { addConsoleInstrumentationHandler };\n//# sourceMappingURL=console.js.map\n","import { DEBUG_BUILD } from './debug-build.js';\nimport { logger } from './logger.js';\nimport { GLOBAL_OBJ } from './worldwide.js';\n\nconst WINDOW = GLOBAL_OBJ ;\n\n/**\n * Tells whether current environment supports ErrorEvent objects\n * {@link supportsErrorEvent}.\n *\n * @returns Answer to the given question.\n */\nfunction supportsErrorEvent() {\n try {\n new ErrorEvent('');\n return true;\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Tells whether current environment supports DOMError objects\n * {@link supportsDOMError}.\n *\n * @returns Answer to the given question.\n */\nfunction supportsDOMError() {\n try {\n // Chrome: VM89:1 Uncaught TypeError: Failed to construct 'DOMError':\n // 1 argument required, but only 0 present.\n // @ts-expect-error It really needs 1 argument, not 0.\n new DOMError('');\n return true;\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Tells whether current environment supports DOMException objects\n * {@link supportsDOMException}.\n *\n * @returns Answer to the given question.\n */\nfunction supportsDOMException() {\n try {\n new DOMException('');\n return true;\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Tells whether current environment supports Fetch API\n * {@link supportsFetch}.\n *\n * @returns Answer to the given question.\n */\nfunction supportsFetch() {\n if (!('fetch' in WINDOW)) {\n return false;\n }\n\n try {\n new Headers();\n new Request('http://www.example.com');\n new Response();\n return true;\n } catch (e) {\n return false;\n }\n}\n\n/**\n * isNative checks if the given function is a native implementation\n */\n// eslint-disable-next-line @typescript-eslint/ban-types\nfunction isNativeFunction(func) {\n return func && /^function\\s+\\w+\\(\\)\\s+\\{\\s+\\[native code\\]\\s+\\}$/.test(func.toString());\n}\n\n/**\n * Tells whether current environment supports Fetch API natively\n * {@link supportsNativeFetch}.\n *\n * @returns true if `window.fetch` is natively implemented, false otherwise\n */\nfunction supportsNativeFetch() {\n if (typeof EdgeRuntime === 'string') {\n return true;\n }\n\n if (!supportsFetch()) {\n return false;\n }\n\n // Fast path to avoid DOM I/O\n // eslint-disable-next-line @typescript-eslint/unbound-method\n if (isNativeFunction(WINDOW.fetch)) {\n return true;\n }\n\n // window.fetch is implemented, but is polyfilled or already wrapped (e.g: by a chrome extension)\n // so create a \"pure\" iframe to see if that has native fetch\n let result = false;\n const doc = WINDOW.document;\n // eslint-disable-next-line deprecation/deprecation\n if (doc && typeof (doc.createElement ) === 'function') {\n try {\n const sandbox = doc.createElement('iframe');\n sandbox.hidden = true;\n doc.head.appendChild(sandbox);\n if (sandbox.contentWindow && sandbox.contentWindow.fetch) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n result = isNativeFunction(sandbox.contentWindow.fetch);\n }\n doc.head.removeChild(sandbox);\n } catch (err) {\n DEBUG_BUILD &&\n logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', err);\n }\n }\n\n return result;\n}\n\n/**\n * Tells whether current environment supports ReportingObserver API\n * {@link supportsReportingObserver}.\n *\n * @returns Answer to the given question.\n */\nfunction supportsReportingObserver() {\n return 'ReportingObserver' in WINDOW;\n}\n\n/**\n * Tells whether current environment supports Referrer Policy API\n * {@link supportsReferrerPolicy}.\n *\n * @returns Answer to the given question.\n */\nfunction supportsReferrerPolicy() {\n // Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default'\n // (see https://caniuse.com/#feat=referrer-policy),\n // it doesn't. And it throws an exception instead of ignoring this parameter...\n // REF: https://github.com/getsentry/raven-js/issues/1233\n\n if (!supportsFetch()) {\n return false;\n }\n\n try {\n new Request('_', {\n referrerPolicy: 'origin' ,\n });\n return true;\n } catch (e) {\n return false;\n }\n}\n\nexport { isNativeFunction, supportsDOMError, supportsDOMException, supportsErrorEvent, supportsFetch, supportsNativeFetch, supportsReferrerPolicy, supportsReportingObserver };\n//# sourceMappingURL=supports.js.map\n","import { GLOBAL_OBJ } from './worldwide.js';\n\nconst ONE_SECOND_IN_MS = 1000;\n\n/**\n * A partial definition of the [Performance Web API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Performance}\n * for accessing a high-resolution monotonic clock.\n */\n\n/**\n * Returns a timestamp in seconds since the UNIX epoch using the Date API.\n *\n * TODO(v8): Return type should be rounded.\n */\nfunction dateTimestampInSeconds() {\n return Date.now() / ONE_SECOND_IN_MS;\n}\n\n/**\n * Returns a wrapper around the native Performance API browser implementation, or undefined for browsers that do not\n * support the API.\n *\n * Wrapping the native API works around differences in behavior from different browsers.\n */\nfunction createUnixTimestampInSecondsFunc() {\n const { performance } = GLOBAL_OBJ ;\n if (!performance || !performance.now) {\n return dateTimestampInSeconds;\n }\n\n // Some browser and environments don't have a timeOrigin, so we fallback to\n // using Date.now() to compute the starting time.\n const approxStartingTimeOrigin = Date.now() - performance.now();\n const timeOrigin = performance.timeOrigin == undefined ? approxStartingTimeOrigin : performance.timeOrigin;\n\n // performance.now() is a monotonic clock, which means it starts at 0 when the process begins. To get the current\n // wall clock time (actual UNIX timestamp), we need to add the starting time origin and the current time elapsed.\n //\n // TODO: This does not account for the case where the monotonic clock that powers performance.now() drifts from the\n // wall clock time, which causes the returned timestamp to be inaccurate. We should investigate how to detect and\n // correct for this.\n // See: https://github.com/getsentry/sentry-javascript/issues/2590\n // See: https://github.com/mdn/content/issues/4713\n // See: https://dev.to/noamr/when-a-millisecond-is-not-a-millisecond-3h6\n return () => {\n return (timeOrigin + performance.now()) / ONE_SECOND_IN_MS;\n };\n}\n\n/**\n * Returns a timestamp in seconds since the UNIX epoch using either the Performance or Date APIs, depending on the\n * availability of the Performance API.\n *\n * BUG: Note that because of how browsers implement the Performance API, the clock might stop when the computer is\n * asleep. This creates a skew between `dateTimestampInSeconds` and `timestampInSeconds`. The\n * skew can grow to arbitrary amounts like days, weeks or months.\n * See https://github.com/getsentry/sentry-javascript/issues/2590.\n */\nconst timestampInSeconds = createUnixTimestampInSecondsFunc();\n\n/**\n * Internal helper to store what is the source of browserPerformanceTimeOrigin below. For debugging only.\n */\nlet _browserPerformanceTimeOriginMode;\n\n/**\n * The number of milliseconds since the UNIX epoch. This value is only usable in a browser, and only when the\n * performance API is available.\n */\nconst browserPerformanceTimeOrigin = (() => {\n // Unfortunately browsers may report an inaccurate time origin data, through either performance.timeOrigin or\n // performance.timing.navigationStart, which results in poor results in performance data. We only treat time origin\n // data as reliable if they are within a reasonable threshold of the current time.\n\n const { performance } = GLOBAL_OBJ ;\n if (!performance || !performance.now) {\n _browserPerformanceTimeOriginMode = 'none';\n return undefined;\n }\n\n const threshold = 3600 * 1000;\n const performanceNow = performance.now();\n const dateNow = Date.now();\n\n // if timeOrigin isn't available set delta to threshold so it isn't used\n const timeOriginDelta = performance.timeOrigin\n ? Math.abs(performance.timeOrigin + performanceNow - dateNow)\n : threshold;\n const timeOriginIsReliable = timeOriginDelta < threshold;\n\n // While performance.timing.navigationStart is deprecated in favor of performance.timeOrigin, performance.timeOrigin\n // is not as widely supported. Namely, performance.timeOrigin is undefined in Safari as of writing.\n // Also as of writing, performance.timing is not available in Web Workers in mainstream browsers, so it is not always\n // a valid fallback. In the absence of an initial time provided by the browser, fallback to the current time from the\n // Date API.\n // eslint-disable-next-line deprecation/deprecation\n const navigationStart = performance.timing && performance.timing.navigationStart;\n const hasNavigationStart = typeof navigationStart === 'number';\n // if navigationStart isn't available set delta to threshold so it isn't used\n const navigationStartDelta = hasNavigationStart ? Math.abs(navigationStart + performanceNow - dateNow) : threshold;\n const navigationStartIsReliable = navigationStartDelta < threshold;\n\n if (timeOriginIsReliable || navigationStartIsReliable) {\n // Use the more reliable time origin\n if (timeOriginDelta <= navigationStartDelta) {\n _browserPerformanceTimeOriginMode = 'timeOrigin';\n return performance.timeOrigin;\n } else {\n _browserPerformanceTimeOriginMode = 'navigationStart';\n return navigationStart;\n }\n }\n\n // Either both timeOrigin and navigationStart are skewed or neither is available, fallback to Date.\n _browserPerformanceTimeOriginMode = 'dateNow';\n return dateNow;\n})();\n\nexport { _browserPerformanceTimeOriginMode, browserPerformanceTimeOrigin, dateTimestampInSeconds, timestampInSeconds };\n//# sourceMappingURL=time.js.map\n","import { isError } from '../is.js';\nimport { fill, addNonEnumerableProperty } from '../object.js';\nimport { supportsNativeFetch } from '../supports.js';\nimport { timestampInSeconds } from '../time.js';\nimport { GLOBAL_OBJ } from '../worldwide.js';\nimport { addHandler, maybeInstrument, triggerHandlers } from './handlers.js';\n\n/**\n * Add an instrumentation handler for when a fetch request happens.\n * The handler function is called once when the request starts and once when it ends,\n * which can be identified by checking if it has an `endTimestamp`.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nfunction addFetchInstrumentationHandler(\n handler,\n skipNativeFetchCheck,\n) {\n const type = 'fetch';\n addHandler(type, handler);\n maybeInstrument(type, () => instrumentFetch(undefined, skipNativeFetchCheck));\n}\n\n/**\n * Add an instrumentation handler for long-lived fetch requests, like consuming server-sent events (SSE) via fetch.\n * The handler will resolve the request body and emit the actual `endTimestamp`, so that the\n * span can be updated accordingly.\n *\n * Only used internally\n * @hidden\n */\nfunction addFetchEndInstrumentationHandler(handler) {\n const type = 'fetch-body-resolved';\n addHandler(type, handler);\n maybeInstrument(type, () => instrumentFetch(streamHandler));\n}\n\nfunction instrumentFetch(onFetchResolved, skipNativeFetchCheck = false) {\n if (skipNativeFetchCheck && !supportsNativeFetch()) {\n return;\n }\n\n fill(GLOBAL_OBJ, 'fetch', function (originalFetch) {\n return function (...args) {\n const { method, url } = parseFetchArgs(args);\n const handlerData = {\n args,\n fetchData: {\n method,\n url,\n },\n startTimestamp: timestampInSeconds() * 1000,\n };\n\n // if there is no callback, fetch is instrumented directly\n if (!onFetchResolved) {\n triggerHandlers('fetch', {\n ...handlerData,\n });\n }\n\n // We capture the stack right here and not in the Promise error callback because Safari (and probably other\n // browsers too) will wipe the stack trace up to this point, only leaving us with this file which is useless.\n\n // NOTE: If you are a Sentry user, and you are seeing this stack frame,\n // it means the error, that was caused by your fetch call did not\n // have a stack trace, so the SDK backfilled the stack trace so\n // you can see which fetch call failed.\n const virtualStackTrace = new Error().stack;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n return originalFetch.apply(GLOBAL_OBJ, args).then(\n async (response) => {\n if (onFetchResolved) {\n onFetchResolved(response);\n } else {\n triggerHandlers('fetch', {\n ...handlerData,\n endTimestamp: timestampInSeconds() * 1000,\n response,\n });\n }\n\n return response;\n },\n (error) => {\n triggerHandlers('fetch', {\n ...handlerData,\n endTimestamp: timestampInSeconds() * 1000,\n error,\n });\n\n if (isError(error) && error.stack === undefined) {\n // NOTE: If you are a Sentry user, and you are seeing this stack frame,\n // it means the error, that was caused by your fetch call did not\n // have a stack trace, so the SDK backfilled the stack trace so\n // you can see which fetch call failed.\n error.stack = virtualStackTrace;\n addNonEnumerableProperty(error, 'framesToPop', 1);\n }\n\n // NOTE: If you are a Sentry user, and you are seeing this stack frame,\n // it means the sentry.javascript SDK caught an error invoking your application code.\n // This is expected behavior and NOT indicative of a bug with sentry.javascript.\n throw error;\n },\n );\n };\n });\n}\n\nasync function resolveResponse(res, onFinishedResolving) {\n if (res && res.body) {\n const body = res.body;\n const responseReader = body.getReader();\n\n // Define a maximum duration after which we just cancel\n const maxFetchDurationTimeout = setTimeout(\n () => {\n body.cancel().then(null, () => {\n // noop\n });\n },\n 90 * 1000, // 90s\n );\n\n let readingActive = true;\n while (readingActive) {\n let chunkTimeout;\n try {\n // abort reading if read op takes more than 5s\n chunkTimeout = setTimeout(() => {\n body.cancel().then(null, () => {\n // noop on error\n });\n }, 5000);\n\n // This .read() call will reject/throw when we abort due to timeouts through `body.cancel()`\n const { done } = await responseReader.read();\n\n clearTimeout(chunkTimeout);\n\n if (done) {\n onFinishedResolving();\n readingActive = false;\n }\n } catch (error) {\n readingActive = false;\n } finally {\n clearTimeout(chunkTimeout);\n }\n }\n\n clearTimeout(maxFetchDurationTimeout);\n\n responseReader.releaseLock();\n body.cancel().then(null, () => {\n // noop on error\n });\n }\n}\n\nfunction streamHandler(response) {\n // clone response for awaiting stream\n let clonedResponseForResolving;\n try {\n clonedResponseForResolving = response.clone();\n } catch (e) {\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n resolveResponse(clonedResponseForResolving, () => {\n triggerHandlers('fetch-body-resolved', {\n endTimestamp: timestampInSeconds() * 1000,\n response,\n });\n });\n}\n\nfunction hasProp(obj, prop) {\n return !!obj && typeof obj === 'object' && !!(obj )[prop];\n}\n\nfunction getUrlFromResource(resource) {\n if (typeof resource === 'string') {\n return resource;\n }\n\n if (!resource) {\n return '';\n }\n\n if (hasProp(resource, 'url')) {\n return resource.url;\n }\n\n if (resource.toString) {\n return resource.toString();\n }\n\n return '';\n}\n\n/**\n * Parses the fetch arguments to find the used Http method and the url of the request.\n * Exported for tests only.\n */\nfunction parseFetchArgs(fetchArgs) {\n if (fetchArgs.length === 0) {\n return { method: 'GET', url: '' };\n }\n\n if (fetchArgs.length === 2) {\n const [url, options] = fetchArgs ;\n\n return {\n url: getUrlFromResource(url),\n method: hasProp(options, 'method') ? String(options.method).toUpperCase() : 'GET',\n };\n }\n\n const arg = fetchArgs[0];\n return {\n url: getUrlFromResource(arg ),\n method: hasProp(arg, 'method') ? String(arg.method).toUpperCase() : 'GET',\n };\n}\n\nexport { addFetchEndInstrumentationHandler, addFetchInstrumentationHandler, parseFetchArgs };\n//# sourceMappingURL=fetch.js.map\n","import { GLOBAL_OBJ } from '../worldwide.js';\nimport { addHandler, maybeInstrument, triggerHandlers } from './handlers.js';\n\nlet _oldOnErrorHandler = null;\n\n/**\n * Add an instrumentation handler for when an error is captured by the global error handler.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nfunction addGlobalErrorInstrumentationHandler(handler) {\n const type = 'error';\n addHandler(type, handler);\n maybeInstrument(type, instrumentError);\n}\n\nfunction instrumentError() {\n _oldOnErrorHandler = GLOBAL_OBJ.onerror;\n\n GLOBAL_OBJ.onerror = function (\n msg,\n url,\n line,\n column,\n error,\n ) {\n const handlerData = {\n column,\n error,\n line,\n msg,\n url,\n };\n triggerHandlers('error', handlerData);\n\n if (_oldOnErrorHandler && !_oldOnErrorHandler.__SENTRY_LOADER__) {\n // eslint-disable-next-line prefer-rest-params\n return _oldOnErrorHandler.apply(this, arguments);\n }\n\n return false;\n };\n\n GLOBAL_OBJ.onerror.__SENTRY_INSTRUMENTED__ = true;\n}\n\nexport { addGlobalErrorInstrumentationHandler };\n//# sourceMappingURL=globalError.js.map\n","import { GLOBAL_OBJ } from '../worldwide.js';\nimport { addHandler, maybeInstrument, triggerHandlers } from './handlers.js';\n\nlet _oldOnUnhandledRejectionHandler = null;\n\n/**\n * Add an instrumentation handler for when an unhandled promise rejection is captured.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nfunction addGlobalUnhandledRejectionInstrumentationHandler(\n handler,\n) {\n const type = 'unhandledrejection';\n addHandler(type, handler);\n maybeInstrument(type, instrumentUnhandledRejection);\n}\n\nfunction instrumentUnhandledRejection() {\n _oldOnUnhandledRejectionHandler = GLOBAL_OBJ.onunhandledrejection;\n\n GLOBAL_OBJ.onunhandledrejection = function (e) {\n const handlerData = e;\n triggerHandlers('unhandledrejection', handlerData);\n\n if (_oldOnUnhandledRejectionHandler && !_oldOnUnhandledRejectionHandler.__SENTRY_LOADER__) {\n // eslint-disable-next-line prefer-rest-params\n return _oldOnUnhandledRejectionHandler.apply(this, arguments);\n }\n\n return true;\n };\n\n GLOBAL_OBJ.onunhandledrejection.__SENTRY_INSTRUMENTED__ = true;\n}\n\nexport { addGlobalUnhandledRejectionInstrumentationHandler };\n//# sourceMappingURL=globalUnhandledRejection.js.map\n","/*\n * This module exists for optimizations in the build process through rollup and terser. We define some global\n * constants, which can be overridden during build. By guarding certain pieces of code with functions that return these\n * constants, we can control whether or not they appear in the final bundle. (Any code guarded by a false condition will\n * never run, and will hence be dropped during treeshaking.) The two primary uses for this are stripping out calls to\n * `logger` and preventing node-related code from appearing in browser bundles.\n *\n * Attention:\n * This file should not be used to define constants/flags that are intended to be used for tree-shaking conducted by\n * users. These flags should live in their respective packages, as we identified user tooling (specifically webpack)\n * having issues tree-shaking these constants across package boundaries.\n * An example for this is the __SENTRY_DEBUG__ constant. It is declared in each package individually because we want\n * users to be able to shake away expressions that it guards.\n */\n\n/**\n * Figures out if we're building a browser bundle.\n *\n * @returns true if this is a browser bundle build.\n */\nfunction isBrowserBundle() {\n return typeof __SENTRY_BROWSER_BUNDLE__ !== 'undefined' && !!__SENTRY_BROWSER_BUNDLE__;\n}\n\n/**\n * Get source of SDK.\n */\nfunction getSDKSource() {\n // This comment is used to identify this line in the CDN bundle build step and replace this with \"return 'cdn';\"\n /* __SENTRY_SDK_SOURCE__ */ return 'npm';\n}\n\nexport { getSDKSource, isBrowserBundle };\n//# sourceMappingURL=env.js.map\n","/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Helper to decycle json objects\n */\nfunction memoBuilder() {\n const hasWeakSet = typeof WeakSet === 'function';\n const inner = hasWeakSet ? new WeakSet() : [];\n function memoize(obj) {\n if (hasWeakSet) {\n if (inner.has(obj)) {\n return true;\n }\n inner.add(obj);\n return false;\n }\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let i = 0; i < inner.length; i++) {\n const value = inner[i];\n if (value === obj) {\n return true;\n }\n }\n inner.push(obj);\n return false;\n }\n\n function unmemoize(obj) {\n if (hasWeakSet) {\n inner.delete(obj);\n } else {\n for (let i = 0; i < inner.length; i++) {\n if (inner[i] === obj) {\n inner.splice(i, 1);\n break;\n }\n }\n }\n }\n return [memoize, unmemoize];\n}\n\nexport { memoBuilder };\n//# sourceMappingURL=memo.js.map\n","import { addNonEnumerableProperty } from './object.js';\nimport { snipLine } from './string.js';\nimport { GLOBAL_OBJ } from './worldwide.js';\n\n/**\n * UUID4 generator\n *\n * @returns string Generated UUID4.\n */\nfunction uuid4() {\n const gbl = GLOBAL_OBJ ;\n const crypto = gbl.crypto || gbl.msCrypto;\n\n let getRandomByte = () => Math.random() * 16;\n try {\n if (crypto && crypto.randomUUID) {\n return crypto.randomUUID().replace(/-/g, '');\n }\n if (crypto && crypto.getRandomValues) {\n getRandomByte = () => {\n // crypto.getRandomValues might return undefined instead of the typed array\n // in old Chromium versions (e.g. 23.0.1235.0 (151422))\n // However, `typedArray` is still filled in-place.\n // @see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#typedarray\n const typedArray = new Uint8Array(1);\n crypto.getRandomValues(typedArray);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return typedArray[0];\n };\n }\n } catch (_) {\n // some runtimes can crash invoking crypto\n // https://github.com/getsentry/sentry-javascript/issues/8935\n }\n\n // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523\n // Concatenating the following numbers as strings results in '10000000100040008000100000000000'\n return (([1e7] ) + 1e3 + 4e3 + 8e3 + 1e11).replace(/[018]/g, c =>\n // eslint-disable-next-line no-bitwise\n ((c ) ^ ((getRandomByte() & 15) >> ((c ) / 4))).toString(16),\n );\n}\n\nfunction getFirstException(event) {\n return event.exception && event.exception.values ? event.exception.values[0] : undefined;\n}\n\n/**\n * Extracts either message or type+value from an event that can be used for user-facing logs\n * @returns event's description\n */\nfunction getEventDescription(event) {\n const { message, event_id: eventId } = event;\n if (message) {\n return message;\n }\n\n const firstException = getFirstException(event);\n if (firstException) {\n if (firstException.type && firstException.value) {\n return `${firstException.type}: ${firstException.value}`;\n }\n return firstException.type || firstException.value || eventId || '';\n }\n return eventId || '';\n}\n\n/**\n * Adds exception values, type and value to an synthetic Exception.\n * @param event The event to modify.\n * @param value Value of the exception.\n * @param type Type of the exception.\n * @hidden\n */\nfunction addExceptionTypeValue(event, value, type) {\n const exception = (event.exception = event.exception || {});\n const values = (exception.values = exception.values || []);\n const firstException = (values[0] = values[0] || {});\n if (!firstException.value) {\n firstException.value = value || '';\n }\n if (!firstException.type) {\n firstException.type = type || 'Error';\n }\n}\n\n/**\n * Adds exception mechanism data to a given event. Uses defaults if the second parameter is not passed.\n *\n * @param event The event to modify.\n * @param newMechanism Mechanism data to add to the event.\n * @hidden\n */\nfunction addExceptionMechanism(event, newMechanism) {\n const firstException = getFirstException(event);\n if (!firstException) {\n return;\n }\n\n const defaultMechanism = { type: 'generic', handled: true };\n const currentMechanism = firstException.mechanism;\n firstException.mechanism = { ...defaultMechanism, ...currentMechanism, ...newMechanism };\n\n if (newMechanism && 'data' in newMechanism) {\n const mergedData = { ...(currentMechanism && currentMechanism.data), ...newMechanism.data };\n firstException.mechanism.data = mergedData;\n }\n}\n\n// https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string\nconst SEMVER_REGEXP =\n /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/;\n\n/**\n * Represents Semantic Versioning object\n */\n\nfunction _parseInt(input) {\n return parseInt(input || '', 10);\n}\n\n/**\n * Parses input into a SemVer interface\n * @param input string representation of a semver version\n */\nfunction parseSemver(input) {\n const match = input.match(SEMVER_REGEXP) || [];\n const major = _parseInt(match[1]);\n const minor = _parseInt(match[2]);\n const patch = _parseInt(match[3]);\n return {\n buildmetadata: match[5],\n major: isNaN(major) ? undefined : major,\n minor: isNaN(minor) ? undefined : minor,\n patch: isNaN(patch) ? undefined : patch,\n prerelease: match[4],\n };\n}\n\n/**\n * This function adds context (pre/post/line) lines to the provided frame\n *\n * @param lines string[] containing all lines\n * @param frame StackFrame that will be mutated\n * @param linesOfContext number of context lines we want to add pre/post\n */\nfunction addContextToFrame(lines, frame, linesOfContext = 5) {\n // When there is no line number in the frame, attaching context is nonsensical and will even break grouping\n if (frame.lineno === undefined) {\n return;\n }\n\n const maxLines = lines.length;\n const sourceLine = Math.max(Math.min(maxLines - 1, frame.lineno - 1), 0);\n\n frame.pre_context = lines\n .slice(Math.max(0, sourceLine - linesOfContext), sourceLine)\n .map((line) => snipLine(line, 0));\n\n // We guard here to ensure this is not larger than the existing number of lines\n const lineIndex = Math.min(maxLines - 1, sourceLine);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n frame.context_line = snipLine(lines[lineIndex], frame.colno || 0);\n\n frame.post_context = lines\n .slice(Math.min(sourceLine + 1, maxLines), sourceLine + 1 + linesOfContext)\n .map((line) => snipLine(line, 0));\n}\n\n/**\n * Checks whether or not we've already captured the given exception (note: not an identical exception - the very object\n * in question), and marks it captured if not.\n *\n * This is useful because it's possible for an error to get captured by more than one mechanism. After we intercept and\n * record an error, we rethrow it (assuming we've intercepted it before it's reached the top-level global handlers), so\n * that we don't interfere with whatever effects the error might have had were the SDK not there. At that point, because\n * the error has been rethrown, it's possible for it to bubble up to some other code we've instrumented. If it's not\n * caught after that, it will bubble all the way up to the global handlers (which of course we also instrument). This\n * function helps us ensure that even if we encounter the same error more than once, we only record it the first time we\n * see it.\n *\n * Note: It will ignore primitives (always return `false` and not mark them as seen), as properties can't be set on\n * them. {@link: Object.objectify} can be used on exceptions to convert any that are primitives into their equivalent\n * object wrapper forms so that this check will always work. However, because we need to flag the exact object which\n * will get rethrown, and because that rethrowing happens outside of the event processing pipeline, the objectification\n * must be done before the exception captured.\n *\n * @param A thrown exception to check or flag as having been seen\n * @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen)\n */\nfunction checkOrSetAlreadyCaught(exception) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (exception && (exception ).__sentry_captured__) {\n return true;\n }\n\n try {\n // set it this way rather than by assignment so that it's not ennumerable and therefore isn't recorded by the\n // `ExtraErrorData` integration\n addNonEnumerableProperty(exception , '__sentry_captured__', true);\n } catch (err) {\n // `exception` is a primitive, so we can't mark it seen\n }\n\n return false;\n}\n\n/**\n * Checks whether the given input is already an array, and if it isn't, wraps it in one.\n *\n * @param maybeArray Input to turn into an array, if necessary\n * @returns The input, if already an array, or an array with the input as the only element, if not\n */\nfunction arrayify(maybeArray) {\n return Array.isArray(maybeArray) ? maybeArray : [maybeArray];\n}\n\nexport { addContextToFrame, addExceptionMechanism, addExceptionTypeValue, arrayify, checkOrSetAlreadyCaught, getEventDescription, parseSemver, uuid4 };\n//# sourceMappingURL=misc.js.map\n","import { isVueViewModel, isSyntheticEvent } from './is.js';\nimport { memoBuilder } from './memo.js';\nimport { convertToPlainObject } from './object.js';\nimport { getFunctionName } from './stacktrace.js';\n\n/**\n * Recursively normalizes the given object.\n *\n * - Creates a copy to prevent original input mutation\n * - Skips non-enumerable properties\n * - When stringifying, calls `toJSON` if implemented\n * - Removes circular references\n * - Translates non-serializable values (`undefined`/`NaN`/functions) to serializable format\n * - Translates known global objects/classes to a string representations\n * - Takes care of `Error` object serialization\n * - Optionally limits depth of final output\n * - Optionally limits number of properties/elements included in any single object/array\n *\n * @param input The object to be normalized.\n * @param depth The max depth to which to normalize the object. (Anything deeper stringified whole.)\n * @param maxProperties The max number of elements or properties to be included in any single array or\n * object in the normalized output.\n * @returns A normalized version of the object, or `\"**non-serializable**\"` if any errors are thrown during normalization.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction normalize(input, depth = 100, maxProperties = +Infinity) {\n try {\n // since we're at the outermost level, we don't provide a key\n return visit('', input, depth, maxProperties);\n } catch (err) {\n return { ERROR: `**non-serializable** (${err})` };\n }\n}\n\n/** JSDoc */\nfunction normalizeToSize(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n object,\n // Default Node.js REPL depth\n depth = 3,\n // 100kB, as 200kB is max payload size, so half sounds reasonable\n maxSize = 100 * 1024,\n) {\n const normalized = normalize(object, depth);\n\n if (jsonSize(normalized) > maxSize) {\n return normalizeToSize(object, depth - 1, maxSize);\n }\n\n return normalized ;\n}\n\n/**\n * Visits a node to perform normalization on it\n *\n * @param key The key corresponding to the given node\n * @param value The node to be visited\n * @param depth Optional number indicating the maximum recursion depth\n * @param maxProperties Optional maximum number of properties/elements included in any single object/array\n * @param memo Optional Memo class handling decycling\n */\nfunction visit(\n key,\n value,\n depth = +Infinity,\n maxProperties = +Infinity,\n memo = memoBuilder(),\n) {\n const [memoize, unmemoize] = memo;\n\n // Get the simple cases out of the way first\n if (\n value == null || // this matches null and undefined -> eqeq not eqeqeq\n ['boolean', 'string'].includes(typeof value) ||\n (typeof value === 'number' && Number.isFinite(value))\n ) {\n return value ;\n }\n\n const stringified = stringifyValue(key, value);\n\n // Anything we could potentially dig into more (objects or arrays) will have come back as `\"[object XXXX]\"`.\n // Everything else will have already been serialized, so if we don't see that pattern, we're done.\n if (!stringified.startsWith('[object ')) {\n return stringified;\n }\n\n // From here on, we can assert that `value` is either an object or an array.\n\n // Do not normalize objects that we know have already been normalized. As a general rule, the\n // \"__sentry_skip_normalization__\" property should only be used sparingly and only should only be set on objects that\n // have already been normalized.\n if ((value )['__sentry_skip_normalization__']) {\n return value ;\n }\n\n // We can set `__sentry_override_normalization_depth__` on an object to ensure that from there\n // We keep a certain amount of depth.\n // This should be used sparingly, e.g. we use it for the redux integration to ensure we get a certain amount of state.\n const remainingDepth =\n typeof (value )['__sentry_override_normalization_depth__'] === 'number'\n ? ((value )['__sentry_override_normalization_depth__'] )\n : depth;\n\n // We're also done if we've reached the max depth\n if (remainingDepth === 0) {\n // At this point we know `serialized` is a string of the form `\"[object XXXX]\"`. Clean it up so it's just `\"[XXXX]\"`.\n return stringified.replace('object ', '');\n }\n\n // If we've already visited this branch, bail out, as it's circular reference. If not, note that we're seeing it now.\n if (memoize(value)) {\n return '[Circular ~]';\n }\n\n // If the value has a `toJSON` method, we call it to extract more information\n const valueWithToJSON = value ;\n if (valueWithToJSON && typeof valueWithToJSON.toJSON === 'function') {\n try {\n const jsonValue = valueWithToJSON.toJSON();\n // We need to normalize the return value of `.toJSON()` in case it has circular references\n return visit('', jsonValue, remainingDepth - 1, maxProperties, memo);\n } catch (err) {\n // pass (The built-in `toJSON` failed, but we can still try to do it ourselves)\n }\n }\n\n // At this point we know we either have an object or an array, we haven't seen it before, and we're going to recurse\n // because we haven't yet reached the max depth. Create an accumulator to hold the results of visiting each\n // property/entry, and keep track of the number of items we add to it.\n const normalized = (Array.isArray(value) ? [] : {}) ;\n let numAdded = 0;\n\n // Before we begin, convert`Error` and`Event` instances into plain objects, since some of each of their relevant\n // properties are non-enumerable and otherwise would get missed.\n const visitable = convertToPlainObject(value );\n\n for (const visitKey in visitable) {\n // Avoid iterating over fields in the prototype if they've somehow been exposed to enumeration.\n if (!Object.prototype.hasOwnProperty.call(visitable, visitKey)) {\n continue;\n }\n\n if (numAdded >= maxProperties) {\n normalized[visitKey] = '[MaxProperties ~]';\n break;\n }\n\n // Recursively visit all the child nodes\n const visitValue = visitable[visitKey];\n normalized[visitKey] = visit(visitKey, visitValue, remainingDepth - 1, maxProperties, memo);\n\n numAdded++;\n }\n\n // Once we've visited all the branches, remove the parent from memo storage\n unmemoize(value);\n\n // Return accumulated values\n return normalized;\n}\n\n/* eslint-disable complexity */\n/**\n * Stringify the given value. Handles various known special values and types.\n *\n * Not meant to be used on simple primitives which already have a string representation, as it will, for example, turn\n * the number 1231 into \"[Object Number]\", nor on `null`, as it will throw.\n *\n * @param value The value to stringify\n * @returns A stringified representation of the given value\n */\nfunction stringifyValue(\n key,\n // this type is a tiny bit of a cheat, since this function does handle NaN (which is technically a number), but for\n // our internal use, it'll do\n value,\n) {\n try {\n if (key === 'domain' && value && typeof value === 'object' && (value )._events) {\n return '[Domain]';\n }\n\n if (key === 'domainEmitter') {\n return '[DomainEmitter]';\n }\n\n // It's safe to use `global`, `window`, and `document` here in this manner, as we are asserting using `typeof` first\n // which won't throw if they are not present.\n\n if (typeof global !== 'undefined' && value === global) {\n return '[Global]';\n }\n\n // eslint-disable-next-line no-restricted-globals\n if (typeof window !== 'undefined' && value === window) {\n return '[Window]';\n }\n\n // eslint-disable-next-line no-restricted-globals\n if (typeof document !== 'undefined' && value === document) {\n return '[Document]';\n }\n\n if (isVueViewModel(value)) {\n return '[VueViewModel]';\n }\n\n // React's SyntheticEvent thingy\n if (isSyntheticEvent(value)) {\n return '[SyntheticEvent]';\n }\n\n if (typeof value === 'number' && !Number.isFinite(value)) {\n return `[${value}]`;\n }\n\n if (typeof value === 'function') {\n return `[Function: ${getFunctionName(value)}]`;\n }\n\n if (typeof value === 'symbol') {\n return `[${String(value)}]`;\n }\n\n // stringified BigInts are indistinguishable from regular numbers, so we need to label them to avoid confusion\n if (typeof value === 'bigint') {\n return `[BigInt: ${String(value)}]`;\n }\n\n // Now that we've knocked out all the special cases and the primitives, all we have left are objects. Simply casting\n // them to strings means that instances of classes which haven't defined their `toStringTag` will just come out as\n // `\"[object Object]\"`. If we instead look at the constructor's name (which is the same as the name of the class),\n // we can make sure that only plain objects come out that way.\n const objName = getConstructorName(value);\n\n // Handle HTML Elements\n if (/^HTML(\\w*)Element$/.test(objName)) {\n return `[HTMLElement: ${objName}]`;\n }\n\n return `[object ${objName}]`;\n } catch (err) {\n return `**non-serializable** (${err})`;\n }\n}\n/* eslint-enable complexity */\n\nfunction getConstructorName(value) {\n const prototype = Object.getPrototypeOf(value);\n\n return prototype ? prototype.constructor.name : 'null prototype';\n}\n\n/** Calculates bytes size of input string */\nfunction utf8Length(value) {\n // eslint-disable-next-line no-bitwise\n return ~-encodeURI(value).split(/%..|./).length;\n}\n\n/** Calculates bytes size of input object */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction jsonSize(value) {\n return utf8Length(JSON.stringify(value));\n}\n\n/**\n * Normalizes URLs in exceptions and stacktraces to a base path so Sentry can fingerprint\n * across platforms and working directory.\n *\n * @param url The URL to be normalized.\n * @param basePath The application base path.\n * @returns The normalized URL.\n */\nfunction normalizeUrlToBase(url, basePath) {\n const escapedBase = basePath\n // Backslash to forward\n .replace(/\\\\/g, '/')\n // Escape RegExp special characters\n .replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&');\n\n let newUrl = url;\n try {\n newUrl = decodeURI(url);\n } catch (_Oo) {\n // Sometime this breaks\n }\n return (\n newUrl\n .replace(/\\\\/g, '/')\n .replace(/webpack:\\/?/g, '') // Remove intermediate base path\n // eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor\n .replace(new RegExp(`(file://)?/*${escapedBase}/*`, 'ig'), 'app:///')\n );\n}\n\nexport { normalize, normalizeToSize, normalizeUrlToBase };\n//# sourceMappingURL=normalize.js.map\n","import { isThenable } from './is.js';\n\n/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/** SyncPromise internal states */\nvar States; (function (States) {\n /** Pending */\n const PENDING = 0; States[States[\"PENDING\"] = PENDING] = \"PENDING\";\n /** Resolved / OK */\n const RESOLVED = 1; States[States[\"RESOLVED\"] = RESOLVED] = \"RESOLVED\";\n /** Rejected / Error */\n const REJECTED = 2; States[States[\"REJECTED\"] = REJECTED] = \"REJECTED\";\n})(States || (States = {}));\n\n// Overloads so we can call resolvedSyncPromise without arguments and generic argument\n\n/**\n * Creates a resolved sync promise.\n *\n * @param value the value to resolve the promise with\n * @returns the resolved sync promise\n */\nfunction resolvedSyncPromise(value) {\n return new SyncPromise(resolve => {\n resolve(value);\n });\n}\n\n/**\n * Creates a rejected sync promise.\n *\n * @param value the value to reject the promise with\n * @returns the rejected sync promise\n */\nfunction rejectedSyncPromise(reason) {\n return new SyncPromise((_, reject) => {\n reject(reason);\n });\n}\n\n/**\n * Thenable class that behaves like a Promise and follows it's interface\n * but is not async internally\n */\nclass SyncPromise {\n\n constructor(\n executor,\n ) {SyncPromise.prototype.__init.call(this);SyncPromise.prototype.__init2.call(this);SyncPromise.prototype.__init3.call(this);SyncPromise.prototype.__init4.call(this);\n this._state = States.PENDING;\n this._handlers = [];\n\n try {\n executor(this._resolve, this._reject);\n } catch (e) {\n this._reject(e);\n }\n }\n\n /** JSDoc */\n then(\n onfulfilled,\n onrejected,\n ) {\n return new SyncPromise((resolve, reject) => {\n this._handlers.push([\n false,\n result => {\n if (!onfulfilled) {\n // TODO: ¯\\_(ツ)_/¯\n // TODO: FIXME\n resolve(result );\n } else {\n try {\n resolve(onfulfilled(result));\n } catch (e) {\n reject(e);\n }\n }\n },\n reason => {\n if (!onrejected) {\n reject(reason);\n } else {\n try {\n resolve(onrejected(reason));\n } catch (e) {\n reject(e);\n }\n }\n },\n ]);\n this._executeHandlers();\n });\n }\n\n /** JSDoc */\n catch(\n onrejected,\n ) {\n return this.then(val => val, onrejected);\n }\n\n /** JSDoc */\n finally(onfinally) {\n return new SyncPromise((resolve, reject) => {\n let val;\n let isRejected;\n\n return this.then(\n value => {\n isRejected = false;\n val = value;\n if (onfinally) {\n onfinally();\n }\n },\n reason => {\n isRejected = true;\n val = reason;\n if (onfinally) {\n onfinally();\n }\n },\n ).then(() => {\n if (isRejected) {\n reject(val);\n return;\n }\n\n resolve(val );\n });\n });\n }\n\n /** JSDoc */\n __init() {this._resolve = (value) => {\n this._setResult(States.RESOLVED, value);\n };}\n\n /** JSDoc */\n __init2() {this._reject = (reason) => {\n this._setResult(States.REJECTED, reason);\n };}\n\n /** JSDoc */\n __init3() {this._setResult = (state, value) => {\n if (this._state !== States.PENDING) {\n return;\n }\n\n if (isThenable(value)) {\n void (value ).then(this._resolve, this._reject);\n return;\n }\n\n this._state = state;\n this._value = value;\n\n this._executeHandlers();\n };}\n\n /** JSDoc */\n __init4() {this._executeHandlers = () => {\n if (this._state === States.PENDING) {\n return;\n }\n\n const cachedHandlers = this._handlers.slice();\n this._handlers = [];\n\n cachedHandlers.forEach(handler => {\n if (handler[0]) {\n return;\n }\n\n if (this._state === States.RESOLVED) {\n handler[1](this._value );\n }\n\n if (this._state === States.REJECTED) {\n handler[2](this._value);\n }\n\n handler[0] = true;\n });\n };}\n}\n\nexport { SyncPromise, rejectedSyncPromise, resolvedSyncPromise };\n//# sourceMappingURL=syncpromise.js.map\n","import { SentryError } from './error.js';\nimport { rejectedSyncPromise, SyncPromise, resolvedSyncPromise } from './syncpromise.js';\n\n/**\n * Creates an new PromiseBuffer object with the specified limit\n * @param limit max number of promises that can be stored in the buffer\n */\nfunction makePromiseBuffer(limit) {\n const buffer = [];\n\n function isReady() {\n return limit === undefined || buffer.length < limit;\n }\n\n /**\n * Remove a promise from the queue.\n *\n * @param task Can be any PromiseLike\n * @returns Removed promise.\n */\n function remove(task) {\n return buffer.splice(buffer.indexOf(task), 1)[0] || Promise.resolve(undefined);\n }\n\n /**\n * Add a promise (representing an in-flight action) to the queue, and set it to remove itself on fulfillment.\n *\n * @param taskProducer A function producing any PromiseLike; In previous versions this used to be `task:\n * PromiseLike`, but under that model, Promises were instantly created on the call-site and their executor\n * functions therefore ran immediately. Thus, even if the buffer was full, the action still happened. By\n * requiring the promise to be wrapped in a function, we can defer promise creation until after the buffer\n * limit check.\n * @returns The original promise.\n */\n function add(taskProducer) {\n if (!isReady()) {\n return rejectedSyncPromise(new SentryError('Not adding Promise because buffer limit was reached.'));\n }\n\n // start the task and add its promise to the queue\n const task = taskProducer();\n if (buffer.indexOf(task) === -1) {\n buffer.push(task);\n }\n void task\n .then(() => remove(task))\n // Use `then(null, rejectionHandler)` rather than `catch(rejectionHandler)` so that we can use `PromiseLike`\n // rather than `Promise`. `PromiseLike` doesn't have a `.catch` method, making its polyfill smaller. (ES5 didn't\n // have promises, so TS has to polyfill when down-compiling.)\n .then(null, () =>\n remove(task).then(null, () => {\n // We have to add another catch here because `remove()` starts a new promise chain.\n }),\n );\n return task;\n }\n\n /**\n * Wait for all promises in the queue to resolve or for timeout to expire, whichever comes first.\n *\n * @param timeout The time, in ms, after which to resolve to `false` if the queue is still non-empty. Passing `0` (or\n * not passing anything) will make the promise wait as long as it takes for the queue to drain before resolving to\n * `true`.\n * @returns A promise which will resolve to `true` if the queue is already empty or drains before the timeout, and\n * `false` otherwise\n */\n function drain(timeout) {\n return new SyncPromise((resolve, reject) => {\n let counter = buffer.length;\n\n if (!counter) {\n return resolve(true);\n }\n\n // wait for `timeout` ms and then resolve to `false` (if not cancelled first)\n const capturedSetTimeout = setTimeout(() => {\n if (timeout && timeout > 0) {\n resolve(false);\n }\n }, timeout);\n\n // if all promises resolve in time, cancel the timer and resolve to `true`\n buffer.forEach(item => {\n void resolvedSyncPromise(item).then(() => {\n if (!--counter) {\n clearTimeout(capturedSetTimeout);\n resolve(true);\n }\n }, reject);\n });\n });\n }\n\n return {\n $: buffer,\n add,\n drain,\n };\n}\n\nexport { makePromiseBuffer };\n//# sourceMappingURL=promisebuffer.js.map\n","/**\n * Parses string form of URL into an object\n * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B\n * // intentionally using regex and not href parsing trick because React Native and other\n * // environments where DOM might not be available\n * @returns parsed URL object\n */\nfunction parseUrl(url) {\n if (!url) {\n return {};\n }\n\n const match = url.match(/^(([^:/?#]+):)?(\\/\\/([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$/);\n\n if (!match) {\n return {};\n }\n\n // coerce to undefined values to empty string so we don't get 'undefined'\n const query = match[6] || '';\n const fragment = match[8] || '';\n return {\n host: match[4],\n path: match[5],\n protocol: match[2],\n search: query,\n hash: fragment,\n relative: match[5] + query + fragment, // everything minus origin\n };\n}\n\n/**\n * Strip the query string and fragment off of a given URL or path (if present)\n *\n * @param urlPath Full URL or path, including possible query string and/or fragment\n * @returns URL or path without query string or fragment\n */\nfunction stripUrlQueryAndFragment(urlPath) {\n return (urlPath.split(/[?#]/, 1) )[0];\n}\n\n/**\n * Returns number of URL segments of a passed string URL.\n */\nfunction getNumberOfUrlSegments(url) {\n // split at '/' or at '\\/' to split regex urls correctly\n return url.split(/\\\\?\\//).filter(s => s.length > 0 && s !== ',').length;\n}\n\n/**\n * Takes a URL object and returns a sanitized string which is safe to use as span name\n * see: https://develop.sentry.dev/sdk/data-handling/#structuring-data\n */\nfunction getSanitizedUrlString(url) {\n const { protocol, host, path } = url;\n\n const filteredHost =\n (host &&\n host\n // Always filter out authority\n .replace(/^.*@/, '[filtered]:[filtered]@')\n // Don't show standard :80 (http) and :443 (https) ports to reduce the noise\n // TODO: Use new URL global if it exists\n .replace(/(:80)$/, '')\n .replace(/(:443)$/, '')) ||\n '';\n\n return `${protocol ? `${protocol}://` : ''}${filteredHost}${path}`;\n}\n\nexport { getNumberOfUrlSegments, getSanitizedUrlString, parseUrl, stripUrlQueryAndFragment };\n//# sourceMappingURL=url.js.map\n","// Note: Ideally the `SeverityLevel` type would be derived from `validSeverityLevels`, but that would mean either\n//\n// a) moving `validSeverityLevels` to `@sentry/types`,\n// b) moving the`SeverityLevel` type here, or\n// c) importing `validSeverityLevels` from here into `@sentry/types`.\n//\n// Option A would make `@sentry/types` a runtime dependency of `@sentry/utils` (not good), and options B and C would\n// create a circular dependency between `@sentry/types` and `@sentry/utils` (also not good). So a TODO accompanying the\n// type, reminding anyone who changes it to change this list also, will have to do.\n\nconst validSeverityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug'];\n\n/**\n * Converts a string-based level into a `SeverityLevel`, normalizing it along the way.\n *\n * @param level String representation of desired `SeverityLevel`.\n * @returns The `SeverityLevel` corresponding to the given string, or 'log' if the string isn't a valid level.\n */\nfunction severityLevelFromString(level) {\n return (level === 'warn' ? 'warning' : validSeverityLevels.includes(level) ? level : 'log') ;\n}\n\nexport { severityLevelFromString, validSeverityLevels };\n//# sourceMappingURL=severity.js.map\n","import { DEBUG_BUILD } from './debug-build.js';\nimport { isString } from './is.js';\nimport { logger } from './logger.js';\n\nconst BAGGAGE_HEADER_NAME = 'baggage';\n\nconst SENTRY_BAGGAGE_KEY_PREFIX = 'sentry-';\n\nconst SENTRY_BAGGAGE_KEY_PREFIX_REGEX = /^sentry-/;\n\n/**\n * Max length of a serialized baggage string\n *\n * https://www.w3.org/TR/baggage/#limits\n */\nconst MAX_BAGGAGE_STRING_LENGTH = 8192;\n\n/**\n * Takes a baggage header and turns it into Dynamic Sampling Context, by extracting all the \"sentry-\" prefixed values\n * from it.\n *\n * @param baggageHeader A very bread definition of a baggage header as it might appear in various frameworks.\n * @returns The Dynamic Sampling Context that was found on `baggageHeader`, if there was any, `undefined` otherwise.\n */\nfunction baggageHeaderToDynamicSamplingContext(\n // Very liberal definition of what any incoming header might look like\n baggageHeader,\n) {\n const baggageObject = parseBaggageHeader(baggageHeader);\n\n if (!baggageObject) {\n return undefined;\n }\n\n // Read all \"sentry-\" prefixed values out of the baggage object and put it onto a dynamic sampling context object.\n const dynamicSamplingContext = Object.entries(baggageObject).reduce((acc, [key, value]) => {\n if (key.match(SENTRY_BAGGAGE_KEY_PREFIX_REGEX)) {\n const nonPrefixedKey = key.slice(SENTRY_BAGGAGE_KEY_PREFIX.length);\n acc[nonPrefixedKey] = value;\n }\n return acc;\n }, {});\n\n // Only return a dynamic sampling context object if there are keys in it.\n // A keyless object means there were no sentry values on the header, which means that there is no DSC.\n if (Object.keys(dynamicSamplingContext).length > 0) {\n return dynamicSamplingContext ;\n } else {\n return undefined;\n }\n}\n\n/**\n * Turns a Dynamic Sampling Object into a baggage header by prefixing all the keys on the object with \"sentry-\".\n *\n * @param dynamicSamplingContext The Dynamic Sampling Context to turn into a header. For convenience and compatibility\n * with the `getDynamicSamplingContext` method on the Transaction class ,this argument can also be `undefined`. If it is\n * `undefined` the function will return `undefined`.\n * @returns a baggage header, created from `dynamicSamplingContext`, or `undefined` either if `dynamicSamplingContext`\n * was `undefined`, or if `dynamicSamplingContext` didn't contain any values.\n */\nfunction dynamicSamplingContextToSentryBaggageHeader(\n // this also takes undefined for convenience and bundle size in other places\n dynamicSamplingContext,\n) {\n if (!dynamicSamplingContext) {\n return undefined;\n }\n\n // Prefix all DSC keys with \"sentry-\" and put them into a new object\n const sentryPrefixedDSC = Object.entries(dynamicSamplingContext).reduce(\n (acc, [dscKey, dscValue]) => {\n if (dscValue) {\n acc[`${SENTRY_BAGGAGE_KEY_PREFIX}${dscKey}`] = dscValue;\n }\n return acc;\n },\n {},\n );\n\n return objectToBaggageHeader(sentryPrefixedDSC);\n}\n\n/**\n * Take a baggage header and parse it into an object.\n */\nfunction parseBaggageHeader(\n baggageHeader,\n) {\n if (!baggageHeader || (!isString(baggageHeader) && !Array.isArray(baggageHeader))) {\n return undefined;\n }\n\n if (Array.isArray(baggageHeader)) {\n // Combine all baggage headers into one object containing the baggage values so we can later read the Sentry-DSC-values from it\n return baggageHeader.reduce((acc, curr) => {\n const currBaggageObject = baggageHeaderToObject(curr);\n Object.entries(currBaggageObject).forEach(([key, value]) => {\n acc[key] = value;\n });\n return acc;\n }, {});\n }\n\n return baggageHeaderToObject(baggageHeader);\n}\n\n/**\n * Will parse a baggage header, which is a simple key-value map, into a flat object.\n *\n * @param baggageHeader The baggage header to parse.\n * @returns a flat object containing all the key-value pairs from `baggageHeader`.\n */\nfunction baggageHeaderToObject(baggageHeader) {\n return baggageHeader\n .split(',')\n .map(baggageEntry => baggageEntry.split('=').map(keyOrValue => decodeURIComponent(keyOrValue.trim())))\n .reduce((acc, [key, value]) => {\n if (key && value) {\n acc[key] = value;\n }\n return acc;\n }, {});\n}\n\n/**\n * Turns a flat object (key-value pairs) into a baggage header, which is also just key-value pairs.\n *\n * @param object The object to turn into a baggage header.\n * @returns a baggage header string, or `undefined` if the object didn't have any values, since an empty baggage header\n * is not spec compliant.\n */\nfunction objectToBaggageHeader(object) {\n if (Object.keys(object).length === 0) {\n // An empty baggage header is not spec compliant: We return undefined.\n return undefined;\n }\n\n return Object.entries(object).reduce((baggageHeader, [objectKey, objectValue], currentIndex) => {\n const baggageEntry = `${encodeURIComponent(objectKey)}=${encodeURIComponent(objectValue)}`;\n const newBaggageHeader = currentIndex === 0 ? baggageEntry : `${baggageHeader},${baggageEntry}`;\n if (newBaggageHeader.length > MAX_BAGGAGE_STRING_LENGTH) {\n DEBUG_BUILD &&\n logger.warn(\n `Not adding key: ${objectKey} with val: ${objectValue} to baggage header due to exceeding baggage size limits.`,\n );\n return baggageHeader;\n } else {\n return newBaggageHeader;\n }\n }, '');\n}\n\nexport { BAGGAGE_HEADER_NAME, MAX_BAGGAGE_STRING_LENGTH, SENTRY_BAGGAGE_KEY_PREFIX, SENTRY_BAGGAGE_KEY_PREFIX_REGEX, baggageHeaderToDynamicSamplingContext, dynamicSamplingContextToSentryBaggageHeader, parseBaggageHeader };\n//# sourceMappingURL=baggage.js.map\n","import { baggageHeaderToDynamicSamplingContext } from './baggage.js';\nimport { uuid4 } from './misc.js';\n\n// eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- RegExp is used for readability here\nconst TRACEPARENT_REGEXP = new RegExp(\n '^[ \\\\t]*' + // whitespace\n '([0-9a-f]{32})?' + // trace_id\n '-?([0-9a-f]{16})?' + // span_id\n '-?([01])?' + // sampled\n '[ \\\\t]*$', // whitespace\n);\n\n/**\n * Extract transaction context data from a `sentry-trace` header.\n *\n * @param traceparent Traceparent string\n *\n * @returns Object containing data from the header, or undefined if traceparent string is malformed\n */\nfunction extractTraceparentData(traceparent) {\n if (!traceparent) {\n return undefined;\n }\n\n const matches = traceparent.match(TRACEPARENT_REGEXP);\n if (!matches) {\n return undefined;\n }\n\n let parentSampled;\n if (matches[3] === '1') {\n parentSampled = true;\n } else if (matches[3] === '0') {\n parentSampled = false;\n }\n\n return {\n traceId: matches[1],\n parentSampled,\n parentSpanId: matches[2],\n };\n}\n\n/**\n * Create a propagation context from incoming headers or\n * creates a minimal new one if the headers are undefined.\n */\nfunction propagationContextFromHeaders(\n sentryTrace,\n baggage,\n) {\n const traceparentData = extractTraceparentData(sentryTrace);\n const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(baggage);\n\n const { traceId, parentSpanId, parentSampled } = traceparentData || {};\n\n if (!traceparentData) {\n return {\n traceId: traceId || uuid4(),\n spanId: uuid4().substring(16),\n };\n } else {\n return {\n traceId: traceId || uuid4(),\n parentSpanId: parentSpanId || uuid4().substring(16),\n spanId: uuid4().substring(16),\n sampled: parentSampled,\n dsc: dynamicSamplingContext || {}, // If we have traceparent data but no DSC it means we are not head of trace and we must freeze it\n };\n }\n}\n\n/**\n * Create sentry-trace header from span context values.\n */\nfunction generateSentryTraceHeader(\n traceId = uuid4(),\n spanId = uuid4().substring(16),\n sampled,\n) {\n let sampledString = '';\n if (sampled !== undefined) {\n sampledString = sampled ? '-1' : '-0';\n }\n return `${traceId}-${spanId}${sampledString}`;\n}\n\nexport { TRACEPARENT_REGEXP, extractTraceparentData, generateSentryTraceHeader, propagationContextFromHeaders };\n//# sourceMappingURL=tracing.js.map\n","import { dsnToString } from './dsn.js';\nimport { normalize } from './normalize.js';\nimport { dropUndefinedKeys } from './object.js';\nimport { GLOBAL_OBJ } from './worldwide.js';\n\n/**\n * Creates an envelope.\n * Make sure to always explicitly provide the generic to this function\n * so that the envelope types resolve correctly.\n */\nfunction createEnvelope(headers, items = []) {\n return [headers, items] ;\n}\n\n/**\n * Add an item to an envelope.\n * Make sure to always explicitly provide the generic to this function\n * so that the envelope types resolve correctly.\n */\nfunction addItemToEnvelope(envelope, newItem) {\n const [headers, items] = envelope;\n return [headers, [...items, newItem]] ;\n}\n\n/**\n * Convenience function to loop through the items and item types of an envelope.\n * (This function was mostly created because working with envelope types is painful at the moment)\n *\n * If the callback returns true, the rest of the items will be skipped.\n */\nfunction forEachEnvelopeItem(\n envelope,\n callback,\n) {\n const envelopeItems = envelope[1];\n\n for (const envelopeItem of envelopeItems) {\n const envelopeItemType = envelopeItem[0].type;\n const result = callback(envelopeItem, envelopeItemType);\n\n if (result) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Returns true if the envelope contains any of the given envelope item types\n */\nfunction envelopeContainsItemType(envelope, types) {\n return forEachEnvelopeItem(envelope, (_, type) => types.includes(type));\n}\n\n/**\n * Encode a string to UTF8 array.\n */\nfunction encodeUTF8(input) {\n return GLOBAL_OBJ.__SENTRY__ && GLOBAL_OBJ.__SENTRY__.encodePolyfill\n ? GLOBAL_OBJ.__SENTRY__.encodePolyfill(input)\n : new TextEncoder().encode(input);\n}\n\n/**\n * Decode a UTF8 array to string.\n */\nfunction decodeUTF8(input) {\n return GLOBAL_OBJ.__SENTRY__ && GLOBAL_OBJ.__SENTRY__.decodePolyfill\n ? GLOBAL_OBJ.__SENTRY__.decodePolyfill(input)\n : new TextDecoder().decode(input);\n}\n\n/**\n * Serializes an envelope.\n */\nfunction serializeEnvelope(envelope) {\n const [envHeaders, items] = envelope;\n\n // Initially we construct our envelope as a string and only convert to binary chunks if we encounter binary data\n let parts = JSON.stringify(envHeaders);\n\n function append(next) {\n if (typeof parts === 'string') {\n parts = typeof next === 'string' ? parts + next : [encodeUTF8(parts), next];\n } else {\n parts.push(typeof next === 'string' ? encodeUTF8(next) : next);\n }\n }\n\n for (const item of items) {\n const [itemHeaders, payload] = item;\n\n append(`\\n${JSON.stringify(itemHeaders)}\\n`);\n\n if (typeof payload === 'string' || payload instanceof Uint8Array) {\n append(payload);\n } else {\n let stringifiedPayload;\n try {\n stringifiedPayload = JSON.stringify(payload);\n } catch (e) {\n // In case, despite all our efforts to keep `payload` circular-dependency-free, `JSON.stringify()` still\n // fails, we try again after normalizing it again with infinite normalization depth. This of course has a\n // performance impact but in this case a performance hit is better than throwing.\n stringifiedPayload = JSON.stringify(normalize(payload));\n }\n append(stringifiedPayload);\n }\n }\n\n return typeof parts === 'string' ? parts : concatBuffers(parts);\n}\n\nfunction concatBuffers(buffers) {\n const totalLength = buffers.reduce((acc, buf) => acc + buf.length, 0);\n\n const merged = new Uint8Array(totalLength);\n let offset = 0;\n for (const buffer of buffers) {\n merged.set(buffer, offset);\n offset += buffer.length;\n }\n\n return merged;\n}\n\n/**\n * Parses an envelope\n */\nfunction parseEnvelope(env) {\n let buffer = typeof env === 'string' ? encodeUTF8(env) : env;\n\n function readBinary(length) {\n const bin = buffer.subarray(0, length);\n // Replace the buffer with the remaining data excluding trailing newline\n buffer = buffer.subarray(length + 1);\n return bin;\n }\n\n function readJson() {\n let i = buffer.indexOf(0xa);\n // If we couldn't find a newline, we must have found the end of the buffer\n if (i < 0) {\n i = buffer.length;\n }\n\n return JSON.parse(decodeUTF8(readBinary(i))) ;\n }\n\n const envelopeHeader = readJson();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const items = [];\n\n while (buffer.length) {\n const itemHeader = readJson();\n const binaryLength = typeof itemHeader.length === 'number' ? itemHeader.length : undefined;\n\n items.push([itemHeader, binaryLength ? readBinary(binaryLength) : readJson()]);\n }\n\n return [envelopeHeader, items];\n}\n\n/**\n * Creates envelope item for a single span\n */\nfunction createSpanEnvelopeItem(spanJson) {\n const spanHeaders = {\n type: 'span',\n };\n\n return [spanHeaders, spanJson];\n}\n\n/**\n * Creates attachment envelope items\n */\nfunction createAttachmentEnvelopeItem(attachment) {\n const buffer = typeof attachment.data === 'string' ? encodeUTF8(attachment.data) : attachment.data;\n\n return [\n dropUndefinedKeys({\n type: 'attachment',\n length: buffer.length,\n filename: attachment.filename,\n content_type: attachment.contentType,\n attachment_type: attachment.attachmentType,\n }),\n buffer,\n ];\n}\n\nconst ITEM_TYPE_TO_DATA_CATEGORY_MAP = {\n session: 'session',\n sessions: 'session',\n attachment: 'attachment',\n transaction: 'transaction',\n event: 'error',\n client_report: 'internal',\n user_report: 'default',\n profile: 'profile',\n profile_chunk: 'profile',\n replay_event: 'replay',\n replay_recording: 'replay',\n check_in: 'monitor',\n feedback: 'feedback',\n span: 'span',\n statsd: 'metric_bucket',\n};\n\n/**\n * Maps the type of an envelope item to a data category.\n */\nfunction envelopeItemTypeToDataCategory(type) {\n return ITEM_TYPE_TO_DATA_CATEGORY_MAP[type];\n}\n\n/** Extracts the minimal SDK info from the metadata or an events */\nfunction getSdkMetadataForEnvelopeHeader(metadataOrEvent) {\n if (!metadataOrEvent || !metadataOrEvent.sdk) {\n return;\n }\n const { name, version } = metadataOrEvent.sdk;\n return { name, version };\n}\n\n/**\n * Creates event envelope headers, based on event, sdk info and tunnel\n * Note: This function was extracted from the core package to make it available in Replay\n */\nfunction createEventEnvelopeHeaders(\n event,\n sdkInfo,\n tunnel,\n dsn,\n) {\n const dynamicSamplingContext = event.sdkProcessingMetadata && event.sdkProcessingMetadata.dynamicSamplingContext;\n return {\n event_id: event.event_id ,\n sent_at: new Date().toISOString(),\n ...(sdkInfo && { sdk: sdkInfo }),\n ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }),\n ...(dynamicSamplingContext && {\n trace: dropUndefinedKeys({ ...dynamicSamplingContext }),\n }),\n };\n}\n\nexport { addItemToEnvelope, createAttachmentEnvelopeItem, createEnvelope, createEventEnvelopeHeaders, createSpanEnvelopeItem, envelopeContainsItemType, envelopeItemTypeToDataCategory, forEachEnvelopeItem, getSdkMetadataForEnvelopeHeader, parseEnvelope, serializeEnvelope };\n//# sourceMappingURL=envelope.js.map\n","import { createEnvelope } from './envelope.js';\nimport { dateTimestampInSeconds } from './time.js';\n\n/**\n * Creates client report envelope\n * @param discarded_events An array of discard events\n * @param dsn A DSN that can be set on the header. Optional.\n */\nfunction createClientReportEnvelope(\n discarded_events,\n dsn,\n timestamp,\n) {\n const clientReportItem = [\n { type: 'client_report' },\n {\n timestamp: timestamp || dateTimestampInSeconds(),\n discarded_events,\n },\n ];\n return createEnvelope(dsn ? { dsn } : {}, [clientReportItem]);\n}\n\nexport { createClientReportEnvelope };\n//# sourceMappingURL=clientreport.js.map\n","// Intentionally keeping the key broad, as we don't know for sure what rate limit headers get returned from backend\n\nconst DEFAULT_RETRY_AFTER = 60 * 1000; // 60 seconds\n\n/**\n * Extracts Retry-After value from the request header or returns default value\n * @param header string representation of 'Retry-After' header\n * @param now current unix timestamp\n *\n */\nfunction parseRetryAfterHeader(header, now = Date.now()) {\n const headerDelay = parseInt(`${header}`, 10);\n if (!isNaN(headerDelay)) {\n return headerDelay * 1000;\n }\n\n const headerDate = Date.parse(`${header}`);\n if (!isNaN(headerDate)) {\n return headerDate - now;\n }\n\n return DEFAULT_RETRY_AFTER;\n}\n\n/**\n * Gets the time that the given category is disabled until for rate limiting.\n * In case no category-specific limit is set but a general rate limit across all categories is active,\n * that time is returned.\n *\n * @return the time in ms that the category is disabled until or 0 if there's no active rate limit.\n */\nfunction disabledUntil(limits, dataCategory) {\n return limits[dataCategory] || limits.all || 0;\n}\n\n/**\n * Checks if a category is rate limited\n */\nfunction isRateLimited(limits, dataCategory, now = Date.now()) {\n return disabledUntil(limits, dataCategory) > now;\n}\n\n/**\n * Update ratelimits from incoming headers.\n *\n * @return the updated RateLimits object.\n */\nfunction updateRateLimits(\n limits,\n { statusCode, headers },\n now = Date.now(),\n) {\n const updatedRateLimits = {\n ...limits,\n };\n\n // \"The name is case-insensitive.\"\n // https://developer.mozilla.org/en-US/docs/Web/API/Headers/get\n const rateLimitHeader = headers && headers['x-sentry-rate-limits'];\n const retryAfterHeader = headers && headers['retry-after'];\n\n if (rateLimitHeader) {\n /**\n * rate limit headers are of the form\n *
,
,..\n * where each
is of the form\n * : : : : \n * where\n * is a delay in seconds\n * is the event type(s) (error, transaction, etc) being rate limited and is of the form\n * ;;...\n * is what's being limited (org, project, or key) - ignored by SDK\n * is an arbitrary string like \"org_quota\" - ignored by SDK\n * Semicolon-separated list of metric namespace identifiers. Defines which namespace(s) will be affected.\n * Only present if rate limit applies to the metric_bucket data category.\n */\n for (const limit of rateLimitHeader.trim().split(',')) {\n const [retryAfter, categories, , , namespaces] = limit.split(':', 5) ;\n const headerDelay = parseInt(retryAfter, 10);\n const delay = (!isNaN(headerDelay) ? headerDelay : 60) * 1000; // 60sec default\n if (!categories) {\n updatedRateLimits.all = now + delay;\n } else {\n for (const category of categories.split(';')) {\n if (category === 'metric_bucket') {\n // namespaces will be present when category === 'metric_bucket'\n if (!namespaces || namespaces.split(';').includes('custom')) {\n updatedRateLimits[category] = now + delay;\n }\n } else {\n updatedRateLimits[category] = now + delay;\n }\n }\n }\n }\n } else if (retryAfterHeader) {\n updatedRateLimits.all = now + parseRetryAfterHeader(retryAfterHeader, now);\n } else if (statusCode === 429) {\n updatedRateLimits.all = now + 60 * 1000;\n }\n\n return updatedRateLimits;\n}\n\nexport { DEFAULT_RETRY_AFTER, disabledUntil, isRateLimited, parseRetryAfterHeader, updateRateLimits };\n//# sourceMappingURL=ratelimit.js.map\n","import { uuid4 } from './misc.js';\n\n/**\n * Returns a new minimal propagation context\n */\nfunction generatePropagationContext() {\n return {\n traceId: uuid4(),\n spanId: uuid4().substring(16),\n };\n}\n\nexport { generatePropagationContext };\n//# sourceMappingURL=propagationContext.js.map\n","import { GLOBAL_OBJ } from './worldwide.js';\n\nconst debugIdStackParserCache = new WeakMap();\n\n/**\n * Returns a map of filenames to debug identifiers.\n */\nfunction getFilenameToDebugIdMap(stackParser) {\n const debugIdMap = GLOBAL_OBJ._sentryDebugIds;\n if (!debugIdMap) {\n return {};\n }\n\n let debugIdStackFramesCache;\n const cachedDebugIdStackFrameCache = debugIdStackParserCache.get(stackParser);\n if (cachedDebugIdStackFrameCache) {\n debugIdStackFramesCache = cachedDebugIdStackFrameCache;\n } else {\n debugIdStackFramesCache = new Map();\n debugIdStackParserCache.set(stackParser, debugIdStackFramesCache);\n }\n\n // Build a map of filename -> debug_id.\n return Object.keys(debugIdMap).reduce((acc, debugIdStackTrace) => {\n let parsedStack;\n\n const cachedParsedStack = debugIdStackFramesCache.get(debugIdStackTrace);\n if (cachedParsedStack) {\n parsedStack = cachedParsedStack;\n } else {\n parsedStack = stackParser(debugIdStackTrace);\n debugIdStackFramesCache.set(debugIdStackTrace, parsedStack);\n }\n\n for (let i = parsedStack.length - 1; i >= 0; i--) {\n const stackFrame = parsedStack[i];\n const file = stackFrame && stackFrame.filename;\n\n if (stackFrame && file) {\n acc[file] = debugIdMap[debugIdStackTrace] ;\n break;\n }\n }\n return acc;\n }, {});\n}\n\n/**\n * Returns a list of debug images for the given resources.\n */\nfunction getDebugImagesForResources(\n stackParser,\n resource_paths,\n) {\n const filenameDebugIdMap = getFilenameToDebugIdMap(stackParser);\n\n const images = [];\n for (const path of resource_paths) {\n if (path && filenameDebugIdMap[path]) {\n images.push({\n type: 'sourcemap',\n code_file: path,\n debug_id: filenameDebugIdMap[path] ,\n });\n }\n }\n\n return images;\n}\n\nexport { getDebugImagesForResources, getFilenameToDebugIdMap };\n//# sourceMappingURL=debug-ids.js.map\n","import { GLOBAL_OBJ } from '../worldwide.js';\n\n// Based on https://github.com/angular/angular.js/pull/13945/files\n// The MIT License\n\n\nconst WINDOW = GLOBAL_OBJ ;\n\n/**\n * Tells whether current environment supports History API\n * {@link supportsHistory}.\n *\n * @returns Answer to the given question.\n */\nfunction supportsHistory() {\n // NOTE: in Chrome App environment, touching history.pushState, *even inside\n // a try/catch block*, will cause Chrome to output an error to console.error\n // borrowed from: https://github.com/angular/angular.js/pull/13945/files\n /* eslint-disable @typescript-eslint/no-unsafe-member-access */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const chromeVar = (WINDOW ).chrome;\n const isChromePackagedApp = chromeVar && chromeVar.app && chromeVar.app.runtime;\n /* eslint-enable @typescript-eslint/no-unsafe-member-access */\n const hasHistoryApi = 'history' in WINDOW && !!WINDOW.history.pushState && !!WINDOW.history.replaceState;\n\n return !isChromePackagedApp && hasHistoryApi;\n}\n\nexport { supportsHistory };\n//# sourceMappingURL=supportsHistory.js.map\n","/**\n * Polyfill for the optional chain operator, `?.`, given previous conversion of the expression into an array of values,\n * descriptors, and functions.\n *\n * Adapted from Sucrase (https://github.com/alangpierce/sucrase)\n * See https://github.com/alangpierce/sucrase/blob/265887868966917f3b924ce38dfad01fbab1329f/src/transformers/OptionalChainingNullishTransformer.ts#L15\n *\n * @param ops Array result of expression conversion\n * @returns The value of the expression\n */\nfunction _optionalChain(ops) {\n let lastAccessLHS = undefined;\n let value = ops[0];\n let i = 1;\n while (i < ops.length) {\n const op = ops[i] ;\n const fn = ops[i + 1] ;\n i += 2;\n // by checking for loose equality to `null`, we catch both `null` and `undefined`\n if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {\n // really we're meaning to return `undefined` as an actual value here, but it saves bytes not to write it\n return;\n }\n if (op === 'access' || op === 'optionalAccess') {\n lastAccessLHS = value;\n value = fn(value);\n } else if (op === 'call' || op === 'optionalCall') {\n value = fn((...args) => (value ).call(lastAccessLHS, ...args));\n lastAccessLHS = undefined;\n }\n }\n return value;\n}\n\n// Sucrase version\n// function _optionalChain(ops) {\n// let lastAccessLHS = undefined;\n// let value = ops[0];\n// let i = 1;\n// while (i < ops.length) {\n// const op = ops[i];\n// const fn = ops[i + 1];\n// i += 2;\n// if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {\n// return undefined;\n// }\n// if (op === 'access' || op === 'optionalAccess') {\n// lastAccessLHS = value;\n// value = fn(value);\n// } else if (op === 'call' || op === 'optionalCall') {\n// value = fn((...args) => value.call(lastAccessLHS, ...args));\n// lastAccessLHS = undefined;\n// }\n// }\n// return value;\n// }\n\nexport { _optionalChain };\n//# sourceMappingURL=_optionalChain.js.map\n","/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nconst DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);\n\nexport { DEBUG_BUILD };\n//# sourceMappingURL=debug-build.js.map\n","import { GLOBAL_OBJ, SDK_VERSION } from '@sentry/utils';\n\n/**\n * An object that contains globally accessible properties and maintains a scope stack.\n * @hidden\n */\n\n/**\n * Returns the global shim registry.\n *\n * FIXME: This function is problematic, because despite always returning a valid Carrier,\n * it has an optional `__SENTRY__` property, which then in turn requires us to always perform an unnecessary check\n * at the call-site. We always access the carrier through this function, so we can guarantee that `__SENTRY__` is there.\n **/\nfunction getMainCarrier() {\n // This ensures a Sentry carrier exists\n getSentryCarrier(GLOBAL_OBJ);\n return GLOBAL_OBJ;\n}\n\n/** Will either get the existing sentry carrier, or create a new one. */\nfunction getSentryCarrier(carrier) {\n const __SENTRY__ = (carrier.__SENTRY__ = carrier.__SENTRY__ || {});\n\n // For now: First SDK that sets the .version property wins\n __SENTRY__.version = __SENTRY__.version || SDK_VERSION;\n\n // Intentionally populating and returning the version of \"this\" SDK instance\n // rather than what's set in .version so that \"this\" SDK always gets its carrier\n return (__SENTRY__[SDK_VERSION] = __SENTRY__[SDK_VERSION] || {});\n}\n\nexport { getMainCarrier, getSentryCarrier };\n//# sourceMappingURL=carrier.js.map\n","import { timestampInSeconds, uuid4, dropUndefinedKeys } from '@sentry/utils';\n\n/**\n * Creates a new `Session` object by setting certain default parameters. If optional @param context\n * is passed, the passed properties are applied to the session object.\n *\n * @param context (optional) additional properties to be applied to the returned session object\n *\n * @returns a new `Session` object\n */\nfunction makeSession(context) {\n // Both timestamp and started are in seconds since the UNIX epoch.\n const startingTime = timestampInSeconds();\n\n const session = {\n sid: uuid4(),\n init: true,\n timestamp: startingTime,\n started: startingTime,\n duration: 0,\n status: 'ok',\n errors: 0,\n ignoreDuration: false,\n toJSON: () => sessionToJSON(session),\n };\n\n if (context) {\n updateSession(session, context);\n }\n\n return session;\n}\n\n/**\n * Updates a session object with the properties passed in the context.\n *\n * Note that this function mutates the passed object and returns void.\n * (Had to do this instead of returning a new and updated session because closing and sending a session\n * makes an update to the session after it was passed to the sending logic.\n * @see BaseClient.captureSession )\n *\n * @param session the `Session` to update\n * @param context the `SessionContext` holding the properties that should be updated in @param session\n */\n// eslint-disable-next-line complexity\nfunction updateSession(session, context = {}) {\n if (context.user) {\n if (!session.ipAddress && context.user.ip_address) {\n session.ipAddress = context.user.ip_address;\n }\n\n if (!session.did && !context.did) {\n session.did = context.user.id || context.user.email || context.user.username;\n }\n }\n\n session.timestamp = context.timestamp || timestampInSeconds();\n\n if (context.abnormal_mechanism) {\n session.abnormal_mechanism = context.abnormal_mechanism;\n }\n\n if (context.ignoreDuration) {\n session.ignoreDuration = context.ignoreDuration;\n }\n if (context.sid) {\n // Good enough uuid validation. — Kamil\n session.sid = context.sid.length === 32 ? context.sid : uuid4();\n }\n if (context.init !== undefined) {\n session.init = context.init;\n }\n if (!session.did && context.did) {\n session.did = `${context.did}`;\n }\n if (typeof context.started === 'number') {\n session.started = context.started;\n }\n if (session.ignoreDuration) {\n session.duration = undefined;\n } else if (typeof context.duration === 'number') {\n session.duration = context.duration;\n } else {\n const duration = session.timestamp - session.started;\n session.duration = duration >= 0 ? duration : 0;\n }\n if (context.release) {\n session.release = context.release;\n }\n if (context.environment) {\n session.environment = context.environment;\n }\n if (!session.ipAddress && context.ipAddress) {\n session.ipAddress = context.ipAddress;\n }\n if (!session.userAgent && context.userAgent) {\n session.userAgent = context.userAgent;\n }\n if (typeof context.errors === 'number') {\n session.errors = context.errors;\n }\n if (context.status) {\n session.status = context.status;\n }\n}\n\n/**\n * Closes a session by setting its status and updating the session object with it.\n * Internally calls `updateSession` to update the passed session object.\n *\n * Note that this function mutates the passed session (@see updateSession for explanation).\n *\n * @param session the `Session` object to be closed\n * @param status the `SessionStatus` with which the session was closed. If you don't pass a status,\n * this function will keep the previously set status, unless it was `'ok'` in which case\n * it is changed to `'exited'`.\n */\nfunction closeSession(session, status) {\n let context = {};\n if (status) {\n context = { status };\n } else if (session.status === 'ok') {\n context = { status: 'exited' };\n }\n\n updateSession(session, context);\n}\n\n/**\n * Serializes a passed session object to a JSON object with a slightly different structure.\n * This is necessary because the Sentry backend requires a slightly different schema of a session\n * than the one the JS SDKs use internally.\n *\n * @param session the session to be converted\n *\n * @returns a JSON object of the passed session\n */\nfunction sessionToJSON(session) {\n return dropUndefinedKeys({\n sid: `${session.sid}`,\n init: session.init,\n // Make sure that sec is converted to ms for date constructor\n started: new Date(session.started * 1000).toISOString(),\n timestamp: new Date(session.timestamp * 1000).toISOString(),\n status: session.status,\n errors: session.errors,\n did: typeof session.did === 'number' || typeof session.did === 'string' ? `${session.did}` : undefined,\n duration: session.duration,\n abnormal_mechanism: session.abnormal_mechanism,\n attrs: {\n release: session.release,\n environment: session.environment,\n ip_address: session.ipAddress,\n user_agent: session.userAgent,\n },\n });\n}\n\nexport { closeSession, makeSession, updateSession };\n//# sourceMappingURL=session.js.map\n","import { addNonEnumerableProperty } from '@sentry/utils';\n\nconst SCOPE_SPAN_FIELD = '_sentrySpan';\n\n/**\n * Set the active span for a given scope.\n * NOTE: This should NOT be used directly, but is only used internally by the trace methods.\n */\nfunction _setSpanForScope(scope, span) {\n if (span) {\n addNonEnumerableProperty(scope , SCOPE_SPAN_FIELD, span);\n } else {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete (scope )[SCOPE_SPAN_FIELD];\n }\n}\n\n/**\n * Get the active span for a given scope.\n * NOTE: This should NOT be used directly, but is only used internally by the trace methods.\n */\nfunction _getSpanForScope(scope) {\n return scope[SCOPE_SPAN_FIELD];\n}\n\nexport { _getSpanForScope, _setSpanForScope };\n//# sourceMappingURL=spanOnScope.js.map\n","import { generatePropagationContext, isPlainObject, dateTimestampInSeconds, uuid4, logger } from '@sentry/utils';\nimport { updateSession } from './session.js';\nimport { _setSpanForScope, _getSpanForScope } from './utils/spanOnScope.js';\n\n/**\n * Default value for maximum number of breadcrumbs added to an event.\n */\nconst DEFAULT_MAX_BREADCRUMBS = 100;\n\n/**\n * Holds additional event information.\n */\nclass ScopeClass {\n /** Flag if notifying is happening. */\n\n /** Callback for client to receive scope changes. */\n\n /** Callback list that will be called during event processing. */\n\n /** Array of breadcrumbs. */\n\n /** User */\n\n /** Tags */\n\n /** Extra */\n\n /** Contexts */\n\n /** Attachments */\n\n /** Propagation Context for distributed tracing */\n\n /**\n * A place to stash data which is needed at some point in the SDK's event processing pipeline but which shouldn't get\n * sent to Sentry\n */\n\n /** Fingerprint */\n\n /** Severity */\n\n /**\n * Transaction Name\n *\n * IMPORTANT: The transaction name on the scope has nothing to do with root spans/transaction objects.\n * It's purpose is to assign a transaction to the scope that's added to non-transaction events.\n */\n\n /** Session */\n\n /** Request Mode Session Status */\n\n /** The client on this scope */\n\n /** Contains the last event id of a captured event. */\n\n // NOTE: Any field which gets added here should get added not only to the constructor but also to the `clone` method.\n\n constructor() {\n this._notifyingListeners = false;\n this._scopeListeners = [];\n this._eventProcessors = [];\n this._breadcrumbs = [];\n this._attachments = [];\n this._user = {};\n this._tags = {};\n this._extra = {};\n this._contexts = {};\n this._sdkProcessingMetadata = {};\n this._propagationContext = generatePropagationContext();\n }\n\n /**\n * @inheritDoc\n */\n clone() {\n const newScope = new ScopeClass();\n newScope._breadcrumbs = [...this._breadcrumbs];\n newScope._tags = { ...this._tags };\n newScope._extra = { ...this._extra };\n newScope._contexts = { ...this._contexts };\n newScope._user = this._user;\n newScope._level = this._level;\n newScope._session = this._session;\n newScope._transactionName = this._transactionName;\n newScope._fingerprint = this._fingerprint;\n newScope._eventProcessors = [...this._eventProcessors];\n newScope._requestSession = this._requestSession;\n newScope._attachments = [...this._attachments];\n newScope._sdkProcessingMetadata = { ...this._sdkProcessingMetadata };\n newScope._propagationContext = { ...this._propagationContext };\n newScope._client = this._client;\n newScope._lastEventId = this._lastEventId;\n\n _setSpanForScope(newScope, _getSpanForScope(this));\n\n return newScope;\n }\n\n /**\n * @inheritDoc\n */\n setClient(client) {\n this._client = client;\n }\n\n /**\n * @inheritDoc\n */\n setLastEventId(lastEventId) {\n this._lastEventId = lastEventId;\n }\n\n /**\n * @inheritDoc\n */\n getClient() {\n return this._client ;\n }\n\n /**\n * @inheritDoc\n */\n lastEventId() {\n return this._lastEventId;\n }\n\n /**\n * @inheritDoc\n */\n addScopeListener(callback) {\n this._scopeListeners.push(callback);\n }\n\n /**\n * @inheritDoc\n */\n addEventProcessor(callback) {\n this._eventProcessors.push(callback);\n return this;\n }\n\n /**\n * @inheritDoc\n */\n setUser(user) {\n // If null is passed we want to unset everything, but still define keys,\n // so that later down in the pipeline any existing values are cleared.\n this._user = user || {\n email: undefined,\n id: undefined,\n ip_address: undefined,\n username: undefined,\n };\n\n if (this._session) {\n updateSession(this._session, { user });\n }\n\n this._notifyScopeListeners();\n return this;\n }\n\n /**\n * @inheritDoc\n */\n getUser() {\n return this._user;\n }\n\n /**\n * @inheritDoc\n */\n getRequestSession() {\n return this._requestSession;\n }\n\n /**\n * @inheritDoc\n */\n setRequestSession(requestSession) {\n this._requestSession = requestSession;\n return this;\n }\n\n /**\n * @inheritDoc\n */\n setTags(tags) {\n this._tags = {\n ...this._tags,\n ...tags,\n };\n this._notifyScopeListeners();\n return this;\n }\n\n /**\n * @inheritDoc\n */\n setTag(key, value) {\n this._tags = { ...this._tags, [key]: value };\n this._notifyScopeListeners();\n return this;\n }\n\n /**\n * @inheritDoc\n */\n setExtras(extras) {\n this._extra = {\n ...this._extra,\n ...extras,\n };\n this._notifyScopeListeners();\n return this;\n }\n\n /**\n * @inheritDoc\n */\n setExtra(key, extra) {\n this._extra = { ...this._extra, [key]: extra };\n this._notifyScopeListeners();\n return this;\n }\n\n /**\n * @inheritDoc\n */\n setFingerprint(fingerprint) {\n this._fingerprint = fingerprint;\n this._notifyScopeListeners();\n return this;\n }\n\n /**\n * @inheritDoc\n */\n setLevel(level) {\n this._level = level;\n this._notifyScopeListeners();\n return this;\n }\n\n /**\n * @inheritDoc\n */\n setTransactionName(name) {\n this._transactionName = name;\n this._notifyScopeListeners();\n return this;\n }\n\n /**\n * @inheritDoc\n */\n setContext(key, context) {\n if (context === null) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete this._contexts[key];\n } else {\n this._contexts[key] = context;\n }\n\n this._notifyScopeListeners();\n return this;\n }\n\n /**\n * @inheritDoc\n */\n setSession(session) {\n if (!session) {\n delete this._session;\n } else {\n this._session = session;\n }\n this._notifyScopeListeners();\n return this;\n }\n\n /**\n * @inheritDoc\n */\n getSession() {\n return this._session;\n }\n\n /**\n * @inheritDoc\n */\n update(captureContext) {\n if (!captureContext) {\n return this;\n }\n\n const scopeToMerge = typeof captureContext === 'function' ? captureContext(this) : captureContext;\n\n const [scopeInstance, requestSession] =\n scopeToMerge instanceof Scope\n ? [scopeToMerge.getScopeData(), scopeToMerge.getRequestSession()]\n : isPlainObject(scopeToMerge)\n ? [captureContext , (captureContext ).requestSession]\n : [];\n\n const { tags, extra, user, contexts, level, fingerprint = [], propagationContext } = scopeInstance || {};\n\n this._tags = { ...this._tags, ...tags };\n this._extra = { ...this._extra, ...extra };\n this._contexts = { ...this._contexts, ...contexts };\n\n if (user && Object.keys(user).length) {\n this._user = user;\n }\n\n if (level) {\n this._level = level;\n }\n\n if (fingerprint.length) {\n this._fingerprint = fingerprint;\n }\n\n if (propagationContext) {\n this._propagationContext = propagationContext;\n }\n\n if (requestSession) {\n this._requestSession = requestSession;\n }\n\n return this;\n }\n\n /**\n * @inheritDoc\n */\n clear() {\n // client is not cleared here on purpose!\n this._breadcrumbs = [];\n this._tags = {};\n this._extra = {};\n this._user = {};\n this._contexts = {};\n this._level = undefined;\n this._transactionName = undefined;\n this._fingerprint = undefined;\n this._requestSession = undefined;\n this._session = undefined;\n _setSpanForScope(this, undefined);\n this._attachments = [];\n this._propagationContext = generatePropagationContext();\n\n this._notifyScopeListeners();\n return this;\n }\n\n /**\n * @inheritDoc\n */\n addBreadcrumb(breadcrumb, maxBreadcrumbs) {\n const maxCrumbs = typeof maxBreadcrumbs === 'number' ? maxBreadcrumbs : DEFAULT_MAX_BREADCRUMBS;\n\n // No data has been changed, so don't notify scope listeners\n if (maxCrumbs <= 0) {\n return this;\n }\n\n const mergedBreadcrumb = {\n timestamp: dateTimestampInSeconds(),\n ...breadcrumb,\n };\n\n const breadcrumbs = this._breadcrumbs;\n breadcrumbs.push(mergedBreadcrumb);\n this._breadcrumbs = breadcrumbs.length > maxCrumbs ? breadcrumbs.slice(-maxCrumbs) : breadcrumbs;\n\n this._notifyScopeListeners();\n\n return this;\n }\n\n /**\n * @inheritDoc\n */\n getLastBreadcrumb() {\n return this._breadcrumbs[this._breadcrumbs.length - 1];\n }\n\n /**\n * @inheritDoc\n */\n clearBreadcrumbs() {\n this._breadcrumbs = [];\n this._notifyScopeListeners();\n return this;\n }\n\n /**\n * @inheritDoc\n */\n addAttachment(attachment) {\n this._attachments.push(attachment);\n return this;\n }\n\n /**\n * @inheritDoc\n */\n clearAttachments() {\n this._attachments = [];\n return this;\n }\n\n /** @inheritDoc */\n getScopeData() {\n return {\n breadcrumbs: this._breadcrumbs,\n attachments: this._attachments,\n contexts: this._contexts,\n tags: this._tags,\n extra: this._extra,\n user: this._user,\n level: this._level,\n fingerprint: this._fingerprint || [],\n eventProcessors: this._eventProcessors,\n propagationContext: this._propagationContext,\n sdkProcessingMetadata: this._sdkProcessingMetadata,\n transactionName: this._transactionName,\n span: _getSpanForScope(this),\n };\n }\n\n /**\n * @inheritDoc\n */\n setSDKProcessingMetadata(newData) {\n this._sdkProcessingMetadata = { ...this._sdkProcessingMetadata, ...newData };\n\n return this;\n }\n\n /**\n * @inheritDoc\n */\n setPropagationContext(context) {\n this._propagationContext = context;\n return this;\n }\n\n /**\n * @inheritDoc\n */\n getPropagationContext() {\n return this._propagationContext;\n }\n\n /**\n * @inheritDoc\n */\n captureException(exception, hint) {\n const eventId = hint && hint.event_id ? hint.event_id : uuid4();\n\n if (!this._client) {\n logger.warn('No client configured on scope - will not capture exception!');\n return eventId;\n }\n\n const syntheticException = new Error('Sentry syntheticException');\n\n this._client.captureException(\n exception,\n {\n originalException: exception,\n syntheticException,\n ...hint,\n event_id: eventId,\n },\n this,\n );\n\n return eventId;\n }\n\n /**\n * @inheritDoc\n */\n captureMessage(message, level, hint) {\n const eventId = hint && hint.event_id ? hint.event_id : uuid4();\n\n if (!this._client) {\n logger.warn('No client configured on scope - will not capture message!');\n return eventId;\n }\n\n const syntheticException = new Error(message);\n\n this._client.captureMessage(\n message,\n level,\n {\n originalException: message,\n syntheticException,\n ...hint,\n event_id: eventId,\n },\n this,\n );\n\n return eventId;\n }\n\n /**\n * @inheritDoc\n */\n captureEvent(event, hint) {\n const eventId = hint && hint.event_id ? hint.event_id : uuid4();\n\n if (!this._client) {\n logger.warn('No client configured on scope - will not capture event!');\n return eventId;\n }\n\n this._client.captureEvent(event, { ...hint, event_id: eventId }, this);\n\n return eventId;\n }\n\n /**\n * This will be called on every set call.\n */\n _notifyScopeListeners() {\n // We need this check for this._notifyingListeners to be able to work on scope during updates\n // If this check is not here we'll produce endless recursion when something is done with the scope\n // during the callback.\n if (!this._notifyingListeners) {\n this._notifyingListeners = true;\n this._scopeListeners.forEach(callback => {\n callback(this);\n });\n this._notifyingListeners = false;\n }\n }\n}\n\n// NOTE: By exporting this here as const & type, instead of doing `export class`,\n// We can get the correct class when importing from `@sentry/core`, but the original type (from `@sentry/types`)\n// This is helpful for interop, e.g. when doing `import type { Scope } from '@sentry/node';` (which re-exports this)\n\n/**\n * Holds additional event information.\n */\nconst Scope = ScopeClass;\n\n/**\n * Holds additional event information.\n */\n\nexport { Scope };\n//# sourceMappingURL=scope.js.map\n","import { getGlobalSingleton } from '@sentry/utils';\nimport { Scope } from './scope.js';\n\n/** Get the default current scope. */\nfunction getDefaultCurrentScope() {\n return getGlobalSingleton('defaultCurrentScope', () => new Scope());\n}\n\n/** Get the default isolation scope. */\nfunction getDefaultIsolationScope() {\n return getGlobalSingleton('defaultIsolationScope', () => new Scope());\n}\n\nexport { getDefaultCurrentScope, getDefaultIsolationScope };\n//# sourceMappingURL=defaultScopes.js.map\n","import { isThenable } from '@sentry/utils';\nimport { getDefaultCurrentScope, getDefaultIsolationScope } from '../defaultScopes.js';\nimport { Scope } from '../scope.js';\nimport { getMainCarrier, getSentryCarrier } from '../carrier.js';\n\n/**\n * This is an object that holds a stack of scopes.\n */\nclass AsyncContextStack {\n\n constructor(scope, isolationScope) {\n let assignedScope;\n if (!scope) {\n assignedScope = new Scope();\n } else {\n assignedScope = scope;\n }\n\n let assignedIsolationScope;\n if (!isolationScope) {\n assignedIsolationScope = new Scope();\n } else {\n assignedIsolationScope = isolationScope;\n }\n\n // scope stack for domains or the process\n this._stack = [{ scope: assignedScope }];\n this._isolationScope = assignedIsolationScope;\n }\n\n /**\n * Fork a scope for the stack.\n */\n withScope(callback) {\n const scope = this._pushScope();\n\n let maybePromiseResult;\n try {\n maybePromiseResult = callback(scope);\n } catch (e) {\n this._popScope();\n throw e;\n }\n\n if (isThenable(maybePromiseResult)) {\n // @ts-expect-error - isThenable returns the wrong type\n return maybePromiseResult.then(\n res => {\n this._popScope();\n return res;\n },\n e => {\n this._popScope();\n throw e;\n },\n );\n }\n\n this._popScope();\n return maybePromiseResult;\n }\n\n /**\n * Get the client of the stack.\n */\n getClient() {\n return this.getStackTop().client ;\n }\n\n /**\n * Returns the scope of the top stack.\n */\n getScope() {\n return this.getStackTop().scope;\n }\n\n /**\n * Get the isolation scope for the stack.\n */\n getIsolationScope() {\n return this._isolationScope;\n }\n\n /**\n * Returns the topmost scope layer in the order domain > local > process.\n */\n getStackTop() {\n return this._stack[this._stack.length - 1] ;\n }\n\n /**\n * Push a scope to the stack.\n */\n _pushScope() {\n // We want to clone the content of prev scope\n const scope = this.getScope().clone();\n this._stack.push({\n client: this.getClient(),\n scope,\n });\n return scope;\n }\n\n /**\n * Pop a scope from the stack.\n */\n _popScope() {\n if (this._stack.length <= 1) return false;\n return !!this._stack.pop();\n }\n}\n\n/**\n * Get the global async context stack.\n * This will be removed during the v8 cycle and is only here to make migration easier.\n */\nfunction getAsyncContextStack() {\n const registry = getMainCarrier();\n const sentry = getSentryCarrier(registry);\n\n return (sentry.stack = sentry.stack || new AsyncContextStack(getDefaultCurrentScope(), getDefaultIsolationScope()));\n}\n\nfunction withScope(callback) {\n return getAsyncContextStack().withScope(callback);\n}\n\nfunction withSetScope(scope, callback) {\n const stack = getAsyncContextStack() ;\n return stack.withScope(() => {\n stack.getStackTop().scope = scope;\n return callback(scope);\n });\n}\n\nfunction withIsolationScope(callback) {\n return getAsyncContextStack().withScope(() => {\n return callback(getAsyncContextStack().getIsolationScope());\n });\n}\n\n/**\n * Get the stack-based async context strategy.\n */\nfunction getStackAsyncContextStrategy() {\n return {\n withIsolationScope,\n withScope,\n withSetScope,\n withSetIsolationScope: (_isolationScope, callback) => {\n return withIsolationScope(callback);\n },\n getCurrentScope: () => getAsyncContextStack().getScope(),\n getIsolationScope: () => getAsyncContextStack().getIsolationScope(),\n };\n}\n\nexport { AsyncContextStack, getStackAsyncContextStrategy };\n//# sourceMappingURL=stackStrategy.js.map\n","import { getMainCarrier, getSentryCarrier } from '../carrier.js';\nimport { getStackAsyncContextStrategy } from './stackStrategy.js';\n\n/**\n * @private Private API with no semver guarantees!\n *\n * Sets the global async context strategy\n */\nfunction setAsyncContextStrategy(strategy) {\n // Get main carrier (global for every environment)\n const registry = getMainCarrier();\n const sentry = getSentryCarrier(registry);\n sentry.acs = strategy;\n}\n\n/**\n * Get the current async context strategy.\n * If none has been setup, the default will be used.\n */\nfunction getAsyncContextStrategy(carrier) {\n const sentry = getSentryCarrier(carrier);\n\n if (sentry.acs) {\n return sentry.acs;\n }\n\n // Otherwise, use the default one (stack)\n return getStackAsyncContextStrategy();\n}\n\nexport { getAsyncContextStrategy, setAsyncContextStrategy };\n//# sourceMappingURL=index.js.map\n","import { getGlobalSingleton } from '@sentry/utils';\nimport { getAsyncContextStrategy } from './asyncContext/index.js';\nimport { getMainCarrier } from './carrier.js';\nimport { Scope } from './scope.js';\n\n/**\n * Get the currently active scope.\n */\nfunction getCurrentScope() {\n const carrier = getMainCarrier();\n const acs = getAsyncContextStrategy(carrier);\n return acs.getCurrentScope();\n}\n\n/**\n * Get the currently active isolation scope.\n * The isolation scope is active for the current execution context.\n */\nfunction getIsolationScope() {\n const carrier = getMainCarrier();\n const acs = getAsyncContextStrategy(carrier);\n return acs.getIsolationScope();\n}\n\n/**\n * Get the global scope.\n * This scope is applied to _all_ events.\n */\nfunction getGlobalScope() {\n return getGlobalSingleton('globalScope', () => new Scope());\n}\n\n/**\n * Creates a new scope with and executes the given operation within.\n * The scope is automatically removed once the operation\n * finishes or throws.\n */\n\n/**\n * Either creates a new active scope, or sets the given scope as active scope in the given callback.\n */\nfunction withScope(\n ...rest\n) {\n const carrier = getMainCarrier();\n const acs = getAsyncContextStrategy(carrier);\n\n // If a scope is defined, we want to make this the active scope instead of the default one\n if (rest.length === 2) {\n const [scope, callback] = rest;\n\n if (!scope) {\n return acs.withScope(callback);\n }\n\n return acs.withSetScope(scope, callback);\n }\n\n return acs.withScope(rest[0]);\n}\n\n/**\n * Attempts to fork the current isolation scope and the current scope based on the current async context strategy. If no\n * async context strategy is set, the isolation scope and the current scope will not be forked (this is currently the\n * case, for example, in the browser).\n *\n * Usage of this function in environments without async context strategy is discouraged and may lead to unexpected behaviour.\n *\n * This function is intended for Sentry SDK and SDK integration development. It is not recommended to be used in \"normal\"\n * applications directly because it comes with pitfalls. Use at your own risk!\n */\n\n/**\n * Either creates a new active isolation scope, or sets the given isolation scope as active scope in the given callback.\n */\nfunction withIsolationScope(\n ...rest\n\n) {\n const carrier = getMainCarrier();\n const acs = getAsyncContextStrategy(carrier);\n\n // If a scope is defined, we want to make this the active scope instead of the default one\n if (rest.length === 2) {\n const [isolationScope, callback] = rest;\n\n if (!isolationScope) {\n return acs.withIsolationScope(callback);\n }\n\n return acs.withSetIsolationScope(isolationScope, callback);\n }\n\n return acs.withIsolationScope(rest[0]);\n}\n\n/**\n * Get the currently active client.\n */\nfunction getClient() {\n return getCurrentScope().getClient();\n}\n\nexport { getClient, getCurrentScope, getGlobalScope, getIsolationScope, withIsolationScope, withScope };\n//# sourceMappingURL=currentScopes.js.map\n","import { dropUndefinedKeys } from '@sentry/utils';\n\n/**\n * key: bucketKey\n * value: [exportKey, MetricSummary]\n */\n\nconst METRICS_SPAN_FIELD = '_sentryMetrics';\n\n/**\n * Fetches the metric summary if it exists for the passed span\n */\nfunction getMetricSummaryJsonForSpan(span) {\n const storage = (span )[METRICS_SPAN_FIELD];\n\n if (!storage) {\n return undefined;\n }\n const output = {};\n\n for (const [, [exportKey, summary]] of storage) {\n const arr = output[exportKey] || (output[exportKey] = []);\n arr.push(dropUndefinedKeys(summary));\n }\n\n return output;\n}\n\n/**\n * Updates the metric summary on a span.\n */\nfunction updateMetricSummaryOnSpan(\n span,\n metricType,\n sanitizedName,\n value,\n unit,\n tags,\n bucketKey,\n) {\n const existingStorage = (span )[METRICS_SPAN_FIELD];\n const storage =\n existingStorage ||\n ((span )[METRICS_SPAN_FIELD] = new Map());\n\n const exportKey = `${metricType}:${sanitizedName}@${unit}`;\n const bucketItem = storage.get(bucketKey);\n\n if (bucketItem) {\n const [, summary] = bucketItem;\n storage.set(bucketKey, [\n exportKey,\n {\n min: Math.min(summary.min, value),\n max: Math.max(summary.max, value),\n count: (summary.count += 1),\n sum: (summary.sum += value),\n tags: summary.tags,\n },\n ]);\n } else {\n storage.set(bucketKey, [\n exportKey,\n {\n min: value,\n max: value,\n count: 1,\n sum: value,\n tags,\n },\n ]);\n }\n}\n\nexport { getMetricSummaryJsonForSpan, updateMetricSummaryOnSpan };\n//# sourceMappingURL=metric-summary.js.map\n","/**\n * Use this attribute to represent the source of a span.\n * Should be one of: custom, url, route, view, component, task, unknown\n *\n */\nconst SEMANTIC_ATTRIBUTE_SENTRY_SOURCE = 'sentry.source';\n\n/**\n * Use this attribute to represent the sample rate used for a span.\n */\nconst SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE = 'sentry.sample_rate';\n\n/**\n * Use this attribute to represent the operation of a span.\n */\nconst SEMANTIC_ATTRIBUTE_SENTRY_OP = 'sentry.op';\n\n/**\n * Use this attribute to represent the origin of a span.\n */\nconst SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'sentry.origin';\n\n/** The reason why an idle span finished. */\nconst SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON = 'sentry.idle_span_finish_reason';\n\n/** The unit of a measurement, which may be stored as a TimedEvent. */\nconst SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT = 'sentry.measurement_unit';\n\n/** The value of a measurement, which may be stored as a TimedEvent. */\nconst SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE = 'sentry.measurement_value';\n\n/**\n * The id of the profile that this span occurred in.\n */\nconst SEMANTIC_ATTRIBUTE_PROFILE_ID = 'sentry.profile_id';\n\nconst SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME = 'sentry.exclusive_time';\n\nconst SEMANTIC_ATTRIBUTE_CACHE_HIT = 'cache.hit';\n\nconst SEMANTIC_ATTRIBUTE_CACHE_KEY = 'cache.key';\n\nconst SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE = 'cache.item_size';\n\n/** TODO: Remove these once we update to latest semantic conventions */\nconst SEMANTIC_ATTRIBUTE_HTTP_REQUEST_METHOD = 'http.request.method';\nconst SEMANTIC_ATTRIBUTE_URL_FULL = 'url.full';\n\nexport { SEMANTIC_ATTRIBUTE_CACHE_HIT, SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE, SEMANTIC_ATTRIBUTE_CACHE_KEY, SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME, SEMANTIC_ATTRIBUTE_HTTP_REQUEST_METHOD, SEMANTIC_ATTRIBUTE_PROFILE_ID, SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_URL_FULL };\n//# sourceMappingURL=semanticAttributes.js.map\n","const SPAN_STATUS_UNSET = 0;\nconst SPAN_STATUS_OK = 1;\nconst SPAN_STATUS_ERROR = 2;\n\n/**\n * Converts a HTTP status code into a sentry status with a message.\n *\n * @param httpStatus The HTTP response status code.\n * @returns The span status or unknown_error.\n */\n// https://develop.sentry.dev/sdk/event-payloads/span/\nfunction getSpanStatusFromHttpCode(httpStatus) {\n if (httpStatus < 400 && httpStatus >= 100) {\n return { code: SPAN_STATUS_OK };\n }\n\n if (httpStatus >= 400 && httpStatus < 500) {\n switch (httpStatus) {\n case 401:\n return { code: SPAN_STATUS_ERROR, message: 'unauthenticated' };\n case 403:\n return { code: SPAN_STATUS_ERROR, message: 'permission_denied' };\n case 404:\n return { code: SPAN_STATUS_ERROR, message: 'not_found' };\n case 409:\n return { code: SPAN_STATUS_ERROR, message: 'already_exists' };\n case 413:\n return { code: SPAN_STATUS_ERROR, message: 'failed_precondition' };\n case 429:\n return { code: SPAN_STATUS_ERROR, message: 'resource_exhausted' };\n case 499:\n return { code: SPAN_STATUS_ERROR, message: 'cancelled' };\n default:\n return { code: SPAN_STATUS_ERROR, message: 'invalid_argument' };\n }\n }\n\n if (httpStatus >= 500 && httpStatus < 600) {\n switch (httpStatus) {\n case 501:\n return { code: SPAN_STATUS_ERROR, message: 'unimplemented' };\n case 503:\n return { code: SPAN_STATUS_ERROR, message: 'unavailable' };\n case 504:\n return { code: SPAN_STATUS_ERROR, message: 'deadline_exceeded' };\n default:\n return { code: SPAN_STATUS_ERROR, message: 'internal_error' };\n }\n }\n\n return { code: SPAN_STATUS_ERROR, message: 'unknown_error' };\n}\n\n/**\n * Sets the Http status attributes on the current span based on the http code.\n * Additionally, the span's status is updated, depending on the http code.\n */\nfunction setHttpStatus(span, httpStatus) {\n span.setAttribute('http.response.status_code', httpStatus);\n\n const spanStatus = getSpanStatusFromHttpCode(httpStatus);\n if (spanStatus.message !== 'unknown_error') {\n span.setStatus(spanStatus);\n }\n}\n\nexport { SPAN_STATUS_ERROR, SPAN_STATUS_OK, SPAN_STATUS_UNSET, getSpanStatusFromHttpCode, setHttpStatus };\n//# sourceMappingURL=spanstatus.js.map\n","import { dropUndefinedKeys, generateSentryTraceHeader, timestampInSeconds, addNonEnumerableProperty } from '@sentry/utils';\nimport { getAsyncContextStrategy } from '../asyncContext/index.js';\nimport { getMainCarrier } from '../carrier.js';\nimport { getCurrentScope } from '../currentScopes.js';\nimport { getMetricSummaryJsonForSpan, updateMetricSummaryOnSpan } from '../metrics/metric-summary.js';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../semanticAttributes.js';\nimport { SPAN_STATUS_UNSET, SPAN_STATUS_OK } from '../tracing/spanstatus.js';\nimport { _getSpanForScope } from './spanOnScope.js';\n\n// These are aligned with OpenTelemetry trace flags\nconst TRACE_FLAG_NONE = 0x0;\nconst TRACE_FLAG_SAMPLED = 0x1;\n\n/**\n * Convert a span to a trace context, which can be sent as the `trace` context in an event.\n * By default, this will only include trace_id, span_id & parent_span_id.\n * If `includeAllData` is true, it will also include data, op, status & origin.\n */\nfunction spanToTransactionTraceContext(span) {\n const { spanId: span_id, traceId: trace_id } = span.spanContext();\n const { data, op, parent_span_id, status, origin } = spanToJSON(span);\n\n return dropUndefinedKeys({\n parent_span_id,\n span_id,\n trace_id,\n data,\n op,\n status,\n origin,\n });\n}\n\n/**\n * Convert a span to a trace context, which can be sent as the `trace` context in a non-transaction event.\n */\nfunction spanToTraceContext(span) {\n const { spanId: span_id, traceId: trace_id } = span.spanContext();\n const { parent_span_id } = spanToJSON(span);\n\n return dropUndefinedKeys({ parent_span_id, span_id, trace_id });\n}\n\n/**\n * Convert a Span to a Sentry trace header.\n */\nfunction spanToTraceHeader(span) {\n const { traceId, spanId } = span.spanContext();\n const sampled = spanIsSampled(span);\n return generateSentryTraceHeader(traceId, spanId, sampled);\n}\n\n/**\n * Convert a span time input into a timestamp in seconds.\n */\nfunction spanTimeInputToSeconds(input) {\n if (typeof input === 'number') {\n return ensureTimestampInSeconds(input);\n }\n\n if (Array.isArray(input)) {\n // See {@link HrTime} for the array-based time format\n return input[0] + input[1] / 1e9;\n }\n\n if (input instanceof Date) {\n return ensureTimestampInSeconds(input.getTime());\n }\n\n return timestampInSeconds();\n}\n\n/**\n * Converts a timestamp to second, if it was in milliseconds, or keeps it as second.\n */\nfunction ensureTimestampInSeconds(timestamp) {\n const isMs = timestamp > 9999999999;\n return isMs ? timestamp / 1000 : timestamp;\n}\n\n/**\n * Convert a span to a JSON representation.\n */\n// Note: Because of this, we currently have a circular type dependency (which we opted out of in package.json).\n// This is not avoidable as we need `spanToJSON` in `spanUtils.ts`, which in turn is needed by `span.ts` for backwards compatibility.\n// And `spanToJSON` needs the Span class from `span.ts` to check here.\nfunction spanToJSON(span) {\n if (spanIsSentrySpan(span)) {\n return span.getSpanJSON();\n }\n\n try {\n const { spanId: span_id, traceId: trace_id } = span.spanContext();\n\n // Handle a span from @opentelemetry/sdk-base-trace's `Span` class\n if (spanIsOpenTelemetrySdkTraceBaseSpan(span)) {\n const { attributes, startTime, name, endTime, parentSpanId, status } = span;\n\n return dropUndefinedKeys({\n span_id,\n trace_id,\n data: attributes,\n description: name,\n parent_span_id: parentSpanId,\n start_timestamp: spanTimeInputToSeconds(startTime),\n // This is [0,0] by default in OTEL, in which case we want to interpret this as no end time\n timestamp: spanTimeInputToSeconds(endTime) || undefined,\n status: getStatusMessage(status),\n op: attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP],\n origin: attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] ,\n _metrics_summary: getMetricSummaryJsonForSpan(span),\n });\n }\n\n // Finally, at least we have `spanContext()`....\n return {\n span_id,\n trace_id,\n };\n } catch (e) {\n return {};\n }\n}\n\nfunction spanIsOpenTelemetrySdkTraceBaseSpan(span) {\n const castSpan = span ;\n return !!castSpan.attributes && !!castSpan.startTime && !!castSpan.name && !!castSpan.endTime && !!castSpan.status;\n}\n\n/** Exported only for tests. */\n\n/**\n * Sadly, due to circular dependency checks we cannot actually import the Span class here and check for instanceof.\n * :( So instead we approximate this by checking if it has the `getSpanJSON` method.\n */\nfunction spanIsSentrySpan(span) {\n return typeof (span ).getSpanJSON === 'function';\n}\n\n/**\n * Returns true if a span is sampled.\n * In most cases, you should just use `span.isRecording()` instead.\n * However, this has a slightly different semantic, as it also returns false if the span is finished.\n * So in the case where this distinction is important, use this method.\n */\nfunction spanIsSampled(span) {\n // We align our trace flags with the ones OpenTelemetry use\n // So we also check for sampled the same way they do.\n const { traceFlags } = span.spanContext();\n return traceFlags === TRACE_FLAG_SAMPLED;\n}\n\n/** Get the status message to use for a JSON representation of a span. */\nfunction getStatusMessage(status) {\n if (!status || status.code === SPAN_STATUS_UNSET) {\n return undefined;\n }\n\n if (status.code === SPAN_STATUS_OK) {\n return 'ok';\n }\n\n return status.message || 'unknown_error';\n}\n\nconst CHILD_SPANS_FIELD = '_sentryChildSpans';\nconst ROOT_SPAN_FIELD = '_sentryRootSpan';\n\n/**\n * Adds an opaque child span reference to a span.\n */\nfunction addChildSpanToSpan(span, childSpan) {\n // We store the root span reference on the child span\n // We need this for `getRootSpan()` to work\n const rootSpan = span[ROOT_SPAN_FIELD] || span;\n addNonEnumerableProperty(childSpan , ROOT_SPAN_FIELD, rootSpan);\n\n // We store a list of child spans on the parent span\n // We need this for `getSpanDescendants()` to work\n if (span[CHILD_SPANS_FIELD]) {\n span[CHILD_SPANS_FIELD].add(childSpan);\n } else {\n addNonEnumerableProperty(span, CHILD_SPANS_FIELD, new Set([childSpan]));\n }\n}\n\n/** This is only used internally by Idle Spans. */\nfunction removeChildSpanFromSpan(span, childSpan) {\n if (span[CHILD_SPANS_FIELD]) {\n span[CHILD_SPANS_FIELD].delete(childSpan);\n }\n}\n\n/**\n * Returns an array of the given span and all of its descendants.\n */\nfunction getSpanDescendants(span) {\n const resultSet = new Set();\n\n function addSpanChildren(span) {\n // This exit condition is required to not infinitely loop in case of a circular dependency.\n if (resultSet.has(span)) {\n return;\n // We want to ignore unsampled spans (e.g. non recording spans)\n } else if (spanIsSampled(span)) {\n resultSet.add(span);\n const childSpans = span[CHILD_SPANS_FIELD] ? Array.from(span[CHILD_SPANS_FIELD]) : [];\n for (const childSpan of childSpans) {\n addSpanChildren(childSpan);\n }\n }\n }\n\n addSpanChildren(span);\n\n return Array.from(resultSet);\n}\n\n/**\n * Returns the root span of a given span.\n */\nfunction getRootSpan(span) {\n return span[ROOT_SPAN_FIELD] || span;\n}\n\n/**\n * Returns the currently active span.\n */\nfunction getActiveSpan() {\n const carrier = getMainCarrier();\n const acs = getAsyncContextStrategy(carrier);\n if (acs.getActiveSpan) {\n return acs.getActiveSpan();\n }\n\n return _getSpanForScope(getCurrentScope());\n}\n\n/**\n * Updates the metric summary on the currently active span\n */\nfunction updateMetricSummaryOnActiveSpan(\n metricType,\n sanitizedName,\n value,\n unit,\n tags,\n bucketKey,\n) {\n const span = getActiveSpan();\n if (span) {\n updateMetricSummaryOnSpan(span, metricType, sanitizedName, value, unit, tags, bucketKey);\n }\n}\n\nexport { TRACE_FLAG_NONE, TRACE_FLAG_SAMPLED, addChildSpanToSpan, getActiveSpan, getRootSpan, getSpanDescendants, getStatusMessage, removeChildSpanFromSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON, spanToTraceContext, spanToTraceHeader, spanToTransactionTraceContext, updateMetricSummaryOnActiveSpan };\n//# sourceMappingURL=spanUtils.js.map\n","import { addGlobalErrorInstrumentationHandler, addGlobalUnhandledRejectionInstrumentationHandler, logger } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build.js';\nimport { getActiveSpan, getRootSpan } from '../utils/spanUtils.js';\nimport { SPAN_STATUS_ERROR } from './spanstatus.js';\n\nlet errorsInstrumented = false;\n\n/**\n * Ensure that global errors automatically set the active span status.\n */\nfunction registerSpanErrorInstrumentation() {\n if (errorsInstrumented) {\n return;\n }\n\n errorsInstrumented = true;\n addGlobalErrorInstrumentationHandler(errorCallback);\n addGlobalUnhandledRejectionInstrumentationHandler(errorCallback);\n}\n\n/**\n * If an error or unhandled promise occurs, we mark the active root span as failed\n */\nfunction errorCallback() {\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n if (rootSpan) {\n const message = 'internal_error';\n DEBUG_BUILD && logger.log(`[Tracing] Root span: ${message} -> Global error occurred`);\n rootSpan.setStatus({ code: SPAN_STATUS_ERROR, message });\n }\n}\n\n// The function name will be lost when bundling but we need to be able to identify this listener later to maintain the\n// node.js default exit behaviour\nerrorCallback.tag = 'sentry_tracingErrorCallback';\n\nexport { registerSpanErrorInstrumentation };\n//# sourceMappingURL=errors.js.map\n","import { addNonEnumerableProperty } from '@sentry/utils';\nexport { stripUrlQueryAndFragment } from '@sentry/utils';\n\nconst SCOPE_ON_START_SPAN_FIELD = '_sentryScope';\nconst ISOLATION_SCOPE_ON_START_SPAN_FIELD = '_sentryIsolationScope';\n\n/** Store the scope & isolation scope for a span, which can the be used when it is finished. */\nfunction setCapturedScopesOnSpan(span, scope, isolationScope) {\n if (span) {\n addNonEnumerableProperty(span, ISOLATION_SCOPE_ON_START_SPAN_FIELD, isolationScope);\n addNonEnumerableProperty(span, SCOPE_ON_START_SPAN_FIELD, scope);\n }\n}\n\n/**\n * Grabs the scope and isolation scope off a span that were active when the span was started.\n */\nfunction getCapturedScopesOnSpan(span) {\n return {\n scope: (span )[SCOPE_ON_START_SPAN_FIELD],\n isolationScope: (span )[ISOLATION_SCOPE_ON_START_SPAN_FIELD],\n };\n}\n\nexport { getCapturedScopesOnSpan, setCapturedScopesOnSpan };\n//# sourceMappingURL=utils.js.map\n","import { getClient } from '../currentScopes.js';\n\n// Treeshakable guard to remove all code related to tracing\n\n/**\n * Determines if tracing is currently enabled.\n *\n * Tracing is enabled when at least one of `tracesSampleRate` and `tracesSampler` is defined in the SDK config.\n */\nfunction hasTracingEnabled(\n maybeOptions,\n) {\n if (typeof __SENTRY_TRACING__ === 'boolean' && !__SENTRY_TRACING__) {\n return false;\n }\n\n const client = getClient();\n const options = maybeOptions || (client && client.getOptions());\n // eslint-disable-next-line deprecation/deprecation\n return !!options && (options.enableTracing || 'tracesSampleRate' in options || 'tracesSampler' in options);\n}\n\nexport { hasTracingEnabled };\n//# sourceMappingURL=hasTracingEnabled.js.map\n","import { uuid4 } from '@sentry/utils';\nimport { TRACE_FLAG_NONE } from '../utils/spanUtils.js';\n\n/**\n * A Sentry Span that is non-recording, meaning it will not be sent to Sentry.\n */\nclass SentryNonRecordingSpan {\n\n constructor(spanContext = {}) {\n this._traceId = spanContext.traceId || uuid4();\n this._spanId = spanContext.spanId || uuid4().substring(16);\n }\n\n /** @inheritdoc */\n spanContext() {\n return {\n spanId: this._spanId,\n traceId: this._traceId,\n traceFlags: TRACE_FLAG_NONE,\n };\n }\n\n /** @inheritdoc */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n end(_timestamp) {}\n\n /** @inheritdoc */\n setAttribute(_key, _value) {\n return this;\n }\n\n /** @inheritdoc */\n setAttributes(_values) {\n return this;\n }\n\n /** @inheritdoc */\n setStatus(_status) {\n return this;\n }\n\n /** @inheritdoc */\n updateName(_name) {\n return this;\n }\n\n /** @inheritdoc */\n isRecording() {\n return false;\n }\n\n /** @inheritdoc */\n addEvent(\n _name,\n _attributesOrStartTime,\n _startTime,\n ) {\n return this;\n }\n\n /**\n * This should generally not be used,\n * but we need it for being compliant with the OTEL Span interface.\n *\n * @hidden\n * @internal\n */\n addLink(_link) {\n return this;\n }\n\n /**\n * This should generally not be used,\n * but we need it for being compliant with the OTEL Span interface.\n *\n * @hidden\n * @internal\n */\n addLinks(_links) {\n return this;\n }\n\n /**\n * This should generally not be used,\n * but we need it for being compliant with the OTEL Span interface.\n *\n * @hidden\n * @internal\n */\n recordException(_exception, _time) {\n // noop\n }\n}\n\nexport { SentryNonRecordingSpan };\n//# sourceMappingURL=sentryNonRecordingSpan.js.map\n","const DEFAULT_ENVIRONMENT = 'production';\n\nexport { DEFAULT_ENVIRONMENT };\n//# sourceMappingURL=constants.js.map\n","import { dropUndefinedKeys, baggageHeaderToDynamicSamplingContext, dynamicSamplingContextToSentryBaggageHeader, addNonEnumerableProperty } from '@sentry/utils';\nimport { DEFAULT_ENVIRONMENT } from '../constants.js';\nimport { getClient } from '../currentScopes.js';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '../semanticAttributes.js';\nimport { hasTracingEnabled } from '../utils/hasTracingEnabled.js';\nimport { spanToJSON, getRootSpan, spanIsSampled } from '../utils/spanUtils.js';\n\n/**\n * If you change this value, also update the terser plugin config to\n * avoid minification of the object property!\n */\nconst FROZEN_DSC_FIELD = '_frozenDsc';\n\n/**\n * Freeze the given DSC on the given span.\n */\nfunction freezeDscOnSpan(span, dsc) {\n const spanWithMaybeDsc = span ;\n addNonEnumerableProperty(spanWithMaybeDsc, FROZEN_DSC_FIELD, dsc);\n}\n\n/**\n * Creates a dynamic sampling context from a client.\n *\n * Dispatches the `createDsc` lifecycle hook as a side effect.\n */\nfunction getDynamicSamplingContextFromClient(trace_id, client) {\n const options = client.getOptions();\n\n const { publicKey: public_key } = client.getDsn() || {};\n\n const dsc = dropUndefinedKeys({\n environment: options.environment || DEFAULT_ENVIRONMENT,\n release: options.release,\n public_key,\n trace_id,\n }) ;\n\n client.emit('createDsc', dsc);\n\n return dsc;\n}\n\n/**\n * Creates a dynamic sampling context from a span (and client and scope)\n *\n * @param span the span from which a few values like the root span name and sample rate are extracted.\n *\n * @returns a dynamic sampling context\n */\nfunction getDynamicSamplingContextFromSpan(span) {\n const client = getClient();\n if (!client) {\n return {};\n }\n\n const dsc = getDynamicSamplingContextFromClient(spanToJSON(span).trace_id || '', client);\n\n const rootSpan = getRootSpan(span);\n\n // For core implementation, we freeze the DSC onto the span as a non-enumerable property\n const frozenDsc = (rootSpan )[FROZEN_DSC_FIELD];\n if (frozenDsc) {\n return frozenDsc;\n }\n\n // For OpenTelemetry, we freeze the DSC on the trace state\n const traceState = rootSpan.spanContext().traceState;\n const traceStateDsc = traceState && traceState.get('sentry.dsc');\n\n // If the span has a DSC, we want it to take precedence\n const dscOnTraceState = traceStateDsc && baggageHeaderToDynamicSamplingContext(traceStateDsc);\n\n if (dscOnTraceState) {\n return dscOnTraceState;\n }\n\n // Else, we generate it from the span\n const jsonSpan = spanToJSON(rootSpan);\n const attributes = jsonSpan.data || {};\n const maybeSampleRate = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE];\n\n if (maybeSampleRate != null) {\n dsc.sample_rate = `${maybeSampleRate}`;\n }\n\n // We don't want to have a transaction name in the DSC if the source is \"url\" because URLs might contain PII\n const source = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];\n\n // after JSON conversion, txn.name becomes jsonSpan.description\n const name = jsonSpan.description;\n if (source !== 'url' && name) {\n dsc.transaction = name;\n }\n\n // How can we even land here with hasTracingEnabled() returning false?\n // Otel creates a Non-recording span in Tracing Without Performance mode when handling incoming requests\n // So we end up with an active span that is not sampled (neither positively nor negatively)\n if (hasTracingEnabled()) {\n dsc.sampled = String(spanIsSampled(rootSpan));\n }\n\n client.emit('createDsc', dsc, rootSpan);\n\n return dsc;\n}\n\n/**\n * Convert a Span to a baggage header.\n */\nfunction spanToBaggageHeader(span) {\n const dsc = getDynamicSamplingContextFromSpan(span);\n return dynamicSamplingContextToSentryBaggageHeader(dsc);\n}\n\nexport { freezeDscOnSpan, getDynamicSamplingContextFromClient, getDynamicSamplingContextFromSpan, spanToBaggageHeader };\n//# sourceMappingURL=dynamicSamplingContext.js.map\n","import { logger } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build.js';\nimport { spanToJSON, spanIsSampled, getRootSpan } from '../utils/spanUtils.js';\n\n/**\n * Print a log message for a started span.\n */\nfunction logSpanStart(span) {\n if (!DEBUG_BUILD) return;\n\n const { description = '< unknown name >', op = '< unknown op >', parent_span_id: parentSpanId } = spanToJSON(span);\n const { spanId } = span.spanContext();\n\n const sampled = spanIsSampled(span);\n const rootSpan = getRootSpan(span);\n const isRootSpan = rootSpan === span;\n\n const header = `[Tracing] Starting ${sampled ? 'sampled' : 'unsampled'} ${isRootSpan ? 'root ' : ''}span`;\n\n const infoParts = [`op: ${op}`, `name: ${description}`, `ID: ${spanId}`];\n\n if (parentSpanId) {\n infoParts.push(`parent ID: ${parentSpanId}`);\n }\n\n if (!isRootSpan) {\n const { op, description } = spanToJSON(rootSpan);\n infoParts.push(`root ID: ${rootSpan.spanContext().spanId}`);\n if (op) {\n infoParts.push(`root op: ${op}`);\n }\n if (description) {\n infoParts.push(`root description: ${description}`);\n }\n }\n\n logger.log(`${header}\n ${infoParts.join('\\n ')}`);\n}\n\n/**\n * Print a log message for an ended span.\n */\nfunction logSpanEnd(span) {\n if (!DEBUG_BUILD) return;\n\n const { description = '< unknown name >', op = '< unknown op >' } = spanToJSON(span);\n const { spanId } = span.spanContext();\n const rootSpan = getRootSpan(span);\n const isRootSpan = rootSpan === span;\n\n const msg = `[Tracing] Finishing \"${op}\" ${isRootSpan ? 'root ' : ''}span \"${description}\" with ID ${spanId}`;\n logger.log(msg);\n}\n\nexport { logSpanEnd, logSpanStart };\n//# sourceMappingURL=logSpans.js.map\n","import { logger } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build.js';\n\n/**\n * Parse a sample rate from a given value.\n * This will either return a boolean or number sample rate, if the sample rate is valid (between 0 and 1).\n * If a string is passed, we try to convert it to a number.\n *\n * Any invalid sample rate will return `undefined`.\n */\nfunction parseSampleRate(sampleRate) {\n if (typeof sampleRate === 'boolean') {\n return Number(sampleRate);\n }\n\n const rate = typeof sampleRate === 'string' ? parseFloat(sampleRate) : sampleRate;\n if (typeof rate !== 'number' || isNaN(rate) || rate < 0 || rate > 1) {\n DEBUG_BUILD &&\n logger.warn(\n `[Tracing] Given sample rate is invalid. Sample rate must be a boolean or a number between 0 and 1. Got ${JSON.stringify(\n sampleRate,\n )} of type ${JSON.stringify(typeof sampleRate)}.`,\n );\n return undefined;\n }\n\n return rate;\n}\n\nexport { parseSampleRate };\n//# sourceMappingURL=parseSampleRate.js.map\n","import { logger } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build.js';\nimport { hasTracingEnabled } from '../utils/hasTracingEnabled.js';\nimport { parseSampleRate } from '../utils/parseSampleRate.js';\n\n/**\n * Makes a sampling decision for the given options.\n *\n * Called every time a root span is created. Only root spans which emerge with a `sampled` value of `true` will be\n * sent to Sentry.\n */\nfunction sampleSpan(\n options,\n samplingContext,\n) {\n // nothing to do if tracing is not enabled\n if (!hasTracingEnabled(options)) {\n return [false];\n }\n\n // we would have bailed already if neither `tracesSampler` nor `tracesSampleRate` nor `enableTracing` were defined, so one of these should\n // work; prefer the hook if so\n let sampleRate;\n if (typeof options.tracesSampler === 'function') {\n sampleRate = options.tracesSampler(samplingContext);\n } else if (samplingContext.parentSampled !== undefined) {\n sampleRate = samplingContext.parentSampled;\n } else if (typeof options.tracesSampleRate !== 'undefined') {\n sampleRate = options.tracesSampleRate;\n } else {\n // When `enableTracing === true`, we use a sample rate of 100%\n sampleRate = 1;\n }\n\n // Since this is coming from the user (or from a function provided by the user), who knows what we might get.\n // (The only valid values are booleans or numbers between 0 and 1.)\n const parsedSampleRate = parseSampleRate(sampleRate);\n\n if (parsedSampleRate === undefined) {\n DEBUG_BUILD && logger.warn('[Tracing] Discarding transaction because of invalid sample rate.');\n return [false];\n }\n\n // if the function returned 0 (or false), or if `tracesSampleRate` is 0, it's a sign the transaction should be dropped\n if (!parsedSampleRate) {\n DEBUG_BUILD &&\n logger.log(\n `[Tracing] Discarding transaction because ${\n typeof options.tracesSampler === 'function'\n ? 'tracesSampler returned 0 or false'\n : 'a negative sampling decision was inherited or tracesSampleRate is set to 0'\n }`,\n );\n return [false, parsedSampleRate];\n }\n\n // Now we roll the dice. Math.random is inclusive of 0, but not of 1, so strict < is safe here. In case sampleRate is\n // a boolean, the < comparison will cause it to be automatically cast to 1 if it's true and 0 if it's false.\n const shouldSample = Math.random() < parsedSampleRate;\n\n // if we're not going to keep it, we're done\n if (!shouldSample) {\n DEBUG_BUILD &&\n logger.log(\n `[Tracing] Discarding transaction because it's not included in the random sample (sampling rate = ${Number(\n sampleRate,\n )})`,\n );\n return [false, parsedSampleRate];\n }\n\n return [true, parsedSampleRate];\n}\n\nexport { sampleSpan };\n//# sourceMappingURL=sampling.js.map\n","import { getSdkMetadataForEnvelopeHeader, dsnToString, createEnvelope, createEventEnvelopeHeaders, createSpanEnvelopeItem } from '@sentry/utils';\nimport { getDynamicSamplingContextFromSpan } from './tracing/dynamicSamplingContext.js';\nimport { spanToJSON } from './utils/spanUtils.js';\n\n/**\n * Apply SdkInfo (name, version, packages, integrations) to the corresponding event key.\n * Merge with existing data if any.\n **/\nfunction enhanceEventWithSdkInfo(event, sdkInfo) {\n if (!sdkInfo) {\n return event;\n }\n event.sdk = event.sdk || {};\n event.sdk.name = event.sdk.name || sdkInfo.name;\n event.sdk.version = event.sdk.version || sdkInfo.version;\n event.sdk.integrations = [...(event.sdk.integrations || []), ...(sdkInfo.integrations || [])];\n event.sdk.packages = [...(event.sdk.packages || []), ...(sdkInfo.packages || [])];\n return event;\n}\n\n/** Creates an envelope from a Session */\nfunction createSessionEnvelope(\n session,\n dsn,\n metadata,\n tunnel,\n) {\n const sdkInfo = getSdkMetadataForEnvelopeHeader(metadata);\n const envelopeHeaders = {\n sent_at: new Date().toISOString(),\n ...(sdkInfo && { sdk: sdkInfo }),\n ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }),\n };\n\n const envelopeItem =\n 'aggregates' in session ? [{ type: 'sessions' }, session] : [{ type: 'session' }, session.toJSON()];\n\n return createEnvelope(envelopeHeaders, [envelopeItem]);\n}\n\n/**\n * Create an Envelope from an event.\n */\nfunction createEventEnvelope(\n event,\n dsn,\n metadata,\n tunnel,\n) {\n const sdkInfo = getSdkMetadataForEnvelopeHeader(metadata);\n\n /*\n Note: Due to TS, event.type may be `replay_event`, theoretically.\n In practice, we never call `createEventEnvelope` with `replay_event` type,\n and we'd have to adjust a looot of types to make this work properly.\n We want to avoid casting this around, as that could lead to bugs (e.g. when we add another type)\n So the safe choice is to really guard against the replay_event type here.\n */\n const eventType = event.type && event.type !== 'replay_event' ? event.type : 'event';\n\n enhanceEventWithSdkInfo(event, metadata && metadata.sdk);\n\n const envelopeHeaders = createEventEnvelopeHeaders(event, sdkInfo, tunnel, dsn);\n\n // Prevent this data (which, if it exists, was used in earlier steps in the processing pipeline) from being sent to\n // sentry. (Note: Our use of this property comes and goes with whatever we might be debugging, whatever hacks we may\n // have temporarily added, etc. Even if we don't happen to be using it at some point in the future, let's not get rid\n // of this `delete`, lest we miss putting it back in the next time the property is in use.)\n delete event.sdkProcessingMetadata;\n\n const eventItem = [{ type: eventType }, event];\n return createEnvelope(envelopeHeaders, [eventItem]);\n}\n\n/**\n * Create envelope from Span item.\n *\n * Takes an optional client and runs spans through `beforeSendSpan` if available.\n */\nfunction createSpanEnvelope(spans, client) {\n function dscHasRequiredProps(dsc) {\n return !!dsc.trace_id && !!dsc.public_key;\n }\n\n // For the moment we'll obtain the DSC from the first span in the array\n // This might need to be changed if we permit sending multiple spans from\n // different segments in one envelope\n const dsc = getDynamicSamplingContextFromSpan(spans[0]);\n\n const dsn = client && client.getDsn();\n const tunnel = client && client.getOptions().tunnel;\n\n const headers = {\n sent_at: new Date().toISOString(),\n ...(dscHasRequiredProps(dsc) && { trace: dsc }),\n ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }),\n };\n\n const beforeSendSpan = client && client.getOptions().beforeSendSpan;\n const convertToSpanJSON = beforeSendSpan\n ? (span) => beforeSendSpan(spanToJSON(span) )\n : (span) => spanToJSON(span);\n\n const items = [];\n for (const span of spans) {\n const spanJson = convertToSpanJSON(span);\n if (spanJson) {\n items.push(createSpanEnvelopeItem(spanJson));\n }\n }\n\n return createEnvelope(headers, items);\n}\n\nexport { createEventEnvelope, createSessionEnvelope, createSpanEnvelope };\n//# sourceMappingURL=envelope.js.map\n","import { SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT } from '../semanticAttributes.js';\nimport { getRootSpan, getActiveSpan } from '../utils/spanUtils.js';\n\n/**\n * Adds a measurement to the active transaction on the current global scope. You can optionally pass in a different span\n * as the 4th parameter.\n */\nfunction setMeasurement(name, value, unit, activeSpan = getActiveSpan()) {\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n if (rootSpan) {\n rootSpan.addEvent(name, {\n [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE]: value,\n [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT]: unit ,\n });\n }\n}\n\n/**\n * Convert timed events to measurements.\n */\nfunction timedEventsToMeasurements(events) {\n if (!events || events.length === 0) {\n return undefined;\n }\n\n const measurements = {};\n events.forEach(event => {\n const attributes = event.attributes || {};\n const unit = attributes[SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT] ;\n const value = attributes[SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE] ;\n\n if (typeof unit === 'string' && typeof value === 'number') {\n measurements[event.name] = { value, unit };\n }\n });\n\n return measurements;\n}\n\nexport { setMeasurement, timedEventsToMeasurements };\n//# sourceMappingURL=measurement.js.map\n","import { uuid4, timestampInSeconds, dropUndefinedKeys, logger } from '@sentry/utils';\nimport { getClient, getCurrentScope } from '../currentScopes.js';\nimport { DEBUG_BUILD } from '../debug-build.js';\nimport { createSpanEnvelope } from '../envelope.js';\nimport { getMetricSummaryJsonForSpan } from '../metrics/metric-summary.js';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_PROFILE_ID, SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME } from '../semanticAttributes.js';\nimport { TRACE_FLAG_SAMPLED, TRACE_FLAG_NONE, spanTimeInputToSeconds, getStatusMessage, getRootSpan, spanToJSON, getSpanDescendants, spanToTransactionTraceContext } from '../utils/spanUtils.js';\nimport { getDynamicSamplingContextFromSpan } from './dynamicSamplingContext.js';\nimport { logSpanEnd } from './logSpans.js';\nimport { timedEventsToMeasurements } from './measurement.js';\nimport { getCapturedScopesOnSpan } from './utils.js';\n\nconst MAX_SPAN_COUNT = 1000;\n\n/**\n * Span contains all data about a span\n */\nclass SentrySpan {\n\n /** Epoch timestamp in seconds when the span started. */\n\n /** Epoch timestamp in seconds when the span ended. */\n\n /** Internal keeper of the status */\n\n /** The timed events added to this span. */\n\n /** if true, treat span as a standalone span (not part of a transaction) */\n\n /**\n * You should never call the constructor manually, always use `Sentry.startSpan()`\n * or other span methods.\n * @internal\n * @hideconstructor\n * @hidden\n */\n constructor(spanContext = {}) {\n this._traceId = spanContext.traceId || uuid4();\n this._spanId = spanContext.spanId || uuid4().substring(16);\n this._startTime = spanContext.startTimestamp || timestampInSeconds();\n\n this._attributes = {};\n this.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: spanContext.op,\n ...spanContext.attributes,\n });\n\n this._name = spanContext.name;\n\n if (spanContext.parentSpanId) {\n this._parentSpanId = spanContext.parentSpanId;\n }\n // We want to include booleans as well here\n if ('sampled' in spanContext) {\n this._sampled = spanContext.sampled;\n }\n if (spanContext.endTimestamp) {\n this._endTime = spanContext.endTimestamp;\n }\n\n this._events = [];\n\n this._isStandaloneSpan = spanContext.isStandalone;\n\n // If the span is already ended, ensure we finalize the span immediately\n if (this._endTime) {\n this._onSpanEnded();\n }\n }\n\n /**\n * This should generally not be used,\n * but it is needed for being compliant with the OTEL Span interface.\n *\n * @hidden\n * @internal\n */\n addLink(_link) {\n return this;\n }\n\n /**\n * This should generally not be used,\n * but it is needed for being compliant with the OTEL Span interface.\n *\n * @hidden\n * @internal\n */\n addLinks(_links) {\n return this;\n }\n\n /**\n * This should generally not be used,\n * but it is needed for being compliant with the OTEL Span interface.\n *\n * @hidden\n * @internal\n */\n recordException(_exception, _time) {\n // noop\n }\n\n /** @inheritdoc */\n spanContext() {\n const { _spanId: spanId, _traceId: traceId, _sampled: sampled } = this;\n return {\n spanId,\n traceId,\n traceFlags: sampled ? TRACE_FLAG_SAMPLED : TRACE_FLAG_NONE,\n };\n }\n\n /** @inheritdoc */\n setAttribute(key, value) {\n if (value === undefined) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete this._attributes[key];\n } else {\n this._attributes[key] = value;\n }\n\n return this;\n }\n\n /** @inheritdoc */\n setAttributes(attributes) {\n Object.keys(attributes).forEach(key => this.setAttribute(key, attributes[key]));\n return this;\n }\n\n /**\n * This should generally not be used,\n * but we need it for browser tracing where we want to adjust the start time afterwards.\n * USE THIS WITH CAUTION!\n *\n * @hidden\n * @internal\n */\n updateStartTime(timeInput) {\n this._startTime = spanTimeInputToSeconds(timeInput);\n }\n\n /**\n * @inheritDoc\n */\n setStatus(value) {\n this._status = value;\n return this;\n }\n\n /**\n * @inheritDoc\n */\n updateName(name) {\n this._name = name;\n this.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'custom');\n return this;\n }\n\n /** @inheritdoc */\n end(endTimestamp) {\n // If already ended, skip\n if (this._endTime) {\n return;\n }\n\n this._endTime = spanTimeInputToSeconds(endTimestamp);\n logSpanEnd(this);\n\n this._onSpanEnded();\n }\n\n /**\n * Get JSON representation of this span.\n *\n * @hidden\n * @internal This method is purely for internal purposes and should not be used outside\n * of SDK code. If you need to get a JSON representation of a span,\n * use `spanToJSON(span)` instead.\n */\n getSpanJSON() {\n return dropUndefinedKeys({\n data: this._attributes,\n description: this._name,\n op: this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP],\n parent_span_id: this._parentSpanId,\n span_id: this._spanId,\n start_timestamp: this._startTime,\n status: getStatusMessage(this._status),\n timestamp: this._endTime,\n trace_id: this._traceId,\n origin: this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] ,\n _metrics_summary: getMetricSummaryJsonForSpan(this),\n profile_id: this._attributes[SEMANTIC_ATTRIBUTE_PROFILE_ID] ,\n exclusive_time: this._attributes[SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME] ,\n measurements: timedEventsToMeasurements(this._events),\n is_segment: (this._isStandaloneSpan && getRootSpan(this) === this) || undefined,\n segment_id: this._isStandaloneSpan ? getRootSpan(this).spanContext().spanId : undefined,\n });\n }\n\n /** @inheritdoc */\n isRecording() {\n return !this._endTime && !!this._sampled;\n }\n\n /**\n * @inheritdoc\n */\n addEvent(\n name,\n attributesOrStartTime,\n startTime,\n ) {\n DEBUG_BUILD && logger.log('[Tracing] Adding an event to span:', name);\n\n const time = isSpanTimeInput(attributesOrStartTime) ? attributesOrStartTime : startTime || timestampInSeconds();\n const attributes = isSpanTimeInput(attributesOrStartTime) ? {} : attributesOrStartTime || {};\n\n const event = {\n name,\n time: spanTimeInputToSeconds(time),\n attributes,\n };\n\n this._events.push(event);\n\n return this;\n }\n\n /**\n * This method should generally not be used,\n * but for now we need a way to publicly check if the `_isStandaloneSpan` flag is set.\n * USE THIS WITH CAUTION!\n * @internal\n * @hidden\n * @experimental\n */\n isStandaloneSpan() {\n return !!this._isStandaloneSpan;\n }\n\n /** Emit `spanEnd` when the span is ended. */\n _onSpanEnded() {\n const client = getClient();\n if (client) {\n client.emit('spanEnd', this);\n }\n\n // A segment span is basically the root span of a local span tree.\n // So for now, this is either what we previously refer to as the root span,\n // or a standalone span.\n const isSegmentSpan = this._isStandaloneSpan || this === getRootSpan(this);\n\n if (!isSegmentSpan) {\n return;\n }\n\n // if this is a standalone span, we send it immediately\n if (this._isStandaloneSpan) {\n if (this._sampled) {\n sendSpanEnvelope(createSpanEnvelope([this], client));\n } else {\n DEBUG_BUILD &&\n logger.log('[Tracing] Discarding standalone span because its trace was not chosen to be sampled.');\n if (client) {\n client.recordDroppedEvent('sample_rate', 'span');\n }\n }\n return;\n }\n\n const transactionEvent = this._convertSpanToTransaction();\n if (transactionEvent) {\n const scope = getCapturedScopesOnSpan(this).scope || getCurrentScope();\n scope.captureEvent(transactionEvent);\n }\n }\n\n /**\n * Finish the transaction & prepare the event to send to Sentry.\n */\n _convertSpanToTransaction() {\n // We can only convert finished spans\n if (!isFullFinishedSpan(spanToJSON(this))) {\n return undefined;\n }\n\n if (!this._name) {\n DEBUG_BUILD && logger.warn('Transaction has no name, falling back to ``.');\n this._name = '';\n }\n\n const { scope: capturedSpanScope, isolationScope: capturedSpanIsolationScope } = getCapturedScopesOnSpan(this);\n const scope = capturedSpanScope || getCurrentScope();\n const client = scope.getClient() || getClient();\n\n if (this._sampled !== true) {\n // At this point if `sampled !== true` we want to discard the transaction.\n DEBUG_BUILD && logger.log('[Tracing] Discarding transaction because its trace was not chosen to be sampled.');\n\n if (client) {\n client.recordDroppedEvent('sample_rate', 'transaction');\n }\n\n return undefined;\n }\n\n // The transaction span itself as well as any potential standalone spans should be filtered out\n const finishedSpans = getSpanDescendants(this).filter(span => span !== this && !isStandaloneSpan(span));\n\n const spans = finishedSpans.map(span => spanToJSON(span)).filter(isFullFinishedSpan);\n\n const source = this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] ;\n\n const transaction = {\n contexts: {\n trace: spanToTransactionTraceContext(this),\n },\n spans:\n // spans.sort() mutates the array, but `spans` is already a copy so we can safely do this here\n // we do not use spans anymore after this point\n spans.length > MAX_SPAN_COUNT\n ? spans.sort((a, b) => a.start_timestamp - b.start_timestamp).slice(0, MAX_SPAN_COUNT)\n : spans,\n start_timestamp: this._startTime,\n timestamp: this._endTime,\n transaction: this._name,\n type: 'transaction',\n sdkProcessingMetadata: {\n capturedSpanScope,\n capturedSpanIsolationScope,\n ...dropUndefinedKeys({\n dynamicSamplingContext: getDynamicSamplingContextFromSpan(this),\n }),\n },\n _metrics_summary: getMetricSummaryJsonForSpan(this),\n ...(source && {\n transaction_info: {\n source,\n },\n }),\n };\n\n const measurements = timedEventsToMeasurements(this._events);\n const hasMeasurements = measurements && Object.keys(measurements).length;\n\n if (hasMeasurements) {\n DEBUG_BUILD &&\n logger.log(\n '[Measurements] Adding measurements to transaction event',\n JSON.stringify(measurements, undefined, 2),\n );\n transaction.measurements = measurements;\n }\n\n return transaction;\n }\n}\n\nfunction isSpanTimeInput(value) {\n return (value && typeof value === 'number') || value instanceof Date || Array.isArray(value);\n}\n\n// We want to filter out any incomplete SpanJSON objects\nfunction isFullFinishedSpan(input) {\n return !!input.start_timestamp && !!input.timestamp && !!input.span_id && !!input.trace_id;\n}\n\n/** `SentrySpan`s can be sent as a standalone span rather than belonging to a transaction */\nfunction isStandaloneSpan(span) {\n return span instanceof SentrySpan && span.isStandaloneSpan();\n}\n\n/**\n * Sends a `SpanEnvelope`.\n *\n * Note: If the envelope's spans are dropped, e.g. via `beforeSendSpan`,\n * the envelope will not be sent either.\n */\nfunction sendSpanEnvelope(envelope) {\n const client = getClient();\n if (!client) {\n return;\n }\n\n const spanItems = envelope[1];\n if (!spanItems || spanItems.length === 0) {\n client.recordDroppedEvent('before_send', 'span');\n return;\n }\n\n // sendEnvelope should not throw\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n client.sendEnvelope(envelope);\n}\n\nexport { SentrySpan };\n//# sourceMappingURL=sentrySpan.js.map\n","import { propagationContextFromHeaders, generatePropagationContext, logger } from '@sentry/utils';\nimport { getMainCarrier } from '../carrier.js';\nimport { withScope, getCurrentScope, getIsolationScope, getClient } from '../currentScopes.js';\nimport { getAsyncContextStrategy } from '../asyncContext/index.js';\nimport { DEBUG_BUILD } from '../debug-build.js';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE } from '../semanticAttributes.js';\nimport { handleCallbackErrors } from '../utils/handleCallbackErrors.js';\nimport { hasTracingEnabled } from '../utils/hasTracingEnabled.js';\nimport { _setSpanForScope, _getSpanForScope } from '../utils/spanOnScope.js';\nimport { spanToJSON, addChildSpanToSpan, spanIsSampled, spanTimeInputToSeconds, getRootSpan } from '../utils/spanUtils.js';\nimport { getDynamicSamplingContextFromSpan, freezeDscOnSpan } from './dynamicSamplingContext.js';\nimport { logSpanStart } from './logSpans.js';\nimport { sampleSpan } from './sampling.js';\nimport { SentryNonRecordingSpan } from './sentryNonRecordingSpan.js';\nimport { SentrySpan } from './sentrySpan.js';\nimport { SPAN_STATUS_ERROR } from './spanstatus.js';\nimport { setCapturedScopesOnSpan } from './utils.js';\n\nconst SUPPRESS_TRACING_KEY = '__SENTRY_SUPPRESS_TRACING__';\n\n/**\n * Wraps a function with a transaction/span and finishes the span after the function is done.\n * The created span is the active span and will be used as parent by other spans created inside the function\n * and can be accessed via `Sentry.getActiveSpan()`, as long as the function is executed while the scope is active.\n *\n * If you want to create a span that is not set as active, use {@link startInactiveSpan}.\n *\n * You'll always get a span passed to the callback,\n * it may just be a non-recording span if the span is not sampled or if tracing is disabled.\n */\nfunction startSpan(options, callback) {\n const acs = getAcs();\n if (acs.startSpan) {\n return acs.startSpan(options, callback);\n }\n\n const spanArguments = parseSentrySpanArguments(options);\n const { forceTransaction, parentSpan: customParentSpan } = options;\n\n return withScope(options.scope, () => {\n // If `options.parentSpan` is defined, we want to wrap the callback in `withActiveSpan`\n const wrapper = getActiveSpanWrapper(customParentSpan);\n\n return wrapper(() => {\n const scope = getCurrentScope();\n const parentSpan = getParentSpan(scope);\n\n const shouldSkipSpan = options.onlyIfParent && !parentSpan;\n const activeSpan = shouldSkipSpan\n ? new SentryNonRecordingSpan()\n : createChildOrRootSpan({\n parentSpan,\n spanArguments,\n forceTransaction,\n scope,\n });\n\n _setSpanForScope(scope, activeSpan);\n\n return handleCallbackErrors(\n () => callback(activeSpan),\n () => {\n // Only update the span status if it hasn't been changed yet, and the span is not yet finished\n const { status } = spanToJSON(activeSpan);\n if (activeSpan.isRecording() && (!status || status === 'ok')) {\n activeSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n },\n () => activeSpan.end(),\n );\n });\n });\n}\n\n/**\n * Similar to `Sentry.startSpan`. Wraps a function with a transaction/span, but does not finish the span\n * after the function is done automatically. You'll have to call `span.end()` manually.\n *\n * The created span is the active span and will be used as parent by other spans created inside the function\n * and can be accessed via `Sentry.getActiveSpan()`, as long as the function is executed while the scope is active.\n *\n * You'll always get a span passed to the callback,\n * it may just be a non-recording span if the span is not sampled or if tracing is disabled.\n */\nfunction startSpanManual(options, callback) {\n const acs = getAcs();\n if (acs.startSpanManual) {\n return acs.startSpanManual(options, callback);\n }\n\n const spanArguments = parseSentrySpanArguments(options);\n const { forceTransaction, parentSpan: customParentSpan } = options;\n\n return withScope(options.scope, () => {\n // If `options.parentSpan` is defined, we want to wrap the callback in `withActiveSpan`\n const wrapper = getActiveSpanWrapper(customParentSpan);\n\n return wrapper(() => {\n const scope = getCurrentScope();\n const parentSpan = getParentSpan(scope);\n\n const shouldSkipSpan = options.onlyIfParent && !parentSpan;\n const activeSpan = shouldSkipSpan\n ? new SentryNonRecordingSpan()\n : createChildOrRootSpan({\n parentSpan,\n spanArguments,\n forceTransaction,\n scope,\n });\n\n _setSpanForScope(scope, activeSpan);\n\n function finishAndSetSpan() {\n activeSpan.end();\n }\n\n return handleCallbackErrors(\n () => callback(activeSpan, finishAndSetSpan),\n () => {\n // Only update the span status if it hasn't been changed yet, and the span is not yet finished\n const { status } = spanToJSON(activeSpan);\n if (activeSpan.isRecording() && (!status || status === 'ok')) {\n activeSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n },\n );\n });\n });\n}\n\n/**\n * Creates a span. This span is not set as active, so will not get automatic instrumentation spans\n * as children or be able to be accessed via `Sentry.getActiveSpan()`.\n *\n * If you want to create a span that is set as active, use {@link startSpan}.\n *\n * This function will always return a span,\n * it may just be a non-recording span if the span is not sampled or if tracing is disabled.\n */\nfunction startInactiveSpan(options) {\n const acs = getAcs();\n if (acs.startInactiveSpan) {\n return acs.startInactiveSpan(options);\n }\n\n const spanArguments = parseSentrySpanArguments(options);\n const { forceTransaction, parentSpan: customParentSpan } = options;\n\n // If `options.scope` is defined, we use this as as a wrapper,\n // If `options.parentSpan` is defined, we want to wrap the callback in `withActiveSpan`\n const wrapper = options.scope\n ? (callback) => withScope(options.scope, callback)\n : customParentSpan !== undefined\n ? (callback) => withActiveSpan(customParentSpan, callback)\n : (callback) => callback();\n\n return wrapper(() => {\n const scope = getCurrentScope();\n const parentSpan = getParentSpan(scope);\n\n const shouldSkipSpan = options.onlyIfParent && !parentSpan;\n\n if (shouldSkipSpan) {\n return new SentryNonRecordingSpan();\n }\n\n return createChildOrRootSpan({\n parentSpan,\n spanArguments,\n forceTransaction,\n scope,\n });\n });\n}\n\n/**\n * Continue a trace from `sentry-trace` and `baggage` values.\n * These values can be obtained from incoming request headers, or in the browser from ``\n * and `` HTML tags.\n *\n * Spans started with `startSpan`, `startSpanManual` and `startInactiveSpan`, within the callback will automatically\n * be attached to the incoming trace.\n */\nconst continueTrace = (\n {\n sentryTrace,\n baggage,\n }\n\n,\n callback,\n) => {\n return withScope(scope => {\n const propagationContext = propagationContextFromHeaders(sentryTrace, baggage);\n scope.setPropagationContext(propagationContext);\n return callback();\n });\n};\n\n/**\n * Forks the current scope and sets the provided span as active span in the context of the provided callback. Can be\n * passed `null` to start an entirely new span tree.\n *\n * @param span Spans started in the context of the provided callback will be children of this span. If `null` is passed,\n * spans started within the callback will not be attached to a parent span.\n * @param callback Execution context in which the provided span will be active. Is passed the newly forked scope.\n * @returns the value returned from the provided callback function.\n */\nfunction withActiveSpan(span, callback) {\n const acs = getAcs();\n if (acs.withActiveSpan) {\n return acs.withActiveSpan(span, callback);\n }\n\n return withScope(scope => {\n _setSpanForScope(scope, span || undefined);\n return callback(scope);\n });\n}\n\n/** Suppress tracing in the given callback, ensuring no spans are generated inside of it. */\nfunction suppressTracing(callback) {\n const acs = getAcs();\n\n if (acs.suppressTracing) {\n return acs.suppressTracing(callback);\n }\n\n return withScope(scope => {\n scope.setSDKProcessingMetadata({ [SUPPRESS_TRACING_KEY]: true });\n return callback();\n });\n}\n\n/**\n * Starts a new trace for the duration of the provided callback. Spans started within the\n * callback will be part of the new trace instead of a potentially previously started trace.\n *\n * Important: Only use this function if you want to override the default trace lifetime and\n * propagation mechanism of the SDK for the duration and scope of the provided callback.\n * The newly created trace will also be the root of a new distributed trace, for example if\n * you make http requests within the callback.\n * This function might be useful if the operation you want to instrument should not be part\n * of a potentially ongoing trace.\n *\n * Default behavior:\n * - Server-side: A new trace is started for each incoming request.\n * - Browser: A new trace is started for each page our route. Navigating to a new route\n * or page will automatically create a new trace.\n */\nfunction startNewTrace(callback) {\n return withScope(scope => {\n scope.setPropagationContext(generatePropagationContext());\n DEBUG_BUILD && logger.info(`Starting a new trace with id ${scope.getPropagationContext().traceId}`);\n return withActiveSpan(null, callback);\n });\n}\n\nfunction createChildOrRootSpan({\n parentSpan,\n spanArguments,\n forceTransaction,\n scope,\n}\n\n) {\n if (!hasTracingEnabled()) {\n return new SentryNonRecordingSpan();\n }\n\n const isolationScope = getIsolationScope();\n\n let span;\n if (parentSpan && !forceTransaction) {\n span = _startChildSpan(parentSpan, scope, spanArguments);\n addChildSpanToSpan(parentSpan, span);\n } else if (parentSpan) {\n // If we forced a transaction but have a parent span, make sure to continue from the parent span, not the scope\n const dsc = getDynamicSamplingContextFromSpan(parentSpan);\n const { traceId, spanId: parentSpanId } = parentSpan.spanContext();\n const parentSampled = spanIsSampled(parentSpan);\n\n span = _startRootSpan(\n {\n traceId,\n parentSpanId,\n ...spanArguments,\n },\n scope,\n parentSampled,\n );\n\n freezeDscOnSpan(span, dsc);\n } else {\n const {\n traceId,\n dsc,\n parentSpanId,\n sampled: parentSampled,\n } = {\n ...isolationScope.getPropagationContext(),\n ...scope.getPropagationContext(),\n };\n\n span = _startRootSpan(\n {\n traceId,\n parentSpanId,\n ...spanArguments,\n },\n scope,\n parentSampled,\n );\n\n if (dsc) {\n freezeDscOnSpan(span, dsc);\n }\n }\n\n logSpanStart(span);\n\n setCapturedScopesOnSpan(span, scope, isolationScope);\n\n return span;\n}\n\n/**\n * This converts StartSpanOptions to SentrySpanArguments.\n * For the most part (for now) we accept the same options,\n * but some of them need to be transformed.\n */\nfunction parseSentrySpanArguments(options) {\n const exp = options.experimental || {};\n const initialCtx = {\n isStandalone: exp.standalone,\n ...options,\n };\n\n if (options.startTime) {\n const ctx = { ...initialCtx };\n ctx.startTimestamp = spanTimeInputToSeconds(options.startTime);\n delete ctx.startTime;\n return ctx;\n }\n\n return initialCtx;\n}\n\nfunction getAcs() {\n const carrier = getMainCarrier();\n return getAsyncContextStrategy(carrier);\n}\n\nfunction _startRootSpan(spanArguments, scope, parentSampled) {\n const client = getClient();\n const options = (client && client.getOptions()) || {};\n\n const { name = '', attributes } = spanArguments;\n const [sampled, sampleRate] = scope.getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY]\n ? [false]\n : sampleSpan(options, {\n name,\n parentSampled,\n attributes,\n transactionContext: {\n name,\n parentSampled,\n },\n });\n\n const rootSpan = new SentrySpan({\n ...spanArguments,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom',\n ...spanArguments.attributes,\n },\n sampled,\n });\n if (sampleRate !== undefined) {\n rootSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, sampleRate);\n }\n\n if (client) {\n client.emit('spanStart', rootSpan);\n }\n\n return rootSpan;\n}\n\n/**\n * Creates a new `Span` while setting the current `Span.id` as `parentSpanId`.\n * This inherits the sampling decision from the parent span.\n */\nfunction _startChildSpan(parentSpan, scope, spanArguments) {\n const { spanId, traceId } = parentSpan.spanContext();\n const sampled = scope.getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY] ? false : spanIsSampled(parentSpan);\n\n const childSpan = sampled\n ? new SentrySpan({\n ...spanArguments,\n parentSpanId: spanId,\n traceId,\n sampled,\n })\n : new SentryNonRecordingSpan({ traceId });\n\n addChildSpanToSpan(parentSpan, childSpan);\n\n const client = getClient();\n if (client) {\n client.emit('spanStart', childSpan);\n // If it has an endTimestamp, it's already ended\n if (spanArguments.endTimestamp) {\n client.emit('spanEnd', childSpan);\n }\n }\n\n return childSpan;\n}\n\nfunction getParentSpan(scope) {\n const span = _getSpanForScope(scope) ;\n\n if (!span) {\n return undefined;\n }\n\n const client = getClient();\n const options = client ? client.getOptions() : {};\n if (options.parentSpanIsAlwaysRootSpan) {\n return getRootSpan(span) ;\n }\n\n return span;\n}\n\nfunction getActiveSpanWrapper(parentSpan) {\n return parentSpan !== undefined\n ? (callback) => {\n return withActiveSpan(parentSpan, callback);\n }\n : (callback) => callback();\n}\n\nexport { continueTrace, startInactiveSpan, startNewTrace, startSpan, startSpanManual, suppressTracing, withActiveSpan };\n//# sourceMappingURL=trace.js.map\n","import { timestampInSeconds, logger } from '@sentry/utils';\nimport { getClient, getCurrentScope } from '../currentScopes.js';\nimport { DEBUG_BUILD } from '../debug-build.js';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON } from '../semanticAttributes.js';\nimport { hasTracingEnabled } from '../utils/hasTracingEnabled.js';\nimport { _setSpanForScope } from '../utils/spanOnScope.js';\nimport { getActiveSpan, spanTimeInputToSeconds, getSpanDescendants, spanToJSON, removeChildSpanFromSpan } from '../utils/spanUtils.js';\nimport { SentryNonRecordingSpan } from './sentryNonRecordingSpan.js';\nimport { SPAN_STATUS_ERROR } from './spanstatus.js';\nimport { startInactiveSpan } from './trace.js';\n\nconst TRACING_DEFAULTS = {\n idleTimeout: 1000,\n finalTimeout: 30000,\n childSpanTimeout: 15000,\n};\n\nconst FINISH_REASON_HEARTBEAT_FAILED = 'heartbeatFailed';\nconst FINISH_REASON_IDLE_TIMEOUT = 'idleTimeout';\nconst FINISH_REASON_FINAL_TIMEOUT = 'finalTimeout';\nconst FINISH_REASON_EXTERNAL_FINISH = 'externalFinish';\n\n/**\n * An idle span is a span that automatically finishes. It does this by tracking child spans as activities.\n * An idle span is always the active span.\n */\nfunction startIdleSpan(startSpanOptions, options = {}) {\n // Activities store a list of active spans\n const activities = new Map();\n\n // We should not use heartbeat if we finished a span\n let _finished = false;\n\n // Timer that tracks idleTimeout\n let _idleTimeoutID;\n\n // The reason why the span was finished\n let _finishReason = FINISH_REASON_EXTERNAL_FINISH;\n\n let _autoFinishAllowed = !options.disableAutoFinish;\n\n const _cleanupHooks = [];\n\n const {\n idleTimeout = TRACING_DEFAULTS.idleTimeout,\n finalTimeout = TRACING_DEFAULTS.finalTimeout,\n childSpanTimeout = TRACING_DEFAULTS.childSpanTimeout,\n beforeSpanEnd,\n } = options;\n\n const client = getClient();\n\n if (!client || !hasTracingEnabled()) {\n return new SentryNonRecordingSpan();\n }\n\n const scope = getCurrentScope();\n const previousActiveSpan = getActiveSpan();\n const span = _startIdleSpan(startSpanOptions);\n\n // We patch span.end to ensure we can run some things before the span is ended\n // eslint-disable-next-line @typescript-eslint/unbound-method\n span.end = new Proxy(span.end, {\n apply(target, thisArg, args) {\n if (beforeSpanEnd) {\n beforeSpanEnd(span);\n }\n\n // Just ensuring that this keeps working, even if we ever have more arguments here\n const [definedEndTimestamp, ...rest] = args;\n const timestamp = definedEndTimestamp || timestampInSeconds();\n const spanEndTimestamp = spanTimeInputToSeconds(timestamp);\n\n // Ensure we end with the last span timestamp, if possible\n const spans = getSpanDescendants(span).filter(child => child !== span);\n\n // If we have no spans, we just end, nothing else to do here\n if (!spans.length) {\n onIdleSpanEnded(spanEndTimestamp);\n return Reflect.apply(target, thisArg, [spanEndTimestamp, ...rest]);\n }\n\n const childEndTimestamps = spans\n .map(span => spanToJSON(span).timestamp)\n .filter(timestamp => !!timestamp) ;\n const latestSpanEndTimestamp = childEndTimestamps.length ? Math.max(...childEndTimestamps) : undefined;\n\n // In reality this should always exist here, but type-wise it may be undefined...\n const spanStartTimestamp = spanToJSON(span).start_timestamp;\n\n // The final endTimestamp should:\n // * Never be before the span start timestamp\n // * Be the latestSpanEndTimestamp, if there is one, and it is smaller than the passed span end timestamp\n // * Otherwise be the passed end timestamp\n // Final timestamp can never be after finalTimeout\n const endTimestamp = Math.min(\n spanStartTimestamp ? spanStartTimestamp + finalTimeout / 1000 : Infinity,\n Math.max(spanStartTimestamp || -Infinity, Math.min(spanEndTimestamp, latestSpanEndTimestamp || Infinity)),\n );\n\n onIdleSpanEnded(endTimestamp);\n return Reflect.apply(target, thisArg, [endTimestamp, ...rest]);\n },\n });\n\n /**\n * Cancels the existing idle timeout, if there is one.\n */\n function _cancelIdleTimeout() {\n if (_idleTimeoutID) {\n clearTimeout(_idleTimeoutID);\n _idleTimeoutID = undefined;\n }\n }\n\n /**\n * Restarts idle timeout, if there is no running idle timeout it will start one.\n */\n function _restartIdleTimeout(endTimestamp) {\n _cancelIdleTimeout();\n _idleTimeoutID = setTimeout(() => {\n if (!_finished && activities.size === 0 && _autoFinishAllowed) {\n _finishReason = FINISH_REASON_IDLE_TIMEOUT;\n span.end(endTimestamp);\n }\n }, idleTimeout);\n }\n\n /**\n * Restarts child span timeout, if there is none running it will start one.\n */\n function _restartChildSpanTimeout(endTimestamp) {\n _idleTimeoutID = setTimeout(() => {\n if (!_finished && _autoFinishAllowed) {\n _finishReason = FINISH_REASON_HEARTBEAT_FAILED;\n span.end(endTimestamp);\n }\n }, childSpanTimeout);\n }\n\n /**\n * Start tracking a specific activity.\n * @param spanId The span id that represents the activity\n */\n function _pushActivity(spanId) {\n _cancelIdleTimeout();\n activities.set(spanId, true);\n\n const endTimestamp = timestampInSeconds();\n // We need to add the timeout here to have the real endtimestamp of the idle span\n // Remember timestampInSeconds is in seconds, timeout is in ms\n _restartChildSpanTimeout(endTimestamp + childSpanTimeout / 1000);\n }\n\n /**\n * Remove an activity from usage\n * @param spanId The span id that represents the activity\n */\n function _popActivity(spanId) {\n if (activities.has(spanId)) {\n activities.delete(spanId);\n }\n\n if (activities.size === 0) {\n const endTimestamp = timestampInSeconds();\n // We need to add the timeout here to have the real endtimestamp of the idle span\n // Remember timestampInSeconds is in seconds, timeout is in ms\n _restartIdleTimeout(endTimestamp + idleTimeout / 1000);\n }\n }\n\n function onIdleSpanEnded(endTimestamp) {\n _finished = true;\n activities.clear();\n\n _cleanupHooks.forEach(cleanup => cleanup());\n\n _setSpanForScope(scope, previousActiveSpan);\n\n const spanJSON = spanToJSON(span);\n\n const { start_timestamp: startTimestamp } = spanJSON;\n // This should never happen, but to make TS happy...\n if (!startTimestamp) {\n return;\n }\n\n const attributes = spanJSON.data || {};\n if (!attributes[SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON]) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, _finishReason);\n }\n\n logger.log(`[Tracing] Idle span \"${spanJSON.op}\" finished`);\n\n const childSpans = getSpanDescendants(span).filter(child => child !== span);\n\n let discardedSpans = 0;\n childSpans.forEach(childSpan => {\n // We cancel all pending spans with status \"cancelled\" to indicate the idle span was finished early\n if (childSpan.isRecording()) {\n childSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'cancelled' });\n childSpan.end(endTimestamp);\n DEBUG_BUILD &&\n logger.log('[Tracing] Cancelling span since span ended early', JSON.stringify(childSpan, undefined, 2));\n }\n\n const childSpanJSON = spanToJSON(childSpan);\n const { timestamp: childEndTimestamp = 0, start_timestamp: childStartTimestamp = 0 } = childSpanJSON;\n\n const spanStartedBeforeIdleSpanEnd = childStartTimestamp <= endTimestamp;\n\n // Add a delta with idle timeout so that we prevent false positives\n const timeoutWithMarginOfError = (finalTimeout + idleTimeout) / 1000;\n const spanEndedBeforeFinalTimeout = childEndTimestamp - childStartTimestamp <= timeoutWithMarginOfError;\n\n if (DEBUG_BUILD) {\n const stringifiedSpan = JSON.stringify(childSpan, undefined, 2);\n if (!spanStartedBeforeIdleSpanEnd) {\n logger.log('[Tracing] Discarding span since it happened after idle span was finished', stringifiedSpan);\n } else if (!spanEndedBeforeFinalTimeout) {\n logger.log('[Tracing] Discarding span since it finished after idle span final timeout', stringifiedSpan);\n }\n }\n\n if (!spanEndedBeforeFinalTimeout || !spanStartedBeforeIdleSpanEnd) {\n removeChildSpanFromSpan(span, childSpan);\n discardedSpans++;\n }\n });\n\n if (discardedSpans > 0) {\n span.setAttribute('sentry.idle_span_discarded_spans', discardedSpans);\n }\n }\n\n _cleanupHooks.push(\n client.on('spanStart', startedSpan => {\n // If we already finished the idle span,\n // or if this is the idle span itself being started,\n // or if the started span has already been closed,\n // we don't care about it for activity\n if (_finished || startedSpan === span || !!spanToJSON(startedSpan).timestamp) {\n return;\n }\n\n const allSpans = getSpanDescendants(span);\n\n // If the span that was just started is a child of the idle span, we should track it\n if (allSpans.includes(startedSpan)) {\n _pushActivity(startedSpan.spanContext().spanId);\n }\n }),\n );\n\n _cleanupHooks.push(\n client.on('spanEnd', endedSpan => {\n if (_finished) {\n return;\n }\n\n _popActivity(endedSpan.spanContext().spanId);\n }),\n );\n\n _cleanupHooks.push(\n client.on('idleSpanEnableAutoFinish', spanToAllowAutoFinish => {\n if (spanToAllowAutoFinish === span) {\n _autoFinishAllowed = true;\n _restartIdleTimeout();\n\n if (activities.size) {\n _restartChildSpanTimeout();\n }\n }\n }),\n );\n\n // We only start the initial idle timeout if we are not delaying the auto finish\n if (!options.disableAutoFinish) {\n _restartIdleTimeout();\n }\n\n setTimeout(() => {\n if (!_finished) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'deadline_exceeded' });\n _finishReason = FINISH_REASON_FINAL_TIMEOUT;\n span.end();\n }\n }, finalTimeout);\n\n return span;\n}\n\nfunction _startIdleSpan(options) {\n const span = startInactiveSpan(options);\n\n _setSpanForScope(getCurrentScope(), span);\n\n DEBUG_BUILD && logger.log('[Tracing] Started span is an idle span');\n\n return span;\n}\n\nexport { TRACING_DEFAULTS, startIdleSpan };\n//# sourceMappingURL=idleSpan.js.map\n","import { SyncPromise, logger, isThenable } from '@sentry/utils';\nimport { DEBUG_BUILD } from './debug-build.js';\n\n/**\n * Process an array of event processors, returning the processed event (or `null` if the event was dropped).\n */\nfunction notifyEventProcessors(\n processors,\n event,\n hint,\n index = 0,\n) {\n return new SyncPromise((resolve, reject) => {\n const processor = processors[index];\n if (event === null || typeof processor !== 'function') {\n resolve(event);\n } else {\n const result = processor({ ...event }, hint) ;\n\n DEBUG_BUILD && processor.id && result === null && logger.log(`Event processor \"${processor.id}\" dropped event`);\n\n if (isThenable(result)) {\n void result\n .then(final => notifyEventProcessors(processors, final, hint, index + 1).then(resolve))\n .then(null, reject);\n } else {\n void notifyEventProcessors(processors, result, hint, index + 1)\n .then(resolve)\n .then(null, reject);\n }\n }\n });\n}\n\nexport { notifyEventProcessors };\n//# sourceMappingURL=eventProcessors.js.map\n","import { dropUndefinedKeys, arrayify } from '@sentry/utils';\nimport { getDynamicSamplingContextFromSpan } from '../tracing/dynamicSamplingContext.js';\nimport { spanToTraceContext, getRootSpan, spanToJSON } from './spanUtils.js';\n\n/**\n * Applies data from the scope to the event and runs all event processors on it.\n */\nfunction applyScopeDataToEvent(event, data) {\n const { fingerprint, span, breadcrumbs, sdkProcessingMetadata } = data;\n\n // Apply general data\n applyDataToEvent(event, data);\n\n // We want to set the trace context for normal events only if there isn't already\n // a trace context on the event. There is a product feature in place where we link\n // errors with transaction and it relies on that.\n if (span) {\n applySpanToEvent(event, span);\n }\n\n applyFingerprintToEvent(event, fingerprint);\n applyBreadcrumbsToEvent(event, breadcrumbs);\n applySdkMetadataToEvent(event, sdkProcessingMetadata);\n}\n\n/** Merge data of two scopes together. */\nfunction mergeScopeData(data, mergeData) {\n const {\n extra,\n tags,\n user,\n contexts,\n level,\n sdkProcessingMetadata,\n breadcrumbs,\n fingerprint,\n eventProcessors,\n attachments,\n propagationContext,\n transactionName,\n span,\n } = mergeData;\n\n mergeAndOverwriteScopeData(data, 'extra', extra);\n mergeAndOverwriteScopeData(data, 'tags', tags);\n mergeAndOverwriteScopeData(data, 'user', user);\n mergeAndOverwriteScopeData(data, 'contexts', contexts);\n mergeAndOverwriteScopeData(data, 'sdkProcessingMetadata', sdkProcessingMetadata);\n\n if (level) {\n data.level = level;\n }\n\n if (transactionName) {\n data.transactionName = transactionName;\n }\n\n if (span) {\n data.span = span;\n }\n\n if (breadcrumbs.length) {\n data.breadcrumbs = [...data.breadcrumbs, ...breadcrumbs];\n }\n\n if (fingerprint.length) {\n data.fingerprint = [...data.fingerprint, ...fingerprint];\n }\n\n if (eventProcessors.length) {\n data.eventProcessors = [...data.eventProcessors, ...eventProcessors];\n }\n\n if (attachments.length) {\n data.attachments = [...data.attachments, ...attachments];\n }\n\n data.propagationContext = { ...data.propagationContext, ...propagationContext };\n}\n\n/**\n * Merges certain scope data. Undefined values will overwrite any existing values.\n * Exported only for tests.\n */\nfunction mergeAndOverwriteScopeData\n\n(data, prop, mergeVal) {\n if (mergeVal && Object.keys(mergeVal).length) {\n // Clone object\n data[prop] = { ...data[prop] };\n for (const key in mergeVal) {\n if (Object.prototype.hasOwnProperty.call(mergeVal, key)) {\n data[prop][key] = mergeVal[key];\n }\n }\n }\n}\n\nfunction applyDataToEvent(event, data) {\n const { extra, tags, user, contexts, level, transactionName } = data;\n\n const cleanedExtra = dropUndefinedKeys(extra);\n if (cleanedExtra && Object.keys(cleanedExtra).length) {\n event.extra = { ...cleanedExtra, ...event.extra };\n }\n\n const cleanedTags = dropUndefinedKeys(tags);\n if (cleanedTags && Object.keys(cleanedTags).length) {\n event.tags = { ...cleanedTags, ...event.tags };\n }\n\n const cleanedUser = dropUndefinedKeys(user);\n if (cleanedUser && Object.keys(cleanedUser).length) {\n event.user = { ...cleanedUser, ...event.user };\n }\n\n const cleanedContexts = dropUndefinedKeys(contexts);\n if (cleanedContexts && Object.keys(cleanedContexts).length) {\n event.contexts = { ...cleanedContexts, ...event.contexts };\n }\n\n if (level) {\n event.level = level;\n }\n\n // transaction events get their `transaction` from the root span name\n if (transactionName && event.type !== 'transaction') {\n event.transaction = transactionName;\n }\n}\n\nfunction applyBreadcrumbsToEvent(event, breadcrumbs) {\n const mergedBreadcrumbs = [...(event.breadcrumbs || []), ...breadcrumbs];\n event.breadcrumbs = mergedBreadcrumbs.length ? mergedBreadcrumbs : undefined;\n}\n\nfunction applySdkMetadataToEvent(event, sdkProcessingMetadata) {\n event.sdkProcessingMetadata = {\n ...event.sdkProcessingMetadata,\n ...sdkProcessingMetadata,\n };\n}\n\nfunction applySpanToEvent(event, span) {\n event.contexts = {\n trace: spanToTraceContext(span),\n ...event.contexts,\n };\n\n event.sdkProcessingMetadata = {\n dynamicSamplingContext: getDynamicSamplingContextFromSpan(span),\n ...event.sdkProcessingMetadata,\n };\n\n const rootSpan = getRootSpan(span);\n const transactionName = spanToJSON(rootSpan).description;\n if (transactionName && !event.transaction && event.type === 'transaction') {\n event.transaction = transactionName;\n }\n}\n\n/**\n * Applies fingerprint from the scope to the event if there's one,\n * uses message if there's one instead or get rid of empty fingerprint\n */\nfunction applyFingerprintToEvent(event, fingerprint) {\n // Make sure it's an array first and we actually have something in place\n event.fingerprint = event.fingerprint ? arrayify(event.fingerprint) : [];\n\n // If we have something on the scope, then merge it with event\n if (fingerprint) {\n event.fingerprint = event.fingerprint.concat(fingerprint);\n }\n\n // If we have no data at all, remove empty array default\n if (event.fingerprint && !event.fingerprint.length) {\n delete event.fingerprint;\n }\n}\n\nexport { applyScopeDataToEvent, mergeAndOverwriteScopeData, mergeScopeData };\n//# sourceMappingURL=applyScopeDataToEvent.js.map\n","import { uuid4, dateTimestampInSeconds, addExceptionMechanism, truncate, getFilenameToDebugIdMap, normalize } from '@sentry/utils';\nimport { DEFAULT_ENVIRONMENT } from '../constants.js';\nimport { getGlobalScope } from '../currentScopes.js';\nimport { notifyEventProcessors } from '../eventProcessors.js';\nimport { Scope } from '../scope.js';\nimport { mergeScopeData, applyScopeDataToEvent } from './applyScopeDataToEvent.js';\n\n/**\n * This type makes sure that we get either a CaptureContext, OR an EventHint.\n * It does not allow mixing them, which could lead to unexpected outcomes, e.g. this is disallowed:\n * { user: { id: '123' }, mechanism: { handled: false } }\n */\n\n/**\n * Adds common information to events.\n *\n * The information includes release and environment from `options`,\n * breadcrumbs and context (extra, tags and user) from the scope.\n *\n * Information that is already present in the event is never overwritten. For\n * nested objects, such as the context, keys are merged.\n *\n * @param event The original event.\n * @param hint May contain additional information about the original exception.\n * @param scope A scope containing event metadata.\n * @returns A new event with more information.\n * @hidden\n */\nfunction prepareEvent(\n options,\n event,\n hint,\n scope,\n client,\n isolationScope,\n) {\n const { normalizeDepth = 3, normalizeMaxBreadth = 1000 } = options;\n const prepared = {\n ...event,\n event_id: event.event_id || hint.event_id || uuid4(),\n timestamp: event.timestamp || dateTimestampInSeconds(),\n };\n const integrations = hint.integrations || options.integrations.map(i => i.name);\n\n applyClientOptions(prepared, options);\n applyIntegrationsMetadata(prepared, integrations);\n\n if (client) {\n client.emit('applyFrameMetadata', event);\n }\n\n // Only put debug IDs onto frames for error events.\n if (event.type === undefined) {\n applyDebugIds(prepared, options.stackParser);\n }\n\n // If we have scope given to us, use it as the base for further modifications.\n // This allows us to prevent unnecessary copying of data if `captureContext` is not provided.\n const finalScope = getFinalScope(scope, hint.captureContext);\n\n if (hint.mechanism) {\n addExceptionMechanism(prepared, hint.mechanism);\n }\n\n const clientEventProcessors = client ? client.getEventProcessors() : [];\n\n // This should be the last thing called, since we want that\n // {@link Scope.addEventProcessor} gets the finished prepared event.\n // Merge scope data together\n const data = getGlobalScope().getScopeData();\n\n if (isolationScope) {\n const isolationData = isolationScope.getScopeData();\n mergeScopeData(data, isolationData);\n }\n\n if (finalScope) {\n const finalScopeData = finalScope.getScopeData();\n mergeScopeData(data, finalScopeData);\n }\n\n const attachments = [...(hint.attachments || []), ...data.attachments];\n if (attachments.length) {\n hint.attachments = attachments;\n }\n\n applyScopeDataToEvent(prepared, data);\n\n const eventProcessors = [\n ...clientEventProcessors,\n // Run scope event processors _after_ all other processors\n ...data.eventProcessors,\n ];\n\n const result = notifyEventProcessors(eventProcessors, prepared, hint);\n\n return result.then(evt => {\n if (evt) {\n // We apply the debug_meta field only after all event processors have ran, so that if any event processors modified\n // file names (e.g.the RewriteFrames integration) the filename -> debug ID relationship isn't destroyed.\n // This should not cause any PII issues, since we're only moving data that is already on the event and not adding\n // any new data\n applyDebugMeta(evt);\n }\n\n if (typeof normalizeDepth === 'number' && normalizeDepth > 0) {\n return normalizeEvent(evt, normalizeDepth, normalizeMaxBreadth);\n }\n return evt;\n });\n}\n\n/**\n * Enhances event using the client configuration.\n * It takes care of all \"static\" values like environment, release and `dist`,\n * as well as truncating overly long values.\n * @param event event instance to be enhanced\n */\nfunction applyClientOptions(event, options) {\n const { environment, release, dist, maxValueLength = 250 } = options;\n\n if (!('environment' in event)) {\n event.environment = 'environment' in options ? environment : DEFAULT_ENVIRONMENT;\n }\n\n if (event.release === undefined && release !== undefined) {\n event.release = release;\n }\n\n if (event.dist === undefined && dist !== undefined) {\n event.dist = dist;\n }\n\n if (event.message) {\n event.message = truncate(event.message, maxValueLength);\n }\n\n const exception = event.exception && event.exception.values && event.exception.values[0];\n if (exception && exception.value) {\n exception.value = truncate(exception.value, maxValueLength);\n }\n\n const request = event.request;\n if (request && request.url) {\n request.url = truncate(request.url, maxValueLength);\n }\n}\n\n/**\n * Puts debug IDs into the stack frames of an error event.\n */\nfunction applyDebugIds(event, stackParser) {\n // Build a map of filename -> debug_id\n const filenameDebugIdMap = getFilenameToDebugIdMap(stackParser);\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n event.exception.values.forEach(exception => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n exception.stacktrace.frames.forEach(frame => {\n if (frame.filename) {\n frame.debug_id = filenameDebugIdMap[frame.filename];\n }\n });\n });\n } catch (e) {\n // To save bundle size we're just try catching here instead of checking for the existence of all the different objects.\n }\n}\n\n/**\n * Moves debug IDs from the stack frames of an error event into the debug_meta field.\n */\nfunction applyDebugMeta(event) {\n // Extract debug IDs and filenames from the stack frames on the event.\n const filenameDebugIdMap = {};\n try {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n event.exception.values.forEach(exception => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n exception.stacktrace.frames.forEach(frame => {\n if (frame.debug_id) {\n if (frame.abs_path) {\n filenameDebugIdMap[frame.abs_path] = frame.debug_id;\n } else if (frame.filename) {\n filenameDebugIdMap[frame.filename] = frame.debug_id;\n }\n delete frame.debug_id;\n }\n });\n });\n } catch (e) {\n // To save bundle size we're just try catching here instead of checking for the existence of all the different objects.\n }\n\n if (Object.keys(filenameDebugIdMap).length === 0) {\n return;\n }\n\n // Fill debug_meta information\n event.debug_meta = event.debug_meta || {};\n event.debug_meta.images = event.debug_meta.images || [];\n const images = event.debug_meta.images;\n Object.entries(filenameDebugIdMap).forEach(([filename, debug_id]) => {\n images.push({\n type: 'sourcemap',\n code_file: filename,\n debug_id,\n });\n });\n}\n\n/**\n * This function adds all used integrations to the SDK info in the event.\n * @param event The event that will be filled with all integrations.\n */\nfunction applyIntegrationsMetadata(event, integrationNames) {\n if (integrationNames.length > 0) {\n event.sdk = event.sdk || {};\n event.sdk.integrations = [...(event.sdk.integrations || []), ...integrationNames];\n }\n}\n\n/**\n * Applies `normalize` function on necessary `Event` attributes to make them safe for serialization.\n * Normalized keys:\n * - `breadcrumbs.data`\n * - `user`\n * - `contexts`\n * - `extra`\n * @param event Event\n * @returns Normalized event\n */\nfunction normalizeEvent(event, depth, maxBreadth) {\n if (!event) {\n return null;\n }\n\n const normalized = {\n ...event,\n ...(event.breadcrumbs && {\n breadcrumbs: event.breadcrumbs.map(b => ({\n ...b,\n ...(b.data && {\n data: normalize(b.data, depth, maxBreadth),\n }),\n })),\n }),\n ...(event.user && {\n user: normalize(event.user, depth, maxBreadth),\n }),\n ...(event.contexts && {\n contexts: normalize(event.contexts, depth, maxBreadth),\n }),\n ...(event.extra && {\n extra: normalize(event.extra, depth, maxBreadth),\n }),\n };\n\n // event.contexts.trace stores information about a Transaction. Similarly,\n // event.spans[] stores information about child Spans. Given that a\n // Transaction is conceptually a Span, normalization should apply to both\n // Transactions and Spans consistently.\n // For now the decision is to skip normalization of Transactions and Spans,\n // so this block overwrites the normalized event to add back the original\n // Transaction information prior to normalization.\n if (event.contexts && event.contexts.trace && normalized.contexts) {\n normalized.contexts.trace = event.contexts.trace;\n\n // event.contexts.trace.data may contain circular/dangerous data so we need to normalize it\n if (event.contexts.trace.data) {\n normalized.contexts.trace.data = normalize(event.contexts.trace.data, depth, maxBreadth);\n }\n }\n\n // event.spans[].data may contain circular/dangerous data so we need to normalize it\n if (event.spans) {\n normalized.spans = event.spans.map(span => {\n return {\n ...span,\n ...(span.data && {\n data: normalize(span.data, depth, maxBreadth),\n }),\n };\n });\n }\n\n return normalized;\n}\n\nfunction getFinalScope(\n scope,\n captureContext,\n) {\n if (!captureContext) {\n return scope;\n }\n\n const finalScope = scope ? scope.clone() : new Scope();\n finalScope.update(captureContext);\n return finalScope;\n}\n\n/**\n * Parse either an `EventHint` directly, or convert a `CaptureContext` to an `EventHint`.\n * This is used to allow to update method signatures that used to accept a `CaptureContext` but should now accept an `EventHint`.\n */\nfunction parseEventHintOrCaptureContext(\n hint,\n) {\n if (!hint) {\n return undefined;\n }\n\n // If you pass a Scope or `() => Scope` as CaptureContext, we just return this as captureContext\n if (hintIsScopeOrFunction(hint)) {\n return { captureContext: hint };\n }\n\n if (hintIsScopeContext(hint)) {\n return {\n captureContext: hint,\n };\n }\n\n return hint;\n}\n\nfunction hintIsScopeOrFunction(\n hint,\n) {\n return hint instanceof Scope || typeof hint === 'function';\n}\n\nconst captureContextKeys = [\n 'user',\n 'level',\n 'extra',\n 'contexts',\n 'tags',\n 'fingerprint',\n 'requestSession',\n 'propagationContext',\n] ;\n\nfunction hintIsScopeContext(hint) {\n return Object.keys(hint).some(key => captureContextKeys.includes(key ));\n}\n\nexport { applyDebugIds, applyDebugMeta, parseEventHintOrCaptureContext, prepareEvent };\n//# sourceMappingURL=prepareEvent.js.map\n","import { logger, uuid4, timestampInSeconds, isThenable, GLOBAL_OBJ } from '@sentry/utils';\nimport { DEFAULT_ENVIRONMENT } from './constants.js';\nimport { getCurrentScope, getIsolationScope, getClient, withIsolationScope } from './currentScopes.js';\nimport { DEBUG_BUILD } from './debug-build.js';\nimport { makeSession, updateSession, closeSession } from './session.js';\nimport { parseEventHintOrCaptureContext } from './utils/prepareEvent.js';\n\n/**\n * Captures an exception event and sends it to Sentry.\n *\n * @param exception The exception to capture.\n * @param hint Optional additional data to attach to the Sentry event.\n * @returns the id of the captured Sentry event.\n */\nfunction captureException(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n exception,\n hint,\n) {\n return getCurrentScope().captureException(exception, parseEventHintOrCaptureContext(hint));\n}\n\n/**\n * Captures a message event and sends it to Sentry.\n *\n * @param message The message to send to Sentry.\n * @param captureContext Define the level of the message or pass in additional data to attach to the message.\n * @returns the id of the captured message.\n */\nfunction captureMessage(message, captureContext) {\n // This is necessary to provide explicit scopes upgrade, without changing the original\n // arity of the `captureMessage(message, level)` method.\n const level = typeof captureContext === 'string' ? captureContext : undefined;\n const context = typeof captureContext !== 'string' ? { captureContext } : undefined;\n return getCurrentScope().captureMessage(message, level, context);\n}\n\n/**\n * Captures a manually created event and sends it to Sentry.\n *\n * @param event The event to send to Sentry.\n * @param hint Optional additional data to attach to the Sentry event.\n * @returns the id of the captured event.\n */\nfunction captureEvent(event, hint) {\n return getCurrentScope().captureEvent(event, hint);\n}\n\n/**\n * Sets context data with the given name.\n * @param name of the context\n * @param context Any kind of data. This data will be normalized.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction setContext(name, context) {\n getIsolationScope().setContext(name, context);\n}\n\n/**\n * Set an object that will be merged sent as extra data with the event.\n * @param extras Extras object to merge into current context.\n */\nfunction setExtras(extras) {\n getIsolationScope().setExtras(extras);\n}\n\n/**\n * Set key:value that will be sent as extra data with the event.\n * @param key String of extra\n * @param extra Any kind of data. This data will be normalized.\n */\nfunction setExtra(key, extra) {\n getIsolationScope().setExtra(key, extra);\n}\n\n/**\n * Set an object that will be merged sent as tags data with the event.\n * @param tags Tags context object to merge into current context.\n */\nfunction setTags(tags) {\n getIsolationScope().setTags(tags);\n}\n\n/**\n * Set key:value that will be sent as tags data with the event.\n *\n * Can also be used to unset a tag, by passing `undefined`.\n *\n * @param key String key of tag\n * @param value Value of tag\n */\nfunction setTag(key, value) {\n getIsolationScope().setTag(key, value);\n}\n\n/**\n * Updates user context information for future events.\n *\n * @param user User context object to be set in the current context. Pass `null` to unset the user.\n */\nfunction setUser(user) {\n getIsolationScope().setUser(user);\n}\n\n/**\n * The last error event id of the isolation scope.\n *\n * Warning: This function really returns the last recorded error event id on the current\n * isolation scope. If you call this function after handling a certain error and another error\n * is captured in between, the last one is returned instead of the one you might expect.\n * Also, ids of events that were never sent to Sentry (for example because\n * they were dropped in `beforeSend`) could be returned.\n *\n * @returns The last event id of the isolation scope.\n */\nfunction lastEventId() {\n return getIsolationScope().lastEventId();\n}\n\n/**\n * Create a cron monitor check in and send it to Sentry.\n *\n * @param checkIn An object that describes a check in.\n * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want\n * to create a monitor automatically when sending a check in.\n */\nfunction captureCheckIn(checkIn, upsertMonitorConfig) {\n const scope = getCurrentScope();\n const client = getClient();\n if (!client) {\n DEBUG_BUILD && logger.warn('Cannot capture check-in. No client defined.');\n } else if (!client.captureCheckIn) {\n DEBUG_BUILD && logger.warn('Cannot capture check-in. Client does not support sending check-ins.');\n } else {\n return client.captureCheckIn(checkIn, upsertMonitorConfig, scope);\n }\n\n return uuid4();\n}\n\n/**\n * Wraps a callback with a cron monitor check in. The check in will be sent to Sentry when the callback finishes.\n *\n * @param monitorSlug The distinct slug of the monitor.\n * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want\n * to create a monitor automatically when sending a check in.\n */\nfunction withMonitor(\n monitorSlug,\n callback,\n upsertMonitorConfig,\n) {\n const checkInId = captureCheckIn({ monitorSlug, status: 'in_progress' }, upsertMonitorConfig);\n const now = timestampInSeconds();\n\n function finishCheckIn(status) {\n captureCheckIn({ monitorSlug, status, checkInId, duration: timestampInSeconds() - now });\n }\n\n return withIsolationScope(() => {\n let maybePromiseResult;\n try {\n maybePromiseResult = callback();\n } catch (e) {\n finishCheckIn('error');\n throw e;\n }\n\n if (isThenable(maybePromiseResult)) {\n Promise.resolve(maybePromiseResult).then(\n () => {\n finishCheckIn('ok');\n },\n e => {\n finishCheckIn('error');\n throw e;\n },\n );\n } else {\n finishCheckIn('ok');\n }\n\n return maybePromiseResult;\n });\n}\n\n/**\n * Call `flush()` on the current client, if there is one. See {@link Client.flush}.\n *\n * @param timeout Maximum time in ms the client should wait to flush its event queue. Omitting this parameter will cause\n * the client to wait until all events are sent before resolving the promise.\n * @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it\n * doesn't (or if there's no client defined).\n */\nasync function flush(timeout) {\n const client = getClient();\n if (client) {\n return client.flush(timeout);\n }\n DEBUG_BUILD && logger.warn('Cannot flush events. No client defined.');\n return Promise.resolve(false);\n}\n\n/**\n * Call `close()` on the current client, if there is one. See {@link Client.close}.\n *\n * @param timeout Maximum time in ms the client should wait to flush its event queue before shutting down. Omitting this\n * parameter will cause the client to wait until all events are sent before disabling itself.\n * @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it\n * doesn't (or if there's no client defined).\n */\nasync function close(timeout) {\n const client = getClient();\n if (client) {\n return client.close(timeout);\n }\n DEBUG_BUILD && logger.warn('Cannot flush events and disable SDK. No client defined.');\n return Promise.resolve(false);\n}\n\n/**\n * Returns true if Sentry has been properly initialized.\n */\nfunction isInitialized() {\n return !!getClient();\n}\n\n/** If the SDK is initialized & enabled. */\nfunction isEnabled() {\n const client = getClient();\n return !!client && client.getOptions().enabled !== false && !!client.getTransport();\n}\n\n/**\n * Add an event processor.\n * This will be added to the current isolation scope, ensuring any event that is processed in the current execution\n * context will have the processor applied.\n */\nfunction addEventProcessor(callback) {\n getIsolationScope().addEventProcessor(callback);\n}\n\n/**\n * Start a session on the current isolation scope.\n *\n * @param context (optional) additional properties to be applied to the returned session object\n *\n * @returns the new active session\n */\nfunction startSession(context) {\n const client = getClient();\n const isolationScope = getIsolationScope();\n const currentScope = getCurrentScope();\n\n const { release, environment = DEFAULT_ENVIRONMENT } = (client && client.getOptions()) || {};\n\n // Will fetch userAgent if called from browser sdk\n const { userAgent } = GLOBAL_OBJ.navigator || {};\n\n const session = makeSession({\n release,\n environment,\n user: currentScope.getUser() || isolationScope.getUser(),\n ...(userAgent && { userAgent }),\n ...context,\n });\n\n // End existing session if there's one\n const currentSession = isolationScope.getSession();\n if (currentSession && currentSession.status === 'ok') {\n updateSession(currentSession, { status: 'exited' });\n }\n\n endSession();\n\n // Afterwards we set the new session on the scope\n isolationScope.setSession(session);\n\n // TODO (v8): Remove this and only use the isolation scope(?).\n // For v7 though, we can't \"soft-break\" people using getCurrentHub().getScope().setSession()\n currentScope.setSession(session);\n\n return session;\n}\n\n/**\n * End the session on the current isolation scope.\n */\nfunction endSession() {\n const isolationScope = getIsolationScope();\n const currentScope = getCurrentScope();\n\n const session = currentScope.getSession() || isolationScope.getSession();\n if (session) {\n closeSession(session);\n }\n _sendSessionUpdate();\n\n // the session is over; take it off of the scope\n isolationScope.setSession();\n\n // TODO (v8): Remove this and only use the isolation scope(?).\n // For v7 though, we can't \"soft-break\" people using getCurrentHub().getScope().setSession()\n currentScope.setSession();\n}\n\n/**\n * Sends the current Session on the scope\n */\nfunction _sendSessionUpdate() {\n const isolationScope = getIsolationScope();\n const currentScope = getCurrentScope();\n const client = getClient();\n // TODO (v8): Remove currentScope and only use the isolation scope(?).\n // For v7 though, we can't \"soft-break\" people using getCurrentHub().getScope().setSession()\n const session = currentScope.getSession() || isolationScope.getSession();\n if (session && client) {\n client.captureSession(session);\n }\n}\n\n/**\n * Sends the current session on the scope to Sentry\n *\n * @param end If set the session will be marked as exited and removed from the scope.\n * Defaults to `false`.\n */\nfunction captureSession(end = false) {\n // both send the update and pull the session from the scope\n if (end) {\n endSession();\n return;\n }\n\n // only send the update\n _sendSessionUpdate();\n}\n\nexport { addEventProcessor, captureCheckIn, captureEvent, captureException, captureMessage, captureSession, close, endSession, flush, isEnabled, isInitialized, lastEventId, setContext, setExtra, setExtras, setTag, setTags, setUser, startSession, withMonitor };\n//# sourceMappingURL=exports.js.map\n","import { makeDsn, dsnToString, urlEncode } from '@sentry/utils';\n\nconst SENTRY_API_VERSION = '7';\n\n/** Returns the prefix to construct Sentry ingestion API endpoints. */\nfunction getBaseApiEndpoint(dsn) {\n const protocol = dsn.protocol ? `${dsn.protocol}:` : '';\n const port = dsn.port ? `:${dsn.port}` : '';\n return `${protocol}//${dsn.host}${port}${dsn.path ? `/${dsn.path}` : ''}/api/`;\n}\n\n/** Returns the ingest API endpoint for target. */\nfunction _getIngestEndpoint(dsn) {\n return `${getBaseApiEndpoint(dsn)}${dsn.projectId}/envelope/`;\n}\n\n/** Returns a URL-encoded string with auth config suitable for a query string. */\nfunction _encodedAuth(dsn, sdkInfo) {\n return urlEncode({\n // We send only the minimum set of required information. See\n // https://github.com/getsentry/sentry-javascript/issues/2572.\n sentry_key: dsn.publicKey,\n sentry_version: SENTRY_API_VERSION,\n ...(sdkInfo && { sentry_client: `${sdkInfo.name}/${sdkInfo.version}` }),\n });\n}\n\n/**\n * Returns the envelope endpoint URL with auth in the query string.\n *\n * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.\n */\nfunction getEnvelopeEndpointWithUrlEncodedAuth(dsn, tunnel, sdkInfo) {\n return tunnel ? tunnel : `${_getIngestEndpoint(dsn)}?${_encodedAuth(dsn, sdkInfo)}`;\n}\n\n/** Returns the url to the report dialog endpoint. */\nfunction getReportDialogEndpoint(\n dsnLike,\n dialogOptions\n\n,\n) {\n const dsn = makeDsn(dsnLike);\n if (!dsn) {\n return '';\n }\n\n const endpoint = `${getBaseApiEndpoint(dsn)}embed/error-page/`;\n\n let encodedOptions = `dsn=${dsnToString(dsn)}`;\n for (const key in dialogOptions) {\n if (key === 'dsn') {\n continue;\n }\n\n if (key === 'onClose') {\n continue;\n }\n\n if (key === 'user') {\n const user = dialogOptions.user;\n if (!user) {\n continue;\n }\n if (user.name) {\n encodedOptions += `&name=${encodeURIComponent(user.name)}`;\n }\n if (user.email) {\n encodedOptions += `&email=${encodeURIComponent(user.email)}`;\n }\n } else {\n encodedOptions += `&${encodeURIComponent(key)}=${encodeURIComponent(dialogOptions[key] )}`;\n }\n }\n\n return `${endpoint}?${encodedOptions}`;\n}\n\nexport { getEnvelopeEndpointWithUrlEncodedAuth, getReportDialogEndpoint };\n//# sourceMappingURL=api.js.map\n","import { arrayify, logger } from '@sentry/utils';\nimport { getClient } from './currentScopes.js';\nimport { DEBUG_BUILD } from './debug-build.js';\n\nconst installedIntegrations = [];\n\n/** Map of integrations assigned to a client */\n\n/**\n * Remove duplicates from the given array, preferring the last instance of any duplicate. Not guaranteed to\n * preserve the order of integrations in the array.\n *\n * @private\n */\nfunction filterDuplicates(integrations) {\n const integrationsByName = {};\n\n integrations.forEach(currentInstance => {\n const { name } = currentInstance;\n\n const existingInstance = integrationsByName[name];\n\n // We want integrations later in the array to overwrite earlier ones of the same type, except that we never want a\n // default instance to overwrite an existing user instance\n if (existingInstance && !existingInstance.isDefaultInstance && currentInstance.isDefaultInstance) {\n return;\n }\n\n integrationsByName[name] = currentInstance;\n });\n\n return Object.values(integrationsByName);\n}\n\n/** Gets integrations to install */\nfunction getIntegrationsToSetup(options) {\n const defaultIntegrations = options.defaultIntegrations || [];\n const userIntegrations = options.integrations;\n\n // We flag default instances, so that later we can tell them apart from any user-created instances of the same class\n defaultIntegrations.forEach(integration => {\n integration.isDefaultInstance = true;\n });\n\n let integrations;\n\n if (Array.isArray(userIntegrations)) {\n integrations = [...defaultIntegrations, ...userIntegrations];\n } else if (typeof userIntegrations === 'function') {\n integrations = arrayify(userIntegrations(defaultIntegrations));\n } else {\n integrations = defaultIntegrations;\n }\n\n const finalIntegrations = filterDuplicates(integrations);\n\n // The `Debug` integration prints copies of the `event` and `hint` which will be passed to `beforeSend` or\n // `beforeSendTransaction`. It therefore has to run after all other integrations, so that the changes of all event\n // processors will be reflected in the printed values. For lack of a more elegant way to guarantee that, we therefore\n // locate it and, assuming it exists, pop it out of its current spot and shove it onto the end of the array.\n const debugIndex = finalIntegrations.findIndex(integration => integration.name === 'Debug');\n if (debugIndex > -1) {\n const [debugInstance] = finalIntegrations.splice(debugIndex, 1) ;\n finalIntegrations.push(debugInstance);\n }\n\n return finalIntegrations;\n}\n\n/**\n * Given a list of integration instances this installs them all. When `withDefaults` is set to `true` then all default\n * integrations are added unless they were already provided before.\n * @param integrations array of integration instances\n * @param withDefault should enable default integrations\n */\nfunction setupIntegrations(client, integrations) {\n const integrationIndex = {};\n\n integrations.forEach(integration => {\n // guard against empty provided integrations\n if (integration) {\n setupIntegration(client, integration, integrationIndex);\n }\n });\n\n return integrationIndex;\n}\n\n/**\n * Execute the `afterAllSetup` hooks of the given integrations.\n */\nfunction afterSetupIntegrations(client, integrations) {\n for (const integration of integrations) {\n // guard against empty provided integrations\n if (integration && integration.afterAllSetup) {\n integration.afterAllSetup(client);\n }\n }\n}\n\n/** Setup a single integration. */\nfunction setupIntegration(client, integration, integrationIndex) {\n if (integrationIndex[integration.name]) {\n DEBUG_BUILD && logger.log(`Integration skipped because it was already installed: ${integration.name}`);\n return;\n }\n integrationIndex[integration.name] = integration;\n\n // `setupOnce` is only called the first time\n if (installedIntegrations.indexOf(integration.name) === -1 && typeof integration.setupOnce === 'function') {\n integration.setupOnce();\n installedIntegrations.push(integration.name);\n }\n\n // `setup` is run for each client\n if (integration.setup && typeof integration.setup === 'function') {\n integration.setup(client);\n }\n\n if (typeof integration.preprocessEvent === 'function') {\n const callback = integration.preprocessEvent.bind(integration) ;\n client.on('preprocessEvent', (event, hint) => callback(event, hint, client));\n }\n\n if (typeof integration.processEvent === 'function') {\n const callback = integration.processEvent.bind(integration) ;\n\n const processor = Object.assign((event, hint) => callback(event, hint, client), {\n id: integration.name,\n });\n\n client.addEventProcessor(processor);\n }\n\n DEBUG_BUILD && logger.log(`Integration installed: ${integration.name}`);\n}\n\n/** Add an integration to the current scope's client. */\nfunction addIntegration(integration) {\n const client = getClient();\n\n if (!client) {\n DEBUG_BUILD && logger.warn(`Cannot add integration \"${integration.name}\" because no SDK Client is available.`);\n return;\n }\n\n client.addIntegration(integration);\n}\n\n/**\n * Define an integration function that can be used to create an integration instance.\n * Note that this by design hides the implementation details of the integration, as they are considered internal.\n */\nfunction defineIntegration(fn) {\n return fn;\n}\n\nexport { addIntegration, afterSetupIntegrations, defineIntegration, getIntegrationsToSetup, installedIntegrations, setupIntegration, setupIntegrations };\n//# sourceMappingURL=integration.js.map\n","import { makeDsn, logger, uuid4, checkOrSetAlreadyCaught, isParameterizedString, isPrimitive, resolvedSyncPromise, addItemToEnvelope, createAttachmentEnvelopeItem, SyncPromise, dropUndefinedKeys, rejectedSyncPromise, SentryError, createClientReportEnvelope, dsnToString, isThenable, isPlainObject } from '@sentry/utils';\nimport { getEnvelopeEndpointWithUrlEncodedAuth } from './api.js';\nimport { getIsolationScope } from './currentScopes.js';\nimport { DEBUG_BUILD } from './debug-build.js';\nimport { createEventEnvelope, createSessionEnvelope } from './envelope.js';\nimport { setupIntegration, afterSetupIntegrations, setupIntegrations } from './integration.js';\nimport { updateSession } from './session.js';\nimport { getDynamicSamplingContextFromClient } from './tracing/dynamicSamplingContext.js';\nimport { parseSampleRate } from './utils/parseSampleRate.js';\nimport { prepareEvent } from './utils/prepareEvent.js';\n\nconst ALREADY_SEEN_ERROR = \"Not capturing exception because it's already been captured.\";\n\n/**\n * Base implementation for all JavaScript SDK clients.\n *\n * Call the constructor with the corresponding options\n * specific to the client subclass. To access these options later, use\n * {@link Client.getOptions}.\n *\n * If a Dsn is specified in the options, it will be parsed and stored. Use\n * {@link Client.getDsn} to retrieve the Dsn at any moment. In case the Dsn is\n * invalid, the constructor will throw a {@link SentryException}. Note that\n * without a valid Dsn, the SDK will not send any events to Sentry.\n *\n * Before sending an event, it is passed through\n * {@link BaseClient._prepareEvent} to add SDK information and scope data\n * (breadcrumbs and context). To add more custom information, override this\n * method and extend the resulting prepared event.\n *\n * To issue automatically created events (e.g. via instrumentation), use\n * {@link Client.captureEvent}. It will prepare the event and pass it through\n * the callback lifecycle. To issue auto-breadcrumbs, use\n * {@link Client.addBreadcrumb}.\n *\n * @example\n * class NodeClient extends BaseClient {\n * public constructor(options: NodeOptions) {\n * super(options);\n * }\n *\n * // ...\n * }\n */\nclass BaseClient {\n /** Options passed to the SDK. */\n\n /** The client Dsn, if specified in options. Without this Dsn, the SDK will be disabled. */\n\n /** Array of set up integrations. */\n\n /** Number of calls being processed */\n\n /** Holds flushable */\n\n // eslint-disable-next-line @typescript-eslint/ban-types\n\n /**\n * Initializes this client instance.\n *\n * @param options Options for the client.\n */\n constructor(options) {\n this._options = options;\n this._integrations = {};\n this._numProcessing = 0;\n this._outcomes = {};\n this._hooks = {};\n this._eventProcessors = [];\n\n if (options.dsn) {\n this._dsn = makeDsn(options.dsn);\n } else {\n DEBUG_BUILD && logger.warn('No DSN provided, client will not send events.');\n }\n\n if (this._dsn) {\n const url = getEnvelopeEndpointWithUrlEncodedAuth(\n this._dsn,\n options.tunnel,\n options._metadata ? options._metadata.sdk : undefined,\n );\n this._transport = options.transport({\n tunnel: this._options.tunnel,\n recordDroppedEvent: this.recordDroppedEvent.bind(this),\n ...options.transportOptions,\n url,\n });\n }\n }\n\n /**\n * @inheritDoc\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n captureException(exception, hint, scope) {\n const eventId = uuid4();\n\n // ensure we haven't captured this very object before\n if (checkOrSetAlreadyCaught(exception)) {\n DEBUG_BUILD && logger.log(ALREADY_SEEN_ERROR);\n return eventId;\n }\n\n const hintWithEventId = {\n event_id: eventId,\n ...hint,\n };\n\n this._process(\n this.eventFromException(exception, hintWithEventId).then(event =>\n this._captureEvent(event, hintWithEventId, scope),\n ),\n );\n\n return hintWithEventId.event_id;\n }\n\n /**\n * @inheritDoc\n */\n captureMessage(\n message,\n level,\n hint,\n currentScope,\n ) {\n const hintWithEventId = {\n event_id: uuid4(),\n ...hint,\n };\n\n const eventMessage = isParameterizedString(message) ? message : String(message);\n\n const promisedEvent = isPrimitive(message)\n ? this.eventFromMessage(eventMessage, level, hintWithEventId)\n : this.eventFromException(message, hintWithEventId);\n\n this._process(promisedEvent.then(event => this._captureEvent(event, hintWithEventId, currentScope)));\n\n return hintWithEventId.event_id;\n }\n\n /**\n * @inheritDoc\n */\n captureEvent(event, hint, currentScope) {\n const eventId = uuid4();\n\n // ensure we haven't captured this very object before\n if (hint && hint.originalException && checkOrSetAlreadyCaught(hint.originalException)) {\n DEBUG_BUILD && logger.log(ALREADY_SEEN_ERROR);\n return eventId;\n }\n\n const hintWithEventId = {\n event_id: eventId,\n ...hint,\n };\n\n const sdkProcessingMetadata = event.sdkProcessingMetadata || {};\n const capturedSpanScope = sdkProcessingMetadata.capturedSpanScope;\n\n this._process(this._captureEvent(event, hintWithEventId, capturedSpanScope || currentScope));\n\n return hintWithEventId.event_id;\n }\n\n /**\n * @inheritDoc\n */\n captureSession(session) {\n if (!(typeof session.release === 'string')) {\n DEBUG_BUILD && logger.warn('Discarded session because of missing or non-string release');\n } else {\n this.sendSession(session);\n // After sending, we set init false to indicate it's not the first occurrence\n updateSession(session, { init: false });\n }\n }\n\n /**\n * @inheritDoc\n */\n getDsn() {\n return this._dsn;\n }\n\n /**\n * @inheritDoc\n */\n getOptions() {\n return this._options;\n }\n\n /**\n * @see SdkMetadata in @sentry/types\n *\n * @return The metadata of the SDK\n */\n getSdkMetadata() {\n return this._options._metadata;\n }\n\n /**\n * @inheritDoc\n */\n getTransport() {\n return this._transport;\n }\n\n /**\n * @inheritDoc\n */\n flush(timeout) {\n const transport = this._transport;\n if (transport) {\n this.emit('flush');\n return this._isClientDoneProcessing(timeout).then(clientFinished => {\n return transport.flush(timeout).then(transportFlushed => clientFinished && transportFlushed);\n });\n } else {\n return resolvedSyncPromise(true);\n }\n }\n\n /**\n * @inheritDoc\n */\n close(timeout) {\n return this.flush(timeout).then(result => {\n this.getOptions().enabled = false;\n this.emit('close');\n return result;\n });\n }\n\n /** Get all installed event processors. */\n getEventProcessors() {\n return this._eventProcessors;\n }\n\n /** @inheritDoc */\n addEventProcessor(eventProcessor) {\n this._eventProcessors.push(eventProcessor);\n }\n\n /** @inheritdoc */\n init() {\n if (\n this._isEnabled() ||\n // Force integrations to be setup even if no DSN was set when we have\n // Spotlight enabled. This is particularly important for browser as we\n // don't support the `spotlight` option there and rely on the users\n // adding the `spotlightBrowserIntegration()` to their integrations which\n // wouldn't get initialized with the check below when there's no DSN set.\n this._options.integrations.some(({ name }) => name.startsWith('Spotlight'))\n ) {\n this._setupIntegrations();\n }\n }\n\n /**\n * Gets an installed integration by its name.\n *\n * @returns The installed integration or `undefined` if no integration with that `name` was installed.\n */\n getIntegrationByName(integrationName) {\n return this._integrations[integrationName] ;\n }\n\n /**\n * @inheritDoc\n */\n addIntegration(integration) {\n const isAlreadyInstalled = this._integrations[integration.name];\n\n // This hook takes care of only installing if not already installed\n setupIntegration(this, integration, this._integrations);\n // Here we need to check manually to make sure to not run this multiple times\n if (!isAlreadyInstalled) {\n afterSetupIntegrations(this, [integration]);\n }\n }\n\n /**\n * @inheritDoc\n */\n sendEvent(event, hint = {}) {\n this.emit('beforeSendEvent', event, hint);\n\n let env = createEventEnvelope(event, this._dsn, this._options._metadata, this._options.tunnel);\n\n for (const attachment of hint.attachments || []) {\n env = addItemToEnvelope(env, createAttachmentEnvelopeItem(attachment));\n }\n\n const promise = this.sendEnvelope(env);\n if (promise) {\n promise.then(sendResponse => this.emit('afterSendEvent', event, sendResponse), null);\n }\n }\n\n /**\n * @inheritDoc\n */\n sendSession(session) {\n const env = createSessionEnvelope(session, this._dsn, this._options._metadata, this._options.tunnel);\n\n // sendEnvelope should not throw\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.sendEnvelope(env);\n }\n\n /**\n * @inheritDoc\n */\n recordDroppedEvent(reason, category, eventOrCount) {\n if (this._options.sendClientReports) {\n // TODO v9: We do not need the `event` passed as third argument anymore, and can possibly remove this overload\n // If event is passed as third argument, we assume this is a count of 1\n const count = typeof eventOrCount === 'number' ? eventOrCount : 1;\n\n // We want to track each category (error, transaction, session, replay_event) separately\n // but still keep the distinction between different type of outcomes.\n // We could use nested maps, but it's much easier to read and type this way.\n // A correct type for map-based implementation if we want to go that route\n // would be `Partial>>>`\n // With typescript 4.1 we could even use template literal types\n const key = `${reason}:${category}`;\n DEBUG_BUILD && logger.log(`Recording outcome: \"${key}\"${count > 1 ? ` (${count} times)` : ''}`);\n this._outcomes[key] = (this._outcomes[key] || 0) + count;\n }\n }\n\n // Keep on() & emit() signatures in sync with types' client.ts interface\n /* eslint-disable @typescript-eslint/unified-signatures */\n\n /** @inheritdoc */\n\n /** @inheritdoc */\n on(hook, callback) {\n const hooks = (this._hooks[hook] = this._hooks[hook] || []);\n\n // @ts-expect-error We assume the types are correct\n hooks.push(callback);\n\n // This function returns a callback execution handler that, when invoked,\n // deregisters a callback. This is crucial for managing instances where callbacks\n // need to be unregistered to prevent self-referencing in callback closures,\n // ensuring proper garbage collection.\n return () => {\n // @ts-expect-error We assume the types are correct\n const cbIndex = hooks.indexOf(callback);\n if (cbIndex > -1) {\n hooks.splice(cbIndex, 1);\n }\n };\n }\n\n /** @inheritdoc */\n\n /** @inheritdoc */\n emit(hook, ...rest) {\n const callbacks = this._hooks[hook];\n if (callbacks) {\n callbacks.forEach(callback => callback(...rest));\n }\n }\n\n /**\n * @inheritdoc\n */\n sendEnvelope(envelope) {\n this.emit('beforeEnvelope', envelope);\n\n if (this._isEnabled() && this._transport) {\n return this._transport.send(envelope).then(null, reason => {\n DEBUG_BUILD && logger.error('Error while sending envelope:', reason);\n return reason;\n });\n }\n\n DEBUG_BUILD && logger.error('Transport disabled');\n\n return resolvedSyncPromise({});\n }\n\n /* eslint-enable @typescript-eslint/unified-signatures */\n\n /** Setup integrations for this client. */\n _setupIntegrations() {\n const { integrations } = this._options;\n this._integrations = setupIntegrations(this, integrations);\n afterSetupIntegrations(this, integrations);\n }\n\n /** Updates existing session based on the provided event */\n _updateSessionFromEvent(session, event) {\n let crashed = false;\n let errored = false;\n const exceptions = event.exception && event.exception.values;\n\n if (exceptions) {\n errored = true;\n\n for (const ex of exceptions) {\n const mechanism = ex.mechanism;\n if (mechanism && mechanism.handled === false) {\n crashed = true;\n break;\n }\n }\n }\n\n // A session is updated and that session update is sent in only one of the two following scenarios:\n // 1. Session with non terminal status and 0 errors + an error occurred -> Will set error count to 1 and send update\n // 2. Session with non terminal status and 1 error + a crash occurred -> Will set status crashed and send update\n const sessionNonTerminal = session.status === 'ok';\n const shouldUpdateAndSend = (sessionNonTerminal && session.errors === 0) || (sessionNonTerminal && crashed);\n\n if (shouldUpdateAndSend) {\n updateSession(session, {\n ...(crashed && { status: 'crashed' }),\n errors: session.errors || Number(errored || crashed),\n });\n this.captureSession(session);\n }\n }\n\n /**\n * Determine if the client is finished processing. Returns a promise because it will wait `timeout` ms before saying\n * \"no\" (resolving to `false`) in order to give the client a chance to potentially finish first.\n *\n * @param timeout The time, in ms, after which to resolve to `false` if the client is still busy. Passing `0` (or not\n * passing anything) will make the promise wait as long as it takes for processing to finish before resolving to\n * `true`.\n * @returns A promise which will resolve to `true` if processing is already done or finishes before the timeout, and\n * `false` otherwise\n */\n _isClientDoneProcessing(timeout) {\n return new SyncPromise(resolve => {\n let ticked = 0;\n const tick = 1;\n\n const interval = setInterval(() => {\n if (this._numProcessing == 0) {\n clearInterval(interval);\n resolve(true);\n } else {\n ticked += tick;\n if (timeout && ticked >= timeout) {\n clearInterval(interval);\n resolve(false);\n }\n }\n }, tick);\n });\n }\n\n /** Determines whether this SDK is enabled and a transport is present. */\n _isEnabled() {\n return this.getOptions().enabled !== false && this._transport !== undefined;\n }\n\n /**\n * Adds common information to events.\n *\n * The information includes release and environment from `options`,\n * breadcrumbs and context (extra, tags and user) from the scope.\n *\n * Information that is already present in the event is never overwritten. For\n * nested objects, such as the context, keys are merged.\n *\n * @param event The original event.\n * @param hint May contain additional information about the original exception.\n * @param currentScope A scope containing event metadata.\n * @returns A new event with more information.\n */\n _prepareEvent(\n event,\n hint,\n currentScope,\n isolationScope = getIsolationScope(),\n ) {\n const options = this.getOptions();\n const integrations = Object.keys(this._integrations);\n if (!hint.integrations && integrations.length > 0) {\n hint.integrations = integrations;\n }\n\n this.emit('preprocessEvent', event, hint);\n\n if (!event.type) {\n isolationScope.setLastEventId(event.event_id || hint.event_id);\n }\n\n return prepareEvent(options, event, hint, currentScope, this, isolationScope).then(evt => {\n if (evt === null) {\n return evt;\n }\n\n const propagationContext = {\n ...isolationScope.getPropagationContext(),\n ...(currentScope ? currentScope.getPropagationContext() : undefined),\n };\n\n const trace = evt.contexts && evt.contexts.trace;\n if (!trace && propagationContext) {\n const { traceId: trace_id, spanId, parentSpanId, dsc } = propagationContext;\n evt.contexts = {\n trace: dropUndefinedKeys({\n trace_id,\n span_id: spanId,\n parent_span_id: parentSpanId,\n }),\n ...evt.contexts,\n };\n\n const dynamicSamplingContext = dsc ? dsc : getDynamicSamplingContextFromClient(trace_id, this);\n\n evt.sdkProcessingMetadata = {\n dynamicSamplingContext,\n ...evt.sdkProcessingMetadata,\n };\n }\n return evt;\n });\n }\n\n /**\n * Processes the event and logs an error in case of rejection\n * @param event\n * @param hint\n * @param scope\n */\n _captureEvent(event, hint = {}, scope) {\n return this._processEvent(event, hint, scope).then(\n finalEvent => {\n return finalEvent.event_id;\n },\n reason => {\n if (DEBUG_BUILD) {\n // If something's gone wrong, log the error as a warning. If it's just us having used a `SentryError` for\n // control flow, log just the message (no stack) as a log-level log.\n const sentryError = reason ;\n if (sentryError.logLevel === 'log') {\n logger.log(sentryError.message);\n } else {\n logger.warn(sentryError);\n }\n }\n return undefined;\n },\n );\n }\n\n /**\n * Processes an event (either error or message) and sends it to Sentry.\n *\n * This also adds breadcrumbs and context information to the event. However,\n * platform specific meta data (such as the User's IP address) must be added\n * by the SDK implementor.\n *\n *\n * @param event The event to send to Sentry.\n * @param hint May contain additional information about the original exception.\n * @param currentScope A scope containing event metadata.\n * @returns A SyncPromise that resolves with the event or rejects in case event was/will not be send.\n */\n _processEvent(event, hint, currentScope) {\n const options = this.getOptions();\n const { sampleRate } = options;\n\n const isTransaction = isTransactionEvent(event);\n const isError = isErrorEvent(event);\n const eventType = event.type || 'error';\n const beforeSendLabel = `before send for type \\`${eventType}\\``;\n\n // 1.0 === 100% events are sent\n // 0.0 === 0% events are sent\n // Sampling for transaction happens somewhere else\n const parsedSampleRate = typeof sampleRate === 'undefined' ? undefined : parseSampleRate(sampleRate);\n if (isError && typeof parsedSampleRate === 'number' && Math.random() > parsedSampleRate) {\n this.recordDroppedEvent('sample_rate', 'error', event);\n return rejectedSyncPromise(\n new SentryError(\n `Discarding event because it's not included in the random sample (sampling rate = ${sampleRate})`,\n 'log',\n ),\n );\n }\n\n const dataCategory = eventType === 'replay_event' ? 'replay' : eventType;\n\n const sdkProcessingMetadata = event.sdkProcessingMetadata || {};\n const capturedSpanIsolationScope = sdkProcessingMetadata.capturedSpanIsolationScope;\n\n return this._prepareEvent(event, hint, currentScope, capturedSpanIsolationScope)\n .then(prepared => {\n if (prepared === null) {\n this.recordDroppedEvent('event_processor', dataCategory, event);\n throw new SentryError('An event processor returned `null`, will not send event.', 'log');\n }\n\n const isInternalException = hint.data && (hint.data ).__sentry__ === true;\n if (isInternalException) {\n return prepared;\n }\n\n const result = processBeforeSend(this, options, prepared, hint);\n return _validateBeforeSendResult(result, beforeSendLabel);\n })\n .then(processedEvent => {\n if (processedEvent === null) {\n this.recordDroppedEvent('before_send', dataCategory, event);\n if (isTransaction) {\n const spans = event.spans || [];\n // the transaction itself counts as one span, plus all the child spans that are added\n const spanCount = 1 + spans.length;\n this.recordDroppedEvent('before_send', 'span', spanCount);\n }\n throw new SentryError(`${beforeSendLabel} returned \\`null\\`, will not send event.`, 'log');\n }\n\n const session = currentScope && currentScope.getSession();\n if (!isTransaction && session) {\n this._updateSessionFromEvent(session, processedEvent);\n }\n\n if (isTransaction) {\n const spanCountBefore =\n (processedEvent.sdkProcessingMetadata && processedEvent.sdkProcessingMetadata.spanCountBeforeProcessing) ||\n 0;\n const spanCountAfter = processedEvent.spans ? processedEvent.spans.length : 0;\n\n const droppedSpanCount = spanCountBefore - spanCountAfter;\n if (droppedSpanCount > 0) {\n this.recordDroppedEvent('before_send', 'span', droppedSpanCount);\n }\n }\n\n // None of the Sentry built event processor will update transaction name,\n // so if the transaction name has been changed by an event processor, we know\n // it has to come from custom event processor added by a user\n const transactionInfo = processedEvent.transaction_info;\n if (isTransaction && transactionInfo && processedEvent.transaction !== event.transaction) {\n const source = 'custom';\n processedEvent.transaction_info = {\n ...transactionInfo,\n source,\n };\n }\n\n this.sendEvent(processedEvent, hint);\n return processedEvent;\n })\n .then(null, reason => {\n if (reason instanceof SentryError) {\n throw reason;\n }\n\n this.captureException(reason, {\n data: {\n __sentry__: true,\n },\n originalException: reason,\n });\n throw new SentryError(\n `Event processing pipeline threw an error, original event will not be sent. Details have been sent as a new event.\\nReason: ${reason}`,\n );\n });\n }\n\n /**\n * Occupies the client with processing and event\n */\n _process(promise) {\n this._numProcessing++;\n void promise.then(\n value => {\n this._numProcessing--;\n return value;\n },\n reason => {\n this._numProcessing--;\n return reason;\n },\n );\n }\n\n /**\n * Clears outcomes on this client and returns them.\n */\n _clearOutcomes() {\n const outcomes = this._outcomes;\n this._outcomes = {};\n return Object.entries(outcomes).map(([key, quantity]) => {\n const [reason, category] = key.split(':') ;\n return {\n reason,\n category,\n quantity,\n };\n });\n }\n\n /**\n * Sends client reports as an envelope.\n */\n _flushOutcomes() {\n DEBUG_BUILD && logger.log('Flushing outcomes...');\n\n const outcomes = this._clearOutcomes();\n\n if (outcomes.length === 0) {\n DEBUG_BUILD && logger.log('No outcomes to send');\n return;\n }\n\n // This is really the only place where we want to check for a DSN and only send outcomes then\n if (!this._dsn) {\n DEBUG_BUILD && logger.log('No dsn provided, will not send outcomes');\n return;\n }\n\n DEBUG_BUILD && logger.log('Sending outcomes:', outcomes);\n\n const envelope = createClientReportEnvelope(outcomes, this._options.tunnel && dsnToString(this._dsn));\n\n // sendEnvelope should not throw\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.sendEnvelope(envelope);\n }\n\n /**\n * @inheritDoc\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n\n}\n\n/**\n * Verifies that return value of configured `beforeSend` or `beforeSendTransaction` is of expected type, and returns the value if so.\n */\nfunction _validateBeforeSendResult(\n beforeSendResult,\n beforeSendLabel,\n) {\n const invalidValueError = `${beforeSendLabel} must return \\`null\\` or a valid event.`;\n if (isThenable(beforeSendResult)) {\n return beforeSendResult.then(\n event => {\n if (!isPlainObject(event) && event !== null) {\n throw new SentryError(invalidValueError);\n }\n return event;\n },\n e => {\n throw new SentryError(`${beforeSendLabel} rejected with ${e}`);\n },\n );\n } else if (!isPlainObject(beforeSendResult) && beforeSendResult !== null) {\n throw new SentryError(invalidValueError);\n }\n return beforeSendResult;\n}\n\n/**\n * Process the matching `beforeSendXXX` callback.\n */\nfunction processBeforeSend(\n client,\n options,\n event,\n hint,\n) {\n const { beforeSend, beforeSendTransaction, beforeSendSpan } = options;\n\n if (isErrorEvent(event) && beforeSend) {\n return beforeSend(event, hint);\n }\n\n if (isTransactionEvent(event)) {\n if (event.spans && beforeSendSpan) {\n const processedSpans = [];\n for (const span of event.spans) {\n const processedSpan = beforeSendSpan(span);\n if (processedSpan) {\n processedSpans.push(processedSpan);\n } else {\n client.recordDroppedEvent('before_send', 'span');\n }\n }\n event.spans = processedSpans;\n }\n\n if (beforeSendTransaction) {\n if (event.spans) {\n // We store the # of spans before processing in SDK metadata,\n // so we can compare it afterwards to determine how many spans were dropped\n const spanCountBefore = event.spans.length;\n event.sdkProcessingMetadata = {\n ...event.sdkProcessingMetadata,\n spanCountBeforeProcessing: spanCountBefore,\n };\n }\n return beforeSendTransaction(event, hint);\n }\n }\n\n return event;\n}\n\nfunction isErrorEvent(event) {\n return event.type === undefined;\n}\n\nfunction isTransactionEvent(event) {\n return event.type === 'transaction';\n}\n\nexport { BaseClient };\n//# sourceMappingURL=baseclient.js.map\n","import { logger, consoleSandbox } from '@sentry/utils';\nimport { getCurrentScope } from './currentScopes.js';\nimport { DEBUG_BUILD } from './debug-build.js';\n\n/** A class object that can instantiate Client objects. */\n\n/**\n * Internal function to create a new SDK client instance. The client is\n * installed and then bound to the current scope.\n *\n * @param clientClass The client class to instantiate.\n * @param options Options to pass to the client.\n */\nfunction initAndBind(\n clientClass,\n options,\n) {\n if (options.debug === true) {\n if (DEBUG_BUILD) {\n logger.enable();\n } else {\n // use `console.warn` rather than `logger.warn` since by non-debug bundles have all `logger.x` statements stripped\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.');\n });\n }\n }\n const scope = getCurrentScope();\n scope.update(options.initialScope);\n\n const client = new clientClass(options);\n setCurrentClient(client);\n client.init();\n return client;\n}\n\n/**\n * Make the given client the current client.\n */\nfunction setCurrentClient(client) {\n getCurrentScope().setClient(client);\n}\n\nexport { initAndBind, setCurrentClient };\n//# sourceMappingURL=sdk.js.map\n","import { makePromiseBuffer, forEachEnvelopeItem, envelopeItemTypeToDataCategory, isRateLimited, resolvedSyncPromise, createEnvelope, SentryError, logger, serializeEnvelope, updateRateLimits } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build.js';\n\nconst DEFAULT_TRANSPORT_BUFFER_SIZE = 64;\n\n/**\n * Creates an instance of a Sentry `Transport`\n *\n * @param options\n * @param makeRequest\n */\nfunction createTransport(\n options,\n makeRequest,\n buffer = makePromiseBuffer(\n options.bufferSize || DEFAULT_TRANSPORT_BUFFER_SIZE,\n ),\n) {\n let rateLimits = {};\n const flush = (timeout) => buffer.drain(timeout);\n\n function send(envelope) {\n const filteredEnvelopeItems = [];\n\n // Drop rate limited items from envelope\n forEachEnvelopeItem(envelope, (item, type) => {\n const dataCategory = envelopeItemTypeToDataCategory(type);\n if (isRateLimited(rateLimits, dataCategory)) {\n const event = getEventForEnvelopeItem(item, type);\n options.recordDroppedEvent('ratelimit_backoff', dataCategory, event);\n } else {\n filteredEnvelopeItems.push(item);\n }\n });\n\n // Skip sending if envelope is empty after filtering out rate limited events\n if (filteredEnvelopeItems.length === 0) {\n return resolvedSyncPromise({});\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const filteredEnvelope = createEnvelope(envelope[0], filteredEnvelopeItems );\n\n // Creates client report for each item in an envelope\n const recordEnvelopeLoss = (reason) => {\n forEachEnvelopeItem(filteredEnvelope, (item, type) => {\n const event = getEventForEnvelopeItem(item, type);\n options.recordDroppedEvent(reason, envelopeItemTypeToDataCategory(type), event);\n });\n };\n\n const requestTask = () =>\n makeRequest({ body: serializeEnvelope(filteredEnvelope) }).then(\n response => {\n // We don't want to throw on NOK responses, but we want to at least log them\n if (response.statusCode !== undefined && (response.statusCode < 200 || response.statusCode >= 300)) {\n DEBUG_BUILD && logger.warn(`Sentry responded with status code ${response.statusCode} to sent event.`);\n }\n\n rateLimits = updateRateLimits(rateLimits, response);\n return response;\n },\n error => {\n recordEnvelopeLoss('network_error');\n throw error;\n },\n );\n\n return buffer.add(requestTask).then(\n result => result,\n error => {\n if (error instanceof SentryError) {\n DEBUG_BUILD && logger.error('Skipped sending event because buffer is full.');\n recordEnvelopeLoss('queue_overflow');\n return resolvedSyncPromise({});\n } else {\n throw error;\n }\n },\n );\n }\n\n return {\n send,\n flush,\n };\n}\n\nfunction getEventForEnvelopeItem(item, type) {\n if (type !== 'event' && type !== 'transaction') {\n return undefined;\n }\n\n return Array.isArray(item) ? (item )[1] : undefined;\n}\n\nexport { DEFAULT_TRANSPORT_BUFFER_SIZE, createTransport };\n//# sourceMappingURL=base.js.map\n","import { SDK_VERSION } from '@sentry/utils';\n\n/**\n * A builder for the SDK metadata in the options for the SDK initialization.\n *\n * Note: This function is identical to `buildMetadata` in Remix and NextJS and SvelteKit.\n * We don't extract it for bundle size reasons.\n * @see https://github.com/getsentry/sentry-javascript/pull/7404\n * @see https://github.com/getsentry/sentry-javascript/pull/4196\n *\n * If you make changes to this function consider updating the others as well.\n *\n * @param options SDK options object that gets mutated\n * @param names list of package names\n */\nfunction applySdkMetadata(options, name, names = [name], source = 'npm') {\n const metadata = options._metadata || {};\n\n if (!metadata.sdk) {\n metadata.sdk = {\n name: `sentry.javascript.${name}`,\n packages: names.map(name => ({\n name: `${source}:@sentry/${name}`,\n version: SDK_VERSION,\n })),\n version: SDK_VERSION,\n };\n }\n\n options._metadata = metadata;\n}\n\nexport { applySdkMetadata };\n//# sourceMappingURL=sdkMetadata.js.map\n","import { dateTimestampInSeconds, consoleSandbox } from '@sentry/utils';\nimport { getClient, getIsolationScope } from './currentScopes.js';\n\n/**\n * Default maximum number of breadcrumbs added to an event. Can be overwritten\n * with {@link Options.maxBreadcrumbs}.\n */\nconst DEFAULT_BREADCRUMBS = 100;\n\n/**\n * Records a new breadcrumb which will be attached to future events.\n *\n * Breadcrumbs will be added to subsequent events to provide more context on\n * user's actions prior to an error or crash.\n */\nfunction addBreadcrumb(breadcrumb, hint) {\n const client = getClient();\n const isolationScope = getIsolationScope();\n\n if (!client) return;\n\n const { beforeBreadcrumb = null, maxBreadcrumbs = DEFAULT_BREADCRUMBS } = client.getOptions();\n\n if (maxBreadcrumbs <= 0) return;\n\n const timestamp = dateTimestampInSeconds();\n const mergedBreadcrumb = { timestamp, ...breadcrumb };\n const finalBreadcrumb = beforeBreadcrumb\n ? (consoleSandbox(() => beforeBreadcrumb(mergedBreadcrumb, hint)) )\n : mergedBreadcrumb;\n\n if (finalBreadcrumb === null) return;\n\n if (client.emit) {\n client.emit('beforeAddBreadcrumb', finalBreadcrumb, hint);\n }\n\n isolationScope.addBreadcrumb(finalBreadcrumb, maxBreadcrumbs);\n}\n\nexport { addBreadcrumb };\n//# sourceMappingURL=breadcrumbs.js.map\n","import { getOriginalFunction } from '@sentry/utils';\nimport { getClient } from '../currentScopes.js';\nimport { defineIntegration } from '../integration.js';\n\nlet originalFunctionToString;\n\nconst INTEGRATION_NAME = 'FunctionToString';\n\nconst SETUP_CLIENTS = new WeakMap();\n\nconst _functionToStringIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n originalFunctionToString = Function.prototype.toString;\n\n // intrinsics (like Function.prototype) might be immutable in some environments\n // e.g. Node with --frozen-intrinsics, XS (an embedded JavaScript engine) or SES (a JavaScript proposal)\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Function.prototype.toString = function ( ...args) {\n const originalFunction = getOriginalFunction(this);\n const context =\n SETUP_CLIENTS.has(getClient() ) && originalFunction !== undefined ? originalFunction : this;\n return originalFunctionToString.apply(context, args);\n };\n } catch (e) {\n // ignore errors here, just don't patch this\n }\n },\n setup(client) {\n SETUP_CLIENTS.set(client, true);\n },\n };\n}) ;\n\n/**\n * Patch toString calls to return proper name for wrapped functions.\n *\n * ```js\n * Sentry.init({\n * integrations: [\n * functionToStringIntegration(),\n * ],\n * });\n * ```\n */\nconst functionToStringIntegration = defineIntegration(_functionToStringIntegration);\n\nexport { functionToStringIntegration };\n//# sourceMappingURL=functiontostring.js.map\n","import { logger, getEventDescription, stringMatchesSomePattern } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build.js';\nimport { defineIntegration } from '../integration.js';\n\n// \"Script error.\" is hard coded into browsers for errors that it can't read.\n// this is the result of a script being pulled in from an external domain and CORS.\nconst DEFAULT_IGNORE_ERRORS = [\n /^Script error\\.?$/,\n /^Javascript error: Script error\\.? on line 0$/,\n /^ResizeObserver loop completed with undelivered notifications.$/, // The browser logs this when a ResizeObserver handler takes a bit longer. Usually this is not an actual issue though. It indicates slowness.\n /^Cannot redefine property: googletag$/, // This is thrown when google tag manager is used in combination with an ad blocker\n \"undefined is not an object (evaluating 'a.L')\", // Random error that happens but not actionable or noticeable to end-users.\n 'can\\'t redefine non-configurable property \"solana\"', // Probably a browser extension or custom browser (Brave) throwing this error\n \"vv().getRestrictions is not a function. (In 'vv().getRestrictions(1,a)', 'vv().getRestrictions' is undefined)\", // Error thrown by GTM, seemingly not affecting end-users\n \"Can't find variable: _AutofillCallbackHandler\", // Unactionable error in instagram webview https://developers.facebook.com/community/threads/320013549791141/\n];\n\n/** Options for the InboundFilters integration */\n\nconst INTEGRATION_NAME = 'InboundFilters';\nconst _inboundFiltersIntegration = ((options = {}) => {\n return {\n name: INTEGRATION_NAME,\n processEvent(event, _hint, client) {\n const clientOptions = client.getOptions();\n const mergedOptions = _mergeOptions(options, clientOptions);\n return _shouldDropEvent(event, mergedOptions) ? null : event;\n },\n };\n}) ;\n\nconst inboundFiltersIntegration = defineIntegration(_inboundFiltersIntegration);\n\nfunction _mergeOptions(\n internalOptions = {},\n clientOptions = {},\n) {\n return {\n allowUrls: [...(internalOptions.allowUrls || []), ...(clientOptions.allowUrls || [])],\n denyUrls: [...(internalOptions.denyUrls || []), ...(clientOptions.denyUrls || [])],\n ignoreErrors: [\n ...(internalOptions.ignoreErrors || []),\n ...(clientOptions.ignoreErrors || []),\n ...(internalOptions.disableErrorDefaults ? [] : DEFAULT_IGNORE_ERRORS),\n ],\n ignoreTransactions: [...(internalOptions.ignoreTransactions || []), ...(clientOptions.ignoreTransactions || [])],\n ignoreInternal: internalOptions.ignoreInternal !== undefined ? internalOptions.ignoreInternal : true,\n };\n}\n\nfunction _shouldDropEvent(event, options) {\n if (options.ignoreInternal && _isSentryError(event)) {\n DEBUG_BUILD &&\n logger.warn(`Event dropped due to being internal Sentry Error.\\nEvent: ${getEventDescription(event)}`);\n return true;\n }\n if (_isIgnoredError(event, options.ignoreErrors)) {\n DEBUG_BUILD &&\n logger.warn(\n `Event dropped due to being matched by \\`ignoreErrors\\` option.\\nEvent: ${getEventDescription(event)}`,\n );\n return true;\n }\n if (_isUselessError(event)) {\n DEBUG_BUILD &&\n logger.warn(\n `Event dropped due to not having an error message, error type or stacktrace.\\nEvent: ${getEventDescription(\n event,\n )}`,\n );\n return true;\n }\n if (_isIgnoredTransaction(event, options.ignoreTransactions)) {\n DEBUG_BUILD &&\n logger.warn(\n `Event dropped due to being matched by \\`ignoreTransactions\\` option.\\nEvent: ${getEventDescription(event)}`,\n );\n return true;\n }\n if (_isDeniedUrl(event, options.denyUrls)) {\n DEBUG_BUILD &&\n logger.warn(\n `Event dropped due to being matched by \\`denyUrls\\` option.\\nEvent: ${getEventDescription(\n event,\n )}.\\nUrl: ${_getEventFilterUrl(event)}`,\n );\n return true;\n }\n if (!_isAllowedUrl(event, options.allowUrls)) {\n DEBUG_BUILD &&\n logger.warn(\n `Event dropped due to not being matched by \\`allowUrls\\` option.\\nEvent: ${getEventDescription(\n event,\n )}.\\nUrl: ${_getEventFilterUrl(event)}`,\n );\n return true;\n }\n return false;\n}\n\nfunction _isIgnoredError(event, ignoreErrors) {\n // If event.type, this is not an error\n if (event.type || !ignoreErrors || !ignoreErrors.length) {\n return false;\n }\n\n return _getPossibleEventMessages(event).some(message => stringMatchesSomePattern(message, ignoreErrors));\n}\n\nfunction _isIgnoredTransaction(event, ignoreTransactions) {\n if (event.type !== 'transaction' || !ignoreTransactions || !ignoreTransactions.length) {\n return false;\n }\n\n const name = event.transaction;\n return name ? stringMatchesSomePattern(name, ignoreTransactions) : false;\n}\n\nfunction _isDeniedUrl(event, denyUrls) {\n // TODO: Use Glob instead?\n if (!denyUrls || !denyUrls.length) {\n return false;\n }\n const url = _getEventFilterUrl(event);\n return !url ? false : stringMatchesSomePattern(url, denyUrls);\n}\n\nfunction _isAllowedUrl(event, allowUrls) {\n // TODO: Use Glob instead?\n if (!allowUrls || !allowUrls.length) {\n return true;\n }\n const url = _getEventFilterUrl(event);\n return !url ? true : stringMatchesSomePattern(url, allowUrls);\n}\n\nfunction _getPossibleEventMessages(event) {\n const possibleMessages = [];\n\n if (event.message) {\n possibleMessages.push(event.message);\n }\n\n let lastException;\n try {\n // @ts-expect-error Try catching to save bundle size\n lastException = event.exception.values[event.exception.values.length - 1];\n } catch (e) {\n // try catching to save bundle size checking existence of variables\n }\n\n if (lastException) {\n if (lastException.value) {\n possibleMessages.push(lastException.value);\n if (lastException.type) {\n possibleMessages.push(`${lastException.type}: ${lastException.value}`);\n }\n }\n }\n\n return possibleMessages;\n}\n\nfunction _isSentryError(event) {\n try {\n // @ts-expect-error can't be a sentry error if undefined\n return event.exception.values[0].type === 'SentryError';\n } catch (e) {\n // ignore\n }\n return false;\n}\n\nfunction _getLastValidUrl(frames = []) {\n for (let i = frames.length - 1; i >= 0; i--) {\n const frame = frames[i];\n\n if (frame && frame.filename !== '' && frame.filename !== '[native code]') {\n return frame.filename || null;\n }\n }\n\n return null;\n}\n\nfunction _getEventFilterUrl(event) {\n try {\n let frames;\n try {\n // @ts-expect-error we only care about frames if the whole thing here is defined\n frames = event.exception.values[0].stacktrace.frames;\n } catch (e) {\n // ignore\n }\n return frames ? _getLastValidUrl(frames) : null;\n } catch (oO) {\n DEBUG_BUILD && logger.error(`Cannot extract url for event ${getEventDescription(event)}`);\n return null;\n }\n}\n\nfunction _isUselessError(event) {\n if (event.type) {\n // event is not an error\n return false;\n }\n\n // We only want to consider events for dropping that actually have recorded exception values.\n if (!event.exception || !event.exception.values || event.exception.values.length === 0) {\n return false;\n }\n\n return (\n // No top-level message\n !event.message &&\n // There are no exception values that have a stacktrace, a non-generic-Error type or value\n !event.exception.values.some(value => value.stacktrace || (value.type && value.type !== 'Error') || value.value)\n );\n}\n\nexport { inboundFiltersIntegration };\n//# sourceMappingURL=inboundfilters.js.map\n","import { CONSOLE_LEVELS, GLOBAL_OBJ, addConsoleInstrumentationHandler, severityLevelFromString, addExceptionMechanism, safeJoin } from '@sentry/utils';\nimport { getClient, withScope } from '../currentScopes.js';\nimport { captureMessage, captureException } from '../exports.js';\nimport { defineIntegration } from '../integration.js';\n\nconst INTEGRATION_NAME = 'CaptureConsole';\n\nconst _captureConsoleIntegration = ((options = {}) => {\n const levels = options.levels || CONSOLE_LEVELS;\n\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n if (!('console' in GLOBAL_OBJ)) {\n return;\n }\n\n addConsoleInstrumentationHandler(({ args, level }) => {\n if (getClient() !== client || !levels.includes(level)) {\n return;\n }\n\n consoleHandler(args, level);\n });\n },\n };\n}) ;\n\n/**\n * Send Console API calls as Sentry Events.\n */\nconst captureConsoleIntegration = defineIntegration(_captureConsoleIntegration);\n\nfunction consoleHandler(args, level) {\n const captureContext = {\n level: severityLevelFromString(level),\n extra: {\n arguments: args,\n },\n };\n\n withScope(scope => {\n scope.addEventProcessor(event => {\n event.logger = 'console';\n\n addExceptionMechanism(event, {\n handled: false,\n type: 'console',\n });\n\n return event;\n });\n\n if (level === 'assert') {\n if (!args[0]) {\n const message = `Assertion failed: ${safeJoin(args.slice(1), ' ') || 'console.assert'}`;\n scope.setExtra('arguments', args.slice(1));\n captureMessage(message, captureContext);\n }\n return;\n }\n\n const error = args.find(arg => arg instanceof Error);\n if (error) {\n captureException(error, captureContext);\n return;\n }\n\n const message = safeJoin(args, ' ');\n captureMessage(message, captureContext);\n });\n}\n\nexport { captureConsoleIntegration };\n//# sourceMappingURL=captureconsole.js.map\n","import { logger, getFramesFromEvent } from '@sentry/utils';\nimport { defineIntegration } from '../integration.js';\nimport { DEBUG_BUILD } from '../debug-build.js';\n\nconst INTEGRATION_NAME = 'Dedupe';\n\nconst _dedupeIntegration = (() => {\n let previousEvent;\n\n return {\n name: INTEGRATION_NAME,\n processEvent(currentEvent) {\n // We want to ignore any non-error type events, e.g. transactions or replays\n // These should never be deduped, and also not be compared against as _previousEvent.\n if (currentEvent.type) {\n return currentEvent;\n }\n\n // Juuust in case something goes wrong\n try {\n if (_shouldDropEvent(currentEvent, previousEvent)) {\n DEBUG_BUILD && logger.warn('Event dropped due to being a duplicate of previously captured event.');\n return null;\n }\n } catch (_oO) {} // eslint-disable-line no-empty\n\n return (previousEvent = currentEvent);\n },\n };\n}) ;\n\n/**\n * Deduplication filter.\n */\nconst dedupeIntegration = defineIntegration(_dedupeIntegration);\n\n/** only exported for tests. */\nfunction _shouldDropEvent(currentEvent, previousEvent) {\n if (!previousEvent) {\n return false;\n }\n\n if (_isSameMessageEvent(currentEvent, previousEvent)) {\n return true;\n }\n\n if (_isSameExceptionEvent(currentEvent, previousEvent)) {\n return true;\n }\n\n return false;\n}\n\nfunction _isSameMessageEvent(currentEvent, previousEvent) {\n const currentMessage = currentEvent.message;\n const previousMessage = previousEvent.message;\n\n // If neither event has a message property, they were both exceptions, so bail out\n if (!currentMessage && !previousMessage) {\n return false;\n }\n\n // If only one event has a stacktrace, but not the other one, they are not the same\n if ((currentMessage && !previousMessage) || (!currentMessage && previousMessage)) {\n return false;\n }\n\n if (currentMessage !== previousMessage) {\n return false;\n }\n\n if (!_isSameFingerprint(currentEvent, previousEvent)) {\n return false;\n }\n\n if (!_isSameStacktrace(currentEvent, previousEvent)) {\n return false;\n }\n\n return true;\n}\n\nfunction _isSameExceptionEvent(currentEvent, previousEvent) {\n const previousException = _getExceptionFromEvent(previousEvent);\n const currentException = _getExceptionFromEvent(currentEvent);\n\n if (!previousException || !currentException) {\n return false;\n }\n\n if (previousException.type !== currentException.type || previousException.value !== currentException.value) {\n return false;\n }\n\n if (!_isSameFingerprint(currentEvent, previousEvent)) {\n return false;\n }\n\n if (!_isSameStacktrace(currentEvent, previousEvent)) {\n return false;\n }\n\n return true;\n}\n\nfunction _isSameStacktrace(currentEvent, previousEvent) {\n let currentFrames = getFramesFromEvent(currentEvent);\n let previousFrames = getFramesFromEvent(previousEvent);\n\n // If neither event has a stacktrace, they are assumed to be the same\n if (!currentFrames && !previousFrames) {\n return true;\n }\n\n // If only one event has a stacktrace, but not the other one, they are not the same\n if ((currentFrames && !previousFrames) || (!currentFrames && previousFrames)) {\n return false;\n }\n\n currentFrames = currentFrames ;\n previousFrames = previousFrames ;\n\n // If number of frames differ, they are not the same\n if (previousFrames.length !== currentFrames.length) {\n return false;\n }\n\n // Otherwise, compare the two\n for (let i = 0; i < previousFrames.length; i++) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const frameA = previousFrames[i];\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const frameB = currentFrames[i];\n\n if (\n frameA.filename !== frameB.filename ||\n frameA.lineno !== frameB.lineno ||\n frameA.colno !== frameB.colno ||\n frameA.function !== frameB.function\n ) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction _isSameFingerprint(currentEvent, previousEvent) {\n let currentFingerprint = currentEvent.fingerprint;\n let previousFingerprint = previousEvent.fingerprint;\n\n // If neither event has a fingerprint, they are assumed to be the same\n if (!currentFingerprint && !previousFingerprint) {\n return true;\n }\n\n // If only one event has a fingerprint, but not the other one, they are not the same\n if ((currentFingerprint && !previousFingerprint) || (!currentFingerprint && previousFingerprint)) {\n return false;\n }\n\n currentFingerprint = currentFingerprint ;\n previousFingerprint = previousFingerprint ;\n\n // Otherwise, compare the two\n try {\n return !!(currentFingerprint.join('') === previousFingerprint.join(''));\n } catch (_oO) {\n return false;\n }\n}\n\nfunction _getExceptionFromEvent(event) {\n return event.exception && event.exception.values && event.exception.values[0];\n}\n\nexport { _shouldDropEvent, dedupeIntegration };\n//# sourceMappingURL=dedupe.js.map\n","import { parseUrl, generateSentryTraceHeader, dynamicSamplingContextToSentryBaggageHeader, isInstanceOf, BAGGAGE_HEADER_NAME, SENTRY_BAGGAGE_KEY_PREFIX } from '@sentry/utils';\nimport { getCurrentScope, getClient, getIsolationScope } from './currentScopes.js';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_OP } from './semanticAttributes.js';\nimport './tracing/errors.js';\nimport './debug-build.js';\nimport { hasTracingEnabled } from './utils/hasTracingEnabled.js';\nimport { getActiveSpan, spanToTraceHeader } from './utils/spanUtils.js';\nimport { SentryNonRecordingSpan } from './tracing/sentryNonRecordingSpan.js';\nimport { setHttpStatus, SPAN_STATUS_ERROR } from './tracing/spanstatus.js';\nimport { startInactiveSpan } from './tracing/trace.js';\nimport { getDynamicSamplingContextFromSpan, getDynamicSamplingContextFromClient } from './tracing/dynamicSamplingContext.js';\n\n/**\n * Create and track fetch request spans for usage in combination with `addFetchInstrumentationHandler`.\n *\n * @returns Span if a span was created, otherwise void.\n */\nfunction instrumentFetchRequest(\n handlerData,\n shouldCreateSpan,\n shouldAttachHeaders,\n spans,\n spanOrigin = 'auto.http.browser',\n) {\n if (!handlerData.fetchData) {\n return undefined;\n }\n\n const shouldCreateSpanResult = hasTracingEnabled() && shouldCreateSpan(handlerData.fetchData.url);\n\n if (handlerData.endTimestamp && shouldCreateSpanResult) {\n const spanId = handlerData.fetchData.__span;\n if (!spanId) return;\n\n const span = spans[spanId];\n if (span) {\n endSpan(span, handlerData);\n\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete spans[spanId];\n }\n return undefined;\n }\n\n const scope = getCurrentScope();\n const client = getClient();\n\n const { method, url } = handlerData.fetchData;\n\n const fullUrl = getFullURL(url);\n const host = fullUrl ? parseUrl(fullUrl).host : undefined;\n\n const hasParent = !!getActiveSpan();\n\n const span =\n shouldCreateSpanResult && hasParent\n ? startInactiveSpan({\n name: `${method} ${url}`,\n attributes: {\n url,\n type: 'fetch',\n 'http.method': method,\n 'http.url': fullUrl,\n 'server.address': host,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: spanOrigin,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client',\n },\n })\n : new SentryNonRecordingSpan();\n\n handlerData.fetchData.__span = span.spanContext().spanId;\n spans[span.spanContext().spanId] = span;\n\n if (shouldAttachHeaders(handlerData.fetchData.url) && client) {\n const request = handlerData.args[0];\n\n // In case the user hasn't set the second argument of a fetch call we default it to `{}`.\n handlerData.args[1] = handlerData.args[1] || {};\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const options = handlerData.args[1];\n\n options.headers = addTracingHeadersToFetchRequest(\n request,\n client,\n scope,\n options,\n // If performance is disabled (TWP) or there's no active root span (pageload/navigation/interaction),\n // we do not want to use the span as base for the trace headers,\n // which means that the headers will be generated from the scope and the sampling decision is deferred\n hasTracingEnabled() && hasParent ? span : undefined,\n );\n }\n\n return span;\n}\n\n/**\n * Adds sentry-trace and baggage headers to the various forms of fetch headers\n */\nfunction addTracingHeadersToFetchRequest(\n request, // unknown is actually type Request but we can't export DOM types from this package,\n client,\n scope,\n fetchOptionsObj\n\n,\n span,\n) {\n const isolationScope = getIsolationScope();\n\n const { traceId, spanId, sampled, dsc } = {\n ...isolationScope.getPropagationContext(),\n ...scope.getPropagationContext(),\n };\n\n const sentryTraceHeader = span ? spanToTraceHeader(span) : generateSentryTraceHeader(traceId, spanId, sampled);\n\n const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader(\n dsc || (span ? getDynamicSamplingContextFromSpan(span) : getDynamicSamplingContextFromClient(traceId, client)),\n );\n\n const headers =\n fetchOptionsObj.headers ||\n (typeof Request !== 'undefined' && isInstanceOf(request, Request) ? (request ).headers : undefined);\n\n if (!headers) {\n return { 'sentry-trace': sentryTraceHeader, baggage: sentryBaggageHeader };\n } else if (typeof Headers !== 'undefined' && isInstanceOf(headers, Headers)) {\n const newHeaders = new Headers(headers );\n\n newHeaders.set('sentry-trace', sentryTraceHeader);\n\n if (sentryBaggageHeader) {\n const prevBaggageHeader = newHeaders.get(BAGGAGE_HEADER_NAME);\n if (prevBaggageHeader) {\n const prevHeaderStrippedFromSentryBaggage = stripBaggageHeaderOfSentryBaggageValues(prevBaggageHeader);\n newHeaders.set(\n BAGGAGE_HEADER_NAME,\n // If there are non-sentry entries (i.e. if the stripped string is non-empty/truthy) combine the stripped header and sentry baggage header\n // otherwise just set the sentry baggage header\n prevHeaderStrippedFromSentryBaggage\n ? `${prevHeaderStrippedFromSentryBaggage},${sentryBaggageHeader}`\n : sentryBaggageHeader,\n );\n } else {\n newHeaders.set(BAGGAGE_HEADER_NAME, sentryBaggageHeader);\n }\n }\n\n return newHeaders ;\n } else if (Array.isArray(headers)) {\n const newHeaders = [\n ...headers\n // Remove any existing sentry-trace headers\n .filter(header => {\n return !(Array.isArray(header) && header[0] === 'sentry-trace');\n })\n // Get rid of previous sentry baggage values in baggage header\n .map(header => {\n if (Array.isArray(header) && header[0] === BAGGAGE_HEADER_NAME && typeof header[1] === 'string') {\n const [headerName, headerValue, ...rest] = header;\n return [headerName, stripBaggageHeaderOfSentryBaggageValues(headerValue), ...rest];\n } else {\n return header;\n }\n }),\n // Attach the new sentry-trace header\n ['sentry-trace', sentryTraceHeader],\n ];\n\n if (sentryBaggageHeader) {\n // If there are multiple entries with the same key, the browser will merge the values into a single request header.\n // Its therefore safe to simply push a \"baggage\" entry, even though there might already be another baggage header.\n newHeaders.push([BAGGAGE_HEADER_NAME, sentryBaggageHeader]);\n }\n\n return newHeaders ;\n } else {\n const existingBaggageHeader = 'baggage' in headers ? headers.baggage : undefined;\n let newBaggageHeaders = [];\n\n if (Array.isArray(existingBaggageHeader)) {\n newBaggageHeaders = existingBaggageHeader\n .map(headerItem =>\n typeof headerItem === 'string' ? stripBaggageHeaderOfSentryBaggageValues(headerItem) : headerItem,\n )\n .filter(headerItem => headerItem === '');\n } else if (existingBaggageHeader) {\n newBaggageHeaders.push(stripBaggageHeaderOfSentryBaggageValues(existingBaggageHeader));\n }\n\n if (sentryBaggageHeader) {\n newBaggageHeaders.push(sentryBaggageHeader);\n }\n\n return {\n ...(headers ),\n 'sentry-trace': sentryTraceHeader,\n baggage: newBaggageHeaders.length > 0 ? newBaggageHeaders.join(',') : undefined,\n };\n }\n}\n\nfunction getFullURL(url) {\n try {\n const parsed = new URL(url);\n return parsed.href;\n } catch (e) {\n return undefined;\n }\n}\n\nfunction endSpan(span, handlerData) {\n if (handlerData.response) {\n setHttpStatus(span, handlerData.response.status);\n\n const contentLength =\n handlerData.response && handlerData.response.headers && handlerData.response.headers.get('content-length');\n\n if (contentLength) {\n const contentLengthNum = parseInt(contentLength);\n if (contentLengthNum > 0) {\n span.setAttribute('http.response_content_length', contentLengthNum);\n }\n }\n } else if (handlerData.error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n span.end();\n}\n\nfunction stripBaggageHeaderOfSentryBaggageValues(baggageHeader) {\n return (\n baggageHeader\n .split(',')\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n .filter(baggageEntry => !baggageEntry.split('=')[0].startsWith(SENTRY_BAGGAGE_KEY_PREFIX))\n .join(',')\n );\n}\n\nexport { addTracingHeadersToFetchRequest, instrumentFetchRequest };\n//# sourceMappingURL=fetch.js.map\n","import { withScope, captureException } from '@sentry/core';\nimport { GLOBAL_OBJ, getOriginalFunction, markFunctionWrapped, addNonEnumerableProperty, addExceptionTypeValue, addExceptionMechanism } from '@sentry/utils';\n\nconst WINDOW = GLOBAL_OBJ ;\n\nlet ignoreOnError = 0;\n\n/**\n * @hidden\n */\nfunction shouldIgnoreOnError() {\n return ignoreOnError > 0;\n}\n\n/**\n * @hidden\n */\nfunction ignoreNextOnError() {\n // onerror should trigger before setTimeout\n ignoreOnError++;\n setTimeout(() => {\n ignoreOnError--;\n });\n}\n\n/**\n * Instruments the given function and sends an event to Sentry every time the\n * function throws an exception.\n *\n * @param fn A function to wrap. It is generally safe to pass an unbound function, because the returned wrapper always\n * has a correct `this` context.\n * @returns The wrapped function.\n * @hidden\n */\nfunction wrap(\n fn,\n options\n\n = {},\n before,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n) {\n // for future readers what this does is wrap a function and then create\n // a bi-directional wrapping between them.\n //\n // example: wrapped = wrap(original);\n // original.__sentry_wrapped__ -> wrapped\n // wrapped.__sentry_original__ -> original\n\n if (typeof fn !== 'function') {\n return fn;\n }\n\n try {\n // if we're dealing with a function that was previously wrapped, return\n // the original wrapper.\n const wrapper = fn.__sentry_wrapped__;\n if (wrapper) {\n if (typeof wrapper === 'function') {\n return wrapper;\n } else {\n // If we find that the `__sentry_wrapped__` function is not a function at the time of accessing it, it means\n // that something messed with it. In that case we want to return the originally passed function.\n return fn;\n }\n }\n\n // We don't wanna wrap it twice\n if (getOriginalFunction(fn)) {\n return fn;\n }\n } catch (e) {\n // Just accessing custom props in some Selenium environments\n // can cause a \"Permission denied\" exception (see raven-js#495).\n // Bail on wrapping and return the function as-is (defers to window.onerror).\n return fn;\n }\n\n /* eslint-disable prefer-rest-params */\n // It is important that `sentryWrapped` is not an arrow function to preserve the context of `this`\n const sentryWrapped = function () {\n const args = Array.prototype.slice.call(arguments);\n\n try {\n if (before && typeof before === 'function') ;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\n const wrappedArguments = args.map((arg) => wrap(arg, options));\n\n // Attempt to invoke user-land function\n // NOTE: If you are a Sentry user, and you are seeing this stack frame, it\n // means the sentry.javascript SDK caught an error invoking your application code. This\n // is expected behavior and NOT indicative of a bug with sentry.javascript.\n return fn.apply(this, wrappedArguments);\n } catch (ex) {\n ignoreNextOnError();\n\n withScope(scope => {\n scope.addEventProcessor(event => {\n if (options.mechanism) {\n addExceptionTypeValue(event, undefined, undefined);\n addExceptionMechanism(event, options.mechanism);\n }\n\n event.extra = {\n ...event.extra,\n arguments: args,\n };\n\n return event;\n });\n\n captureException(ex);\n });\n\n throw ex;\n }\n };\n /* eslint-enable prefer-rest-params */\n\n // Accessing some objects may throw\n // ref: https://github.com/getsentry/sentry-javascript/issues/1168\n try {\n for (const property in fn) {\n if (Object.prototype.hasOwnProperty.call(fn, property)) {\n sentryWrapped[property] = fn[property];\n }\n }\n } catch (_oO) {} // eslint-disable-line no-empty\n\n // Signal that this function has been wrapped/filled already\n // for both debugging and to prevent it to being wrapped/filled twice\n markFunctionWrapped(sentryWrapped, fn);\n\n addNonEnumerableProperty(fn, '__sentry_wrapped__', sentryWrapped);\n\n // Restore original function name (not all browsers allow that)\n try {\n const descriptor = Object.getOwnPropertyDescriptor(sentryWrapped, 'name') ;\n if (descriptor.configurable) {\n Object.defineProperty(sentryWrapped, 'name', {\n get() {\n return fn.name;\n },\n });\n }\n // eslint-disable-next-line no-empty\n } catch (_oO) {}\n\n return sentryWrapped;\n}\n\nexport { WINDOW, ignoreNextOnError, shouldIgnoreOnError, wrap };\n//# sourceMappingURL=helpers.js.map\n","/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nconst DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);\n\nexport { DEBUG_BUILD };\n//# sourceMappingURL=debug-build.js.map\n","import { getClient } from '@sentry/core';\nimport { addExceptionMechanism, resolvedSyncPromise, isErrorEvent, isDOMError, isDOMException, addExceptionTypeValue, isError, isPlainObject, isEvent, isParameterizedString, normalizeToSize, extractExceptionKeysForMessage } from '@sentry/utils';\n\n/**\n * This function creates an exception from a JavaScript Error\n */\nfunction exceptionFromError(stackParser, ex) {\n // Get the frames first since Opera can lose the stack if we touch anything else first\n const frames = parseStackFrames(stackParser, ex);\n\n const exception = {\n type: extractType(ex),\n value: extractMessage(ex),\n };\n\n if (frames.length) {\n exception.stacktrace = { frames };\n }\n\n if (exception.type === undefined && exception.value === '') {\n exception.value = 'Unrecoverable error caught';\n }\n\n return exception;\n}\n\nfunction eventFromPlainObject(\n stackParser,\n exception,\n syntheticException,\n isUnhandledRejection,\n) {\n const client = getClient();\n const normalizeDepth = client && client.getOptions().normalizeDepth;\n\n // If we can, we extract an exception from the object properties\n const errorFromProp = getErrorPropertyFromObject(exception);\n\n const extra = {\n __serialized__: normalizeToSize(exception, normalizeDepth),\n };\n\n if (errorFromProp) {\n return {\n exception: {\n values: [exceptionFromError(stackParser, errorFromProp)],\n },\n extra,\n };\n }\n\n const event = {\n exception: {\n values: [\n {\n type: isEvent(exception) ? exception.constructor.name : isUnhandledRejection ? 'UnhandledRejection' : 'Error',\n value: getNonErrorObjectExceptionValue(exception, { isUnhandledRejection }),\n } ,\n ],\n },\n extra,\n } ;\n\n if (syntheticException) {\n const frames = parseStackFrames(stackParser, syntheticException);\n if (frames.length) {\n // event.exception.values[0] has been set above\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n event.exception.values[0].stacktrace = { frames };\n }\n }\n\n return event;\n}\n\nfunction eventFromError(stackParser, ex) {\n return {\n exception: {\n values: [exceptionFromError(stackParser, ex)],\n },\n };\n}\n\n/** Parses stack frames from an error */\nfunction parseStackFrames(\n stackParser,\n ex,\n) {\n // Access and store the stacktrace property before doing ANYTHING\n // else to it because Opera is not very good at providing it\n // reliably in other circumstances.\n const stacktrace = ex.stacktrace || ex.stack || '';\n\n const skipLines = getSkipFirstStackStringLines(ex);\n const framesToPop = getPopFirstTopFrames(ex);\n\n try {\n return stackParser(stacktrace, skipLines, framesToPop);\n } catch (e) {\n // no-empty\n }\n\n return [];\n}\n\n// Based on our own mapping pattern - https://github.com/getsentry/sentry/blob/9f08305e09866c8bd6d0c24f5b0aabdd7dd6c59c/src/sentry/lang/javascript/errormapping.py#L83-L108\nconst reactMinifiedRegexp = /Minified React error #\\d+;/i;\n\n/**\n * Certain known React errors contain links that would be falsely\n * parsed as frames. This function check for these errors and\n * returns number of the stack string lines to skip.\n */\nfunction getSkipFirstStackStringLines(ex) {\n if (ex && reactMinifiedRegexp.test(ex.message)) {\n return 1;\n }\n\n return 0;\n}\n\n/**\n * If error has `framesToPop` property, it means that the\n * creator tells us the first x frames will be useless\n * and should be discarded. Typically error from wrapper function\n * which don't point to the actual location in the developer's code.\n *\n * Example: https://github.com/zertosh/invariant/blob/master/invariant.js#L46\n */\nfunction getPopFirstTopFrames(ex) {\n if (typeof ex.framesToPop === 'number') {\n return ex.framesToPop;\n }\n\n return 0;\n}\n\n// https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/Exception\n// @ts-expect-error - WebAssembly.Exception is a valid class\nfunction isWebAssemblyException(exception) {\n // Check for support\n // @ts-expect-error - WebAssembly.Exception is a valid class\n if (typeof WebAssembly !== 'undefined' && typeof WebAssembly.Exception !== 'undefined') {\n // @ts-expect-error - WebAssembly.Exception is a valid class\n return exception instanceof WebAssembly.Exception;\n } else {\n return false;\n }\n}\n\n/**\n * Extracts from errors what we use as the exception `type` in error events.\n *\n * Usually, this is the `name` property on Error objects but WASM errors need to be treated differently.\n */\nfunction extractType(ex) {\n const name = ex && ex.name;\n\n // The name for WebAssembly.Exception Errors needs to be extracted differently.\n // Context: https://github.com/getsentry/sentry-javascript/issues/13787\n if (!name && isWebAssemblyException(ex)) {\n // Emscripten sets array[type, message] to the \"message\" property on the WebAssembly.Exception object\n const hasTypeInMessage = ex.message && Array.isArray(ex.message) && ex.message.length == 2;\n return hasTypeInMessage ? ex.message[0] : 'WebAssembly.Exception';\n }\n\n return name;\n}\n\n/**\n * There are cases where stacktrace.message is an Event object\n * https://github.com/getsentry/sentry-javascript/issues/1949\n * In this specific case we try to extract stacktrace.message.error.message\n */\nfunction extractMessage(ex) {\n const message = ex && ex.message;\n\n if (!message) {\n return 'No error message';\n }\n\n if (message.error && typeof message.error.message === 'string') {\n return message.error.message;\n }\n\n // Emscripten sets array[type, message] to the \"message\" property on the WebAssembly.Exception object\n if (isWebAssemblyException(ex) && Array.isArray(ex.message) && ex.message.length == 2) {\n return ex.message[1];\n }\n\n return message;\n}\n\n/**\n * Creates an {@link Event} from all inputs to `captureException` and non-primitive inputs to `captureMessage`.\n * @hidden\n */\nfunction eventFromException(\n stackParser,\n exception,\n hint,\n attachStacktrace,\n) {\n const syntheticException = (hint && hint.syntheticException) || undefined;\n const event = eventFromUnknownInput(stackParser, exception, syntheticException, attachStacktrace);\n addExceptionMechanism(event); // defaults to { type: 'generic', handled: true }\n event.level = 'error';\n if (hint && hint.event_id) {\n event.event_id = hint.event_id;\n }\n return resolvedSyncPromise(event);\n}\n\n/**\n * Builds and Event from a Message\n * @hidden\n */\nfunction eventFromMessage(\n stackParser,\n message,\n level = 'info',\n hint,\n attachStacktrace,\n) {\n const syntheticException = (hint && hint.syntheticException) || undefined;\n const event = eventFromString(stackParser, message, syntheticException, attachStacktrace);\n event.level = level;\n if (hint && hint.event_id) {\n event.event_id = hint.event_id;\n }\n return resolvedSyncPromise(event);\n}\n\n/**\n * @hidden\n */\nfunction eventFromUnknownInput(\n stackParser,\n exception,\n syntheticException,\n attachStacktrace,\n isUnhandledRejection,\n) {\n let event;\n\n if (isErrorEvent(exception ) && (exception ).error) {\n // If it is an ErrorEvent with `error` property, extract it to get actual Error\n const errorEvent = exception ;\n return eventFromError(stackParser, errorEvent.error );\n }\n\n // If it is a `DOMError` (which is a legacy API, but still supported in some browsers) then we just extract the name\n // and message, as it doesn't provide anything else. According to the spec, all `DOMExceptions` should also be\n // `Error`s, but that's not the case in IE11, so in that case we treat it the same as we do a `DOMError`.\n //\n // https://developer.mozilla.org/en-US/docs/Web/API/DOMError\n // https://developer.mozilla.org/en-US/docs/Web/API/DOMException\n // https://webidl.spec.whatwg.org/#es-DOMException-specialness\n if (isDOMError(exception) || isDOMException(exception )) {\n const domException = exception ;\n\n if ('stack' in (exception )) {\n event = eventFromError(stackParser, exception );\n } else {\n const name = domException.name || (isDOMError(domException) ? 'DOMError' : 'DOMException');\n const message = domException.message ? `${name}: ${domException.message}` : name;\n event = eventFromString(stackParser, message, syntheticException, attachStacktrace);\n addExceptionTypeValue(event, message);\n }\n if ('code' in domException) {\n // eslint-disable-next-line deprecation/deprecation\n event.tags = { ...event.tags, 'DOMException.code': `${domException.code}` };\n }\n\n return event;\n }\n if (isError(exception)) {\n // we have a real Error object, do nothing\n return eventFromError(stackParser, exception);\n }\n if (isPlainObject(exception) || isEvent(exception)) {\n // If it's a plain object or an instance of `Event` (the built-in JS kind, not this SDK's `Event` type), serialize\n // it manually. This will allow us to group events based on top-level keys which is much better than creating a new\n // group on any key/value change.\n const objectException = exception ;\n event = eventFromPlainObject(stackParser, objectException, syntheticException, isUnhandledRejection);\n addExceptionMechanism(event, {\n synthetic: true,\n });\n return event;\n }\n\n // If none of previous checks were valid, then it means that it's not:\n // - an instance of DOMError\n // - an instance of DOMException\n // - an instance of Event\n // - an instance of Error\n // - a valid ErrorEvent (one with an error property)\n // - a plain Object\n //\n // So bail out and capture it as a simple message:\n event = eventFromString(stackParser, exception , syntheticException, attachStacktrace);\n addExceptionTypeValue(event, `${exception}`, undefined);\n addExceptionMechanism(event, {\n synthetic: true,\n });\n\n return event;\n}\n\nfunction eventFromString(\n stackParser,\n message,\n syntheticException,\n attachStacktrace,\n) {\n const event = {};\n\n if (attachStacktrace && syntheticException) {\n const frames = parseStackFrames(stackParser, syntheticException);\n if (frames.length) {\n event.exception = {\n values: [{ value: message, stacktrace: { frames } }],\n };\n }\n }\n\n if (isParameterizedString(message)) {\n const { __sentry_template_string__, __sentry_template_values__ } = message;\n\n event.logentry = {\n message: __sentry_template_string__,\n params: __sentry_template_values__,\n };\n return event;\n }\n\n event.message = message;\n return event;\n}\n\nfunction getNonErrorObjectExceptionValue(\n exception,\n { isUnhandledRejection },\n) {\n const keys = extractExceptionKeysForMessage(exception);\n const captureType = isUnhandledRejection ? 'promise rejection' : 'exception';\n\n // Some ErrorEvent instances do not have an `error` property, which is why they are not handled before\n // We still want to try to get a decent message for these cases\n if (isErrorEvent(exception)) {\n return `Event \\`ErrorEvent\\` captured as ${captureType} with message \\`${exception.message}\\``;\n }\n\n if (isEvent(exception)) {\n const className = getObjectClassName(exception);\n return `Event \\`${className}\\` (type=${exception.type}) captured as ${captureType}`;\n }\n\n return `Object captured as ${captureType} with keys: ${keys}`;\n}\n\nfunction getObjectClassName(obj) {\n try {\n const prototype = Object.getPrototypeOf(obj);\n return prototype ? prototype.constructor.name : undefined;\n } catch (e) {\n // ignore errors here\n }\n}\n\n/** If a plain object has a property that is an `Error`, return this error. */\nfunction getErrorPropertyFromObject(obj) {\n for (const prop in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, prop)) {\n const value = obj[prop];\n if (value instanceof Error) {\n return value;\n }\n }\n }\n\n return undefined;\n}\n\nexport { eventFromException, eventFromMessage, eventFromUnknownInput, exceptionFromError, extractMessage, extractType };\n//# sourceMappingURL=eventbuilder.js.map\n","import { dsnToString, createEnvelope } from '@sentry/utils';\n\n/**\n * Creates an envelope from a user feedback.\n */\nfunction createUserFeedbackEnvelope(\n feedback,\n {\n metadata,\n tunnel,\n dsn,\n }\n\n,\n) {\n const headers = {\n event_id: feedback.event_id,\n sent_at: new Date().toISOString(),\n ...(metadata &&\n metadata.sdk && {\n sdk: {\n name: metadata.sdk.name,\n version: metadata.sdk.version,\n },\n }),\n ...(!!tunnel && !!dsn && { dsn: dsnToString(dsn) }),\n };\n const item = createUserFeedbackEnvelopeItem(feedback);\n\n return createEnvelope(headers, [item]);\n}\n\nfunction createUserFeedbackEnvelopeItem(feedback) {\n const feedbackHeaders = {\n type: 'user_report',\n };\n return [feedbackHeaders, feedback];\n}\n\nexport { createUserFeedbackEnvelope };\n//# sourceMappingURL=userfeedback.js.map\n","import { BaseClient, applySdkMetadata } from '@sentry/core';\nimport { getSDKSource, logger } from '@sentry/utils';\nimport { DEBUG_BUILD } from './debug-build.js';\nimport { eventFromException, eventFromMessage } from './eventbuilder.js';\nimport { WINDOW } from './helpers.js';\nimport { createUserFeedbackEnvelope } from './userfeedback.js';\n\n/**\n * Configuration options for the Sentry Browser SDK.\n * @see @sentry/types Options for more information.\n */\n\n/**\n * The Sentry Browser SDK Client.\n *\n * @see BrowserOptions for documentation on configuration options.\n * @see SentryClient for usage documentation.\n */\nclass BrowserClient extends BaseClient {\n /**\n * Creates a new Browser SDK instance.\n *\n * @param options Configuration options for this SDK.\n */\n constructor(options) {\n const opts = {\n // We default this to true, as it is the safer scenario\n parentSpanIsAlwaysRootSpan: true,\n ...options,\n };\n const sdkSource = WINDOW.SENTRY_SDK_SOURCE || getSDKSource();\n applySdkMetadata(opts, 'browser', ['browser'], sdkSource);\n\n super(opts);\n\n if (opts.sendClientReports && WINDOW.document) {\n WINDOW.document.addEventListener('visibilitychange', () => {\n if (WINDOW.document.visibilityState === 'hidden') {\n this._flushOutcomes();\n }\n });\n }\n }\n\n /**\n * @inheritDoc\n */\n eventFromException(exception, hint) {\n return eventFromException(this._options.stackParser, exception, hint, this._options.attachStacktrace);\n }\n\n /**\n * @inheritDoc\n */\n eventFromMessage(\n message,\n level = 'info',\n hint,\n ) {\n return eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace);\n }\n\n /**\n * Sends user feedback to Sentry.\n *\n * @deprecated Use `captureFeedback` instead.\n */\n captureUserFeedback(feedback) {\n if (!this._isEnabled()) {\n DEBUG_BUILD && logger.warn('SDK not enabled, will not capture user feedback.');\n return;\n }\n\n const envelope = createUserFeedbackEnvelope(feedback, {\n metadata: this.getSdkMetadata(),\n dsn: this.getDsn(),\n tunnel: this.getOptions().tunnel,\n });\n\n // sendEnvelope should not throw\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.sendEnvelope(envelope);\n }\n\n /**\n * @inheritDoc\n */\n _prepareEvent(event, hint, scope) {\n event.platform = event.platform || 'javascript';\n return super._prepareEvent(event, hint, scope);\n }\n}\n\nexport { BrowserClient };\n//# sourceMappingURL=client.js.map\n","/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nconst DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);\n\nexport { DEBUG_BUILD };\n//# sourceMappingURL=debug-build.js.map\n","const getRating = (value, thresholds) => {\n if (value > thresholds[1]) {\n return 'poor';\n }\n if (value > thresholds[0]) {\n return 'needs-improvement';\n }\n return 'good';\n};\n\nconst bindReporter = (\n callback,\n metric,\n thresholds,\n reportAllChanges,\n) => {\n let prevValue;\n let delta;\n return (forceReport) => {\n if (metric.value >= 0) {\n if (forceReport || reportAllChanges) {\n delta = metric.value - (prevValue || 0);\n\n // Report the metric if there's a non-zero delta or if no previous\n // value exists (which can happen in the case of the document becoming\n // hidden when the metric value is 0).\n // See: https://github.com/GoogleChrome/web-vitals/issues/14\n if (delta || prevValue === undefined) {\n prevValue = metric.value;\n metric.delta = delta;\n metric.rating = getRating(metric.value, thresholds);\n callback(metric);\n }\n }\n }\n };\n};\n\nexport { bindReporter };\n//# sourceMappingURL=bindReporter.js.map\n","import { GLOBAL_OBJ } from '@sentry/utils';\n\nconst WINDOW = GLOBAL_OBJ\n\n;\n\nexport { WINDOW };\n//# sourceMappingURL=types.js.map\n","/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Performantly generate a unique, 30-char string by combining a version\n * number, the current timestamp with a 13-digit number integer.\n * @return {string}\n */\nconst generateUniqueID = () => {\n return `v3-${Date.now()}-${Math.floor(Math.random() * (9e12 - 1)) + 1e12}`;\n};\n\nexport { generateUniqueID };\n//# sourceMappingURL=generateUniqueID.js.map\n","import { WINDOW } from '../../../types.js';\n\n/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nconst getNavigationEntry = () => {\n return WINDOW.performance && performance.getEntriesByType && performance.getEntriesByType('navigation')[0];\n};\n\nexport { getNavigationEntry };\n//# sourceMappingURL=getNavigationEntry.js.map\n","import { getNavigationEntry } from './getNavigationEntry.js';\n\n/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nconst getActivationStart = () => {\n const navEntry = getNavigationEntry();\n return (navEntry && navEntry.activationStart) || 0;\n};\n\nexport { getActivationStart };\n//# sourceMappingURL=getActivationStart.js.map\n","import { WINDOW } from '../../../types.js';\nimport { generateUniqueID } from './generateUniqueID.js';\nimport { getActivationStart } from './getActivationStart.js';\nimport { getNavigationEntry } from './getNavigationEntry.js';\n\n/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nconst initMetric = (name, value) => {\n const navEntry = getNavigationEntry();\n let navigationType = 'navigate';\n\n if (navEntry) {\n if ((WINDOW.document && WINDOW.document.prerendering) || getActivationStart() > 0) {\n navigationType = 'prerender';\n } else if (WINDOW.document && WINDOW.document.wasDiscarded) {\n navigationType = 'restore';\n } else if (navEntry.type) {\n navigationType = navEntry.type.replace(/_/g, '-') ;\n }\n }\n\n // Use `entries` type specific for the metric.\n const entries = [];\n\n return {\n name,\n value: typeof value === 'undefined' ? -1 : value,\n rating: 'good' , // If needed, will be updated when reported. `const` to keep the type from widening to `string`.\n delta: 0,\n entries,\n id: generateUniqueID(),\n navigationType,\n };\n};\n\nexport { initMetric };\n//# sourceMappingURL=initMetric.js.map\n","/**\n * Takes a performance entry type and a callback function, and creates a\n * `PerformanceObserver` instance that will observe the specified entry type\n * with buffering enabled and call the callback _for each entry_.\n *\n * This function also feature-detects entry support and wraps the logic in a\n * try/catch to avoid errors in unsupporting browsers.\n */\nconst observe = (\n type,\n callback,\n opts,\n) => {\n try {\n if (PerformanceObserver.supportedEntryTypes.includes(type)) {\n const po = new PerformanceObserver(list => {\n // Delay by a microtask to workaround a bug in Safari where the\n // callback is invoked immediately, rather than in a separate task.\n // See: https://github.com/GoogleChrome/web-vitals/issues/277\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n Promise.resolve().then(() => {\n callback(list.getEntries() );\n });\n });\n po.observe(\n Object.assign(\n {\n type,\n buffered: true,\n },\n opts || {},\n ) ,\n );\n return po;\n }\n } catch (e) {\n // Do nothing.\n }\n return;\n};\n\nexport { observe };\n//# sourceMappingURL=observe.js.map\n","import { WINDOW } from '../../../types.js';\n\n/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nconst onHidden = (cb) => {\n const onHiddenOrPageHide = (event) => {\n if (event.type === 'pagehide' || (WINDOW.document && WINDOW.document.visibilityState === 'hidden')) {\n cb(event);\n }\n };\n\n if (WINDOW.document) {\n addEventListener('visibilitychange', onHiddenOrPageHide, true);\n // Some browsers have buggy implementations of visibilitychange,\n // so we use pagehide in addition, just to be safe.\n addEventListener('pagehide', onHiddenOrPageHide, true);\n }\n};\n\nexport { onHidden };\n//# sourceMappingURL=onHidden.js.map\n","/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst runOnce = (cb) => {\n let called = false;\n return (arg) => {\n if (!called) {\n cb(arg);\n called = true;\n }\n };\n};\n\nexport { runOnce };\n//# sourceMappingURL=runOnce.js.map\n","import { WINDOW } from '../../../types.js';\n\n/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nlet firstHiddenTime = -1;\n\nconst initHiddenTime = () => {\n // If the document is hidden when this code runs, assume it was always\n // hidden and the page was loaded in the background, with the one exception\n // that visibility state is always 'hidden' during prerendering, so we have\n // to ignore that case until prerendering finishes (see: `prerenderingchange`\n // event logic below).\n firstHiddenTime = WINDOW.document.visibilityState === 'hidden' && !WINDOW.document.prerendering ? 0 : Infinity;\n};\n\nconst onVisibilityUpdate = (event) => {\n // If the document is 'hidden' and no previous hidden timestamp has been\n // set, update it based on the current event data.\n if (WINDOW.document.visibilityState === 'hidden' && firstHiddenTime > -1) {\n // If the event is a 'visibilitychange' event, it means the page was\n // visible prior to this change, so the event timestamp is the first\n // hidden time.\n // However, if the event is not a 'visibilitychange' event, then it must\n // be a 'prerenderingchange' event, and the fact that the document is\n // still 'hidden' from the above check means the tab was activated\n // in a background state and so has always been hidden.\n firstHiddenTime = event.type === 'visibilitychange' ? event.timeStamp : 0;\n\n // Remove all listeners now that a `firstHiddenTime` value has been set.\n removeEventListener('visibilitychange', onVisibilityUpdate, true);\n removeEventListener('prerenderingchange', onVisibilityUpdate, true);\n }\n};\n\nconst addChangeListeners = () => {\n addEventListener('visibilitychange', onVisibilityUpdate, true);\n // IMPORTANT: when a page is prerendering, its `visibilityState` is\n // 'hidden', so in order to account for cases where this module checks for\n // visibility during prerendering, an additional check after prerendering\n // completes is also required.\n addEventListener('prerenderingchange', onVisibilityUpdate, true);\n};\n\nconst getVisibilityWatcher = () => {\n if (WINDOW.document && firstHiddenTime < 0) {\n // If the document is hidden when this code runs, assume it was hidden\n // since navigation start. This isn't a perfect heuristic, but it's the\n // best we can do until an API is available to support querying past\n // visibilityState.\n initHiddenTime();\n addChangeListeners();\n }\n return {\n get firstHiddenTime() {\n return firstHiddenTime;\n },\n };\n};\n\nexport { getVisibilityWatcher };\n//# sourceMappingURL=getVisibilityWatcher.js.map\n","import { WINDOW } from '../../../types.js';\n\n/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nconst whenActivated = (callback) => {\n if (WINDOW.document && WINDOW.document.prerendering) {\n addEventListener('prerenderingchange', () => callback(), true);\n } else {\n callback();\n }\n};\n\nexport { whenActivated };\n//# sourceMappingURL=whenActivated.js.map\n","import { bindReporter } from './lib/bindReporter.js';\nimport { getActivationStart } from './lib/getActivationStart.js';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher.js';\nimport { initMetric } from './lib/initMetric.js';\nimport { observe } from './lib/observe.js';\nimport { whenActivated } from './lib/whenActivated.js';\n\n/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/** Thresholds for FCP. See https://web.dev/articles/fcp#what_is_a_good_fcp_score */\nconst FCPThresholds = [1800, 3000];\n\n/**\n * Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and\n * calls the `callback` function once the value is ready, along with the\n * relevant `paint` performance entry used to determine the value. The reported\n * value is a `DOMHighResTimeStamp`.\n */\nconst onFCP = (onReport, opts = {}) => {\n whenActivated(() => {\n const visibilityWatcher = getVisibilityWatcher();\n const metric = initMetric('FCP');\n let report;\n\n const handleEntries = (entries) => {\n (entries ).forEach(entry => {\n if (entry.name === 'first-contentful-paint') {\n po.disconnect();\n\n // Only report if the page wasn't hidden prior to the first paint.\n if (entry.startTime < visibilityWatcher.firstHiddenTime) {\n // The activationStart reference is used because FCP should be\n // relative to page activation rather than navigation start if the\n // page was prerendered. But in cases where `activationStart` occurs\n // after the FCP, this time should be clamped at 0.\n metric.value = Math.max(entry.startTime - getActivationStart(), 0);\n metric.entries.push(entry);\n report(true);\n }\n }\n });\n };\n\n const po = observe('paint', handleEntries);\n\n if (po) {\n report = bindReporter(onReport, metric, FCPThresholds, opts.reportAllChanges);\n }\n });\n};\n\nexport { FCPThresholds, onFCP };\n//# sourceMappingURL=onFCP.js.map\n","import { bindReporter } from './lib/bindReporter.js';\nimport { initMetric } from './lib/initMetric.js';\nimport { observe } from './lib/observe.js';\nimport { onHidden } from './lib/onHidden.js';\nimport { runOnce } from './lib/runOnce.js';\nimport { onFCP } from './onFCP.js';\n\n/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/** Thresholds for CLS. See https://web.dev/articles/cls#what_is_a_good_cls_score */\nconst CLSThresholds = [0.1, 0.25];\n\n/**\n * Calculates the [CLS](https://web.dev/articles/cls) value for the current page and\n * calls the `callback` function once the value is ready to be reported, along\n * with all `layout-shift` performance entries that were used in the metric\n * value calculation. The reported value is a `double` (corresponding to a\n * [layout shift score](https://web.dev/articles/cls#layout_shift_score)).\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called as soon as the value is initially\n * determined as well as any time the value changes throughout the page\n * lifespan.\n *\n * _**Important:** CLS should be continually monitored for changes throughout\n * the entire lifespan of a page—including if the user returns to the page after\n * it's been hidden/backgrounded. However, since browsers often [will not fire\n * additional callbacks once the user has backgrounded a\n * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),\n * `callback` is always called when the page's visibility state changes to\n * hidden. As a result, the `callback` function might be called multiple times\n * during the same page load._\n */\nconst onCLS = (onReport, opts = {}) => {\n // Start monitoring FCP so we can only report CLS if FCP is also reported.\n // Note: this is done to match the current behavior of CrUX.\n onFCP(\n runOnce(() => {\n const metric = initMetric('CLS', 0);\n let report;\n\n let sessionValue = 0;\n let sessionEntries = [];\n\n const handleEntries = (entries) => {\n entries.forEach(entry => {\n // Only count layout shifts without recent user input.\n if (!entry.hadRecentInput) {\n const firstSessionEntry = sessionEntries[0];\n const lastSessionEntry = sessionEntries[sessionEntries.length - 1];\n\n // If the entry occurred less than 1 second after the previous entry\n // and less than 5 seconds after the first entry in the session,\n // include the entry in the current session. Otherwise, start a new\n // session.\n if (\n sessionValue &&\n firstSessionEntry &&\n lastSessionEntry &&\n entry.startTime - lastSessionEntry.startTime < 1000 &&\n entry.startTime - firstSessionEntry.startTime < 5000\n ) {\n sessionValue += entry.value;\n sessionEntries.push(entry);\n } else {\n sessionValue = entry.value;\n sessionEntries = [entry];\n }\n }\n });\n\n // If the current session value is larger than the current CLS value,\n // update CLS and the entries contributing to it.\n if (sessionValue > metric.value) {\n metric.value = sessionValue;\n metric.entries = sessionEntries;\n report();\n }\n };\n\n const po = observe('layout-shift', handleEntries);\n if (po) {\n report = bindReporter(onReport, metric, CLSThresholds, opts.reportAllChanges);\n\n onHidden(() => {\n handleEntries(po.takeRecords() );\n report(true);\n });\n\n // Queue a task to report (if nothing else triggers a report first).\n // This allows CLS to be reported as soon as FCP fires when\n // `reportAllChanges` is true.\n setTimeout(report, 0);\n }\n }),\n );\n};\n\nexport { CLSThresholds, onCLS };\n//# sourceMappingURL=getCLS.js.map\n","import { bindReporter } from './lib/bindReporter.js';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher.js';\nimport { initMetric } from './lib/initMetric.js';\nimport { observe } from './lib/observe.js';\nimport { onHidden } from './lib/onHidden.js';\nimport { runOnce } from './lib/runOnce.js';\nimport { whenActivated } from './lib/whenActivated.js';\n\n/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/** Thresholds for FID. See https://web.dev/articles/fid#what_is_a_good_fid_score */\nconst FIDThresholds = [100, 300];\n\n/**\n * Calculates the [FID](https://web.dev/articles/fid) value for the current page and\n * calls the `callback` function once the value is ready, along with the\n * relevant `first-input` performance entry used to determine the value. The\n * reported value is a `DOMHighResTimeStamp`.\n *\n * _**Important:** since FID is only reported after the user interacts with the\n * page, it's possible that it will not be reported for some page loads._\n */\nconst onFID = (onReport, opts = {}) => {\n whenActivated(() => {\n const visibilityWatcher = getVisibilityWatcher();\n const metric = initMetric('FID');\n // eslint-disable-next-line prefer-const\n let report;\n\n const handleEntry = (entry) => {\n // Only report if the page wasn't hidden prior to the first input.\n if (entry.startTime < visibilityWatcher.firstHiddenTime) {\n metric.value = entry.processingStart - entry.startTime;\n metric.entries.push(entry);\n report(true);\n }\n };\n\n const handleEntries = (entries) => {\n (entries ).forEach(handleEntry);\n };\n\n const po = observe('first-input', handleEntries);\n report = bindReporter(onReport, metric, FIDThresholds, opts.reportAllChanges);\n\n if (po) {\n onHidden(\n runOnce(() => {\n handleEntries(po.takeRecords() );\n po.disconnect();\n }),\n );\n }\n });\n};\n\nexport { FIDThresholds, onFID };\n//# sourceMappingURL=getFID.js.map\n","import { observe } from '../observe.js';\n\nlet interactionCountEstimate = 0;\nlet minKnownInteractionId = Infinity;\nlet maxKnownInteractionId = 0;\n\nconst updateEstimate = (entries) => {\n (entries ).forEach(e => {\n if (e.interactionId) {\n minKnownInteractionId = Math.min(minKnownInteractionId, e.interactionId);\n maxKnownInteractionId = Math.max(maxKnownInteractionId, e.interactionId);\n\n interactionCountEstimate = maxKnownInteractionId ? (maxKnownInteractionId - minKnownInteractionId) / 7 + 1 : 0;\n }\n });\n};\n\nlet po;\n\n/**\n * Returns the `interactionCount` value using the native API (if available)\n * or the polyfill estimate in this module.\n */\nconst getInteractionCount = () => {\n return po ? interactionCountEstimate : performance.interactionCount || 0;\n};\n\n/**\n * Feature detects native support or initializes the polyfill if needed.\n */\nconst initInteractionCountPolyfill = () => {\n if ('interactionCount' in performance || po) return;\n\n po = observe('event', updateEstimate, {\n type: 'event',\n buffered: true,\n durationThreshold: 0,\n } );\n};\n\nexport { getInteractionCount, initInteractionCountPolyfill };\n//# sourceMappingURL=interactionCountPolyfill.js.map\n","import { WINDOW } from '../../types.js';\nimport { bindReporter } from './lib/bindReporter.js';\nimport { initMetric } from './lib/initMetric.js';\nimport { observe } from './lib/observe.js';\nimport { onHidden } from './lib/onHidden.js';\nimport { initInteractionCountPolyfill, getInteractionCount } from './lib/polyfills/interactionCountPolyfill.js';\nimport { whenActivated } from './lib/whenActivated.js';\n\n/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/** Thresholds for INP. See https://web.dev/articles/inp#what_is_a_good_inp_score */\nconst INPThresholds = [200, 500];\n\n// Used to store the interaction count after a bfcache restore, since p98\n// interaction latencies should only consider the current navigation.\nconst prevInteractionCount = 0;\n\n/**\n * Returns the interaction count since the last bfcache restore (or for the\n * full page lifecycle if there were no bfcache restores).\n */\nconst getInteractionCountForNavigation = () => {\n return getInteractionCount() - prevInteractionCount;\n};\n\n// To prevent unnecessary memory usage on pages with lots of interactions,\n// store at most 10 of the longest interactions to consider as INP candidates.\nconst MAX_INTERACTIONS_TO_CONSIDER = 10;\n\n// A list of longest interactions on the page (by latency) sorted so the\n// longest one is first. The list is as most MAX_INTERACTIONS_TO_CONSIDER long.\nconst longestInteractionList = [];\n\n// A mapping of longest interactions by their interaction ID.\n// This is used for faster lookup.\nconst longestInteractionMap = {};\n\n/**\n * Takes a performance entry and adds it to the list of worst interactions\n * if its duration is long enough to make it among the worst. If the\n * entry is part of an existing interaction, it is merged and the latency\n * and entries list is updated as needed.\n */\nconst processEntry = (entry) => {\n // The least-long of the 10 longest interactions.\n const minLongestInteraction = longestInteractionList[longestInteractionList.length - 1];\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const existingInteraction = longestInteractionMap[entry.interactionId];\n\n // Only process the entry if it's possibly one of the ten longest,\n // or if it's part of an existing interaction.\n if (\n existingInteraction ||\n longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER ||\n (minLongestInteraction && entry.duration > minLongestInteraction.latency)\n ) {\n // If the interaction already exists, update it. Otherwise create one.\n if (existingInteraction) {\n existingInteraction.entries.push(entry);\n existingInteraction.latency = Math.max(existingInteraction.latency, entry.duration);\n } else {\n const interaction = {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n id: entry.interactionId,\n latency: entry.duration,\n entries: [entry],\n };\n longestInteractionMap[interaction.id] = interaction;\n longestInteractionList.push(interaction);\n }\n\n // Sort the entries by latency (descending) and keep only the top ten.\n longestInteractionList.sort((a, b) => b.latency - a.latency);\n longestInteractionList.splice(MAX_INTERACTIONS_TO_CONSIDER).forEach(i => {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete longestInteractionMap[i.id];\n });\n }\n};\n\n/**\n * Returns the estimated p98 longest interaction based on the stored\n * interaction candidates and the interaction count for the current page.\n */\nconst estimateP98LongestInteraction = () => {\n const candidateInteractionIndex = Math.min(\n longestInteractionList.length - 1,\n Math.floor(getInteractionCountForNavigation() / 50),\n );\n\n return longestInteractionList[candidateInteractionIndex];\n};\n\n/**\n * Calculates the [INP](https://web.dev/articles/inp) value for the current\n * page and calls the `callback` function once the value is ready, along with\n * the `event` performance entries reported for that interaction. The reported\n * value is a `DOMHighResTimeStamp`.\n *\n * A custom `durationThreshold` configuration option can optionally be passed to\n * control what `event-timing` entries are considered for INP reporting. The\n * default threshold is `40`, which means INP scores of less than 40 are\n * reported as 0. Note that this will not affect your 75th percentile INP value\n * unless that value is also less than 40 (well below the recommended\n * [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold).\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called as soon as the value is initially\n * determined as well as any time the value changes throughout the page\n * lifespan.\n *\n * _**Important:** INP should be continually monitored for changes throughout\n * the entire lifespan of a page—including if the user returns to the page after\n * it's been hidden/backgrounded. However, since browsers often [will not fire\n * additional callbacks once the user has backgrounded a\n * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),\n * `callback` is always called when the page's visibility state changes to\n * hidden. As a result, the `callback` function might be called multiple times\n * during the same page load._\n */\nconst onINP = (onReport, opts = {}) => {\n whenActivated(() => {\n // TODO(philipwalton): remove once the polyfill is no longer needed.\n initInteractionCountPolyfill();\n\n const metric = initMetric('INP');\n // eslint-disable-next-line prefer-const\n let report;\n\n const handleEntries = (entries) => {\n entries.forEach(entry => {\n if (entry.interactionId) {\n processEntry(entry);\n }\n\n // Entries of type `first-input` don't currently have an `interactionId`,\n // so to consider them in INP we have to first check that an existing\n // entry doesn't match the `duration` and `startTime`.\n // Note that this logic assumes that `event` entries are dispatched\n // before `first-input` entries. This is true in Chrome (the only browser\n // that currently supports INP).\n // TODO(philipwalton): remove once crbug.com/1325826 is fixed.\n if (entry.entryType === 'first-input') {\n const noMatchingEntry = !longestInteractionList.some(interaction => {\n return interaction.entries.some(prevEntry => {\n return entry.duration === prevEntry.duration && entry.startTime === prevEntry.startTime;\n });\n });\n if (noMatchingEntry) {\n processEntry(entry);\n }\n }\n });\n\n const inp = estimateP98LongestInteraction();\n\n if (inp && inp.latency !== metric.value) {\n metric.value = inp.latency;\n metric.entries = inp.entries;\n report();\n }\n };\n\n const po = observe('event', handleEntries, {\n // Event Timing entries have their durations rounded to the nearest 8ms,\n // so a duration of 40ms would be any event that spans 2.5 or more frames\n // at 60Hz. This threshold is chosen to strike a balance between usefulness\n // and performance. Running this callback for any interaction that spans\n // just one or two frames is likely not worth the insight that could be\n // gained.\n durationThreshold: opts.durationThreshold != null ? opts.durationThreshold : 40,\n } );\n\n report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges);\n\n if (po) {\n // If browser supports interactionId (and so supports INP), also\n // observe entries of type `first-input`. This is useful in cases\n // where the first interaction is less than the `durationThreshold`.\n if ('PerformanceEventTiming' in WINDOW && 'interactionId' in PerformanceEventTiming.prototype) {\n po.observe({ type: 'first-input', buffered: true });\n }\n\n onHidden(() => {\n handleEntries(po.takeRecords() );\n\n // If the interaction count shows that there were interactions but\n // none were captured by the PerformanceObserver, report a latency of 0.\n if (metric.value < 0 && getInteractionCountForNavigation() > 0) {\n metric.value = 0;\n metric.entries = [];\n }\n\n report(true);\n });\n }\n });\n};\n\nexport { INPThresholds, onINP };\n//# sourceMappingURL=getINP.js.map\n","import { WINDOW } from '../../types.js';\nimport { bindReporter } from './lib/bindReporter.js';\nimport { getActivationStart } from './lib/getActivationStart.js';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher.js';\nimport { initMetric } from './lib/initMetric.js';\nimport { observe } from './lib/observe.js';\nimport { onHidden } from './lib/onHidden.js';\nimport { runOnce } from './lib/runOnce.js';\nimport { whenActivated } from './lib/whenActivated.js';\n\n/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */\nconst LCPThresholds = [2500, 4000];\n\nconst reportedMetricIDs = {};\n\n/**\n * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and\n * calls the `callback` function once the value is ready (along with the\n * relevant `largest-contentful-paint` performance entry used to determine the\n * value). The reported value is a `DOMHighResTimeStamp`.\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called any time a new `largest-contentful-paint`\n * performance entry is dispatched, or once the final value of the metric has\n * been determined.\n */\nconst onLCP = (onReport, opts = {}) => {\n whenActivated(() => {\n const visibilityWatcher = getVisibilityWatcher();\n const metric = initMetric('LCP');\n let report;\n\n const handleEntries = (entries) => {\n const lastEntry = entries[entries.length - 1] ;\n if (lastEntry) {\n // Only report if the page wasn't hidden prior to LCP.\n if (lastEntry.startTime < visibilityWatcher.firstHiddenTime) {\n // The startTime attribute returns the value of the renderTime if it is\n // not 0, and the value of the loadTime otherwise. The activationStart\n // reference is used because LCP should be relative to page activation\n // rather than navigation start if the page was prerendered. But in cases\n // where `activationStart` occurs after the LCP, this time should be\n // clamped at 0.\n metric.value = Math.max(lastEntry.startTime - getActivationStart(), 0);\n metric.entries = [lastEntry];\n report();\n }\n }\n };\n\n const po = observe('largest-contentful-paint', handleEntries);\n\n if (po) {\n report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges);\n\n const stopListening = runOnce(() => {\n if (!reportedMetricIDs[metric.id]) {\n handleEntries(po.takeRecords() );\n po.disconnect();\n reportedMetricIDs[metric.id] = true;\n report(true);\n }\n });\n\n // Stop listening after input. Note: while scrolling is an input that\n // stops LCP observation, it's unreliable since it can be programmatically\n // generated. See: https://github.com/GoogleChrome/web-vitals/issues/75\n ['keydown', 'click'].forEach(type => {\n if (WINDOW.document) {\n // Wrap in a setTimeout so the callback is run in a separate task\n // to avoid extending the keyboard/click handler to reduce INP impact\n // https://github.com/GoogleChrome/web-vitals/issues/383\n addEventListener(type, () => setTimeout(stopListening, 0), true);\n }\n });\n\n onHidden(stopListening);\n }\n });\n};\n\nexport { LCPThresholds, onLCP };\n//# sourceMappingURL=getLCP.js.map\n","import { WINDOW } from '../../types.js';\nimport { bindReporter } from './lib/bindReporter.js';\nimport { getActivationStart } from './lib/getActivationStart.js';\nimport { getNavigationEntry } from './lib/getNavigationEntry.js';\nimport { initMetric } from './lib/initMetric.js';\nimport { whenActivated } from './lib/whenActivated.js';\n\n/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n/** Thresholds for TTFB. See https://web.dev/articles/ttfb#what_is_a_good_ttfb_score */\nconst TTFBThresholds = [800, 1800];\n\n/**\n * Runs in the next task after the page is done loading and/or prerendering.\n * @param callback\n */\nconst whenReady = (callback) => {\n if (WINDOW.document && WINDOW.document.prerendering) {\n whenActivated(() => whenReady(callback));\n } else if (WINDOW.document && WINDOW.document.readyState !== 'complete') {\n addEventListener('load', () => whenReady(callback), true);\n } else {\n // Queue a task so the callback runs after `loadEventEnd`.\n setTimeout(callback, 0);\n }\n};\n\n/**\n * Calculates the [TTFB](https://web.dev/articles/ttfb) value for the\n * current page and calls the `callback` function once the page has loaded,\n * along with the relevant `navigation` performance entry used to determine the\n * value. The reported value is a `DOMHighResTimeStamp`.\n *\n * Note, this function waits until after the page is loaded to call `callback`\n * in order to ensure all properties of the `navigation` entry are populated.\n * This is useful if you want to report on other metrics exposed by the\n * [Navigation Timing API](https://w3c.github.io/navigation-timing/). For\n * example, the TTFB metric starts from the page's [time\n * origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it\n * includes time spent on DNS lookup, connection negotiation, network latency,\n * and server processing time.\n */\nconst onTTFB = (onReport, opts = {}) => {\n const metric = initMetric('TTFB');\n const report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges);\n\n whenReady(() => {\n const navEntry = getNavigationEntry();\n\n if (navEntry) {\n const responseStart = navEntry.responseStart;\n\n // In some cases no value is reported by the browser (for\n // privacy/security reasons), and in other cases (bugs) the value is\n // negative or is larger than the current page time. Ignore these cases:\n // https://github.com/GoogleChrome/web-vitals/issues/137\n // https://github.com/GoogleChrome/web-vitals/issues/162\n // https://github.com/GoogleChrome/web-vitals/issues/275\n if (responseStart <= 0 || responseStart > performance.now()) return;\n\n // The activationStart reference is used because TTFB should be\n // relative to page activation rather than navigation start if the\n // page was prerendered. But in cases where `activationStart` occurs\n // after the first byte is received, this time should be clamped at 0.\n metric.value = Math.max(responseStart - getActivationStart(), 0);\n\n metric.entries = [navEntry];\n report(true);\n }\n });\n};\n\nexport { TTFBThresholds, onTTFB };\n//# sourceMappingURL=onTTFB.js.map\n","import { logger, getFunctionName } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build.js';\nimport { onCLS } from './web-vitals/getCLS.js';\nimport { onFID } from './web-vitals/getFID.js';\nimport { onINP } from './web-vitals/getINP.js';\nimport { onLCP } from './web-vitals/getLCP.js';\nimport { observe } from './web-vitals/lib/observe.js';\nimport { onTTFB } from './web-vitals/onTTFB.js';\n\nconst handlers = {};\nconst instrumented = {};\n\nlet _previousCls;\nlet _previousFid;\nlet _previousLcp;\nlet _previousTtfb;\nlet _previousInp;\n\n/**\n * Add a callback that will be triggered when a CLS metric is available.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n *\n * Pass `stopOnCallback = true` to stop listening for CLS when the cleanup callback is called.\n * This will lead to the CLS being finalized and frozen.\n */\nfunction addClsInstrumentationHandler(\n callback,\n stopOnCallback = false,\n) {\n return addMetricObserver('cls', callback, instrumentCls, _previousCls, stopOnCallback);\n}\n\n/**\n * Add a callback that will be triggered when a LCP metric is available.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n *\n * Pass `stopOnCallback = true` to stop listening for LCP when the cleanup callback is called.\n * This will lead to the LCP being finalized and frozen.\n */\nfunction addLcpInstrumentationHandler(\n callback,\n stopOnCallback = false,\n) {\n return addMetricObserver('lcp', callback, instrumentLcp, _previousLcp, stopOnCallback);\n}\n\n/**\n * Add a callback that will be triggered when a FID metric is available.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n */\nfunction addFidInstrumentationHandler(callback) {\n return addMetricObserver('fid', callback, instrumentFid, _previousFid);\n}\n\n/**\n * Add a callback that will be triggered when a FID metric is available.\n */\nfunction addTtfbInstrumentationHandler(callback) {\n return addMetricObserver('ttfb', callback, instrumentTtfb, _previousTtfb);\n}\n\n/**\n * Add a callback that will be triggered when a INP metric is available.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n */\nfunction addInpInstrumentationHandler(\n callback,\n) {\n return addMetricObserver('inp', callback, instrumentInp, _previousInp);\n}\n\n/**\n * Add a callback that will be triggered when a performance observer is triggered,\n * and receives the entries of the observer.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n */\nfunction addPerformanceInstrumentationHandler(\n type,\n callback,\n) {\n addHandler(type, callback);\n\n if (!instrumented[type]) {\n instrumentPerformanceObserver(type);\n instrumented[type] = true;\n }\n\n return getCleanupCallback(type, callback);\n}\n\n/** Trigger all handlers of a given type. */\nfunction triggerHandlers(type, data) {\n const typeHandlers = handlers[type];\n\n if (!typeHandlers || !typeHandlers.length) {\n return;\n }\n\n for (const handler of typeHandlers) {\n try {\n handler(data);\n } catch (e) {\n DEBUG_BUILD &&\n logger.error(\n `Error while triggering instrumentation handler.\\nType: ${type}\\nName: ${getFunctionName(handler)}\\nError:`,\n e,\n );\n }\n }\n}\n\nfunction instrumentCls() {\n return onCLS(\n metric => {\n triggerHandlers('cls', {\n metric,\n });\n _previousCls = metric;\n },\n // We want the callback to be called whenever the CLS value updates.\n // By default, the callback is only called when the tab goes to the background.\n { reportAllChanges: true },\n );\n}\n\nfunction instrumentFid() {\n return onFID(metric => {\n triggerHandlers('fid', {\n metric,\n });\n _previousFid = metric;\n });\n}\n\nfunction instrumentLcp() {\n return onLCP(\n metric => {\n triggerHandlers('lcp', {\n metric,\n });\n _previousLcp = metric;\n },\n // We want the callback to be called whenever the LCP value updates.\n // By default, the callback is only called when the tab goes to the background.\n { reportAllChanges: true },\n );\n}\n\nfunction instrumentTtfb() {\n return onTTFB(metric => {\n triggerHandlers('ttfb', {\n metric,\n });\n _previousTtfb = metric;\n });\n}\n\nfunction instrumentInp() {\n return onINP(metric => {\n triggerHandlers('inp', {\n metric,\n });\n _previousInp = metric;\n });\n}\n\nfunction addMetricObserver(\n type,\n callback,\n instrumentFn,\n previousValue,\n stopOnCallback = false,\n) {\n addHandler(type, callback);\n\n let stopListening;\n\n if (!instrumented[type]) {\n stopListening = instrumentFn();\n instrumented[type] = true;\n }\n\n if (previousValue) {\n callback({ metric: previousValue });\n }\n\n return getCleanupCallback(type, callback, stopOnCallback ? stopListening : undefined);\n}\n\nfunction instrumentPerformanceObserver(type) {\n const options = {};\n\n // Special per-type options we want to use\n if (type === 'event') {\n options.durationThreshold = 0;\n }\n\n observe(\n type,\n entries => {\n triggerHandlers(type, { entries });\n },\n options,\n );\n}\n\nfunction addHandler(type, handler) {\n handlers[type] = handlers[type] || [];\n (handlers[type] ).push(handler);\n}\n\n// Get a callback which can be called to remove the instrumentation handler\nfunction getCleanupCallback(\n type,\n callback,\n stopListening,\n) {\n return () => {\n if (stopListening) {\n stopListening();\n }\n\n const typeHandlers = handlers[type];\n\n if (!typeHandlers) {\n return;\n }\n\n const index = typeHandlers.indexOf(callback);\n if (index !== -1) {\n typeHandlers.splice(index, 1);\n }\n };\n}\n\n/**\n * Check if a PerformanceEntry is a PerformanceEventTiming by checking for the `duration` property.\n */\nfunction isPerformanceEventTiming(entry) {\n return 'duration' in entry;\n}\n\nexport { addClsInstrumentationHandler, addFidInstrumentationHandler, addInpInstrumentationHandler, addLcpInstrumentationHandler, addPerformanceInstrumentationHandler, addTtfbInstrumentationHandler, isPerformanceEventTiming };\n//# sourceMappingURL=instrument.js.map\n","import { spanToJSON, withActiveSpan, startInactiveSpan, getClient, getCurrentScope } from '@sentry/core';\nimport { WINDOW } from '../types.js';\n\n/**\n * Checks if a given value is a valid measurement value.\n */\nfunction isMeasurementValue(value) {\n return typeof value === 'number' && isFinite(value);\n}\n\n/**\n * Helper function to start child on transactions. This function will make sure that the transaction will\n * use the start timestamp of the created child span if it is earlier than the transactions actual\n * start timestamp.\n */\nfunction startAndEndSpan(\n parentSpan,\n startTimeInSeconds,\n endTime,\n { ...ctx },\n) {\n const parentStartTime = spanToJSON(parentSpan).start_timestamp;\n if (parentStartTime && parentStartTime > startTimeInSeconds) {\n // We can only do this for SentrySpans...\n if (typeof (parentSpan ).updateStartTime === 'function') {\n (parentSpan ).updateStartTime(startTimeInSeconds);\n }\n }\n\n // The return value only exists for tests\n return withActiveSpan(parentSpan, () => {\n const span = startInactiveSpan({\n startTime: startTimeInSeconds,\n ...ctx,\n });\n\n if (span) {\n span.end(endTime);\n }\n\n return span;\n });\n}\n\n/**\n * Starts an inactive, standalone span used to send web vital values to Sentry.\n * DO NOT use this for arbitrary spans, as these spans require special handling\n * during ingestion to extract metrics.\n *\n * This function adds a bunch of attributes and data to the span that's shared\n * by all web vital standalone spans. However, you need to take care of adding\n * the actual web vital value as an event to the span. Also, you need to assign\n * a transaction name and some other values that are specific to the web vital.\n *\n * Ultimately, you also need to take care of ending the span to send it off.\n *\n * @param options\n *\n * @returns an inactive, standalone and NOT YET ended span\n */\nfunction startStandaloneWebVitalSpan(options) {\n const client = getClient();\n if (!client) {\n return;\n }\n\n const { name, transaction, attributes: passedAttributes, startTime } = options;\n\n const { release, environment } = client.getOptions();\n // We need to get the replay, user, and activeTransaction from the current scope\n // so that we can associate replay id, profile id, and a user display to the span\n const replay = client.getIntegrationByName('Replay');\n const replayId = replay && replay.getReplayId();\n\n const scope = getCurrentScope();\n\n const user = scope.getUser();\n const userDisplay = user !== undefined ? user.email || user.id || user.ip_address : undefined;\n\n let profileId;\n try {\n // @ts-expect-error skip optional chaining to save bundle size with try catch\n profileId = scope.getScopeData().contexts.profile.profile_id;\n } catch (e) {\n // do nothing\n }\n\n const attributes = {\n release,\n environment,\n\n user: userDisplay || undefined,\n profile_id: profileId || undefined,\n replay_id: replayId || undefined,\n\n transaction,\n\n // Web vital score calculation relies on the user agent to account for different\n // browsers setting different thresholds for what is considered a good/meh/bad value.\n // For example: Chrome vs. Chrome Mobile\n 'user_agent.original': WINDOW.navigator && WINDOW.navigator.userAgent,\n\n ...passedAttributes,\n };\n\n return startInactiveSpan({\n name,\n attributes,\n startTime,\n experimental: {\n standalone: true,\n },\n });\n}\n\n/** Get the browser performance API. */\nfunction getBrowserPerformanceAPI() {\n // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are\n return WINDOW && WINDOW.addEventListener && WINDOW.performance;\n}\n\n/**\n * Converts from milliseconds to seconds\n * @param time time in ms\n */\nfunction msToSec(time) {\n return time / 1000;\n}\n\nexport { getBrowserPerformanceAPI, isMeasurementValue, msToSec, startAndEndSpan, startStandaloneWebVitalSpan };\n//# sourceMappingURL=utils.js.map\n","import { _optionalChain } from '@sentry/utils';\nimport { getClient, getActiveSpan, getRootSpan, spanToJSON, getCurrentScope, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE } from '@sentry/core';\nimport { logger, browserPerformanceTimeOrigin, htmlTreeAsString, dropUndefinedKeys } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build.js';\nimport { addClsInstrumentationHandler } from './instrument.js';\nimport { msToSec, startStandaloneWebVitalSpan } from './utils.js';\nimport { onHidden } from './web-vitals/lib/onHidden.js';\n\n/**\n * Starts tracking the Cumulative Layout Shift on the current page and collects the value once\n *\n * - the page visibility is hidden\n * - a navigation span is started (to stop CLS measurement for SPA soft navigations)\n *\n * Once either of these events triggers, the CLS value is sent as a standalone span and we stop\n * measuring CLS.\n */\nfunction trackClsAsStandaloneSpan() {\n let standaloneCLsValue = 0;\n let standaloneClsEntry;\n let pageloadSpanId;\n\n if (!supportsLayoutShift()) {\n return;\n }\n\n let sentSpan = false;\n function _collectClsOnce() {\n if (sentSpan) {\n return;\n }\n sentSpan = true;\n if (pageloadSpanId) {\n sendStandaloneClsSpan(standaloneCLsValue, standaloneClsEntry, pageloadSpanId);\n }\n cleanupClsHandler();\n }\n\n const cleanupClsHandler = addClsInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1] ;\n if (!entry) {\n return;\n }\n standaloneCLsValue = metric.value;\n standaloneClsEntry = entry;\n }, true);\n\n // use pagehide event from web-vitals\n onHidden(() => {\n _collectClsOnce();\n });\n\n // Since the call chain of this function is synchronous and evaluates before the SDK client is created,\n // we need to wait with subscribing to a client hook until the client is created. Therefore, we defer\n // to the next tick after the SDK setup.\n setTimeout(() => {\n const client = getClient();\n\n const unsubscribeStartNavigation = _optionalChain([client, 'optionalAccess', _ => _.on, 'call', _2 => _2('startNavigationSpan', () => {\n _collectClsOnce();\n unsubscribeStartNavigation && unsubscribeStartNavigation();\n })]);\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n const spanJSON = rootSpan && spanToJSON(rootSpan);\n if (spanJSON && spanJSON.op === 'pageload') {\n pageloadSpanId = rootSpan.spanContext().spanId;\n }\n }, 0);\n}\n\nfunction sendStandaloneClsSpan(clsValue, entry, pageloadSpanId) {\n DEBUG_BUILD && logger.log(`Sending CLS span (${clsValue})`);\n\n const startTime = msToSec((browserPerformanceTimeOrigin || 0) + (_optionalChain([entry, 'optionalAccess', _3 => _3.startTime]) || 0));\n const routeName = getCurrentScope().getScopeData().transactionName;\n\n const name = entry ? htmlTreeAsString(_optionalChain([entry, 'access', _4 => _4.sources, 'access', _5 => _5[0], 'optionalAccess', _6 => _6.node])) : 'Layout shift';\n\n const attributes = dropUndefinedKeys({\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser.cls',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'ui.webvital.cls',\n [SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME]: _optionalChain([entry, 'optionalAccess', _7 => _7.duration]) || 0,\n // attach the pageload span id to the CLS span so that we can link them in the UI\n 'sentry.pageload.span_id': pageloadSpanId,\n });\n\n const span = startStandaloneWebVitalSpan({\n name,\n transaction: routeName,\n attributes,\n startTime,\n });\n\n _optionalChain([span, 'optionalAccess', _8 => _8.addEvent, 'call', _9 => _9('cls', {\n [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT]: '',\n [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE]: clsValue,\n })]);\n\n // LayoutShift performance entries always have a duration of 0, so we don't need to add `entry.duration` here\n // see: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceEntry/duration\n _optionalChain([span, 'optionalAccess', _10 => _10.end, 'call', _11 => _11(startTime)]);\n}\n\nfunction supportsLayoutShift() {\n try {\n return _optionalChain([PerformanceObserver, 'access', _12 => _12.supportedEntryTypes, 'optionalAccess', _13 => _13.includes, 'call', _14 => _14('layout-shift')]);\n } catch (e) {\n return false;\n }\n}\n\nexport { trackClsAsStandaloneSpan };\n//# sourceMappingURL=cls.js.map\n","import { getActiveSpan, spanToJSON, setMeasurement, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';\nimport { browserPerformanceTimeOrigin, logger, parseUrl, htmlTreeAsString, getComponentName } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build.js';\nimport { WINDOW } from '../types.js';\nimport { trackClsAsStandaloneSpan } from './cls.js';\nimport { addPerformanceInstrumentationHandler, addClsInstrumentationHandler, addLcpInstrumentationHandler, addFidInstrumentationHandler, addTtfbInstrumentationHandler } from './instrument.js';\nimport { getBrowserPerformanceAPI, msToSec, startAndEndSpan, isMeasurementValue } from './utils.js';\nimport { getActivationStart } from './web-vitals/lib/getActivationStart.js';\nimport { getNavigationEntry } from './web-vitals/lib/getNavigationEntry.js';\nimport { getVisibilityWatcher } from './web-vitals/lib/getVisibilityWatcher.js';\n\n/* eslint-disable max-lines */\n\nconst MAX_INT_AS_BYTES = 2147483647;\n\nlet _performanceCursor = 0;\n\nlet _measurements = {};\nlet _lcpEntry;\nlet _clsEntry;\n\n/**\n * Start tracking web vitals.\n * The callback returned by this function can be used to stop tracking & ensure all measurements are final & captured.\n *\n * @returns A function that forces web vitals collection\n */\nfunction startTrackingWebVitals({ recordClsStandaloneSpans }) {\n const performance = getBrowserPerformanceAPI();\n if (performance && browserPerformanceTimeOrigin) {\n // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are\n if (performance.mark) {\n WINDOW.performance.mark('sentry-tracing-init');\n }\n const fidCleanupCallback = _trackFID();\n const lcpCleanupCallback = _trackLCP();\n const ttfbCleanupCallback = _trackTtfb();\n const clsCleanupCallback = recordClsStandaloneSpans ? trackClsAsStandaloneSpan() : _trackCLS();\n\n return () => {\n fidCleanupCallback();\n lcpCleanupCallback();\n ttfbCleanupCallback();\n clsCleanupCallback && clsCleanupCallback();\n };\n }\n\n return () => undefined;\n}\n\n/**\n * Start tracking long tasks.\n */\nfunction startTrackingLongTasks() {\n addPerformanceInstrumentationHandler('longtask', ({ entries }) => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n\n const { op: parentOp, start_timestamp: parentStartTimestamp } = spanToJSON(parent);\n\n for (const entry of entries) {\n const startTime = msToSec((browserPerformanceTimeOrigin ) + entry.startTime);\n const duration = msToSec(entry.duration);\n\n if (parentOp === 'navigation' && parentStartTimestamp && startTime < parentStartTimestamp) {\n // Skip adding a span if the long task started before the navigation started.\n // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n // time, potentially skewing the duration of the actual navigation as reported via our\n // routing instrumentations\n continue;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, {\n name: 'Main UI thread blocked',\n op: 'ui.long-task',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n }\n });\n}\n\n/**\n * Start tracking long animation frames.\n */\nfunction startTrackingLongAnimationFrames() {\n // NOTE: the current web-vitals version (3.5.2) does not support long-animation-frame, so\n // we directly observe `long-animation-frame` events instead of through the web-vitals\n // `observe` helper function.\n const observer = new PerformanceObserver(list => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n for (const entry of list.getEntries() ) {\n if (!entry.scripts[0]) {\n continue;\n }\n\n const startTime = msToSec((browserPerformanceTimeOrigin ) + entry.startTime);\n\n const { start_timestamp: parentStartTimestamp, op: parentOp } = spanToJSON(parent);\n\n if (parentOp === 'navigation' && parentStartTimestamp && startTime < parentStartTimestamp) {\n // Skip adding the span if the long animation frame started before the navigation started.\n // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n // time, potentially skewing the duration of the actual navigation as reported via our\n // routing instrumentations\n continue;\n }\n\n const duration = msToSec(entry.duration);\n\n const attributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n };\n\n const initialScript = entry.scripts[0];\n const { invoker, invokerType, sourceURL, sourceFunctionName, sourceCharPosition } = initialScript;\n attributes['browser.script.invoker'] = invoker;\n attributes['browser.script.invoker_type'] = invokerType;\n if (sourceURL) {\n attributes['code.filepath'] = sourceURL;\n }\n if (sourceFunctionName) {\n attributes['code.function'] = sourceFunctionName;\n }\n if (sourceCharPosition !== -1) {\n attributes['browser.script.source_char_position'] = sourceCharPosition;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, {\n name: 'Main UI thread blocked',\n op: 'ui.long-animation-frame',\n attributes,\n });\n }\n });\n\n observer.observe({ type: 'long-animation-frame', buffered: true });\n}\n\n/**\n * Start tracking interaction events.\n */\nfunction startTrackingInteractions() {\n addPerformanceInstrumentationHandler('event', ({ entries }) => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n for (const entry of entries) {\n if (entry.name === 'click') {\n const startTime = msToSec((browserPerformanceTimeOrigin ) + entry.startTime);\n const duration = msToSec(entry.duration);\n\n const spanOptions = {\n name: htmlTreeAsString(entry.target),\n op: `ui.interaction.${entry.name}`,\n startTime: startTime,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n };\n\n const componentName = getComponentName(entry.target);\n if (componentName) {\n spanOptions.attributes['ui.component_name'] = componentName;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, spanOptions);\n }\n }\n });\n}\n\n/**\n * Starts tracking the Cumulative Layout Shift on the current page and collects the value and last entry\n * to the `_measurements` object which ultimately is applied to the pageload span's measurements.\n */\nfunction _trackCLS() {\n return addClsInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1] ;\n if (!entry) {\n return;\n }\n DEBUG_BUILD && logger.log(`[Measurements] Adding CLS ${metric.value}`);\n _measurements['cls'] = { value: metric.value, unit: '' };\n _clsEntry = entry;\n }, true);\n}\n\n/** Starts tracking the Largest Contentful Paint on the current page. */\nfunction _trackLCP() {\n return addLcpInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n DEBUG_BUILD && logger.log('[Measurements] Adding LCP');\n _measurements['lcp'] = { value: metric.value, unit: 'millisecond' };\n _lcpEntry = entry ;\n }, true);\n}\n\n/** Starts tracking the First Input Delay on the current page. */\nfunction _trackFID() {\n return addFidInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n const timeOrigin = msToSec(browserPerformanceTimeOrigin );\n const startTime = msToSec(entry.startTime);\n DEBUG_BUILD && logger.log('[Measurements] Adding FID');\n _measurements['fid'] = { value: metric.value, unit: 'millisecond' };\n _measurements['mark.fid'] = { value: timeOrigin + startTime, unit: 'second' };\n });\n}\n\nfunction _trackTtfb() {\n return addTtfbInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n DEBUG_BUILD && logger.log('[Measurements] Adding TTFB');\n _measurements['ttfb'] = { value: metric.value, unit: 'millisecond' };\n });\n}\n\n/** Add performance related spans to a transaction */\nfunction addPerformanceEntries(span, options) {\n const performance = getBrowserPerformanceAPI();\n if (!performance || !WINDOW.performance.getEntries || !browserPerformanceTimeOrigin) {\n // Gatekeeper if performance API not available\n return;\n }\n\n DEBUG_BUILD && logger.log('[Tracing] Adding & adjusting spans using Performance API');\n const timeOrigin = msToSec(browserPerformanceTimeOrigin);\n\n const performanceEntries = performance.getEntries();\n\n const { op, start_timestamp: transactionStartTime } = spanToJSON(span);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n performanceEntries.slice(_performanceCursor).forEach((entry) => {\n const startTime = msToSec(entry.startTime);\n const duration = msToSec(\n // Inexplicably, Chrome sometimes emits a negative duration. We need to work around this.\n // There is a SO post attempting to explain this, but it leaves one with open questions: https://stackoverflow.com/questions/23191918/peformance-getentries-and-negative-duration-display\n // The way we clamp the value is probably not accurate, since we have observed this happen for things that may take a while to load, like for example the replay worker.\n // TODO: Investigate why this happens and how to properly mitigate. For now, this is a workaround to prevent transactions being dropped due to negative duration spans.\n Math.max(0, entry.duration),\n );\n\n if (op === 'navigation' && transactionStartTime && timeOrigin + startTime < transactionStartTime) {\n return;\n }\n\n switch (entry.entryType) {\n case 'navigation': {\n _addNavigationSpans(span, entry, timeOrigin);\n break;\n }\n case 'mark':\n case 'paint':\n case 'measure': {\n _addMeasureSpans(span, entry, startTime, duration, timeOrigin);\n\n // capture web vitals\n const firstHidden = getVisibilityWatcher();\n // Only report if the page wasn't hidden prior to the web vital.\n const shouldRecord = entry.startTime < firstHidden.firstHiddenTime;\n\n if (entry.name === 'first-paint' && shouldRecord) {\n DEBUG_BUILD && logger.log('[Measurements] Adding FP');\n _measurements['fp'] = { value: entry.startTime, unit: 'millisecond' };\n }\n if (entry.name === 'first-contentful-paint' && shouldRecord) {\n DEBUG_BUILD && logger.log('[Measurements] Adding FCP');\n _measurements['fcp'] = { value: entry.startTime, unit: 'millisecond' };\n }\n break;\n }\n case 'resource': {\n _addResourceSpans(span, entry, entry.name , startTime, duration, timeOrigin);\n break;\n }\n // Ignore other entry types.\n }\n });\n\n _performanceCursor = Math.max(performanceEntries.length - 1, 0);\n\n _trackNavigator(span);\n\n // Measurements are only available for pageload transactions\n if (op === 'pageload') {\n _addTtfbRequestTimeToMeasurements(_measurements);\n\n const fidMark = _measurements['mark.fid'];\n if (fidMark && _measurements['fid']) {\n // create span for FID\n startAndEndSpan(span, fidMark.value, fidMark.value + msToSec(_measurements['fid'].value), {\n name: 'first input delay',\n op: 'ui.action',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n\n // Delete mark.fid as we don't want it to be part of final payload\n delete _measurements['mark.fid'];\n }\n\n // If FCP is not recorded we should not record the cls value\n // according to the new definition of CLS.\n // TODO: Check if the first condition is still necessary: `onCLS` already only fires once `onFCP` was called.\n if (!('fcp' in _measurements) || !options.recordClsOnPageloadSpan) {\n delete _measurements.cls;\n }\n\n Object.entries(_measurements).forEach(([measurementName, measurement]) => {\n setMeasurement(measurementName, measurement.value, measurement.unit);\n });\n\n // Set timeOrigin which denotes the timestamp which to base the LCP/FCP/FP/TTFB measurements on\n span.setAttribute('performance.timeOrigin', timeOrigin);\n\n // In prerendering scenarios, where a page might be prefetched and pre-rendered before the user clicks the link,\n // the navigation starts earlier than when the user clicks it. Web Vitals should always be based on the\n // user-perceived time, so they are not reported from the actual start of the navigation, but rather from the\n // time where the user actively started the navigation, for example by clicking a link.\n // This is user action is called \"activation\" and the time between navigation and activation is stored in\n // the `activationStart` attribute of the \"navigation\" PerformanceEntry.\n span.setAttribute('performance.activationStart', getActivationStart());\n\n _setWebVitalAttributes(span);\n }\n\n _lcpEntry = undefined;\n _clsEntry = undefined;\n _measurements = {};\n}\n\n/** Create measure related spans */\nfunction _addMeasureSpans(\n span,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n entry,\n startTime,\n duration,\n timeOrigin,\n) {\n const navEntry = getNavigationEntry();\n const requestTime = msToSec(navEntry ? navEntry.requestStart : 0);\n // Because performance.measure accepts arbitrary timestamps it can produce\n // spans that happen before the browser even makes a request for the page.\n //\n // An example of this is the automatically generated Next.js-before-hydration\n // spans created by the Next.js framework.\n //\n // To prevent this we will pin the start timestamp to the request start time\n // This does make duration inaccurate, so if this does happen, we will add\n // an attribute to the span\n const measureStartTimestamp = timeOrigin + Math.max(startTime, requestTime);\n const startTimeStamp = timeOrigin + startTime;\n const measureEndTimestamp = startTimeStamp + duration;\n\n const attributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n };\n\n if (measureStartTimestamp !== startTimeStamp) {\n attributes['sentry.browser.measure_happened_before_request'] = true;\n attributes['sentry.browser.measure_start_time'] = measureStartTimestamp;\n }\n\n startAndEndSpan(span, measureStartTimestamp, measureEndTimestamp, {\n name: entry.name ,\n op: entry.entryType ,\n attributes,\n });\n\n return measureStartTimestamp;\n}\n\n/** Instrument navigation entries */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction _addNavigationSpans(span, entry, timeOrigin) {\n ['unloadEvent', 'redirect', 'domContentLoadedEvent', 'loadEvent', 'connect'].forEach(event => {\n _addPerformanceNavigationTiming(span, entry, event, timeOrigin);\n });\n _addPerformanceNavigationTiming(span, entry, 'secureConnection', timeOrigin, 'TLS/SSL', 'connectEnd');\n _addPerformanceNavigationTiming(span, entry, 'fetch', timeOrigin, 'cache', 'domainLookupStart');\n _addPerformanceNavigationTiming(span, entry, 'domainLookup', timeOrigin, 'DNS');\n _addRequest(span, entry, timeOrigin);\n}\n\n/** Create performance navigation related spans */\nfunction _addPerformanceNavigationTiming(\n span,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n entry,\n event,\n timeOrigin,\n name,\n eventEnd,\n) {\n const end = eventEnd ? (entry[eventEnd] ) : (entry[`${event}End`] );\n const start = entry[`${event}Start`] ;\n if (!start || !end) {\n return;\n }\n startAndEndSpan(span, timeOrigin + msToSec(start), timeOrigin + msToSec(end), {\n op: `browser.${name || event}`,\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n}\n\n/** Create request and response related spans */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction _addRequest(span, entry, timeOrigin) {\n const requestStartTimestamp = timeOrigin + msToSec(entry.requestStart );\n const responseEndTimestamp = timeOrigin + msToSec(entry.responseEnd );\n const responseStartTimestamp = timeOrigin + msToSec(entry.responseStart );\n if (entry.responseEnd) {\n // It is possible that we are collecting these metrics when the page hasn't finished loading yet, for example when the HTML slowly streams in.\n // In this case, ie. when the document request hasn't finished yet, `entry.responseEnd` will be 0.\n // In order not to produce faulty spans, where the end timestamp is before the start timestamp, we will only collect\n // these spans when the responseEnd value is available. The backend (Relay) would drop the entire span if it contained faulty spans.\n startAndEndSpan(span, requestStartTimestamp, responseEndTimestamp, {\n op: 'browser.request',\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n\n startAndEndSpan(span, responseStartTimestamp, responseEndTimestamp, {\n op: 'browser.response',\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n }\n}\n\n/** Create resource-related spans */\nfunction _addResourceSpans(\n span,\n entry,\n resourceUrl,\n startTime,\n duration,\n timeOrigin,\n) {\n // we already instrument based on fetch and xhr, so we don't need to\n // duplicate spans here.\n if (entry.initiatorType === 'xmlhttprequest' || entry.initiatorType === 'fetch') {\n return;\n }\n\n const parsedUrl = parseUrl(resourceUrl);\n\n const attributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n };\n setResourceEntrySizeData(attributes, entry, 'transferSize', 'http.response_transfer_size');\n setResourceEntrySizeData(attributes, entry, 'encodedBodySize', 'http.response_content_length');\n setResourceEntrySizeData(attributes, entry, 'decodedBodySize', 'http.decoded_response_content_length');\n\n if (entry.deliveryType != null) {\n attributes['http.response_delivery_type'] = entry.deliveryType;\n }\n\n if ('renderBlockingStatus' in entry) {\n attributes['resource.render_blocking_status'] = entry.renderBlockingStatus;\n }\n if (parsedUrl.protocol) {\n attributes['url.scheme'] = parsedUrl.protocol.split(':').pop(); // the protocol returned by parseUrl includes a :, but OTEL spec does not, so we remove it.\n }\n\n if (parsedUrl.host) {\n attributes['server.address'] = parsedUrl.host;\n }\n\n attributes['url.same_origin'] = resourceUrl.includes(WINDOW.location.origin);\n\n const startTimestamp = timeOrigin + startTime;\n const endTimestamp = startTimestamp + duration;\n\n startAndEndSpan(span, startTimestamp, endTimestamp, {\n name: resourceUrl.replace(WINDOW.location.origin, ''),\n op: entry.initiatorType ? `resource.${entry.initiatorType}` : 'resource.other',\n attributes,\n });\n}\n\n/**\n * Capture the information of the user agent.\n */\nfunction _trackNavigator(span) {\n const navigator = WINDOW.navigator ;\n if (!navigator) {\n return;\n }\n\n // track network connectivity\n const connection = navigator.connection;\n if (connection) {\n if (connection.effectiveType) {\n span.setAttribute('effectiveConnectionType', connection.effectiveType);\n }\n\n if (connection.type) {\n span.setAttribute('connectionType', connection.type);\n }\n\n if (isMeasurementValue(connection.rtt)) {\n _measurements['connection.rtt'] = { value: connection.rtt, unit: 'millisecond' };\n }\n }\n\n if (isMeasurementValue(navigator.deviceMemory)) {\n span.setAttribute('deviceMemory', `${navigator.deviceMemory} GB`);\n }\n\n if (isMeasurementValue(navigator.hardwareConcurrency)) {\n span.setAttribute('hardwareConcurrency', String(navigator.hardwareConcurrency));\n }\n}\n\n/** Add LCP / CLS data to span to allow debugging */\nfunction _setWebVitalAttributes(span) {\n if (_lcpEntry) {\n DEBUG_BUILD && logger.log('[Measurements] Adding LCP Data');\n\n // Capture Properties of the LCP element that contributes to the LCP.\n\n if (_lcpEntry.element) {\n span.setAttribute('lcp.element', htmlTreeAsString(_lcpEntry.element));\n }\n\n if (_lcpEntry.id) {\n span.setAttribute('lcp.id', _lcpEntry.id);\n }\n\n if (_lcpEntry.url) {\n // Trim URL to the first 200 characters.\n span.setAttribute('lcp.url', _lcpEntry.url.trim().slice(0, 200));\n }\n\n span.setAttribute('lcp.size', _lcpEntry.size);\n }\n\n // See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift\n if (_clsEntry && _clsEntry.sources) {\n DEBUG_BUILD && logger.log('[Measurements] Adding CLS Data');\n _clsEntry.sources.forEach((source, index) =>\n span.setAttribute(`cls.source.${index + 1}`, htmlTreeAsString(source.node)),\n );\n }\n}\n\nfunction setResourceEntrySizeData(\n attributes,\n entry,\n key,\n dataKey,\n) {\n const entryVal = entry[key];\n if (entryVal != null && entryVal < MAX_INT_AS_BYTES) {\n attributes[dataKey] = entryVal;\n }\n}\n\n/**\n * Add ttfb request time information to measurements.\n *\n * ttfb information is added via vendored web vitals library.\n */\nfunction _addTtfbRequestTimeToMeasurements(_measurements) {\n const navEntry = getNavigationEntry();\n if (!navEntry) {\n return;\n }\n\n const { responseStart, requestStart } = navEntry;\n\n if (requestStart <= responseStart) {\n DEBUG_BUILD && logger.log('[Measurements] Adding TTFB Request Time');\n _measurements['ttfb.requestTime'] = {\n value: responseStart - requestStart,\n unit: 'millisecond',\n };\n }\n}\n\nexport { _addMeasureSpans, _addResourceSpans, addPerformanceEntries, startTrackingInteractions, startTrackingLongAnimationFrames, startTrackingLongTasks, startTrackingWebVitals };\n//# sourceMappingURL=browserMetrics.js.map\n","import { addHandler, maybeInstrument, triggerHandlers, fill, addNonEnumerableProperty, uuid4 } from '@sentry/utils';\nimport { WINDOW } from '../types.js';\n\nconst DEBOUNCE_DURATION = 1000;\n\nlet debounceTimerID;\nlet lastCapturedEventType;\nlet lastCapturedEventTargetId;\n\n/**\n * Add an instrumentation handler for when a click or a keypress happens.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nfunction addClickKeypressInstrumentationHandler(handler) {\n const type = 'dom';\n addHandler(type, handler);\n maybeInstrument(type, instrumentDOM);\n}\n\n/** Exported for tests only. */\nfunction instrumentDOM() {\n if (!WINDOW.document) {\n return;\n }\n\n // Make it so that any click or keypress that is unhandled / bubbled up all the way to the document triggers our dom\n // handlers. (Normally we have only one, which captures a breadcrumb for each click or keypress.) Do this before\n // we instrument `addEventListener` so that we don't end up attaching this handler twice.\n const triggerDOMHandler = triggerHandlers.bind(null, 'dom');\n const globalDOMEventHandler = makeDOMEventHandler(triggerDOMHandler, true);\n WINDOW.document.addEventListener('click', globalDOMEventHandler, false);\n WINDOW.document.addEventListener('keypress', globalDOMEventHandler, false);\n\n // After hooking into click and keypress events bubbled up to `document`, we also hook into user-handled\n // clicks & keypresses, by adding an event listener of our own to any element to which they add a listener. That\n // way, whenever one of their handlers is triggered, ours will be, too. (This is needed because their handler\n // could potentially prevent the event from bubbling up to our global listeners. This way, our handler are still\n // guaranteed to fire at least once.)\n ['EventTarget', 'Node'].forEach((target) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const proto = (WINDOW )[target] && (WINDOW )[target].prototype;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins\n if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {\n return;\n }\n\n fill(proto, 'addEventListener', function (originalAddEventListener) {\n return function (\n\n type,\n listener,\n options,\n ) {\n if (type === 'click' || type == 'keypress') {\n try {\n const el = this ;\n const handlers = (el.__sentry_instrumentation_handlers__ = el.__sentry_instrumentation_handlers__ || {});\n const handlerForType = (handlers[type] = handlers[type] || { refCount: 0 });\n\n if (!handlerForType.handler) {\n const handler = makeDOMEventHandler(triggerDOMHandler);\n handlerForType.handler = handler;\n originalAddEventListener.call(this, type, handler, options);\n }\n\n handlerForType.refCount++;\n } catch (e) {\n // Accessing dom properties is always fragile.\n // Also allows us to skip `addEventListeners` calls with no proper `this` context.\n }\n }\n\n return originalAddEventListener.call(this, type, listener, options);\n };\n });\n\n fill(\n proto,\n 'removeEventListener',\n function (originalRemoveEventListener) {\n return function (\n\n type,\n listener,\n options,\n ) {\n if (type === 'click' || type == 'keypress') {\n try {\n const el = this ;\n const handlers = el.__sentry_instrumentation_handlers__ || {};\n const handlerForType = handlers[type];\n\n if (handlerForType) {\n handlerForType.refCount--;\n // If there are no longer any custom handlers of the current type on this element, we can remove ours, too.\n if (handlerForType.refCount <= 0) {\n originalRemoveEventListener.call(this, type, handlerForType.handler, options);\n handlerForType.handler = undefined;\n delete handlers[type]; // eslint-disable-line @typescript-eslint/no-dynamic-delete\n }\n\n // If there are no longer any custom handlers of any type on this element, cleanup everything.\n if (Object.keys(handlers).length === 0) {\n delete el.__sentry_instrumentation_handlers__;\n }\n }\n } catch (e) {\n // Accessing dom properties is always fragile.\n // Also allows us to skip `addEventListeners` calls with no proper `this` context.\n }\n }\n\n return originalRemoveEventListener.call(this, type, listener, options);\n };\n },\n );\n });\n}\n\n/**\n * Check whether the event is similar to the last captured one. For example, two click events on the same button.\n */\nfunction isSimilarToLastCapturedEvent(event) {\n // If both events have different type, then user definitely performed two separate actions. e.g. click + keypress.\n if (event.type !== lastCapturedEventType) {\n return false;\n }\n\n try {\n // If both events have the same type, it's still possible that actions were performed on different targets.\n // e.g. 2 clicks on different buttons.\n if (!event.target || (event.target )._sentryId !== lastCapturedEventTargetId) {\n return false;\n }\n } catch (e) {\n // just accessing `target` property can throw an exception in some rare circumstances\n // see: https://github.com/getsentry/sentry-javascript/issues/838\n }\n\n // If both events have the same type _and_ same `target` (an element which triggered an event, _not necessarily_\n // to which an event listener was attached), we treat them as the same action, as we want to capture\n // only one breadcrumb. e.g. multiple clicks on the same button, or typing inside a user input box.\n return true;\n}\n\n/**\n * Decide whether an event should be captured.\n * @param event event to be captured\n */\nfunction shouldSkipDOMEvent(eventType, target) {\n // We are only interested in filtering `keypress` events for now.\n if (eventType !== 'keypress') {\n return false;\n }\n\n if (!target || !target.tagName) {\n return true;\n }\n\n // Only consider keypress events on actual input elements. This will disregard keypresses targeting body\n // e.g.tabbing through elements, hotkeys, etc.\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Wraps addEventListener to capture UI breadcrumbs\n */\nfunction makeDOMEventHandler(\n handler,\n globalListener = false,\n) {\n return (event) => {\n // It's possible this handler might trigger multiple times for the same\n // event (e.g. event propagation through node ancestors).\n // Ignore if we've already captured that event.\n if (!event || event['_sentryCaptured']) {\n return;\n }\n\n const target = getEventTarget(event);\n\n // We always want to skip _some_ events.\n if (shouldSkipDOMEvent(event.type, target)) {\n return;\n }\n\n // Mark event as \"seen\"\n addNonEnumerableProperty(event, '_sentryCaptured', true);\n\n if (target && !target._sentryId) {\n // Add UUID to event target so we can identify if\n addNonEnumerableProperty(target, '_sentryId', uuid4());\n }\n\n const name = event.type === 'keypress' ? 'input' : event.type;\n\n // If there is no last captured event, it means that we can safely capture the new event and store it for future comparisons.\n // If there is a last captured event, see if the new event is different enough to treat it as a unique one.\n // If that's the case, emit the previous event and store locally the newly-captured DOM event.\n if (!isSimilarToLastCapturedEvent(event)) {\n const handlerData = { event, name, global: globalListener };\n handler(handlerData);\n lastCapturedEventType = event.type;\n lastCapturedEventTargetId = target ? target._sentryId : undefined;\n }\n\n // Start a new debounce timer that will prevent us from capturing multiple events that should be grouped together.\n clearTimeout(debounceTimerID);\n debounceTimerID = WINDOW.setTimeout(() => {\n lastCapturedEventTargetId = undefined;\n lastCapturedEventType = undefined;\n }, DEBOUNCE_DURATION);\n };\n}\n\nfunction getEventTarget(event) {\n try {\n return event.target ;\n } catch (e) {\n // just accessing `target` property can throw an exception in some rare circumstances\n // see: https://github.com/getsentry/sentry-javascript/issues/838\n return null;\n }\n}\n\nexport { addClickKeypressInstrumentationHandler, instrumentDOM };\n//# sourceMappingURL=dom.js.map\n","import { addHandler, maybeInstrument, supportsHistory, triggerHandlers, fill } from '@sentry/utils';\nimport { WINDOW } from '../types.js';\n\nlet lastHref;\n\n/**\n * Add an instrumentation handler for when a fetch request happens.\n * The handler function is called once when the request starts and once when it ends,\n * which can be identified by checking if it has an `endTimestamp`.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nfunction addHistoryInstrumentationHandler(handler) {\n const type = 'history';\n addHandler(type, handler);\n maybeInstrument(type, instrumentHistory);\n}\n\nfunction instrumentHistory() {\n if (!supportsHistory()) {\n return;\n }\n\n const oldOnPopState = WINDOW.onpopstate;\n WINDOW.onpopstate = function ( ...args) {\n const to = WINDOW.location.href;\n // keep track of the current URL state, as we always receive only the updated state\n const from = lastHref;\n lastHref = to;\n const handlerData = { from, to };\n triggerHandlers('history', handlerData);\n if (oldOnPopState) {\n // Apparently this can throw in Firefox when incorrectly implemented plugin is installed.\n // https://github.com/getsentry/sentry-javascript/issues/3344\n // https://github.com/bugsnag/bugsnag-js/issues/469\n try {\n return oldOnPopState.apply(this, args);\n } catch (_oO) {\n // no-empty\n }\n }\n };\n\n function historyReplacementFunction(originalHistoryFunction) {\n return function ( ...args) {\n const url = args.length > 2 ? args[2] : undefined;\n if (url) {\n // coerce to string (this is what pushState does)\n const from = lastHref;\n const to = String(url);\n // keep track of the current URL state, as we always receive only the updated state\n lastHref = to;\n const handlerData = { from, to };\n triggerHandlers('history', handlerData);\n }\n return originalHistoryFunction.apply(this, args);\n };\n }\n\n fill(WINDOW.history, 'pushState', historyReplacementFunction);\n fill(WINDOW.history, 'replaceState', historyReplacementFunction);\n}\n\nexport { addHistoryInstrumentationHandler };\n//# sourceMappingURL=history.js.map\n","import { isNativeFunction, logger } from '@sentry/utils';\nimport { DEBUG_BUILD } from './debug-build.js';\nimport { WINDOW } from './types.js';\n\n/**\n * We generally want to use window.fetch / window.setTimeout.\n * However, in some cases this may be wrapped (e.g. by Zone.js for Angular),\n * so we try to get an unpatched version of this from a sandboxed iframe.\n */\n\nconst cachedImplementations = {};\n\n/**\n * Get the native implementation of a browser function.\n *\n * This can be used to ensure we get an unwrapped version of a function, in cases where a wrapped function can lead to problems.\n *\n * The following methods can be retrieved:\n * - `setTimeout`: This can be wrapped by e.g. Angular, causing change detection to be triggered.\n * - `fetch`: This can be wrapped by e.g. ad-blockers, causing an infinite loop when a request is blocked.\n */\nfunction getNativeImplementation(\n name,\n) {\n const cached = cachedImplementations[name];\n if (cached) {\n return cached;\n }\n\n let impl = WINDOW[name] ;\n\n // Fast path to avoid DOM I/O\n if (isNativeFunction(impl)) {\n return (cachedImplementations[name] = impl.bind(WINDOW) );\n }\n\n const document = WINDOW.document;\n // eslint-disable-next-line deprecation/deprecation\n if (document && typeof document.createElement === 'function') {\n try {\n const sandbox = document.createElement('iframe');\n sandbox.hidden = true;\n document.head.appendChild(sandbox);\n const contentWindow = sandbox.contentWindow;\n if (contentWindow && contentWindow[name]) {\n impl = contentWindow[name] ;\n }\n document.head.removeChild(sandbox);\n } catch (e) {\n // Could not create sandbox iframe, just use window.xxx\n DEBUG_BUILD && logger.warn(`Could not create sandbox iframe for ${name} check, bailing to window.${name}: `, e);\n }\n }\n\n // Sanity check: This _should_ not happen, but if it does, we just skip caching...\n // This can happen e.g. in tests where fetch may not be available in the env, or similar.\n if (!impl) {\n return impl;\n }\n\n return (cachedImplementations[name] = impl.bind(WINDOW) );\n}\n\n/** Clear a cached implementation. */\nfunction clearCachedImplementation(name) {\n cachedImplementations[name] = undefined;\n}\n\n/**\n * A special usecase for incorrectly wrapped Fetch APIs in conjunction with ad-blockers.\n * Whenever someone wraps the Fetch API and returns the wrong promise chain,\n * this chain becomes orphaned and there is no possible way to capture it's rejections\n * other than allowing it bubble up to this very handler. eg.\n *\n * const f = window.fetch;\n * window.fetch = function () {\n * const p = f.apply(this, arguments);\n *\n * p.then(function() {\n * console.log('hi.');\n * });\n *\n * return p;\n * }\n *\n * `p.then(function () { ... })` is producing a completely separate promise chain,\n * however, what's returned is `p` - the result of original `fetch` call.\n *\n * This mean, that whenever we use the Fetch API to send our own requests, _and_\n * some ad-blocker blocks it, this orphaned chain will _always_ reject,\n * effectively causing another event to be captured.\n * This makes a whole process become an infinite loop, which we need to somehow\n * deal with, and break it in one way or another.\n *\n * To deal with this issue, we are making sure that we _always_ use the real\n * browser Fetch API, instead of relying on what `window.fetch` exposes.\n * The only downside to this would be missing our own requests as breadcrumbs,\n * but because we are already not doing this, it should be just fine.\n *\n * Possible failed fetch error messages per-browser:\n *\n * Chrome: Failed to fetch\n * Edge: Failed to Fetch\n * Firefox: NetworkError when attempting to fetch resource\n * Safari: resource blocked by content blocker\n */\nfunction fetch(...rest) {\n return getNativeImplementation('fetch')(...rest);\n}\n\n/**\n * Get an unwrapped `setTimeout` method.\n * This ensures that even if e.g. Angular wraps `setTimeout`, we get the native implementation,\n * avoiding triggering change detection.\n */\nfunction setTimeout(...rest) {\n return getNativeImplementation('setTimeout')(...rest);\n}\n\nexport { clearCachedImplementation, fetch, getNativeImplementation, setTimeout };\n//# sourceMappingURL=getNativeImplementation.js.map\n","import { addHandler, maybeInstrument, timestampInSeconds, isString, triggerHandlers } from '@sentry/utils';\nimport { WINDOW } from '../types.js';\n\nconst SENTRY_XHR_DATA_KEY = '__sentry_xhr_v3__';\n\n/**\n * Add an instrumentation handler for when an XHR request happens.\n * The handler function is called once when the request starts and once when it ends,\n * which can be identified by checking if it has an `endTimestamp`.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nfunction addXhrInstrumentationHandler(handler) {\n const type = 'xhr';\n addHandler(type, handler);\n maybeInstrument(type, instrumentXHR);\n}\n\n/** Exported only for tests. */\nfunction instrumentXHR() {\n if (!(WINDOW ).XMLHttpRequest) {\n return;\n }\n\n const xhrproto = XMLHttpRequest.prototype;\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n xhrproto.open = new Proxy(xhrproto.open, {\n apply(originalOpen, xhrOpenThisArg, xhrOpenArgArray) {\n const startTimestamp = timestampInSeconds() * 1000;\n\n // open() should always be called with two or more arguments\n // But to be on the safe side, we actually validate this and bail out if we don't have a method & url\n const method = isString(xhrOpenArgArray[0]) ? xhrOpenArgArray[0].toUpperCase() : undefined;\n const url = parseUrl(xhrOpenArgArray[1]);\n\n if (!method || !url) {\n return originalOpen.apply(xhrOpenThisArg, xhrOpenArgArray);\n }\n\n xhrOpenThisArg[SENTRY_XHR_DATA_KEY] = {\n method,\n url,\n request_headers: {},\n };\n\n // if Sentry key appears in URL, don't capture it as a request\n if (method === 'POST' && url.match(/sentry_key/)) {\n xhrOpenThisArg.__sentry_own_request__ = true;\n }\n\n const onreadystatechangeHandler = () => {\n // For whatever reason, this is not the same instance here as from the outer method\n const xhrInfo = xhrOpenThisArg[SENTRY_XHR_DATA_KEY];\n\n if (!xhrInfo) {\n return;\n }\n\n if (xhrOpenThisArg.readyState === 4) {\n try {\n // touching statusCode in some platforms throws\n // an exception\n xhrInfo.status_code = xhrOpenThisArg.status;\n } catch (e) {\n /* do nothing */\n }\n\n const handlerData = {\n endTimestamp: timestampInSeconds() * 1000,\n startTimestamp,\n xhr: xhrOpenThisArg,\n };\n triggerHandlers('xhr', handlerData);\n }\n };\n\n if ('onreadystatechange' in xhrOpenThisArg && typeof xhrOpenThisArg.onreadystatechange === 'function') {\n xhrOpenThisArg.onreadystatechange = new Proxy(xhrOpenThisArg.onreadystatechange, {\n apply(originalOnreadystatechange, onreadystatechangeThisArg, onreadystatechangeArgArray) {\n onreadystatechangeHandler();\n return originalOnreadystatechange.apply(onreadystatechangeThisArg, onreadystatechangeArgArray);\n },\n });\n } else {\n xhrOpenThisArg.addEventListener('readystatechange', onreadystatechangeHandler);\n }\n\n // Intercepting `setRequestHeader` to access the request headers of XHR instance.\n // This will only work for user/library defined headers, not for the default/browser-assigned headers.\n // Request cookies are also unavailable for XHR, as `Cookie` header can't be defined by `setRequestHeader`.\n xhrOpenThisArg.setRequestHeader = new Proxy(xhrOpenThisArg.setRequestHeader, {\n apply(\n originalSetRequestHeader,\n setRequestHeaderThisArg,\n setRequestHeaderArgArray,\n ) {\n const [header, value] = setRequestHeaderArgArray;\n\n const xhrInfo = setRequestHeaderThisArg[SENTRY_XHR_DATA_KEY];\n\n if (xhrInfo && isString(header) && isString(value)) {\n xhrInfo.request_headers[header.toLowerCase()] = value;\n }\n\n return originalSetRequestHeader.apply(setRequestHeaderThisArg, setRequestHeaderArgArray);\n },\n });\n\n return originalOpen.apply(xhrOpenThisArg, xhrOpenArgArray);\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n xhrproto.send = new Proxy(xhrproto.send, {\n apply(originalSend, sendThisArg, sendArgArray) {\n const sentryXhrData = sendThisArg[SENTRY_XHR_DATA_KEY];\n\n if (!sentryXhrData) {\n return originalSend.apply(sendThisArg, sendArgArray);\n }\n\n if (sendArgArray[0] !== undefined) {\n sentryXhrData.body = sendArgArray[0];\n }\n\n const handlerData = {\n startTimestamp: timestampInSeconds() * 1000,\n xhr: sendThisArg,\n };\n triggerHandlers('xhr', handlerData);\n\n return originalSend.apply(sendThisArg, sendArgArray);\n },\n });\n}\n\nfunction parseUrl(url) {\n if (isString(url)) {\n return url;\n }\n\n try {\n // url can be a string or URL\n // but since URL is not available in IE11, we do not check for it,\n // but simply assume it is an URL and return `toString()` from it (which returns the full URL)\n // If that fails, we just return undefined\n return (url ).toString();\n } catch (e2) {} // eslint-disable-line no-empty\n\n return undefined;\n}\n\nexport { SENTRY_XHR_DATA_KEY, addXhrInstrumentationHandler, instrumentXHR };\n//# sourceMappingURL=xhr.js.map\n","import { _optionalChain } from '@sentry/utils';\nimport { getActiveSpan, getRootSpan, spanToJSON, getCurrentScope, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE } from '@sentry/core';\nimport { browserPerformanceTimeOrigin, htmlTreeAsString, dropUndefinedKeys } from '@sentry/utils';\nimport { addInpInstrumentationHandler, addPerformanceInstrumentationHandler, isPerformanceEventTiming } from './instrument.js';\nimport { getBrowserPerformanceAPI, msToSec, startStandaloneWebVitalSpan } from './utils.js';\n\nconst LAST_INTERACTIONS = [];\nconst INTERACTIONS_SPAN_MAP = new Map();\n\n/**\n * Start tracking INP webvital events.\n */\nfunction startTrackingINP() {\n const performance = getBrowserPerformanceAPI();\n if (performance && browserPerformanceTimeOrigin) {\n const inpCallback = _trackINP();\n\n return () => {\n inpCallback();\n };\n }\n\n return () => undefined;\n}\n\nconst INP_ENTRY_MAP = {\n click: 'click',\n pointerdown: 'click',\n pointerup: 'click',\n mousedown: 'click',\n mouseup: 'click',\n touchstart: 'click',\n touchend: 'click',\n mouseover: 'hover',\n mouseout: 'hover',\n mouseenter: 'hover',\n mouseleave: 'hover',\n pointerover: 'hover',\n pointerout: 'hover',\n pointerenter: 'hover',\n pointerleave: 'hover',\n dragstart: 'drag',\n dragend: 'drag',\n drag: 'drag',\n dragenter: 'drag',\n dragleave: 'drag',\n dragover: 'drag',\n drop: 'drag',\n keydown: 'press',\n keyup: 'press',\n keypress: 'press',\n input: 'press',\n};\n\n/** Starts tracking the Interaction to Next Paint on the current page. */\nfunction _trackINP() {\n return addInpInstrumentationHandler(({ metric }) => {\n if (metric.value == undefined) {\n return;\n }\n\n const entry = metric.entries.find(entry => entry.duration === metric.value && INP_ENTRY_MAP[entry.name]);\n\n if (!entry) {\n return;\n }\n\n const { interactionId } = entry;\n const interactionType = INP_ENTRY_MAP[entry.name];\n\n /** Build the INP span, create an envelope from the span, and then send the envelope */\n const startTime = msToSec((browserPerformanceTimeOrigin ) + entry.startTime);\n const duration = msToSec(metric.value);\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n // We first try to lookup the span from our INTERACTIONS_SPAN_MAP,\n // where we cache the route per interactionId\n const cachedSpan = interactionId != null ? INTERACTIONS_SPAN_MAP.get(interactionId) : undefined;\n\n const spanToUse = cachedSpan || rootSpan;\n\n // Else, we try to use the active span.\n // Finally, we fall back to look at the transactionName on the scope\n const routeName = spanToUse ? spanToJSON(spanToUse).description : getCurrentScope().getScopeData().transactionName;\n\n const name = htmlTreeAsString(entry.target);\n const attributes = dropUndefinedKeys({\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser.inp',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `ui.interaction.${interactionType}`,\n [SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME]: entry.duration,\n });\n\n const span = startStandaloneWebVitalSpan({\n name,\n transaction: routeName,\n attributes,\n startTime,\n });\n\n _optionalChain([span, 'optionalAccess', _ => _.addEvent, 'call', _2 => _2('inp', {\n [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT]: 'millisecond',\n [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE]: metric.value,\n })]);\n\n _optionalChain([span, 'optionalAccess', _3 => _3.end, 'call', _4 => _4(startTime + duration)]);\n });\n}\n\n/**\n * Register a listener to cache route information for INP interactions.\n * TODO(v9): `latestRoute` no longer needs to be passed in and will be removed in v9.\n */\nfunction registerInpInteractionListener(_latestRoute) {\n const handleEntries = ({ entries }) => {\n const activeSpan = getActiveSpan();\n const activeRootSpan = activeSpan && getRootSpan(activeSpan);\n\n entries.forEach(entry => {\n if (!isPerformanceEventTiming(entry) || !activeRootSpan) {\n return;\n }\n\n const interactionId = entry.interactionId;\n if (interactionId == null) {\n return;\n }\n\n // If the interaction was already recorded before, nothing more to do\n if (INTERACTIONS_SPAN_MAP.has(interactionId)) {\n return;\n }\n\n // We keep max. 10 interactions in the list, then remove the oldest one & clean up\n if (LAST_INTERACTIONS.length > 10) {\n const last = LAST_INTERACTIONS.shift() ;\n INTERACTIONS_SPAN_MAP.delete(last);\n }\n\n // We add the interaction to the list of recorded interactions\n // and store the span for this interaction\n LAST_INTERACTIONS.push(interactionId);\n INTERACTIONS_SPAN_MAP.set(interactionId, activeRootSpan);\n });\n };\n\n addPerformanceInstrumentationHandler('event', handleEntries);\n addPerformanceInstrumentationHandler('first-input', handleEntries);\n}\n\nexport { registerInpInteractionListener, startTrackingINP };\n//# sourceMappingURL=inp.js.map\n","import { getNativeImplementation, clearCachedImplementation } from '@sentry-internal/browser-utils';\nimport { createTransport } from '@sentry/core';\nimport { rejectedSyncPromise } from '@sentry/utils';\n\n/**\n * Creates a Transport that uses the Fetch API to send events to Sentry.\n */\nfunction makeFetchTransport(\n options,\n nativeFetch = getNativeImplementation('fetch'),\n) {\n let pendingBodySize = 0;\n let pendingCount = 0;\n\n function makeRequest(request) {\n const requestSize = request.body.length;\n pendingBodySize += requestSize;\n pendingCount++;\n\n const requestOptions = {\n body: request.body,\n method: 'POST',\n referrerPolicy: 'origin',\n headers: options.headers,\n // Outgoing requests are usually cancelled when navigating to a different page, causing a \"TypeError: Failed to\n // fetch\" error and sending a \"network_error\" client-outcome - in Chrome, the request status shows \"(cancelled)\".\n // The `keepalive` flag keeps outgoing requests alive, even when switching pages. We want this since we're\n // frequently sending events right before the user is switching pages (eg. when finishing navigation transactions).\n // Gotchas:\n // - `keepalive` isn't supported by Firefox\n // - As per spec (https://fetch.spec.whatwg.org/#http-network-or-cache-fetch):\n // If the sum of contentLength and inflightKeepaliveBytes is greater than 64 kibibytes, then return a network error.\n // We will therefore only activate the flag when we're below that limit.\n // There is also a limit of requests that can be open at the same time, so we also limit this to 15\n // See https://github.com/getsentry/sentry-javascript/pull/7553 for details\n keepalive: pendingBodySize <= 60000 && pendingCount < 15,\n ...options.fetchOptions,\n };\n\n if (!nativeFetch) {\n clearCachedImplementation('fetch');\n return rejectedSyncPromise('No fetch implementation available');\n }\n\n try {\n // TODO: This may need a `suppressTracing` call in the future when we switch the browser SDK to OTEL\n return nativeFetch(options.url, requestOptions).then(response => {\n pendingBodySize -= requestSize;\n pendingCount--;\n return {\n statusCode: response.status,\n headers: {\n 'x-sentry-rate-limits': response.headers.get('X-Sentry-Rate-Limits'),\n 'retry-after': response.headers.get('Retry-After'),\n },\n };\n });\n } catch (e) {\n clearCachedImplementation('fetch');\n pendingBodySize -= requestSize;\n pendingCount--;\n return rejectedSyncPromise(e);\n }\n }\n\n return createTransport(options, makeRequest);\n}\n\nexport { makeFetchTransport };\n//# sourceMappingURL=fetch.js.map\n","import { createStackParser, UNKNOWN_FUNCTION } from '@sentry/utils';\n\nconst OPERA10_PRIORITY = 10;\nconst OPERA11_PRIORITY = 20;\nconst CHROME_PRIORITY = 30;\nconst WINJS_PRIORITY = 40;\nconst GECKO_PRIORITY = 50;\n\nfunction createFrame(filename, func, lineno, colno) {\n const frame = {\n filename,\n function: func === '' ? UNKNOWN_FUNCTION : func,\n in_app: true, // All browser frames are considered in_app\n };\n\n if (lineno !== undefined) {\n frame.lineno = lineno;\n }\n\n if (colno !== undefined) {\n frame.colno = colno;\n }\n\n return frame;\n}\n\n// This regex matches frames that have no function name (ie. are at the top level of a module).\n// For example \"at http://localhost:5000//script.js:1:126\"\n// Frames _with_ function names usually look as follows: \"at commitLayoutEffects (react-dom.development.js:23426:1)\"\nconst chromeRegexNoFnName = /^\\s*at (\\S+?)(?::(\\d+))(?::(\\d+))\\s*$/i;\n\n// This regex matches all the frames that have a function name.\nconst chromeRegex =\n /^\\s*at (?:(.+?\\)(?: \\[.+\\])?|.*?) ?\\((?:address at )?)?(?:async )?((?:|[-a-z]+:|.*bundle|\\/)?.*?)(?::(\\d+))?(?::(\\d+))?\\)?\\s*$/i;\n\nconst chromeEvalRegex = /\\((\\S*)(?::(\\d+))(?::(\\d+))\\)/;\n\n// Chromium based browsers: Chrome, Brave, new Opera, new Edge\n// We cannot call this variable `chrome` because it can conflict with global `chrome` variable in certain environments\n// See: https://github.com/getsentry/sentry-javascript/issues/6880\nconst chromeStackParserFn = line => {\n // If the stack line has no function name, we need to parse it differently\n const noFnParts = chromeRegexNoFnName.exec(line) ;\n\n if (noFnParts) {\n const [, filename, line, col] = noFnParts;\n return createFrame(filename, UNKNOWN_FUNCTION, +line, +col);\n }\n\n const parts = chromeRegex.exec(line) ;\n\n if (parts) {\n const isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line\n\n if (isEval) {\n const subMatch = chromeEvalRegex.exec(parts[2]) ;\n\n if (subMatch) {\n // throw out eval line/column and use top-most line/column number\n parts[2] = subMatch[1]; // url\n parts[3] = subMatch[2]; // line\n parts[4] = subMatch[3]; // column\n }\n }\n\n // Kamil: One more hack won't hurt us right? Understanding and adding more rules on top of these regexps right now\n // would be way too time consuming. (TODO: Rewrite whole RegExp to be more readable)\n const [func, filename] = extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]);\n\n return createFrame(filename, func, parts[3] ? +parts[3] : undefined, parts[4] ? +parts[4] : undefined);\n }\n\n return;\n};\n\nconst chromeStackLineParser = [CHROME_PRIORITY, chromeStackParserFn];\n\n// gecko regex: `(?:bundle|\\d+\\.js)`: `bundle` is for react native, `\\d+\\.js` also but specifically for ram bundles because it\n// generates filenames without a prefix like `file://` the filenames in the stacktrace are just 42.js\n// We need this specific case for now because we want no other regex to match.\nconst geckoREgex =\n /^\\s*(.*?)(?:\\((.*?)\\))?(?:^|@)?((?:[-a-z]+)?:\\/.*?|\\[native code\\]|[^@]*(?:bundle|\\d+\\.js)|\\/[\\w\\-. /=]+)(?::(\\d+))?(?::(\\d+))?\\s*$/i;\nconst geckoEvalRegex = /(\\S+) line (\\d+)(?: > eval line \\d+)* > eval/i;\n\nconst gecko = line => {\n const parts = geckoREgex.exec(line) ;\n\n if (parts) {\n const isEval = parts[3] && parts[3].indexOf(' > eval') > -1;\n if (isEval) {\n const subMatch = geckoEvalRegex.exec(parts[3]) ;\n\n if (subMatch) {\n // throw out eval line/column and use top-most line number\n parts[1] = parts[1] || 'eval';\n parts[3] = subMatch[1];\n parts[4] = subMatch[2];\n parts[5] = ''; // no column when eval\n }\n }\n\n let filename = parts[3];\n let func = parts[1] || UNKNOWN_FUNCTION;\n [func, filename] = extractSafariExtensionDetails(func, filename);\n\n return createFrame(filename, func, parts[4] ? +parts[4] : undefined, parts[5] ? +parts[5] : undefined);\n }\n\n return;\n};\n\nconst geckoStackLineParser = [GECKO_PRIORITY, gecko];\n\nconst winjsRegex = /^\\s*at (?:((?:\\[object object\\])?.+) )?\\(?((?:[-a-z]+):.*?):(\\d+)(?::(\\d+))?\\)?\\s*$/i;\n\nconst winjs = line => {\n const parts = winjsRegex.exec(line) ;\n\n return parts\n ? createFrame(parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : undefined)\n : undefined;\n};\n\nconst winjsStackLineParser = [WINJS_PRIORITY, winjs];\n\nconst opera10Regex = / line (\\d+).*script (?:in )?(\\S+)(?:: in function (\\S+))?$/i;\n\nconst opera10 = line => {\n const parts = opera10Regex.exec(line) ;\n return parts ? createFrame(parts[2], parts[3] || UNKNOWN_FUNCTION, +parts[1]) : undefined;\n};\n\nconst opera10StackLineParser = [OPERA10_PRIORITY, opera10];\n\nconst opera11Regex =\n / line (\\d+), column (\\d+)\\s*(?:in (?:]+)>|([^)]+))\\(.*\\))? in (.*):\\s*$/i;\n\nconst opera11 = line => {\n const parts = opera11Regex.exec(line) ;\n return parts ? createFrame(parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : undefined;\n};\n\nconst opera11StackLineParser = [OPERA11_PRIORITY, opera11];\n\nconst defaultStackLineParsers = [chromeStackLineParser, geckoStackLineParser];\n\nconst defaultStackParser = createStackParser(...defaultStackLineParsers);\n\n/**\n * Safari web extensions, starting version unknown, can produce \"frames-only\" stacktraces.\n * What it means, is that instead of format like:\n *\n * Error: wat\n * at function@url:row:col\n * at function@url:row:col\n * at function@url:row:col\n *\n * it produces something like:\n *\n * function@url:row:col\n * function@url:row:col\n * function@url:row:col\n *\n * Because of that, it won't be captured by `chrome` RegExp and will fall into `Gecko` branch.\n * This function is extracted so that we can use it in both places without duplicating the logic.\n * Unfortunately \"just\" changing RegExp is too complicated now and making it pass all tests\n * and fix this case seems like an impossible, or at least way too time-consuming task.\n */\nconst extractSafariExtensionDetails = (func, filename) => {\n const isSafariExtension = func.indexOf('safari-extension') !== -1;\n const isSafariWebExtension = func.indexOf('safari-web-extension') !== -1;\n\n return isSafariExtension || isSafariWebExtension\n ? [\n func.indexOf('@') !== -1 ? (func.split('@')[0] ) : UNKNOWN_FUNCTION,\n isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`,\n ]\n : [func, filename];\n};\n\nexport { chromeStackLineParser, defaultStackLineParsers, defaultStackParser, geckoStackLineParser, opera10StackLineParser, opera11StackLineParser, winjsStackLineParser };\n//# sourceMappingURL=stack-parsers.js.map\n","import { addClickKeypressInstrumentationHandler, addXhrInstrumentationHandler, addHistoryInstrumentationHandler, SENTRY_XHR_DATA_KEY } from '@sentry-internal/browser-utils';\nimport { defineIntegration, getClient, addBreadcrumb } from '@sentry/core';\nimport { addConsoleInstrumentationHandler, addFetchInstrumentationHandler, getEventDescription, logger, htmlTreeAsString, getComponentName, severityLevelFromString, safeJoin, getBreadcrumbLogLevelFromHttpStatusCode, parseUrl } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build.js';\nimport { WINDOW } from '../helpers.js';\n\n/** maxStringLength gets capped to prevent 100 breadcrumbs exceeding 1MB event payload size */\nconst MAX_ALLOWED_STRING_LENGTH = 1024;\n\nconst INTEGRATION_NAME = 'Breadcrumbs';\n\nconst _breadcrumbsIntegration = ((options = {}) => {\n const _options = {\n console: true,\n dom: true,\n fetch: true,\n history: true,\n sentry: true,\n xhr: true,\n ...options,\n };\n\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n if (_options.console) {\n addConsoleInstrumentationHandler(_getConsoleBreadcrumbHandler(client));\n }\n if (_options.dom) {\n addClickKeypressInstrumentationHandler(_getDomBreadcrumbHandler(client, _options.dom));\n }\n if (_options.xhr) {\n addXhrInstrumentationHandler(_getXhrBreadcrumbHandler(client));\n }\n if (_options.fetch) {\n addFetchInstrumentationHandler(_getFetchBreadcrumbHandler(client));\n }\n if (_options.history) {\n addHistoryInstrumentationHandler(_getHistoryBreadcrumbHandler(client));\n }\n if (_options.sentry) {\n client.on('beforeSendEvent', _getSentryBreadcrumbHandler(client));\n }\n },\n };\n}) ;\n\nconst breadcrumbsIntegration = defineIntegration(_breadcrumbsIntegration);\n\n/**\n * Adds a breadcrumb for Sentry events or transactions if this option is enabled.\n */\nfunction _getSentryBreadcrumbHandler(client) {\n return function addSentryBreadcrumb(event) {\n if (getClient() !== client) {\n return;\n }\n\n addBreadcrumb(\n {\n category: `sentry.${event.type === 'transaction' ? 'transaction' : 'event'}`,\n event_id: event.event_id,\n level: event.level,\n message: getEventDescription(event),\n },\n {\n event,\n },\n );\n };\n}\n\n/**\n * A HOC that creates a function that creates breadcrumbs from DOM API calls.\n * This is a HOC so that we get access to dom options in the closure.\n */\nfunction _getDomBreadcrumbHandler(\n client,\n dom,\n) {\n return function _innerDomBreadcrumb(handlerData) {\n if (getClient() !== client) {\n return;\n }\n\n let target;\n let componentName;\n let keyAttrs = typeof dom === 'object' ? dom.serializeAttribute : undefined;\n\n let maxStringLength =\n typeof dom === 'object' && typeof dom.maxStringLength === 'number' ? dom.maxStringLength : undefined;\n if (maxStringLength && maxStringLength > MAX_ALLOWED_STRING_LENGTH) {\n DEBUG_BUILD &&\n logger.warn(\n `\\`dom.maxStringLength\\` cannot exceed ${MAX_ALLOWED_STRING_LENGTH}, but a value of ${maxStringLength} was configured. Sentry will use ${MAX_ALLOWED_STRING_LENGTH} instead.`,\n );\n maxStringLength = MAX_ALLOWED_STRING_LENGTH;\n }\n\n if (typeof keyAttrs === 'string') {\n keyAttrs = [keyAttrs];\n }\n\n // Accessing event.target can throw (see getsentry/raven-js#838, #768)\n try {\n const event = handlerData.event ;\n const element = _isEvent(event) ? event.target : event;\n\n target = htmlTreeAsString(element, { keyAttrs, maxStringLength });\n componentName = getComponentName(element);\n } catch (e) {\n target = '';\n }\n\n if (target.length === 0) {\n return;\n }\n\n const breadcrumb = {\n category: `ui.${handlerData.name}`,\n message: target,\n };\n\n if (componentName) {\n breadcrumb.data = { 'ui.component_name': componentName };\n }\n\n addBreadcrumb(breadcrumb, {\n event: handlerData.event,\n name: handlerData.name,\n global: handlerData.global,\n });\n };\n}\n\n/**\n * Creates breadcrumbs from console API calls\n */\nfunction _getConsoleBreadcrumbHandler(client) {\n return function _consoleBreadcrumb(handlerData) {\n if (getClient() !== client) {\n return;\n }\n\n const breadcrumb = {\n category: 'console',\n data: {\n arguments: handlerData.args,\n logger: 'console',\n },\n level: severityLevelFromString(handlerData.level),\n message: safeJoin(handlerData.args, ' '),\n };\n\n if (handlerData.level === 'assert') {\n if (handlerData.args[0] === false) {\n breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;\n breadcrumb.data.arguments = handlerData.args.slice(1);\n } else {\n // Don't capture a breadcrumb for passed assertions\n return;\n }\n }\n\n addBreadcrumb(breadcrumb, {\n input: handlerData.args,\n level: handlerData.level,\n });\n };\n}\n\n/**\n * Creates breadcrumbs from XHR API calls\n */\nfunction _getXhrBreadcrumbHandler(client) {\n return function _xhrBreadcrumb(handlerData) {\n if (getClient() !== client) {\n return;\n }\n\n const { startTimestamp, endTimestamp } = handlerData;\n\n const sentryXhrData = handlerData.xhr[SENTRY_XHR_DATA_KEY];\n\n // We only capture complete, non-sentry requests\n if (!startTimestamp || !endTimestamp || !sentryXhrData) {\n return;\n }\n\n const { method, url, status_code, body } = sentryXhrData;\n\n const data = {\n method,\n url,\n status_code,\n };\n\n const hint = {\n xhr: handlerData.xhr,\n input: body,\n startTimestamp,\n endTimestamp,\n };\n\n const level = getBreadcrumbLogLevelFromHttpStatusCode(status_code);\n\n addBreadcrumb(\n {\n category: 'xhr',\n data,\n type: 'http',\n level,\n },\n hint,\n );\n };\n}\n\n/**\n * Creates breadcrumbs from fetch API calls\n */\nfunction _getFetchBreadcrumbHandler(client) {\n return function _fetchBreadcrumb(handlerData) {\n if (getClient() !== client) {\n return;\n }\n\n const { startTimestamp, endTimestamp } = handlerData;\n\n // We only capture complete fetch requests\n if (!endTimestamp) {\n return;\n }\n\n if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {\n // We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)\n return;\n }\n\n if (handlerData.error) {\n const data = handlerData.fetchData;\n const hint = {\n data: handlerData.error,\n input: handlerData.args,\n startTimestamp,\n endTimestamp,\n };\n\n addBreadcrumb(\n {\n category: 'fetch',\n data,\n level: 'error',\n type: 'http',\n },\n hint,\n );\n } else {\n const response = handlerData.response ;\n const data = {\n ...handlerData.fetchData,\n status_code: response && response.status,\n };\n const hint = {\n input: handlerData.args,\n response,\n startTimestamp,\n endTimestamp,\n };\n const level = getBreadcrumbLogLevelFromHttpStatusCode(data.status_code);\n\n addBreadcrumb(\n {\n category: 'fetch',\n data,\n type: 'http',\n level,\n },\n hint,\n );\n }\n };\n}\n\n/**\n * Creates breadcrumbs from history API calls\n */\nfunction _getHistoryBreadcrumbHandler(client) {\n return function _historyBreadcrumb(handlerData) {\n if (getClient() !== client) {\n return;\n }\n\n let from = handlerData.from;\n let to = handlerData.to;\n const parsedLoc = parseUrl(WINDOW.location.href);\n let parsedFrom = from ? parseUrl(from) : undefined;\n const parsedTo = parseUrl(to);\n\n // Initial pushState doesn't provide `from` information\n if (!parsedFrom || !parsedFrom.path) {\n parsedFrom = parsedLoc;\n }\n\n // Use only the path component of the URL if the URL matches the current\n // document (almost all the time when using pushState)\n if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) {\n to = parsedTo.relative;\n }\n if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) {\n from = parsedFrom.relative;\n }\n\n addBreadcrumb({\n category: 'navigation',\n data: {\n from,\n to,\n },\n });\n };\n}\n\nfunction _isEvent(event) {\n return !!event && !!(event ).target;\n}\n\nexport { breadcrumbsIntegration };\n//# sourceMappingURL=breadcrumbs.js.map\n","import { defineIntegration } from '@sentry/core';\nimport { fill, getFunctionName, getOriginalFunction } from '@sentry/utils';\nimport { WINDOW, wrap } from '../helpers.js';\n\nconst DEFAULT_EVENT_TARGET = [\n 'EventTarget',\n 'Window',\n 'Node',\n 'ApplicationCache',\n 'AudioTrackList',\n 'BroadcastChannel',\n 'ChannelMergerNode',\n 'CryptoOperation',\n 'EventSource',\n 'FileReader',\n 'HTMLUnknownElement',\n 'IDBDatabase',\n 'IDBRequest',\n 'IDBTransaction',\n 'KeyOperation',\n 'MediaController',\n 'MessagePort',\n 'ModalWindow',\n 'Notification',\n 'SVGElementInstance',\n 'Screen',\n 'SharedWorker',\n 'TextTrack',\n 'TextTrackCue',\n 'TextTrackList',\n 'WebSocket',\n 'WebSocketWorker',\n 'Worker',\n 'XMLHttpRequest',\n 'XMLHttpRequestEventTarget',\n 'XMLHttpRequestUpload',\n];\n\nconst INTEGRATION_NAME = 'BrowserApiErrors';\n\nconst _browserApiErrorsIntegration = ((options = {}) => {\n const _options = {\n XMLHttpRequest: true,\n eventTarget: true,\n requestAnimationFrame: true,\n setInterval: true,\n setTimeout: true,\n ...options,\n };\n\n return {\n name: INTEGRATION_NAME,\n // TODO: This currently only works for the first client this is setup\n // We may want to adjust this to check for client etc.\n setupOnce() {\n if (_options.setTimeout) {\n fill(WINDOW, 'setTimeout', _wrapTimeFunction);\n }\n\n if (_options.setInterval) {\n fill(WINDOW, 'setInterval', _wrapTimeFunction);\n }\n\n if (_options.requestAnimationFrame) {\n fill(WINDOW, 'requestAnimationFrame', _wrapRAF);\n }\n\n if (_options.XMLHttpRequest && 'XMLHttpRequest' in WINDOW) {\n fill(XMLHttpRequest.prototype, 'send', _wrapXHR);\n }\n\n const eventTargetOption = _options.eventTarget;\n if (eventTargetOption) {\n const eventTarget = Array.isArray(eventTargetOption) ? eventTargetOption : DEFAULT_EVENT_TARGET;\n eventTarget.forEach(_wrapEventTarget);\n }\n },\n };\n}) ;\n\n/**\n * Wrap timer functions and event targets to catch errors and provide better meta data.\n */\nconst browserApiErrorsIntegration = defineIntegration(_browserApiErrorsIntegration);\n\nfunction _wrapTimeFunction(original) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return function ( ...args) {\n const originalCallback = args[0];\n args[0] = wrap(originalCallback, {\n mechanism: {\n data: { function: getFunctionName(original) },\n handled: false,\n type: 'instrument',\n },\n });\n return original.apply(this, args);\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction _wrapRAF(original) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return function ( callback) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n return original.apply(this, [\n wrap(callback, {\n mechanism: {\n data: {\n function: 'requestAnimationFrame',\n handler: getFunctionName(original),\n },\n handled: false,\n type: 'instrument',\n },\n }),\n ]);\n };\n}\n\nfunction _wrapXHR(originalSend) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return function ( ...args) {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const xhr = this;\n const xmlHttpRequestProps = ['onload', 'onerror', 'onprogress', 'onreadystatechange'];\n\n xmlHttpRequestProps.forEach(prop => {\n if (prop in xhr && typeof xhr[prop] === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fill(xhr, prop, function (original) {\n const wrapOptions = {\n mechanism: {\n data: {\n function: prop,\n handler: getFunctionName(original),\n },\n handled: false,\n type: 'instrument',\n },\n };\n\n // If Instrument integration has been called before BrowserApiErrors, get the name of original function\n const originalFunction = getOriginalFunction(original);\n if (originalFunction) {\n wrapOptions.mechanism.data.handler = getFunctionName(originalFunction);\n }\n\n // Otherwise wrap directly\n return wrap(original, wrapOptions);\n });\n }\n });\n\n return originalSend.apply(this, args);\n };\n}\n\nfunction _wrapEventTarget(target) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const globalObject = WINDOW ;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const proto = globalObject[target] && globalObject[target].prototype;\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins\n if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {\n return;\n }\n\n fill(proto, 'addEventListener', function (original,)\n\n {\n return function (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n\n eventName,\n fn,\n options,\n ) {\n try {\n if (typeof fn.handleEvent === 'function') {\n // ESlint disable explanation:\n // First, it is generally safe to call `wrap` with an unbound function. Furthermore, using `.bind()` would\n // introduce a bug here, because bind returns a new function that doesn't have our\n // flags(like __sentry_original__) attached. `wrap` checks for those flags to avoid unnecessary wrapping.\n // Without those flags, every call to addEventListener wraps the function again, causing a memory leak.\n // eslint-disable-next-line @typescript-eslint/unbound-method\n fn.handleEvent = wrap(fn.handleEvent, {\n mechanism: {\n data: {\n function: 'handleEvent',\n handler: getFunctionName(fn),\n target,\n },\n handled: false,\n type: 'instrument',\n },\n });\n }\n } catch (err) {\n // can sometimes get 'Permission denied to access property \"handle Event'\n }\n\n return original.apply(this, [\n eventName,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n wrap(fn , {\n mechanism: {\n data: {\n function: 'addEventListener',\n handler: getFunctionName(fn),\n target,\n },\n handled: false,\n type: 'instrument',\n },\n }),\n options,\n ]);\n };\n });\n\n fill(\n proto,\n 'removeEventListener',\n function (\n originalRemoveEventListener,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ) {\n return function (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n\n eventName,\n fn,\n options,\n ) {\n /**\n * There are 2 possible scenarios here:\n *\n * 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified\n * method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function\n * as a pass-through, and call original `removeEventListener` with it.\n *\n * 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using\n * our wrapped version of `addEventListener`, which internally calls `wrap` helper.\n * This helper \"wraps\" whole callback inside a try/catch statement, and attached appropriate metadata to it,\n * in order for us to make a distinction between wrapped/non-wrapped functions possible.\n * If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.\n *\n * When someone adds a handler prior to initialization, and then do it again, but after,\n * then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible\n * to get rid of the initial handler and it'd stick there forever.\n */\n const wrappedEventHandler = fn ;\n try {\n const originalEventHandler = wrappedEventHandler && wrappedEventHandler.__sentry_wrapped__;\n if (originalEventHandler) {\n originalRemoveEventListener.call(this, eventName, originalEventHandler, options);\n }\n } catch (e) {\n // ignore, accessing __sentry_wrapped__ will throw in some Selenium environments\n }\n return originalRemoveEventListener.call(this, eventName, wrappedEventHandler, options);\n };\n },\n );\n}\n\nexport { browserApiErrorsIntegration };\n//# sourceMappingURL=browserapierrors.js.map\n","import { defineIntegration, getClient, captureEvent } from '@sentry/core';\nimport { addGlobalErrorInstrumentationHandler, addGlobalUnhandledRejectionInstrumentationHandler, isPrimitive, isString, getLocationHref, UNKNOWN_FUNCTION, logger } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build.js';\nimport { eventFromUnknownInput } from '../eventbuilder.js';\nimport { shouldIgnoreOnError } from '../helpers.js';\n\nconst INTEGRATION_NAME = 'GlobalHandlers';\n\nconst _globalHandlersIntegration = ((options = {}) => {\n const _options = {\n onerror: true,\n onunhandledrejection: true,\n ...options,\n };\n\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n Error.stackTraceLimit = 50;\n },\n setup(client) {\n if (_options.onerror) {\n _installGlobalOnErrorHandler(client);\n globalHandlerLog('onerror');\n }\n if (_options.onunhandledrejection) {\n _installGlobalOnUnhandledRejectionHandler(client);\n globalHandlerLog('onunhandledrejection');\n }\n },\n };\n}) ;\n\nconst globalHandlersIntegration = defineIntegration(_globalHandlersIntegration);\n\nfunction _installGlobalOnErrorHandler(client) {\n addGlobalErrorInstrumentationHandler(data => {\n const { stackParser, attachStacktrace } = getOptions();\n\n if (getClient() !== client || shouldIgnoreOnError()) {\n return;\n }\n\n const { msg, url, line, column, error } = data;\n\n const event = _enhanceEventWithInitialFrame(\n eventFromUnknownInput(stackParser, error || msg, undefined, attachStacktrace, false),\n url,\n line,\n column,\n );\n\n event.level = 'error';\n\n captureEvent(event, {\n originalException: error,\n mechanism: {\n handled: false,\n type: 'onerror',\n },\n });\n });\n}\n\nfunction _installGlobalOnUnhandledRejectionHandler(client) {\n addGlobalUnhandledRejectionInstrumentationHandler(e => {\n const { stackParser, attachStacktrace } = getOptions();\n\n if (getClient() !== client || shouldIgnoreOnError()) {\n return;\n }\n\n const error = _getUnhandledRejectionError(e );\n\n const event = isPrimitive(error)\n ? _eventFromRejectionWithPrimitive(error)\n : eventFromUnknownInput(stackParser, error, undefined, attachStacktrace, true);\n\n event.level = 'error';\n\n captureEvent(event, {\n originalException: error,\n mechanism: {\n handled: false,\n type: 'onunhandledrejection',\n },\n });\n });\n}\n\nfunction _getUnhandledRejectionError(error) {\n if (isPrimitive(error)) {\n return error;\n }\n\n // dig the object of the rejection out of known event types\n try {\n\n // PromiseRejectionEvents store the object of the rejection under 'reason'\n // see https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent\n if ('reason' in (error )) {\n return (error ).reason;\n }\n\n // something, somewhere, (likely a browser extension) effectively casts PromiseRejectionEvents\n // to CustomEvents, moving the `promise` and `reason` attributes of the PRE into\n // the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec\n // see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and\n // https://github.com/getsentry/sentry-javascript/issues/2380\n if ('detail' in (error ) && 'reason' in (error ).detail) {\n return (error ).detail.reason;\n }\n } catch (e2) {} // eslint-disable-line no-empty\n\n return error;\n}\n\n/**\n * Create an event from a promise rejection where the `reason` is a primitive.\n *\n * @param reason: The `reason` property of the promise rejection\n * @returns An Event object with an appropriate `exception` value\n */\nfunction _eventFromRejectionWithPrimitive(reason) {\n return {\n exception: {\n values: [\n {\n type: 'UnhandledRejection',\n // String() is needed because the Primitive type includes symbols (which can't be automatically stringified)\n value: `Non-Error promise rejection captured with value: ${String(reason)}`,\n },\n ],\n },\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction _enhanceEventWithInitialFrame(event, url, line, column) {\n // event.exception\n const e = (event.exception = event.exception || {});\n // event.exception.values\n const ev = (e.values = e.values || []);\n // event.exception.values[0]\n const ev0 = (ev[0] = ev[0] || {});\n // event.exception.values[0].stacktrace\n const ev0s = (ev0.stacktrace = ev0.stacktrace || {});\n // event.exception.values[0].stacktrace.frames\n const ev0sf = (ev0s.frames = ev0s.frames || []);\n\n const colno = isNaN(parseInt(column, 10)) ? undefined : column;\n const lineno = isNaN(parseInt(line, 10)) ? undefined : line;\n const filename = isString(url) && url.length > 0 ? url : getLocationHref();\n\n // event.exception.values[0].stacktrace.frames\n if (ev0sf.length === 0) {\n ev0sf.push({\n colno,\n filename,\n function: UNKNOWN_FUNCTION,\n in_app: true,\n lineno,\n });\n }\n\n return event;\n}\n\nfunction globalHandlerLog(type) {\n DEBUG_BUILD && logger.log(`Global Handler attached: ${type}`);\n}\n\nfunction getOptions() {\n const client = getClient();\n const options = (client && client.getOptions()) || {\n stackParser: () => [],\n attachStacktrace: false,\n };\n return options;\n}\n\nexport { globalHandlersIntegration };\n//# sourceMappingURL=globalhandlers.js.map\n","import { defineIntegration } from '@sentry/core';\nimport { WINDOW } from '../helpers.js';\n\n/**\n * Collects information about HTTP request headers and\n * attaches them to the event.\n */\nconst httpContextIntegration = defineIntegration(() => {\n return {\n name: 'HttpContext',\n preprocessEvent(event) {\n // if none of the information we want exists, don't bother\n if (!WINDOW.navigator && !WINDOW.location && !WINDOW.document) {\n return;\n }\n\n // grab as much info as exists and add it to the event\n const url = (event.request && event.request.url) || (WINDOW.location && WINDOW.location.href);\n const { referrer } = WINDOW.document || {};\n const { userAgent } = WINDOW.navigator || {};\n\n const headers = {\n ...(event.request && event.request.headers),\n ...(referrer && { Referer: referrer }),\n ...(userAgent && { 'User-Agent': userAgent }),\n };\n const request = { ...event.request, ...(url && { url }), headers };\n\n event.request = request;\n },\n };\n});\n\nexport { httpContextIntegration };\n//# sourceMappingURL=httpcontext.js.map\n","import { defineIntegration } from '@sentry/core';\nimport { applyAggregateErrorsToEvent } from '@sentry/utils';\nimport { exceptionFromError } from '../eventbuilder.js';\n\nconst DEFAULT_KEY = 'cause';\nconst DEFAULT_LIMIT = 5;\n\nconst INTEGRATION_NAME = 'LinkedErrors';\n\nconst _linkedErrorsIntegration = ((options = {}) => {\n const limit = options.limit || DEFAULT_LIMIT;\n const key = options.key || DEFAULT_KEY;\n\n return {\n name: INTEGRATION_NAME,\n preprocessEvent(event, hint, client) {\n const options = client.getOptions();\n\n applyAggregateErrorsToEvent(\n // This differs from the LinkedErrors integration in core by using a different exceptionFromError function\n exceptionFromError,\n options.stackParser,\n options.maxValueLength,\n key,\n limit,\n event,\n hint,\n );\n },\n };\n}) ;\n\n/**\n * Aggregrate linked errors in an event.\n */\nconst linkedErrorsIntegration = defineIntegration(_linkedErrorsIntegration);\n\nexport { linkedErrorsIntegration };\n//# sourceMappingURL=linkederrors.js.map\n","import { inboundFiltersIntegration, functionToStringIntegration, dedupeIntegration, getIntegrationsToSetup, initAndBind, getCurrentScope, lastEventId, getReportDialogEndpoint, startSession, captureSession, getClient } from '@sentry/core';\nimport { consoleSandbox, supportsFetch, logger, stackParserFromStackParserOptions } from '@sentry/utils';\nimport { addHistoryInstrumentationHandler } from '@sentry-internal/browser-utils';\nimport { BrowserClient } from './client.js';\nimport { DEBUG_BUILD } from './debug-build.js';\nimport { WINDOW } from './helpers.js';\nimport { breadcrumbsIntegration } from './integrations/breadcrumbs.js';\nimport { browserApiErrorsIntegration } from './integrations/browserapierrors.js';\nimport { globalHandlersIntegration } from './integrations/globalhandlers.js';\nimport { httpContextIntegration } from './integrations/httpcontext.js';\nimport { linkedErrorsIntegration } from './integrations/linkederrors.js';\nimport { defaultStackParser } from './stack-parsers.js';\nimport { makeFetchTransport } from './transports/fetch.js';\n\n/** Get the default integrations for the browser SDK. */\nfunction getDefaultIntegrations(_options) {\n /**\n * Note: Please make sure this stays in sync with Angular SDK, which re-exports\n * `getDefaultIntegrations` but with an adjusted set of integrations.\n */\n return [\n inboundFiltersIntegration(),\n functionToStringIntegration(),\n browserApiErrorsIntegration(),\n breadcrumbsIntegration(),\n globalHandlersIntegration(),\n linkedErrorsIntegration(),\n dedupeIntegration(),\n httpContextIntegration(),\n ];\n}\n\nfunction applyDefaultOptions(optionsArg = {}) {\n const defaultOptions = {\n defaultIntegrations: getDefaultIntegrations(),\n release:\n typeof __SENTRY_RELEASE__ === 'string' // This allows build tooling to find-and-replace __SENTRY_RELEASE__ to inject a release value\n ? __SENTRY_RELEASE__\n : WINDOW.SENTRY_RELEASE && WINDOW.SENTRY_RELEASE.id // This supports the variable that sentry-webpack-plugin injects\n ? WINDOW.SENTRY_RELEASE.id\n : undefined,\n autoSessionTracking: true,\n sendClientReports: true,\n };\n\n // TODO: Instead of dropping just `defaultIntegrations`, we should simply\n // call `dropUndefinedKeys` on the entire `optionsArg`.\n // However, for this to work we need to adjust the `hasTracingEnabled()` logic\n // first as it differentiates between `undefined` and the key not being in the object.\n if (optionsArg.defaultIntegrations == null) {\n delete optionsArg.defaultIntegrations;\n }\n\n return { ...defaultOptions, ...optionsArg };\n}\n\nfunction shouldShowBrowserExtensionError() {\n const windowWithMaybeExtension =\n typeof WINDOW.window !== 'undefined' && (WINDOW );\n if (!windowWithMaybeExtension) {\n // No need to show the error if we're not in a browser window environment (e.g. service workers)\n return false;\n }\n\n const extensionKey = windowWithMaybeExtension.chrome ? 'chrome' : 'browser';\n const extensionObject = windowWithMaybeExtension[extensionKey];\n\n const runtimeId = extensionObject && extensionObject.runtime && extensionObject.runtime.id;\n const href = (WINDOW.location && WINDOW.location.href) || '';\n\n const extensionProtocols = ['chrome-extension:', 'moz-extension:', 'ms-browser-extension:', 'safari-web-extension:'];\n\n // Running the SDK in a dedicated extension page and calling Sentry.init is fine; no risk of data leakage\n const isDedicatedExtensionPage =\n !!runtimeId && WINDOW === WINDOW.top && extensionProtocols.some(protocol => href.startsWith(`${protocol}//`));\n\n // Running the SDK in NW.js, which appears like a browser extension but isn't, is also fine\n // see: https://github.com/getsentry/sentry-javascript/issues/12668\n const isNWjs = typeof windowWithMaybeExtension.nw !== 'undefined';\n\n return !!runtimeId && !isDedicatedExtensionPage && !isNWjs;\n}\n\n/**\n * A magic string that build tooling can leverage in order to inject a release value into the SDK.\n */\n\n/**\n * The Sentry Browser SDK Client.\n *\n * To use this SDK, call the {@link init} function as early as possible when\n * loading the web page. To set context information or send manual events, use\n * the provided methods.\n *\n * @example\n *\n * ```\n *\n * import { init } from '@sentry/browser';\n *\n * init({\n * dsn: '__DSN__',\n * // ...\n * });\n * ```\n *\n * @example\n * ```\n *\n * import { addBreadcrumb } from '@sentry/browser';\n * addBreadcrumb({\n * message: 'My Breadcrumb',\n * // ...\n * });\n * ```\n *\n * @example\n *\n * ```\n *\n * import * as Sentry from '@sentry/browser';\n * Sentry.captureMessage('Hello, world!');\n * Sentry.captureException(new Error('Good bye'));\n * Sentry.captureEvent({\n * message: 'Manual',\n * stacktrace: [\n * // ...\n * ],\n * });\n * ```\n *\n * @see {@link BrowserOptions} for documentation on configuration options.\n */\nfunction init(browserOptions = {}) {\n const options = applyDefaultOptions(browserOptions);\n\n if (!options.skipBrowserExtensionCheck && shouldShowBrowserExtensionError()) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.error(\n '[Sentry] You cannot run Sentry this way in a browser extension, check: https://docs.sentry.io/platforms/javascript/best-practices/browser-extensions/',\n );\n });\n return;\n }\n\n if (DEBUG_BUILD) {\n if (!supportsFetch()) {\n logger.warn(\n 'No Fetch API detected. The Sentry SDK requires a Fetch API compatible environment to send events. Please add a Fetch API polyfill.',\n );\n }\n }\n const clientOptions = {\n ...options,\n stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),\n integrations: getIntegrationsToSetup(options),\n transport: options.transport || makeFetchTransport,\n };\n\n const client = initAndBind(BrowserClient, clientOptions);\n\n if (options.autoSessionTracking) {\n startSessionTracking();\n }\n\n return client;\n}\n\n/**\n * All properties the report dialog supports\n */\n\n/**\n * Present the user with a report dialog.\n *\n * @param options Everything is optional, we try to fetch all info need from the global scope.\n */\nfunction showReportDialog(options = {}) {\n // doesn't work without a document (React Native)\n if (!WINDOW.document) {\n DEBUG_BUILD && logger.error('Global document not defined in showReportDialog call');\n return;\n }\n\n const scope = getCurrentScope();\n const client = scope.getClient();\n const dsn = client && client.getDsn();\n\n if (!dsn) {\n DEBUG_BUILD && logger.error('DSN not configured for showReportDialog call');\n return;\n }\n\n if (scope) {\n options.user = {\n ...scope.getUser(),\n ...options.user,\n };\n }\n\n if (!options.eventId) {\n const eventId = lastEventId();\n if (eventId) {\n options.eventId = eventId;\n }\n }\n\n const script = WINDOW.document.createElement('script');\n script.async = true;\n script.crossOrigin = 'anonymous';\n script.src = getReportDialogEndpoint(dsn, options);\n\n if (options.onLoad) {\n script.onload = options.onLoad;\n }\n\n const { onClose } = options;\n if (onClose) {\n const reportDialogClosedMessageHandler = (event) => {\n if (event.data === '__sentry_reportdialog_closed__') {\n try {\n onClose();\n } finally {\n WINDOW.removeEventListener('message', reportDialogClosedMessageHandler);\n }\n }\n };\n WINDOW.addEventListener('message', reportDialogClosedMessageHandler);\n }\n\n const injectionPoint = WINDOW.document.head || WINDOW.document.body;\n if (injectionPoint) {\n injectionPoint.appendChild(script);\n } else {\n DEBUG_BUILD && logger.error('Not injecting report dialog. No injection point found in HTML');\n }\n}\n\n/**\n * This function is here to be API compatible with the loader.\n * @hidden\n */\nfunction forceLoad() {\n // Noop\n}\n\n/**\n * This function is here to be API compatible with the loader.\n * @hidden\n */\nfunction onLoad(callback) {\n callback();\n}\n\n/**\n * Enable automatic Session Tracking for the initial page load.\n */\nfunction startSessionTracking() {\n if (typeof WINDOW.document === 'undefined') {\n DEBUG_BUILD && logger.warn('Session tracking in non-browser environment with @sentry/browser is not supported.');\n return;\n }\n\n // The session duration for browser sessions does not track a meaningful\n // concept that can be used as a metric.\n // Automatically captured sessions are akin to page views, and thus we\n // discard their duration.\n startSession({ ignoreDuration: true });\n captureSession();\n\n // We want to create a session for every navigation as well\n addHistoryInstrumentationHandler(({ from, to }) => {\n // Don't create an additional session for the initial route or if the location did not change\n if (from !== undefined && from !== to) {\n startSession({ ignoreDuration: true });\n captureSession();\n }\n });\n}\n\n/**\n * Captures user feedback and sends it to Sentry.\n *\n * @deprecated Use `captureFeedback` instead.\n */\nfunction captureUserFeedback(feedback) {\n const client = getClient();\n if (client) {\n // eslint-disable-next-line deprecation/deprecation\n client.captureUserFeedback(feedback);\n }\n}\n\nexport { captureUserFeedback, forceLoad, getDefaultIntegrations, init, onLoad, showReportDialog };\n//# sourceMappingURL=sdk.js.map\n","import { addXhrInstrumentationHandler, addPerformanceInstrumentationHandler, SENTRY_XHR_DATA_KEY } from '@sentry-internal/browser-utils';\nimport { instrumentFetchRequest, spanToJSON, hasTracingEnabled, setHttpStatus, getActiveSpan, startInactiveSpan, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_OP, SentryNonRecordingSpan, getClient, getCurrentScope, getIsolationScope, spanToTraceHeader, getDynamicSamplingContextFromSpan, getDynamicSamplingContextFromClient } from '@sentry/core';\nimport { addFetchEndInstrumentationHandler, addFetchInstrumentationHandler, parseUrl, browserPerformanceTimeOrigin, generateSentryTraceHeader, dynamicSamplingContextToSentryBaggageHeader, BAGGAGE_HEADER_NAME, stringMatchesSomePattern } from '@sentry/utils';\nimport { WINDOW } from '../helpers.js';\n\n/* eslint-disable max-lines */\n\n/** Options for Request Instrumentation */\n\nconst responseToSpanId = new WeakMap();\nconst spanIdToEndTimestamp = new Map();\n\nconst defaultRequestInstrumentationOptions = {\n traceFetch: true,\n traceXHR: true,\n enableHTTPTimings: true,\n trackFetchStreamPerformance: false,\n};\n\n/** Registers span creators for xhr and fetch requests */\nfunction instrumentOutgoingRequests(client, _options) {\n const {\n traceFetch,\n traceXHR,\n trackFetchStreamPerformance,\n shouldCreateSpanForRequest,\n enableHTTPTimings,\n tracePropagationTargets,\n } = {\n traceFetch: defaultRequestInstrumentationOptions.traceFetch,\n traceXHR: defaultRequestInstrumentationOptions.traceXHR,\n trackFetchStreamPerformance: defaultRequestInstrumentationOptions.trackFetchStreamPerformance,\n ..._options,\n };\n\n const shouldCreateSpan =\n typeof shouldCreateSpanForRequest === 'function' ? shouldCreateSpanForRequest : (_) => true;\n\n const shouldAttachHeadersWithTargets = (url) => shouldAttachHeaders(url, tracePropagationTargets);\n\n const spans = {};\n\n if (traceFetch) {\n // Keeping track of http requests, whose body payloads resolved later than the initial resolved request\n // e.g. streaming using server sent events (SSE)\n client.addEventProcessor(event => {\n if (event.type === 'transaction' && event.spans) {\n event.spans.forEach(span => {\n if (span.op === 'http.client') {\n const updatedTimestamp = spanIdToEndTimestamp.get(span.span_id);\n if (updatedTimestamp) {\n span.timestamp = updatedTimestamp / 1000;\n spanIdToEndTimestamp.delete(span.span_id);\n }\n }\n });\n }\n return event;\n });\n\n if (trackFetchStreamPerformance) {\n addFetchEndInstrumentationHandler(handlerData => {\n if (handlerData.response) {\n const span = responseToSpanId.get(handlerData.response);\n if (span && handlerData.endTimestamp) {\n spanIdToEndTimestamp.set(span, handlerData.endTimestamp);\n }\n }\n });\n }\n\n addFetchInstrumentationHandler(handlerData => {\n const createdSpan = instrumentFetchRequest(handlerData, shouldCreateSpan, shouldAttachHeadersWithTargets, spans);\n\n if (handlerData.response && handlerData.fetchData.__span) {\n responseToSpanId.set(handlerData.response, handlerData.fetchData.__span);\n }\n\n // We cannot use `window.location` in the generic fetch instrumentation,\n // but we need it for reliable `server.address` attribute.\n // so we extend this in here\n if (createdSpan) {\n const fullUrl = getFullURL(handlerData.fetchData.url);\n const host = fullUrl ? parseUrl(fullUrl).host : undefined;\n createdSpan.setAttributes({\n 'http.url': fullUrl,\n 'server.address': host,\n });\n }\n\n if (enableHTTPTimings && createdSpan) {\n addHTTPTimings(createdSpan);\n }\n });\n }\n\n if (traceXHR) {\n addXhrInstrumentationHandler(handlerData => {\n const createdSpan = xhrCallback(handlerData, shouldCreateSpan, shouldAttachHeadersWithTargets, spans);\n if (enableHTTPTimings && createdSpan) {\n addHTTPTimings(createdSpan);\n }\n });\n }\n}\n\nfunction isPerformanceResourceTiming(entry) {\n return (\n entry.entryType === 'resource' &&\n 'initiatorType' in entry &&\n typeof (entry ).nextHopProtocol === 'string' &&\n (entry.initiatorType === 'fetch' || entry.initiatorType === 'xmlhttprequest')\n );\n}\n\n/**\n * Creates a temporary observer to listen to the next fetch/xhr resourcing timings,\n * so that when timings hit their per-browser limit they don't need to be removed.\n *\n * @param span A span that has yet to be finished, must contain `url` on data.\n */\nfunction addHTTPTimings(span) {\n const { url } = spanToJSON(span).data || {};\n\n if (!url || typeof url !== 'string') {\n return;\n }\n\n const cleanup = addPerformanceInstrumentationHandler('resource', ({ entries }) => {\n entries.forEach(entry => {\n if (isPerformanceResourceTiming(entry) && entry.name.endsWith(url)) {\n const spanData = resourceTimingEntryToSpanData(entry);\n spanData.forEach(data => span.setAttribute(...data));\n // In the next tick, clean this handler up\n // We have to wait here because otherwise this cleans itself up before it is fully done\n setTimeout(cleanup);\n }\n });\n });\n}\n\n/**\n * Converts ALPN protocol ids to name and version.\n *\n * (https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids)\n * @param nextHopProtocol PerformanceResourceTiming.nextHopProtocol\n */\nfunction extractNetworkProtocol(nextHopProtocol) {\n let name = 'unknown';\n let version = 'unknown';\n let _name = '';\n for (const char of nextHopProtocol) {\n // http/1.1 etc.\n if (char === '/') {\n [name, version] = nextHopProtocol.split('/') ;\n break;\n }\n // h2, h3 etc.\n if (!isNaN(Number(char))) {\n name = _name === 'h' ? 'http' : _name;\n version = nextHopProtocol.split(_name)[1] ;\n break;\n }\n _name += char;\n }\n if (_name === nextHopProtocol) {\n // webrtc, ftp, etc.\n name = _name;\n }\n return { name, version };\n}\n\nfunction getAbsoluteTime(time = 0) {\n return ((browserPerformanceTimeOrigin || performance.timeOrigin) + time) / 1000;\n}\n\nfunction resourceTimingEntryToSpanData(resourceTiming) {\n const { name, version } = extractNetworkProtocol(resourceTiming.nextHopProtocol);\n\n const timingSpanData = [];\n\n timingSpanData.push(['network.protocol.version', version], ['network.protocol.name', name]);\n\n if (!browserPerformanceTimeOrigin) {\n return timingSpanData;\n }\n return [\n ...timingSpanData,\n ['http.request.redirect_start', getAbsoluteTime(resourceTiming.redirectStart)],\n ['http.request.fetch_start', getAbsoluteTime(resourceTiming.fetchStart)],\n ['http.request.domain_lookup_start', getAbsoluteTime(resourceTiming.domainLookupStart)],\n ['http.request.domain_lookup_end', getAbsoluteTime(resourceTiming.domainLookupEnd)],\n ['http.request.connect_start', getAbsoluteTime(resourceTiming.connectStart)],\n ['http.request.secure_connection_start', getAbsoluteTime(resourceTiming.secureConnectionStart)],\n ['http.request.connection_end', getAbsoluteTime(resourceTiming.connectEnd)],\n ['http.request.request_start', getAbsoluteTime(resourceTiming.requestStart)],\n ['http.request.response_start', getAbsoluteTime(resourceTiming.responseStart)],\n ['http.request.response_end', getAbsoluteTime(resourceTiming.responseEnd)],\n ];\n}\n\n/**\n * A function that determines whether to attach tracing headers to a request.\n * We only export this function for testing purposes.\n */\nfunction shouldAttachHeaders(\n targetUrl,\n tracePropagationTargets,\n) {\n // window.location.href not being defined is an edge case in the browser but we need to handle it.\n // Potentially dangerous situations where it may not be defined: Browser Extensions, Web Workers, patching of the location obj\n const href = WINDOW.location && WINDOW.location.href;\n\n if (!href) {\n // If there is no window.location.origin, we default to only attaching tracing headers to relative requests, i.e. ones that start with `/`\n // BIG DISCLAIMER: Users can call URLs with a double slash (fetch(\"//example.com/api\")), this is a shorthand for \"send to the same protocol\",\n // so we need a to exclude those requests, because they might be cross origin.\n const isRelativeSameOriginRequest = !!targetUrl.match(/^\\/(?!\\/)/);\n if (!tracePropagationTargets) {\n return isRelativeSameOriginRequest;\n } else {\n return stringMatchesSomePattern(targetUrl, tracePropagationTargets);\n }\n } else {\n let resolvedUrl;\n let currentOrigin;\n\n // URL parsing may fail, we default to not attaching trace headers in that case.\n try {\n resolvedUrl = new URL(targetUrl, href);\n currentOrigin = new URL(href).origin;\n } catch (e) {\n return false;\n }\n\n const isSameOriginRequest = resolvedUrl.origin === currentOrigin;\n if (!tracePropagationTargets) {\n return isSameOriginRequest;\n } else {\n return (\n stringMatchesSomePattern(resolvedUrl.toString(), tracePropagationTargets) ||\n (isSameOriginRequest && stringMatchesSomePattern(resolvedUrl.pathname, tracePropagationTargets))\n );\n }\n }\n}\n\n/**\n * Create and track xhr request spans\n *\n * @returns Span if a span was created, otherwise void.\n */\nfunction xhrCallback(\n handlerData,\n shouldCreateSpan,\n shouldAttachHeaders,\n spans,\n) {\n const xhr = handlerData.xhr;\n const sentryXhrData = xhr && xhr[SENTRY_XHR_DATA_KEY];\n\n if (!xhr || xhr.__sentry_own_request__ || !sentryXhrData) {\n return undefined;\n }\n\n const shouldCreateSpanResult = hasTracingEnabled() && shouldCreateSpan(sentryXhrData.url);\n\n // check first if the request has finished and is tracked by an existing span which should now end\n if (handlerData.endTimestamp && shouldCreateSpanResult) {\n const spanId = xhr.__sentry_xhr_span_id__;\n if (!spanId) return;\n\n const span = spans[spanId];\n if (span && sentryXhrData.status_code !== undefined) {\n setHttpStatus(span, sentryXhrData.status_code);\n span.end();\n\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete spans[spanId];\n }\n return undefined;\n }\n\n const fullUrl = getFullURL(sentryXhrData.url);\n const host = fullUrl ? parseUrl(fullUrl).host : undefined;\n\n const hasParent = !!getActiveSpan();\n\n const span =\n shouldCreateSpanResult && hasParent\n ? startInactiveSpan({\n name: `${sentryXhrData.method} ${sentryXhrData.url}`,\n attributes: {\n type: 'xhr',\n 'http.method': sentryXhrData.method,\n 'http.url': fullUrl,\n url: sentryXhrData.url,\n 'server.address': host,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client',\n },\n })\n : new SentryNonRecordingSpan();\n\n xhr.__sentry_xhr_span_id__ = span.spanContext().spanId;\n spans[xhr.__sentry_xhr_span_id__] = span;\n\n const client = getClient();\n\n if (xhr.setRequestHeader && shouldAttachHeaders(sentryXhrData.url) && client) {\n addTracingHeadersToXhrRequest(\n xhr,\n client,\n // If performance is disabled (TWP) or there's no active root span (pageload/navigation/interaction),\n // we do not want to use the span as base for the trace headers,\n // which means that the headers will be generated from the scope and the sampling decision is deferred\n hasTracingEnabled() && hasParent ? span : undefined,\n );\n }\n\n return span;\n}\n\nfunction addTracingHeadersToXhrRequest(xhr, client, span) {\n const scope = getCurrentScope();\n const isolationScope = getIsolationScope();\n const { traceId, spanId, sampled, dsc } = {\n ...isolationScope.getPropagationContext(),\n ...scope.getPropagationContext(),\n };\n\n const sentryTraceHeader =\n span && hasTracingEnabled() ? spanToTraceHeader(span) : generateSentryTraceHeader(traceId, spanId, sampled);\n\n const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader(\n dsc || (span ? getDynamicSamplingContextFromSpan(span) : getDynamicSamplingContextFromClient(traceId, client)),\n );\n\n setHeaderOnXhr(xhr, sentryTraceHeader, sentryBaggageHeader);\n}\n\nfunction setHeaderOnXhr(\n xhr,\n sentryTraceHeader,\n sentryBaggageHeader,\n) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n xhr.setRequestHeader('sentry-trace', sentryTraceHeader);\n if (sentryBaggageHeader) {\n // From MDN: \"If this method is called several times with the same header, the values are merged into one single request header.\"\n // We can therefore simply set a baggage header without checking what was there before\n // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n xhr.setRequestHeader(BAGGAGE_HEADER_NAME, sentryBaggageHeader);\n }\n } catch (_) {\n // Error: InvalidStateError: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.\n }\n}\n\nfunction getFullURL(url) {\n try {\n // By adding a base URL to new URL(), this will also work for relative urls\n // If `url` is a full URL, the base URL is ignored anyhow\n const parsed = new URL(url, WINDOW.location.origin);\n return parsed.href;\n } catch (e2) {\n return undefined;\n }\n}\n\nexport { defaultRequestInstrumentationOptions, extractNetworkProtocol, instrumentOutgoingRequests, shouldAttachHeaders, xhrCallback };\n//# sourceMappingURL=request.js.map\n","import { getActiveSpan, getRootSpan, spanToJSON, SPAN_STATUS_ERROR } from '@sentry/core';\nimport { logger } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build.js';\nimport { WINDOW } from '../helpers.js';\n\n/**\n * Add a listener that cancels and finishes a transaction when the global\n * document is hidden.\n */\nfunction registerBackgroundTabDetection() {\n if (WINDOW && WINDOW.document) {\n WINDOW.document.addEventListener('visibilitychange', () => {\n const activeSpan = getActiveSpan();\n if (!activeSpan) {\n return;\n }\n\n const rootSpan = getRootSpan(activeSpan);\n\n if (WINDOW.document.hidden && rootSpan) {\n const cancelledStatus = 'cancelled';\n\n const { op, status } = spanToJSON(rootSpan);\n\n if (DEBUG_BUILD) {\n logger.log(`[Tracing] Transaction: ${cancelledStatus} -> since tab moved to the background, op: ${op}`);\n }\n\n // We should not set status if it is already set, this prevent important statuses like\n // error or data loss from being overwritten on transaction.\n if (!status) {\n rootSpan.setStatus({ code: SPAN_STATUS_ERROR, message: cancelledStatus });\n }\n\n rootSpan.setAttribute('sentry.cancellation_reason', 'document.hidden');\n rootSpan.end();\n }\n });\n } else {\n DEBUG_BUILD && logger.warn('[Tracing] Could not set up background tab detection due to lack of global document');\n }\n}\n\nexport { registerBackgroundTabDetection };\n//# sourceMappingURL=backgroundtab.js.map\n","import { startTrackingWebVitals, startTrackingINP, startTrackingLongAnimationFrames, startTrackingLongTasks, startTrackingInteractions, addHistoryInstrumentationHandler, registerInpInteractionListener, addPerformanceEntries } from '@sentry-internal/browser-utils';\nimport { TRACING_DEFAULTS, registerSpanErrorInstrumentation, getClient, spanToJSON, getCurrentScope, getRootSpan, spanIsSampled, getDynamicSamplingContextFromSpan, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, getActiveSpan, getIsolationScope, startIdleSpan, SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON } from '@sentry/core';\nimport { GLOBAL_OBJ, logger, propagationContextFromHeaders, browserPerformanceTimeOrigin, generatePropagationContext, getDomElement } from '@sentry/utils';\nimport { DEBUG_BUILD } from '../debug-build.js';\nimport { WINDOW } from '../helpers.js';\nimport { registerBackgroundTabDetection } from './backgroundtab.js';\nimport { defaultRequestInstrumentationOptions, instrumentOutgoingRequests } from './request.js';\n\n/* eslint-disable max-lines */\n\nconst BROWSER_TRACING_INTEGRATION_ID = 'BrowserTracing';\n\nconst DEFAULT_BROWSER_TRACING_OPTIONS = {\n ...TRACING_DEFAULTS,\n instrumentNavigation: true,\n instrumentPageLoad: true,\n markBackgroundSpan: true,\n enableLongTask: true,\n enableLongAnimationFrame: true,\n enableInp: true,\n _experiments: {},\n ...defaultRequestInstrumentationOptions,\n};\n\n/**\n * The Browser Tracing integration automatically instruments browser pageload/navigation\n * actions as transactions, and captures requests, metrics and errors as spans.\n *\n * The integration can be configured with a variety of options, and can be extended to use\n * any routing library.\n *\n * We explicitly export the proper type here, as this has to be extended in some cases.\n */\nconst browserTracingIntegration = ((_options = {}) => {\n registerSpanErrorInstrumentation();\n\n const {\n enableInp,\n enableLongTask,\n enableLongAnimationFrame,\n _experiments: { enableInteractions, enableStandaloneClsSpans },\n beforeStartSpan,\n idleTimeout,\n finalTimeout,\n childSpanTimeout,\n markBackgroundSpan,\n traceFetch,\n traceXHR,\n trackFetchStreamPerformance,\n shouldCreateSpanForRequest,\n enableHTTPTimings,\n instrumentPageLoad,\n instrumentNavigation,\n } = {\n ...DEFAULT_BROWSER_TRACING_OPTIONS,\n ..._options,\n };\n\n const _collectWebVitals = startTrackingWebVitals({ recordClsStandaloneSpans: enableStandaloneClsSpans || false });\n\n if (enableInp) {\n startTrackingINP();\n }\n\n if (\n enableLongAnimationFrame &&\n GLOBAL_OBJ.PerformanceObserver &&\n PerformanceObserver.supportedEntryTypes &&\n PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')\n ) {\n startTrackingLongAnimationFrames();\n } else if (enableLongTask) {\n startTrackingLongTasks();\n }\n\n if (enableInteractions) {\n startTrackingInteractions();\n }\n\n const latestRoute = {\n name: undefined,\n source: undefined,\n };\n\n /** Create routing idle transaction. */\n function _createRouteSpan(client, startSpanOptions) {\n const isPageloadTransaction = startSpanOptions.op === 'pageload';\n\n const finalStartSpanOptions = beforeStartSpan\n ? beforeStartSpan(startSpanOptions)\n : startSpanOptions;\n\n const attributes = finalStartSpanOptions.attributes || {};\n\n // If `finalStartSpanOptions.name` is different than `startSpanOptions.name`\n // it is because `beforeStartSpan` set a custom name. Therefore we set the source to 'custom'.\n if (startSpanOptions.name !== finalStartSpanOptions.name) {\n attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] = 'custom';\n finalStartSpanOptions.attributes = attributes;\n }\n\n latestRoute.name = finalStartSpanOptions.name;\n latestRoute.source = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];\n\n const idleSpan = startIdleSpan(finalStartSpanOptions, {\n idleTimeout,\n finalTimeout,\n childSpanTimeout,\n // should wait for finish signal if it's a pageload transaction\n disableAutoFinish: isPageloadTransaction,\n beforeSpanEnd: span => {\n _collectWebVitals();\n addPerformanceEntries(span, { recordClsOnPageloadSpan: !enableStandaloneClsSpans });\n },\n });\n\n function emitFinish() {\n if (['interactive', 'complete'].includes(WINDOW.document.readyState)) {\n client.emit('idleSpanEnableAutoFinish', idleSpan);\n }\n }\n\n if (isPageloadTransaction && WINDOW.document) {\n WINDOW.document.addEventListener('readystatechange', () => {\n emitFinish();\n });\n\n emitFinish();\n }\n\n return idleSpan;\n }\n\n return {\n name: BROWSER_TRACING_INTEGRATION_ID,\n afterAllSetup(client) {\n let activeSpan;\n let startingUrl = WINDOW.location && WINDOW.location.href;\n\n client.on('startNavigationSpan', startSpanOptions => {\n if (getClient() !== client) {\n return;\n }\n\n if (activeSpan && !spanToJSON(activeSpan).timestamp) {\n DEBUG_BUILD && logger.log(`[Tracing] Finishing current root span with op: ${spanToJSON(activeSpan).op}`);\n // If there's an open transaction on the scope, we need to finish it before creating an new one.\n activeSpan.end();\n }\n\n activeSpan = _createRouteSpan(client, {\n op: 'navigation',\n ...startSpanOptions,\n });\n });\n\n client.on('startPageLoadSpan', (startSpanOptions, traceOptions = {}) => {\n if (getClient() !== client) {\n return;\n }\n\n if (activeSpan && !spanToJSON(activeSpan).timestamp) {\n DEBUG_BUILD && logger.log(`[Tracing] Finishing current root span with op: ${spanToJSON(activeSpan).op}`);\n // If there's an open transaction on the scope, we need to finish it before creating an new one.\n activeSpan.end();\n }\n\n const sentryTrace = traceOptions.sentryTrace || getMetaContent('sentry-trace');\n const baggage = traceOptions.baggage || getMetaContent('baggage');\n\n const propagationContext = propagationContextFromHeaders(sentryTrace, baggage);\n getCurrentScope().setPropagationContext(propagationContext);\n\n activeSpan = _createRouteSpan(client, {\n op: 'pageload',\n ...startSpanOptions,\n });\n });\n\n // A trace should to stay the consistent over the entire time span of one route.\n // Therefore, when the initial pageload or navigation root span ends, we update the\n // scope's propagation context to keep span-specific attributes like the `sampled` decision and\n // the dynamic sampling context valid, even after the root span has ended.\n // This ensures that the trace data is consistent for the entire duration of the route.\n client.on('spanEnd', span => {\n const op = spanToJSON(span).op;\n if (span !== getRootSpan(span) || (op !== 'navigation' && op !== 'pageload')) {\n return;\n }\n\n const scope = getCurrentScope();\n const oldPropagationContext = scope.getPropagationContext();\n\n scope.setPropagationContext({\n ...oldPropagationContext,\n sampled: oldPropagationContext.sampled !== undefined ? oldPropagationContext.sampled : spanIsSampled(span),\n dsc: oldPropagationContext.dsc || getDynamicSamplingContextFromSpan(span),\n });\n });\n\n if (WINDOW.location) {\n if (instrumentPageLoad) {\n startBrowserTracingPageLoadSpan(client, {\n name: WINDOW.location.pathname,\n // pageload should always start at timeOrigin (and needs to be in s, not ms)\n startTime: browserPerformanceTimeOrigin ? browserPerformanceTimeOrigin / 1000 : undefined,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.browser',\n },\n });\n }\n\n if (instrumentNavigation) {\n addHistoryInstrumentationHandler(({ to, from }) => {\n /**\n * This early return is there to account for some cases where a navigation transaction starts right after\n * long-running pageload. We make sure that if `from` is undefined and a valid `startingURL` exists, we don't\n * create an uneccessary navigation transaction.\n *\n * This was hard to duplicate, but this behavior stopped as soon as this fix was applied. This issue might also\n * only be caused in certain development environments where the usage of a hot module reloader is causing\n * errors.\n */\n if (from === undefined && startingUrl && startingUrl.indexOf(to) !== -1) {\n startingUrl = undefined;\n return;\n }\n\n if (from !== to) {\n startingUrl = undefined;\n startBrowserTracingNavigationSpan(client, {\n name: WINDOW.location.pathname,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.browser',\n },\n });\n }\n });\n }\n }\n\n if (markBackgroundSpan) {\n registerBackgroundTabDetection();\n }\n\n if (enableInteractions) {\n registerInteractionListener(idleTimeout, finalTimeout, childSpanTimeout, latestRoute);\n }\n\n if (enableInp) {\n registerInpInteractionListener();\n }\n\n instrumentOutgoingRequests(client, {\n traceFetch,\n traceXHR,\n trackFetchStreamPerformance,\n tracePropagationTargets: client.getOptions().tracePropagationTargets,\n shouldCreateSpanForRequest,\n enableHTTPTimings,\n });\n },\n };\n}) ;\n\n/**\n * Manually start a page load span.\n * This will only do something if a browser tracing integration integration has been setup.\n *\n * If you provide a custom `traceOptions` object, it will be used to continue the trace\n * instead of the default behavior, which is to look it up on the tags.\n */\nfunction startBrowserTracingPageLoadSpan(\n client,\n spanOptions,\n traceOptions,\n) {\n client.emit('startPageLoadSpan', spanOptions, traceOptions);\n\n getCurrentScope().setTransactionName(spanOptions.name);\n\n const span = getActiveSpan();\n const op = span && spanToJSON(span).op;\n return op === 'pageload' ? span : undefined;\n}\n\n/**\n * Manually start a navigation span.\n * This will only do something if a browser tracing integration has been setup.\n */\nfunction startBrowserTracingNavigationSpan(client, spanOptions) {\n getIsolationScope().setPropagationContext(generatePropagationContext());\n getCurrentScope().setPropagationContext(generatePropagationContext());\n\n client.emit('startNavigationSpan', spanOptions);\n\n getCurrentScope().setTransactionName(spanOptions.name);\n\n const span = getActiveSpan();\n const op = span && spanToJSON(span).op;\n return op === 'navigation' ? span : undefined;\n}\n\n/** Returns the value of a meta tag */\nfunction getMetaContent(metaName) {\n // Can't specify generic to `getDomElement` because tracing can be used\n // in a variety of environments, have to disable `no-unsafe-member-access`\n // as a result.\n const metaTag = getDomElement(`meta[name=${metaName}]`);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n return metaTag ? metaTag.getAttribute('content') : undefined;\n}\n\n/** Start listener for interaction transactions */\nfunction registerInteractionListener(\n idleTimeout,\n finalTimeout,\n childSpanTimeout,\n latestRoute,\n) {\n let inflightInteractionSpan;\n const registerInteractionTransaction = () => {\n const op = 'ui.action.click';\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n if (rootSpan) {\n const currentRootSpanOp = spanToJSON(rootSpan).op;\n if (['navigation', 'pageload'].includes(currentRootSpanOp )) {\n DEBUG_BUILD &&\n logger.warn(`[Tracing] Did not create ${op} span because a pageload or navigation span is in progress.`);\n return undefined;\n }\n }\n\n if (inflightInteractionSpan) {\n inflightInteractionSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, 'interactionInterrupted');\n inflightInteractionSpan.end();\n inflightInteractionSpan = undefined;\n }\n\n if (!latestRoute.name) {\n DEBUG_BUILD && logger.warn(`[Tracing] Did not create ${op} transaction because _latestRouteName is missing.`);\n return undefined;\n }\n\n inflightInteractionSpan = startIdleSpan(\n {\n name: latestRoute.name,\n op,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: latestRoute.source || 'url',\n },\n },\n {\n idleTimeout,\n finalTimeout,\n childSpanTimeout,\n },\n );\n };\n\n if (WINDOW.document) {\n addEventListener('click', registerInteractionTransaction, { once: false, capture: true });\n }\n}\n\nexport { BROWSER_TRACING_INTEGRATION_ID, browserTracingIntegration, getMetaContent, startBrowserTracingNavigationSpan, startBrowserTracingPageLoadSpan };\n//# sourceMappingURL=browserTracingIntegration.js.map\n","import { setContext, init as init$1 } from '@sentry/browser';\nimport { applySdkMetadata } from '@sentry/core';\nimport { version } from 'react';\n\n/**\n * Inits the React SDK\n */\nfunction init(options) {\n const opts = {\n ...options,\n };\n\n applySdkMetadata(opts, 'react');\n setContext('react', { version });\n return init$1(opts);\n}\n\nexport { init };\n//# sourceMappingURL=sdk.js.map\n","import { getGlobalScope, getCurrentScope, addBreadcrumb, getClient } from '@sentry/core';\nimport { addNonEnumerableProperty } from '@sentry/utils';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nconst ACTION_BREADCRUMB_CATEGORY = 'redux.action';\nconst ACTION_BREADCRUMB_TYPE = 'info';\n\nconst defaultOptions = {\n attachReduxState: true,\n actionTransformer: action => action,\n stateTransformer: state => state || null,\n};\n\n/**\n * Creates an enhancer that would be passed to Redux's createStore to log actions and the latest state to Sentry.\n *\n * @param enhancerOptions Options to pass to the enhancer\n */\nfunction createReduxEnhancer(enhancerOptions) {\n // Note: We return an any type as to not have type conflicts.\n const options = {\n ...defaultOptions,\n ...enhancerOptions,\n };\n\n return (next) =>\n (reducer, initialState) => {\n options.attachReduxState &&\n getGlobalScope().addEventProcessor((event, hint) => {\n try {\n // @ts-expect-error try catch to reduce bundle size\n if (event.type === undefined && event.contexts.state.state.type === 'redux') {\n hint.attachments = [\n ...(hint.attachments || []),\n // @ts-expect-error try catch to reduce bundle size\n { filename: 'redux_state.json', data: JSON.stringify(event.contexts.state.state.value) },\n ];\n }\n } catch (_) {\n // empty\n }\n return event;\n });\n\n const sentryReducer = (state, action) => {\n const newState = reducer(state, action);\n\n const scope = getCurrentScope();\n\n /* Action breadcrumbs */\n const transformedAction = options.actionTransformer(action);\n if (typeof transformedAction !== 'undefined' && transformedAction !== null) {\n addBreadcrumb({\n category: ACTION_BREADCRUMB_CATEGORY,\n data: transformedAction,\n type: ACTION_BREADCRUMB_TYPE,\n });\n }\n\n /* Set latest state to scope */\n const transformedState = options.stateTransformer(newState);\n if (typeof transformedState !== 'undefined' && transformedState !== null) {\n const client = getClient();\n const options = client && client.getOptions();\n const normalizationDepth = (options && options.normalizeDepth) || 3; // default state normalization depth to 3\n\n // Set the normalization depth of the redux state to the configured `normalizeDepth` option or a sane number as a fallback\n const newStateContext = { state: { type: 'redux', value: transformedState } };\n addNonEnumerableProperty(\n newStateContext,\n '__sentry_override_normalization_depth__',\n 3 + // 3 layers for `state.value.transformedState`\n normalizationDepth, // rest for the actual state\n );\n\n scope.setContext('state', newStateContext);\n } else {\n scope.setContext('state', null);\n }\n\n /* Allow user to configure scope with latest state */\n const { configureScopeWithState } = options;\n if (typeof configureScopeWithState === 'function') {\n configureScopeWithState(scope, newState);\n }\n\n return newState;\n };\n\n return next(sentryReducer, initialState);\n };\n}\n\nexport { createReduxEnhancer };\n//# sourceMappingURL=redux.js.map\n","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { if (typeof Symbol === \"undefined\" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar REPLACERS = [[/yyyy|YYYY/, function (date) {\n return date.getFullYear();\n}], [/yy|YY/, function (date) {\n return date.getFullYear().toString().slice(2);\n}], ['MM', function (date) {\n return DateFormatter._addLeadingZeros(date.getMonth() + 1);\n}], ['M', function (date) {\n return date.getMonth() + 1;\n}], ['DD', function (date) {\n return DateFormatter._addLeadingZeros(date.getDate());\n}], ['D', function (date) {\n return date.getDate();\n}], ['HH', function (date) {\n return DateFormatter._addLeadingZeros(date.getHours());\n}], ['H', function (date) {\n return date.getHours();\n}], ['mm', function (date) {\n return DateFormatter._addLeadingZeros(date.getMinutes());\n}], ['m', function (date) {\n return date.getMinutes();\n}], ['ss', function (date) {\n return DateFormatter._addLeadingZeros(date.getSeconds());\n}], ['s', function (date) {\n return date.getSeconds();\n}], ['SSS', function (date) {\n return date.getMilliseconds();\n}], ['SS', function (date) {\n return Math.floor(date.getMilliseconds() / 10);\n}], ['S', function (date) {\n return Math.floor(date.getMilliseconds() / 100);\n}]];\n/**\n * Handles formatting of dates.\n */\n\nvar DateFormatter = /*#__PURE__*/function () {\n function DateFormatter() {\n _classCallCheck(this, DateFormatter);\n }\n\n _createClass(DateFormatter, null, [{\n key: \"isoStringToDate\",\n\n /**\n * Formats a date.\n *\n * @param {string} dateString Date string.\n * @returns {Date} Formatted date.\n */\n value: function isoStringToDate(dateString) {\n return new Date(dateString.replace('Z', ''));\n }\n /**\n * Formats a date object to a date string.\n *\n * @param {Date|string|number} date Date object, or string/number to pass into the date constructor.\n * @param {string} [format] Format to use. Default is \"YYYY-MM-DD\".\n * @returns {string} Formatted date.\n */\n\n }, {\n key: \"dateToString\",\n value: function dateToString(date) {\n var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'YYYY-MM-DD';\n\n if (!(date instanceof Date)) {\n date = new Date(date);\n }\n\n if (isNaN(date.getTime())) {\n return date.toString();\n }\n\n return REPLACERS.reduce(function (str, _ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n pattern = _ref2[0],\n fnc = _ref2[1];\n\n var arr = str.split(pattern);\n\n if (arr.length === 1) {\n return arr[0];\n }\n\n return arr.join(fnc(date));\n }, format);\n }\n /**\n * Adds leading zeross to a number.\n *\n * @param {number|string} value Number to add leading zeros to.\n * @returns {string} Number with leading zeros converted to a string.\n */\n\n }, {\n key: \"_addLeadingZeros\",\n value: function _addLeadingZeros(value) {\n value = String(value);\n\n while (value.length < 2) {\n value = '0' + value;\n }\n\n return value;\n }\n }]);\n\n return DateFormatter;\n}();\n\nexports.default = DateFormatter;","/* FileSaver.js\n * A saveAs() FileSaver implementation.\n * 1.3.2\n * 2016-06-16 18:25:19\n *\n * By Eli Grey, http://eligrey.com\n * License: MIT\n * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md\n */\n\n/*global self */\n/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */\n\n/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */\n\nvar saveAs = saveAs || (function(view) {\n\t\"use strict\";\n\t// IE <10 is explicitly unsupported\n\tif (typeof view === \"undefined\" || typeof navigator !== \"undefined\" && /MSIE [1-9]\\./.test(navigator.userAgent)) {\n\t\treturn;\n\t}\n\tvar\n\t\t doc = view.document\n\t\t // only get URL when necessary in case Blob.js hasn't overridden it yet\n\t\t, get_URL = function() {\n\t\t\treturn view.URL || view.webkitURL || view;\n\t\t}\n\t\t, save_link = doc.createElementNS(\"http://www.w3.org/1999/xhtml\", \"a\")\n\t\t, can_use_save_link = \"download\" in save_link\n\t\t, click = function(node) {\n\t\t\tvar event = new MouseEvent(\"click\");\n\t\t\tnode.dispatchEvent(event);\n\t\t}\n\t\t, is_safari = /constructor/i.test(view.HTMLElement) || view.safari\n\t\t, is_chrome_ios =/CriOS\\/[\\d]+/.test(navigator.userAgent)\n\t\t, throw_outside = function(ex) {\n\t\t\t(view.setImmediate || view.setTimeout)(function() {\n\t\t\t\tthrow ex;\n\t\t\t}, 0);\n\t\t}\n\t\t, force_saveable_type = \"application/octet-stream\"\n\t\t// the Blob API is fundamentally broken as there is no \"downloadfinished\" event to subscribe to\n\t\t, arbitrary_revoke_timeout = 1000 * 40 // in ms\n\t\t, revoke = function(file) {\n\t\t\tvar revoker = function() {\n\t\t\t\tif (typeof file === \"string\") { // file is an object URL\n\t\t\t\t\tget_URL().revokeObjectURL(file);\n\t\t\t\t} else { // file is a File\n\t\t\t\t\tfile.remove();\n\t\t\t\t}\n\t\t\t};\n\t\t\tsetTimeout(revoker, arbitrary_revoke_timeout);\n\t\t}\n\t\t, dispatch = function(filesaver, event_types, event) {\n\t\t\tevent_types = [].concat(event_types);\n\t\t\tvar i = event_types.length;\n\t\t\twhile (i--) {\n\t\t\t\tvar listener = filesaver[\"on\" + event_types[i]];\n\t\t\t\tif (typeof listener === \"function\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlistener.call(filesaver, event || filesaver);\n\t\t\t\t\t} catch (ex) {\n\t\t\t\t\t\tthrow_outside(ex);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t, auto_bom = function(blob) {\n\t\t\t// prepend BOM for UTF-8 XML and text/* types (including HTML)\n\t\t\t// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF\n\t\t\tif (/^\\s*(?:text\\/\\S*|application\\/xml|\\S*\\/\\S*\\+xml)\\s*;.*charset\\s*=\\s*utf-8/i.test(blob.type)) {\n\t\t\t\treturn new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});\n\t\t\t}\n\t\t\treturn blob;\n\t\t}\n\t\t, FileSaver = function(blob, name, no_auto_bom) {\n\t\t\tif (!no_auto_bom) {\n\t\t\t\tblob = auto_bom(blob);\n\t\t\t}\n\t\t\t// First try a.download, then web filesystem, then object URLs\n\t\t\tvar\n\t\t\t\t filesaver = this\n\t\t\t\t, type = blob.type\n\t\t\t\t, force = type === force_saveable_type\n\t\t\t\t, object_url\n\t\t\t\t, dispatch_all = function() {\n\t\t\t\t\tdispatch(filesaver, \"writestart progress write writeend\".split(\" \"));\n\t\t\t\t}\n\t\t\t\t// on any filesys errors revert to saving with object URLs\n\t\t\t\t, fs_error = function() {\n\t\t\t\t\tif ((is_chrome_ios || (force && is_safari)) && view.FileReader) {\n\t\t\t\t\t\t// Safari doesn't allow downloading of blob urls\n\t\t\t\t\t\tvar reader = new FileReader();\n\t\t\t\t\t\treader.onloadend = function() {\n\t\t\t\t\t\t\tvar url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');\n\t\t\t\t\t\t\tvar popup = view.open(url, '_blank');\n\t\t\t\t\t\t\tif(!popup) view.location.href = url;\n\t\t\t\t\t\t\turl=undefined; // release reference before dispatching\n\t\t\t\t\t\t\tfilesaver.readyState = filesaver.DONE;\n\t\t\t\t\t\t\tdispatch_all();\n\t\t\t\t\t\t};\n\t\t\t\t\t\treader.readAsDataURL(blob);\n\t\t\t\t\t\tfilesaver.readyState = filesaver.INIT;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// don't create more object URLs than needed\n\t\t\t\t\tif (!object_url) {\n\t\t\t\t\t\tobject_url = get_URL().createObjectURL(blob);\n\t\t\t\t\t}\n\t\t\t\t\tif (force) {\n\t\t\t\t\t\tview.location.href = object_url;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar opened = view.open(object_url, \"_blank\");\n\t\t\t\t\t\tif (!opened) {\n\t\t\t\t\t\t\t// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html\n\t\t\t\t\t\t\tview.location.href = object_url;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfilesaver.readyState = filesaver.DONE;\n\t\t\t\t\tdispatch_all();\n\t\t\t\t\trevoke(object_url);\n\t\t\t\t}\n\t\t\t;\n\t\t\tfilesaver.readyState = filesaver.INIT;\n\n\t\t\tif (can_use_save_link) {\n\t\t\t\tobject_url = get_URL().createObjectURL(blob);\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\tsave_link.href = object_url;\n\t\t\t\t\tsave_link.download = name;\n\t\t\t\t\tclick(save_link);\n\t\t\t\t\tdispatch_all();\n\t\t\t\t\trevoke(object_url);\n\t\t\t\t\tfilesaver.readyState = filesaver.DONE;\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfs_error();\n\t\t}\n\t\t, FS_proto = FileSaver.prototype\n\t\t, saveAs = function(blob, name, no_auto_bom) {\n\t\t\treturn new FileSaver(blob, name || blob.name || \"download\", no_auto_bom);\n\t\t}\n\t;\n\t// IE 10+ (native saveAs)\n\tif (typeof navigator !== \"undefined\" && navigator.msSaveOrOpenBlob) {\n\t\treturn function(blob, name, no_auto_bom) {\n\t\t\tname = name || blob.name || \"download\";\n\n\t\t\tif (!no_auto_bom) {\n\t\t\t\tblob = auto_bom(blob);\n\t\t\t}\n\t\t\treturn navigator.msSaveOrOpenBlob(blob, name);\n\t\t};\n\t}\n\n\tFS_proto.abort = function(){};\n\tFS_proto.readyState = FS_proto.INIT = 0;\n\tFS_proto.WRITING = 1;\n\tFS_proto.DONE = 2;\n\n\tFS_proto.error =\n\tFS_proto.onwritestart =\n\tFS_proto.onprogress =\n\tFS_proto.onwrite =\n\tFS_proto.onabort =\n\tFS_proto.onerror =\n\tFS_proto.onwriteend =\n\t\tnull;\n\n\treturn saveAs;\n}(\n\t typeof self !== \"undefined\" && self\n\t|| typeof window !== \"undefined\" && window\n\t|| this.content\n));\n// `self` is undefined in Firefox for Android content script context\n// while `this` is nsIContentFrameMessageManager\n// with an attribute `content` that corresponds to the window\n\nif (typeof module !== \"undefined\" && module.exports) {\n module.exports.saveAs = saveAs;\n} else if ((typeof define !== \"undefined\" && define !== null) && (define.amd !== null)) {\n define(\"FileSaver.js\", function() {\n return saveAs;\n });\n}\n","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _fileSaver = _interopRequireDefault(require(\"file-saver\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Handles file utilities.\n */\nvar FileUtility = /*#__PURE__*/function () {\n function FileUtility() {\n _classCallCheck(this, FileUtility);\n }\n\n _createClass(FileUtility, null, [{\n key: \"saveAsJson\",\n\n /**\n * Saves data as JSON to a file.\n *\n * @param {string} filename Filename to use.\n * @param {object} data Data to export.\n */\n value: function saveAsJson(filename, data) {\n var blob = new Blob([JSON.stringify(data, null, 4)], {\n type: 'application/json; charset=utf-8'\n });\n this.saveAs(filename, blob);\n }\n /**\n * Saves data as any file type.\n *\n * @param {string} filename Filename to use.\n * @param {object} blob Blob object.\n */\n\n }, {\n key: \"saveAs\",\n value: function saveAs(filename, blob) {\n _fileSaver.default.saveAs(blob, filename);\n }\n /**\n * Opens a file dialog and returns the file buffer result.\n *\n * @example FileSaver.openFileDialog().then(result => { }).catch(error => { });\n * @param {string} type File type to open.\n * @param {boolean} [readAsText] TRUE to read the data as text. Default is FALSE.\n * @returns {Promise} Promise object.\n */\n\n }, {\n key: \"openFileDialog\",\n value: function openFileDialog(type) {\n var readAsText = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n return new Promise(function (resolve, reject) {\n var label;\n var input = document.createElement('input'); //Fix for IE - It will trick IE to open the dialog if standard input.click() does not work\n\n var ieTimeout = setTimeout(function () {\n input.id = 'file_input';\n label = document.createElement('label');\n label.setAttribute('for', 'file_input');\n label.click();\n document.body.appendChild(label);\n }, 100);\n input.style.cssText = 'position:absolute;left:0;top:-999rem;';\n input.type = 'file';\n input.setAttribute('accept', '.' + type);\n input.addEventListener('change', function (event) {\n var files = event.target.files;\n clearTimeout(ieTimeout);\n\n if (files && files.length > 0) {\n var file = files[0];\n\n if (file.name.endsWith(type)) {\n var reader = new FileReader();\n\n reader.onload = function (event) {\n resolve(event.target.result || null);\n };\n\n if (readAsText) {\n reader.readAsText(file);\n } else {\n reader.readAsDataURL(file);\n }\n } else {\n reject(new Error('The file is not of type ' + type + '. Please select a file with valid type.'));\n }\n } else {\n resolve(null);\n }\n\n document.body.removeChild(input);\n\n if (label) {\n document.body.removeChild(label);\n }\n });\n document.body.appendChild(input);\n input.click();\n setTimeout(function () {\n input.focus();\n input.blur();\n }, 0);\n });\n }\n }]);\n\n return FileUtility;\n}();\n\nexports.default = FileUtility;","module.exports = {\n \"orientation\": {\n \"landscape\": \"landscape\",\n \"portrait\": \"portrait\"\n },\n \"maxWidth\": 1280,\n \"maxHeightLandscape\": 800,\n \"minWidthLandscape\": 800,\n \"minHeightLandscape\": 560,\n \"maxRatioLandscape\": 2,\n \"deviceType\": {\n \"desktop\": \"desktop\",\n \"tablet\": \"tablet\",\n \"mobile\": \"mobile\"\n },\n \"preferredRatio\": {\n \"landscape\": \"16/10\",\n \"portrait\": \"9/16\"\n },\n \"screenWidthLimits\": {\n \"landscape\": {\n \"mobile\": 860,\n \"tablet\": 1280\n },\n \"portrait\": {\n \"mobile\": 480,\n \"tablet\": 800\n }\n },\n \"nwpHeaders\": {\n \"desktop\": 82,\n \"tablet\": 72,\n \"mobile\": 56\n },\n \"unavailableHeight\": {\n \"desktop\": 100,\n \"tablet\": 80,\n \"mobile\": 60\n }\n}\n;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === \"undefined\" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === \"number\") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Easings are taken from: https://gist.github.com/gre/1650294\n */\nvar EASINGS = {\n easeInOutCubic: function easeInOutCubic(t) {\n return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;\n }\n};\n/**\n * This class is used for creating an animation with an easing.\n */\n\nvar EasingAnimation = /*#__PURE__*/function () {\n /**\n * Class constructor.\n */\n function EasingAnimation() {\n _classCallCheck(this, EasingAnimation);\n\n this.startValue = 0; // Start value\n\n this.endValue = 20; // End value\n\n this.callback = function () {}; // Callback to be called between each iteration\n\n\n this.easingType = 'easeInOutCubic'; // Type of easing\n\n this.animationDuration = 500; // Animation duration in ms\n\n this.frameInterval = 20; // Min time between frames in ms\n\n this._value = 0;\n this._animationStartTime = 0;\n this._lastFrame = 0;\n this._animationFrameId = null;\n this._events = {\n frame: [],\n end: []\n };\n }\n /**\n * Adds an event listener.\n *\n * @param {string} eventName Event name (frame, end).\n * @param {Function} callback Callback to be called.\n */\n\n\n _createClass(EasingAnimation, [{\n key: \"on\",\n value: function on(eventName, callback) {\n this._events[eventName].push(callback);\n }\n /**\n * Removes an event listener.\n *\n * @param {string} eventName Event name (frame, end).\n * @param {Function} callback Callback to be called.\n */\n\n }, {\n key: \"off\",\n value: function off(eventName, callback) {\n var index = this._events[eventName].indexOf(callback);\n\n if (index > -1) {\n this._events[eventName].splice(index, 1);\n }\n }\n /**\n * Triggers an event.\n *\n * @param {string} eventName Event name (frame, end).\n * @param {string} data Data to send to the callback.\n */\n\n }, {\n key: \"trigger\",\n value: function trigger(eventName, data) {\n var _iterator = _createForOfIteratorHelper(this._events[eventName]),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var callback = _step.value;\n callback(data);\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n /**\n * Starts the animation.\n */\n\n }, {\n key: \"start\",\n value: function start() {\n cancelAnimationFrame(this._animationFrameId);\n this._value = this.startValue;\n this._animationStartTime = performance.now();\n this._animationFrameId = requestAnimationFrame(this._animate.bind(this));\n }\n /**\n * Stops the animation.\n */\n\n }, {\n key: \"stop\",\n value: function stop() {\n cancelAnimationFrame(this._animationFrameId);\n this.trigger('end', this._value);\n }\n /**\n * Calculate eased value, from start value to end value, based on percent of progress.\n *\n * @param {number} startValue Initial value for easing.\n * @param {number} endValue Final value for easing.\n * @param {number} progress Progress of animation [0 to 1].\n * @returns {number} New value based on easing and progress.\n */\n\n }, {\n key: \"_calculateValue\",\n value: function _calculateValue(startValue, endValue, progress) {\n var newValue = 0;\n\n if (startValue < endValue) {\n newValue = startValue + (endValue - startValue) * EASINGS[this.easingType](progress);\n } else {\n newValue = startValue - (startValue - endValue) * EASINGS[this.easingType](progress);\n }\n\n if (startValue === Math.round(startValue) && endValue === Math.round(endValue)) {\n newValue = Math.round(newValue);\n }\n\n if (progress > 1) {\n newValue = endValue;\n }\n\n return newValue;\n }\n /**\n * Animation frame - callback passed to rAF.\n *\n * @param {DOMHighResTimeStamp} now Current time when rAF start to fire callback.\n */\n\n }, {\n key: \"_animate\",\n value: function _animate(now) {\n var animationElapsedTime = now - this._animationStartTime;\n var frameElapsedTime = now - this._lastFrame;\n this._value = this._calculateValue(this.startValue, this.endValue, animationElapsedTime / this.animationDuration);\n\n if (animationElapsedTime > this.animationDuration) {\n this.trigger('frame', this.endValue);\n this.stop();\n } else {\n this._animationFrameId = requestAnimationFrame(this._animate.bind(this));\n\n if (frameElapsedTime > this.frameInterval) {\n this.trigger('frame', this._value);\n this._lastFrame = now - frameElapsedTime % this.frameInterval;\n }\n }\n }\n }]);\n\n return EasingAnimation;\n}();\n\nexports.default = EasingAnimation;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _IframeConfigJson = _interopRequireDefault(require(\"./IframeConfig.json.js\"));\n\nvar _EasingAnimation = _interopRequireDefault(require(\"../animation/EasingAnimation\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar DEFAULT_SCROLL_OPTIONS = {\n element: null,\n platform: null,\n animate: true,\n center: true,\n minDistance: 200,\n scrollTopMargin: 10\n};\n/**\n * This class is used for calculating the application size when inside an iframe.\n */\n\nvar IframeUtility = /*#__PURE__*/function () {\n function IframeUtility() {\n _classCallCheck(this, IframeUtility);\n }\n\n _createClass(IframeUtility, null, [{\n key: \"calculateHeight\",\n\n /**\n * Calculates the application height based on width and platform.\n *\n * @param {object} width Application width.\n * @param {string} [platform] Application plattform (nwp or irw). Default is \"irw\".\n * @returns {number} Calculated height.\n */\n value: function calculateHeight(width) {\n var platform = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'irw';\n\n var screen = this._getScreen(width);\n\n var deviceType = this._calculateDeviceType(screen.width, screen.orientation);\n\n var appWidth = Math.min(width, _IframeConfigJson.default.maxWidth);\n\n var availableHeight = this._getAvailableHeight(screen.height, platform, deviceType);\n\n var height = appWidth / this._getRatio(screen.orientation);\n\n height = Math.min(height, availableHeight, _IframeConfigJson.default.maxHeightLandscape);\n\n if (screen.orientation === _IframeConfigJson.default.orientation.landscape) {\n height = Math.max(height, this._getMinHeightLandscape(deviceType, appWidth));\n }\n\n return Math.floor(height);\n }\n /**\n * Returns the device type based on the application size.\n *\n * @returns {string} Device type (mobile, desktop or tablet).\n */\n\n }, {\n key: \"getDeviceType\",\n value: function getDeviceType() {\n var minMeasurement = Math.min(window.screen.availWidth, window.screen.availHeight);\n return this._calculateDeviceType(minMeasurement, _IframeConfigJson.default.orientation.portrait);\n }\n /**\n * Returns the current orientation based on width.\n *\n * @param {number} width Application width.\n * @returns {string} Orientation (landscape or portrait).\n */\n\n }, {\n key: \"getOrientation\",\n value: function getOrientation(width) {\n return this._getScreen(width).orientation;\n }\n /**\n * Returns the header height.\n *\n * @param {string} platform Platform (nwp, irw, m2, mobile etc.).\n * @returns {number} Available height.\n */\n\n }, {\n key: \"getHeaderHeight\",\n value: function getHeaderHeight(platform) {\n // Is KOMPIS\n if (window.getIframeComponent) {\n return window.screen.width < 1024 ? 52 : 72;\n }\n\n return platform === 'nwp' ? _IframeConfigJson.default.nwpHeaders[this.getDeviceType()] : 0;\n }\n /**\n * Scrolls the parent window to make the element visible.\n *\n * @param {object} options Options object.\n * @param {Element} options.element Element to scroll into view.\n * @param {string} options.platform Platform (nwp, irw, m2, mobile etc.).\n * @param {boolean} [options.animate] TRUE to animate. Default is TRUE.\n * @param {boolean} [options.center] TRUE to center the element. Default is TRUE.\n * @param {number} [options.minDistance] Minimal distance before scroll will be activated. Default is \"200\" (px).\n * @param {number} [options.scrollTopMargin] Scroll top margin that will be offset from the top of the element when the element height is greater than the screen height. Default is \"10\" (px);.\n * @returns {EasingAnimation|null} Returns the easing animation if \"animate\" has been set to \"true\".\n */\n\n }, {\n key: \"scrollToElement\",\n value: function scrollToElement(options) {\n options = Object.assign({}, DEFAULT_SCROLL_OPTIONS, options);\n\n if (this.isInsideIframe()) {\n var screenHeight = window.parent.innerHeight;\n var headerHeight = this.getHeaderHeight(options.platform);\n var availableScreenHeight = screenHeight - headerHeight;\n\n var parentScrollPosition = this._getScrollPosition(window.parent);\n\n var scrollY = parentScrollPosition.y;\n var iframeTop = window.frameElement.getBoundingClientRect().top + scrollY - headerHeight;\n var elementTop = options.element.getBoundingClientRect().top + this._getScrollPosition().y + iframeTop;\n var elementHeight = options.element.offsetHeight;\n var centeredElementScrollY = elementHeight > availableScreenHeight ? elementTop - options.scrollTopMargin : elementTop - screenHeight / 2 + headerHeight + elementHeight / 2 - options.scrollTopMargin;\n var elementScrollY = options.center ? centeredElementScrollY : elementTop + headerHeight - options.scrollTopMargin;\n var newScrollY = elementScrollY > 0 ? elementScrollY : 0;\n var distanceY = newScrollY < scrollY ? scrollY - newScrollY : newScrollY - scrollY;\n\n if (options.animate) {\n var frames = Math.floor(distanceY / 10);\n\n if (distanceY > options.minDistance || elementHeight > availableScreenHeight) {\n var animation = new _EasingAnimation.default();\n animation.on('frame', function (y) {\n return window.parent.scrollTo(parentScrollPosition.x, y);\n });\n animation.startValue = scrollY;\n animation.endValue = newScrollY;\n animation.frames = frames;\n animation.start();\n return animation;\n }\n } else {\n window.parent.scrollTo(parentScrollPosition.x, newScrollY);\n }\n }\n\n return null;\n }\n /**\n * Checks if the application is inside an iframe.\n *\n * @returns {boolean} TRUE if inside an iframe.\n */\n\n }, {\n key: \"isInsideIframe\",\n value: function isInsideIframe() {\n try {\n if (window.parent && window.parent.innerHeight && window.frameElement && window.self !== window.top) {\n return true;\n }\n } catch (error) {// Ignore error\n }\n\n return false;\n }\n /**\n * Returns parent scroll position.\n *\n * @param {object} frame Frame object. Defaults to \"window\".\n * @returns {{y: number, x: number}} Scroll position.\n */\n\n }, {\n key: \"_getScrollPosition\",\n value: function _getScrollPosition() {\n var frame = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window;\n return {\n y: frame.pageYOffset !== undefined ? frame.pageYOffset : frame.document.documentElement.scrollTop,\n x: frame.pageXOffset !== undefined ? frame.pageXOffset : frame.document.documentElement.scrollLeft\n };\n }\n /**\n * Returns the current screen data: width, height and orientation.\n *\n * @param {number} width Application width.\n * @returns {object} Screen setup.\n */\n\n }, {\n key: \"_getScreen\",\n value: function _getScreen(width) {\n var screen = {};\n /*\n * Some devices may return same availWidth/availHeight despite rotation\n * using given iframe width and assuming that it will not be greater that the actual screen width,\n * we can assume that we are in portrait if the iframe width is smaller or same as the smallest of the values\n */\n\n if (width <= Math.min(window.screen.availWidth, window.screen.availHeight, _IframeConfigJson.default.minWidthLandscape)) {\n screen.width = Math.min(window.screen.availWidth, window.screen.availHeight);\n screen.height = Math.max(window.screen.availWidth, window.screen.availHeight);\n screen.orientation = _IframeConfigJson.default.orientation.portrait;\n } else {\n screen.width = Math.max(window.screen.availWidth, window.screen.availHeight);\n screen.height = Math.min(window.screen.availWidth, window.screen.availHeight);\n screen.orientation = _IframeConfigJson.default.orientation.landscape;\n }\n\n return screen;\n }\n /**\n * Returns the available height.\n *\n * @param {number} screenHeight The screen height.\n * @param {string} platform Platform (nwp or irw).\n * @param {string} deviceType Device type (mobile, desktop or tablet).\n * @returns {number} Available height.\n */\n\n }, {\n key: \"_getAvailableHeight\",\n value: function _getAvailableHeight(screenHeight, platform, deviceType) {\n var bannerHeight = platform === 'nwp' ? _IframeConfigJson.default.nwpHeaders[deviceType] : 0;\n return screenHeight - _IframeConfigJson.default.unavailableHeight[deviceType] - bannerHeight;\n }\n /**\n * Calculates the device type.\n *\n * @param {number} screenWidth The screen width.\n * @param {string} orientation Orientation (portrait or landscape).\n * @returns {string} Device type (mobile, desktop or tablet).\n */\n\n }, {\n key: \"_calculateDeviceType\",\n value: function _calculateDeviceType(screenWidth, orientation) {\n if (screenWidth < _IframeConfigJson.default.screenWidthLimits[orientation][_IframeConfigJson.default.deviceType.mobile]) {\n // largest known phone is 736 (iPhone 6+), smallest known tablet is 1024 (iPad)\n return _IframeConfigJson.default.deviceType.mobile;\n }\n\n if (screenWidth <= _IframeConfigJson.default.screenWidthLimits[orientation][_IframeConfigJson.default.deviceType.tablet]) {\n // tablets larger than this may use full desktop ui\n return _IframeConfigJson.default.deviceType.tablet;\n }\n\n return _IframeConfigJson.default.deviceType.desktop;\n }\n /**\n * Returns the minimal possible height when in landscape.\n *\n * @param {string} deviceType Device type (mobile, desktop or tablet).\n * @param {number} appWidth Application width.\n * @returns {number} Minimal height for landscape.\n */\n\n }, {\n key: \"_getMinHeightLandscape\",\n value: function _getMinHeightLandscape(deviceType, appWidth) {\n if (deviceType == _IframeConfigJson.default.deviceType.mobile) {\n return appWidth / _IframeConfigJson.default.maxRatioLandscape;\n }\n\n return _IframeConfigJson.default.minHeightLandscape;\n }\n /**\n * Returns the current ratio.\n *\n * @param {string} orientation Orientation (portrait or landscape).\n * @returns {number} Ratio.\n */\n\n }, {\n key: \"_getRatio\",\n value: function _getRatio(orientation) {\n var ratio = _IframeConfigJson.default.preferredRatio[orientation].split('/');\n\n return parseInt(ratio[0]) / parseInt(ratio[1]);\n }\n }]);\n\n return IframeUtility;\n}();\n\nexports.default = IframeUtility;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Provide with helpful JSON utility functions.\n */\nvar JsonUtility = /*#__PURE__*/function () {\n function JsonUtility() {\n _classCallCheck(this, JsonUtility);\n }\n\n _createClass(JsonUtility, null, [{\n key: \"toSortedJson\",\n\n /**\n * Converts an object to sorted JSON.\n *\n * @param {object} object Object.\n * @returns {string} Sorted JSON.\n */\n value: function toSortedJson(object) {\n var _this = this;\n\n if (_typeof(object) === 'object') {\n return '{' + Object.keys(object).sort().map(function (key) {\n return '\"' + key + '\":' + _this.toSortedJson(object[key]);\n }).join(',') + '}';\n }\n\n return JSON.stringify(object);\n }\n }]);\n\n return JsonUtility;\n}();\n\nexports.default = JsonUtility;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar THOUSAND_SEPERATOR_REGEXP = /(\\d+)(\\d{3})/;\n/**\n * Handles formatting of prices.\n */\n\nvar PriceFormatter = /*#__PURE__*/function () {\n function PriceFormatter() {\n _classCallCheck(this, PriceFormatter);\n }\n\n _createClass(PriceFormatter, null, [{\n key: \"format\",\n\n /**\n * Formats a price.\n *\n * @param {number} amount Price amount.\n * @param {object} config Configuration to use. Usually recieved from common translations under the \"prices\" property.\n * @param {number} config.currencyCode Currency code used.\n * @param {number} config.numberOfDecimals Number of decimals.\n * @param {boolean} config.thousandSeparatorEnabled TRUE to enable thousand separator.\n * @param {string} config.thousandSeparator Thousand separator.\n * @param {boolean} config.replaceNoValueDecimals TRUE to replace no value decimals.\n * @param {string} config.noValueDecimalsString No value decimals string.\n * @param {string} config.decimalSeparator Decimal separator.\n * @param {number} config.numberOfDecimals Number of decimals.\n * @param {string} config.symbolSpacing Symbol spacing.\n * @param {string} config.currencySymbol Currency symbol.\n * @param {string} config.currencyPosition Currency position (\"before\" or \"after\").\n * @param {boolean} [useHtml] TRUE to use HTML. This will add a span with dir=\"ltr\", so that '1 400' wont get reversed in morocco. Default is TRUE.\n * @returns {string} Formatted price with currency.\n */\n value: function format(amount, config) {\n var useHtml = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n\n if (typeof amount !== 'number' || isNaN(amount)) {\n return '';\n }\n\n config.numberOfDecimals = parseInt(config.numberOfDecimals);\n\n if (isNaN(config.numberOfDecimals)) {\n config.numberOfDecimals = 2;\n }\n\n config.thousandSeparator = config.thousandSeparator || ' ';\n\n if (config.noValueDecimalsString === ' ') {\n config.noValueDecimalsString = '';\n }\n\n var priceString, integer; // Since the number of trailing zeroes is set with the toFixed,\n // The values cannot be integers\n\n amount = amount.toFixed(config.numberOfDecimals).split('.');\n integer = amount[0];\n var fraction = amount.length === 2 ? amount[1] : 0;\n\n if (config.currencyCode === 'INR') {\n var result = [];\n var thousand = '';\n\n if (integer.length > 3) {\n thousand = ',' + integer.substr(integer.length - 3);\n integer = integer.substr(0, integer.length - 3);\n\n while (integer.length > 2) {\n result.unshift(integer.substr(integer.length - 2));\n integer = integer.substr(0, integer.length - 2);\n }\n }\n\n if (integer.length > 0) {\n result.unshift(integer);\n }\n\n integer = result.join(',') + thousand;\n } else if (config.thousandSeparatorEnabled && integer.length > 3) {\n while (THOUSAND_SEPERATOR_REGEXP.test(integer)) {\n integer = integer.replace(THOUSAND_SEPERATOR_REGEXP, '$1' + config.thousandSeparator + '$2');\n }\n }\n\n if (config.replaceNoValueDecimals && typeof config.noValueDecimalsString === 'string' && Number(fraction) === 0) {\n priceString = integer + config.noValueDecimalsString;\n } else if (config.decimalSeparator && config.numberOfDecimals !== 0) {\n priceString = integer + config.decimalSeparator + fraction;\n } else {\n priceString = integer;\n } // Add ltr so that '1 400' wont get reversed in morocco\n\n\n if (useHtml) {\n priceString = '' + priceString + '';\n }\n\n var priceWithCurrency = [priceString, config.symbolSpacing ? ' ' : '', config.currencySymbol];\n\n if (config.currencyPosition === 'before') {\n priceWithCurrency.reverse();\n }\n\n return useHtml ? '' + priceWithCurrency.join('') + '' : priceWithCurrency.join('');\n }\n /**\n * Formats a price to be used for a single article.\n *\n * @param {number} amount Price amount.\n * @param {object} config Configuration to use. Usually recieved from common translations under the \"prices\" property.\n * @param {number} config.currencyCode Currency code used.\n * @param {number} config.numberOfDecimals Number of decimals.\n * @param {boolean} config.thousandSeparatorEnabled TRUE to enable thousand separator.\n * @param {string} config.thousandSeparator Thousand separator.\n * @param {boolean} config.replaceNoValueDecimals TRUE to replace no value decimals.\n * @param {string} config.noValueDecimalsString No value decimals string.\n * @param {string} config.decimalSeparator Decimal separator.\n * @param {number} config.numberOfDecimals Number of decimals.\n * @param {string} config.symbolSpacing Symbol spacing.\n * @param {string} config.currencySymbol Currency symbol.\n * @param {string} config.currencyPosition Currency position (\"before\" or \"after\").\n * @param {object} article An article object returned from ArticleServiceFacade when formatting is done on a single item. Additional information like package information will be added.\n * @param {boolean} [useHtml] TRUE to use HTML. This will add a span with dir=\"ltr\", so that '1 400' wont get reversed in morocco. Default is TRUE.\n * @returns {string} Formatted price with currency.\n */\n\n }, {\n key: \"formatForArticle\",\n value: function formatForArticle(amount, config, article) {\n var useHtml = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;\n var priceWithCurrency = this.format(amount, config, useHtml);\n var priceUnitFactor = parseFloat(article.PriceUnitFactor);\n\n if (priceWithCurrency === '') {\n return '';\n }\n\n if (!isNaN(priceUnitFactor) && typeof article.PriceUnitText === 'string' && (priceUnitFactor > 1 || article.PriceUnitTextEn && article.PriceUnitTextEn !== 'pack')) {\n if (useHtml) {\n return priceWithCurrency.slice(0, -7) + '/' + article.PriceUnitFactor + ' ' + article.PriceUnitText + '';\n }\n\n return priceWithCurrency + '/' + article.PriceUnitFactor + ' ' + article.PriceUnitText;\n }\n\n return priceWithCurrency;\n }\n }]);\n\n return PriceFormatter;\n}();\n\nexports.default = PriceFormatter;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === \"undefined\" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === \"number\") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar DEFAULT_COUNTRY = 'se';\nvar DEFAULT_LANGUAGE = 'sv';\nvar DEFAULT_UI_PLATFORM = 'irw';\n/**\n * Provide with URL utility functions.\n */\n\nvar UrlUtility = /*#__PURE__*/function () {\n function UrlUtility() {\n _classCallCheck(this, UrlUtility);\n }\n\n _createClass(UrlUtility, null, [{\n key: \"getAppInfo\",\n\n /**\n * Returns application information from query string.\n *\n * @returns {{ country: string, language: string, uiPlatform: string }} Country, Language and UI platform in an object. Default values: { country: 'se', language: 'sv', uiPlatform: 'irw' }.\n */\n value: function getAppInfo() {\n if (this._appInfo) {\n return this._appInfo;\n }\n\n var query = this.getCombinedQuery();\n var country = DEFAULT_COUNTRY;\n var language = DEFAULT_LANGUAGE;\n\n if (query.locale) {\n var locale = query.locale.split('_');\n\n if (locale.length > 1 && locale[0].length === 2 && locale[1].length === 2) {\n country = locale[1].toLowerCase();\n language = locale[0].toLowerCase();\n }\n }\n\n this._appInfo = {\n country: country,\n language: language,\n uiPlatform: query.uiPlatform || DEFAULT_UI_PLATFORM,\n storeId: query.storeId || null,\n applicationName: query.applicationName || null,\n seriesGallery: {\n applications: query.applications ? query.applications.split(',') : [],\n defaultApplication: query.defaultApplication || null\n }\n };\n return this._appInfo;\n }\n /**\n * Returns the query string merged with both search and hash as variables.\n *\n * @returns {object} Object with key value pairs of the data in the query string.\n */\n\n }, {\n key: \"getCombinedQuery\",\n value: function getCombinedQuery() {\n return Object.assign(this.getSearchQuery(), this.getHashQuery());\n }\n /**\n * Returns the query string as variables.\n *\n * @returns {object} Object with key value pairs of the data in the query string.\n */\n\n }, {\n key: \"getSearchQuery\",\n value: function getSearchQuery() {\n var search = window.location.search ? window.location.search.substring(1) : '';\n return this._parseQueryString(search);\n }\n /**\n * Sets search query.\n *\n * @param {object} query Query to set.\n */\n\n }, {\n key: \"setSearchQuery\",\n value: function setSearchQuery(query) {\n window.location.href = window.location.href.split('?')[0] + this.buildQueryString(query);\n }\n /**\n * Returns the query string defined in hash as variables.\n *\n * @returns {object} Object with key value pairs of the data in the query string.\n */\n\n }, {\n key: \"getHashQuery\",\n value: function getHashQuery() {\n var hash = window.location.hash ? window.location.hash.split('?').reverse()[0] : '';\n return this._parseQueryString(hash);\n }\n /**\n * Sets hash query.\n *\n * @param {object} query Query to set.\n */\n\n }, {\n key: \"setHashQuery\",\n value: function setHashQuery(query) {\n window.location.hash = '#' + window.location.hash.split('?')[0].replace('#', '') + this.buildQueryString(query);\n }\n /**\n * Builds search query.\n *\n * @param {object} query Query to build.\n * @returns {string} Query string.\n */\n\n }, {\n key: \"buildQueryString\",\n value: function buildQueryString(query) {\n var queryString = [];\n\n for (var _i = 0, _Object$keys = Object.keys(query); _i < _Object$keys.length; _i++) {\n var key = _Object$keys[_i];\n queryString.push(key + '=' + query[key]);\n }\n\n return '?' + queryString.join('&');\n }\n /**\n * Clears cache.\n */\n\n }, {\n key: \"clearCache\",\n value: function clearCache() {\n delete this._appInfo;\n }\n /**\n * Parses a query.\n *\n * @param {string} queryString Query string.\n * @returns {object} Object with key value pairs of the data in the query string.\n */\n\n }, {\n key: \"_parseQueryString\",\n value: function _parseQueryString(queryString) {\n var variables = queryString.split('&');\n var query = {};\n\n var _iterator = _createForOfIteratorHelper(variables),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var variable = _step.value;\n\n if (variable) {\n var pair = variable.split('=');\n query[pair[0]] = pair[1];\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n return query;\n }\n }]);\n\n return UrlUtility;\n}();\n\nexports.default = UrlUtility;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Handles string utilities.\n */\nvar StringUtility = /*#__PURE__*/function () {\n function StringUtility() {\n _classCallCheck(this, StringUtility);\n }\n\n _createClass(StringUtility, null, [{\n key: \"capitalizeFirstLetter\",\n\n /**\n * Capitalizes first letter.\n *\n * @param {string} string String to use.\n * @returns {string} String with first letter capitalized.\n */\n value: function capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1);\n }\n /**\n * Converts a camel case string to separate words with space inbetween.\n *\n * @param {string} string String to use.\n * @returns {string} Converted string.\n */\n\n }, {\n key: \"camelCaseToWords\",\n value: function camelCaseToWords(string) {\n return this.capitalizeFirstLetter(string.replace(/([A-Z0-9])/g, ' $1'));\n }\n /**\n * Converts a camel case string to kebab case.\n *\n * @example \"buttonEnabled\" will be converted to \"button-enabled\".\n * @param {string} string String to use.\n * @returns {string} Converted string.\n */\n\n }, {\n key: \"camelToKebabCase\",\n value: function camelToKebabCase(string) {\n return string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n }\n /**\n * Converts a kebab case string to words.\n *\n * @example \"button-enabled\" will be converted to \"Button Enabled\".\n * @param {string} string String to use.\n * @returns {string} Converted string.\n */\n\n }, {\n key: \"kebabCaseToWords\",\n value: function kebabCaseToWords(string) {\n string = string.split('-');\n\n for (var i = 0, max = string.length; i < max; i++) {\n string[i] = this.capitalizeFirstLetter(string[i]);\n }\n\n return string.join(' ');\n }\n }]);\n\n return StringUtility;\n}();\n\nexports.default = StringUtility;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar deprecatedIcons = ['threstles', 'threstle', 'arrow-right', 'arrow-left', 'arrow_down', 'arrow_up', 'select-all_2', 'chair_bar', 'chair_long', 'storage_accessories', 'extractor_hood', 'landscape_to_portrait'].map(function (iconName) {\n return 'IKEA--icon-' + iconName;\n});\n/**\n * StyleUtility\n */\n\nvar StyleUtility = /*#__PURE__*/function () {\n function StyleUtility() {\n _classCallCheck(this, StyleUtility);\n }\n\n _createClass(StyleUtility, null, [{\n key: \"getIconClasses\",\n\n /**\n * Gets all IKEA icons css classes.\n *\n * @returns {Array} - IKEA icons css classes.\n */\n value: function getIconClasses() {\n var icons = [];\n var sheet = document.styleSheets;\n var rule = null,\n i = sheet.length,\n j;\n\n while (0 <= --i) {\n try {\n rule = sheet[i].rules || sheet[i].cssRules || [];\n } catch (error) {\n rule = [];\n }\n\n j = rule.length;\n\n while (0 <= --j) {\n if (rule[j].constructor === CSSStyleRule && rule[j].selectorText.includes('.IKEA--icon')) {\n var selectorText = rule[j].selectorText.match(/(.ikea--icon-.*)::before/gi);\n\n if (selectorText) {\n var icon = selectorText[0].replace('::before', '').replace('.', '');\n\n if (!icons.includes(icon) && !deprecatedIcons.includes(icon)) {\n icons.push(icon);\n }\n }\n }\n }\n }\n\n return icons.sort();\n }\n /**\n * Get Icons names.\n *\n * @returns {Array} - IKEA icons names.\n */\n\n }, {\n key: \"getIconNames\",\n value: function getIconNames() {\n return this.getIconClasses().map(function (value) {\n return value.replace('IKEA--icon-', '');\n });\n }\n }]);\n\n return StyleUtility;\n}();\n\nexports.default = StyleUtility;","module.exports = {\n \"40\": \"xxu\",\n \"80\": \"xu\",\n \"160\": \"u\",\n \"300\": \"xxxs\",\n \"400\": \"xxs\",\n \"500\": \"xs\",\n \"600\": \"s\",\n \"700\": \"m\",\n \"750\": \"l\",\n \"900\": \"xl\",\n \"1100\": \"xxl\",\n \"1400\": \"xxxl\"\n};","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _AkamaiImageSizesJson = _interopRequireDefault(require(\"./AkamaiImageSizes.json.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === \"undefined\" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === \"number\") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar SIZE_NUMBERS = Object.keys(_AkamaiImageSizesJson.default).map(function (size) {\n return parseInt(size);\n});\nvar POLICY = 'f';\n/**\n * This class is used for Image utility function.s\n */\n\nvar ImageUtility = /*#__PURE__*/function () {\n function ImageUtility() {\n _classCallCheck(this, ImageUtility);\n }\n\n _createClass(ImageUtility, null, [{\n key: \"getAkamaiQueryString\",\n\n /**\n * Returns an Akamai query string based on size.\n *\n * @param {number} size Size of the image.\n * @returns {string} Query string.\n */\n value: function getAkamaiQueryString(size) {\n return \"?\".concat(POLICY, \"=\").concat(this._getAkamaiSize(size));\n }\n /**\n * Get Akamai formatted size.\n *\n * @param {number} size Image size.\n * @returns {string} Size.\n */\n\n }, {\n key: \"_getAkamaiSize\",\n value: function _getAkamaiSize(size) {\n var _iterator = _createForOfIteratorHelper(SIZE_NUMBERS),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var akamaiSize = _step.value;\n\n if (size <= akamaiSize) {\n return _AkamaiImageSizesJson.default[akamaiSize.toString()];\n }\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n return _AkamaiImageSizesJson.default[SIZE_NUMBERS[SIZE_NUMBERS.length - 1].toString()];\n }\n }]);\n\n return ImageUtility;\n}();\n\nexports.default = ImageUtility;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\nvar _default = {\n UNKNOWN: 'UNKNOWN',\n CODE: 'CODE',\n SERVER: 'SERVER',\n CONNECTION: 'CONNECTION'\n};\nexports.default = _default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _ExceptionTypeConstant = _interopRequireDefault(require(\"../constant/ExceptionTypeConstant\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === \"function\" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== \"function\") { throw new TypeError(\"Super expression must either be null or a function\"); } if (typeof _cache !== \"undefined\") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf(\"[native code]\") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n/**\n * Custom exception.\n */\nvar Exception = /*#__PURE__*/function (_Error) {\n _inherits(Exception, _Error);\n\n var _super = _createSuper(Exception);\n\n /**\n * Class constructor.\n *\n * @param {string} message The error message.\n * @param {string} [exceptionType] The exception type.\n */\n function Exception(message) {\n var _this;\n\n var exceptionType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'Exception';\n\n _classCallCheck(this, Exception);\n\n _this = _super.call(this, message);\n _this.message = 'Uncaught ' + exceptionType + ': ' + message;\n _this.name = _this.constructor.name;\n _this.stack = new Error().stack;\n _this.thrownBy = 'UNKNOWN';\n _this.type = _ExceptionTypeConstant.default.UNKNOWN;\n _this.exceptionType = exceptionType;\n return _this;\n }\n\n return Exception;\n}( /*#__PURE__*/_wrapNativeSuper(Error));\n\nexports.default = Exception;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _Exception2 = _interopRequireDefault(require(\"./Exception\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n/**\n * Custom exception.\n */\nvar ComponentException = /*#__PURE__*/function (_Exception) {\n _inherits(ComponentException, _Exception);\n\n var _super = _createSuper(ComponentException);\n\n /**\n * Class constructor.\n *\n * @param {string} message The error message.\n * @param {AbstractComponent|string} [component] The component instance throwing the error.\n */\n function ComponentException(message) {\n var _this;\n\n var component = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n\n _classCallCheck(this, ComponentException);\n\n _this = _super.call(this, message, 'ComponentException');\n _this.thrownBy = component !== null && _typeof(component) === 'object' && component.constructor.componentName ? component.constructor.componentName : typeof component === 'string' ? component : 'UNKNOWN';\n _this.message = 'Uncaught ComponentException: ' + (_this.thrownBy !== 'UNKNOWN' ? _this.thrownBy + ': ' : '') + message;\n return _this;\n }\n\n return ComponentException;\n}(_Exception2.default);\n\nexports.default = ComponentException;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _ComponentException = _interopRequireDefault(require(\"../exception/ComponentException\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === \"undefined\" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === \"number\") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Component Event Handler.\n */\nvar EventHandler = /*#__PURE__*/function () {\n /**\n * Class constructor.\n *\n * @param {object} options Options object.\n * @param {string[]} options.supportedEvents Supported events.\n * @param {string} options.componentName Component name.\n * @param {object} [options.scope] Scope to call callback in.\n */\n function EventHandler(options) {\n _classCallCheck(this, EventHandler);\n\n this.supportedEvents = options.supportedEvents;\n this._events = {};\n this._componentName = options.componentName;\n this._scope = options.scope || this;\n }\n /**\n * Adds an event listener.\n *\n * @param {string} name Event name.\n * @param {Function} listener The listener.\n */\n\n\n _createClass(EventHandler, [{\n key: \"on\",\n value: function on(name, listener) {\n if (!this.supportedEvents.includes(name)) {\n throw new _ComponentException.default('Event with name \"' + name + '\" is not supported.', this._componentName);\n }\n\n this._events[name] = this._events[name] || [];\n\n this._events[name].push(listener);\n }\n /**\n * Removes an event listener.\n *\n * @param {string} name Event name.\n * @param {Function} [listener] The listener. Will remove all listeners if not defined.\n */\n\n }, {\n key: \"off\",\n value: function off(name) {\n var listener = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n\n if (!this.supportedEvents.includes(name)) {\n throw new _ComponentException.default('Event with name \"' + name + '\" is not supported.', this._componentName);\n }\n\n this._events[name] = this._events[name] || [];\n\n if (listener === null) {\n delete this._events[name];\n } else {\n var index = this._events[name].indexOf(listener);\n\n if (index !== -1) {\n this._events[name].splice(index, 1);\n }\n }\n }\n /**\n * Triggers an event.\n *\n * @param {string} name Event name.\n * @param {...object} args Arguments to send.\n */\n\n }, {\n key: \"trigger\",\n value: function trigger(name) {\n if (!this.supportedEvents.includes(name)) {\n throw new _ComponentException.default('Event with name \"' + name + '\" is not supported.', this._componentName);\n }\n\n this._events[name] = this._events[name] || [];\n this._events[name].isTriggered = true;\n\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n var _iterator = _createForOfIteratorHelper(this._events[name]),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var listener = _step.value;\n listener.apply(this._scope, args);\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n /**\n * Checks if an event has been triggered before.\n *\n * @param {string} name Event name.\n * @returns {boolean} TRUE if triggered before.\n */\n\n }, {\n key: \"isTriggered\",\n value: function isTriggered(name) {\n return Array.isArray(this._events[name]) && this._events[name].isTriggered === true;\n }\n /**\n * Returns changed events based on an object with new events.\n *\n * @param {object} newEvents Events to set as key/value. Example: { click: () => {} }.\n * @returns {object} Changed events.\n */\n\n }, {\n key: \"getChangedEvents\",\n value: function getChangedEvents(newEvents) {\n var changedEvents = {};\n\n if (newEvents) {\n for (var _i = 0, _Object$keys = Object.keys(newEvents); _i < _Object$keys.length; _i++) {\n var key = _Object$keys[_i];\n\n if (!this._events[name] || !this._events[name].includes(newEvents[key])) {\n changedEvents[name] = newEvents[name];\n }\n }\n }\n\n return changedEvents;\n }\n }]);\n\n return EventHandler;\n}();\n\nexports.default = EventHandler;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _EventHandler2 = _interopRequireDefault(require(\"../event/EventHandler\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n/**\n * This class is used for observer changes to the size of the window and send it to the iframe.\n */\nvar ApplicationResizeObserver = /*#__PURE__*/function (_EventHandler) {\n _inherits(ApplicationResizeObserver, _EventHandler);\n\n var _super = _createSuper(ApplicationResizeObserver);\n\n /**\n * Clas constructor.\n *\n * @param {Element} [context] Context to watch.\n */\n function ApplicationResizeObserver() {\n var _this;\n\n var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n\n _classCallCheck(this, ApplicationResizeObserver);\n\n _this = _super.call(this, {\n supportedEvents: ['resize'],\n componentName: 'ApplicationResizeObserver'\n });\n _this.context = context || document.body;\n _this._images = _this.context.getElementsByTagName('img');\n _this._observer = null;\n _this._size = {\n height: 0,\n width: 0\n };\n _this._updateTimeout = null;\n\n _this._updateListener = function (event) {\n clearTimeout(_this._updateTimeout);\n _this._updateTimeout = setTimeout(_this.update.bind(_assertThisInitialized(_this)));\n\n if (event && event.target && event.target && event.target.tagName === 'IMG') {\n event.target.removeEventListener('load', _this._updateListener);\n }\n };\n\n return _this;\n }\n /**\n * Handles an update.\n */\n\n\n _createClass(ApplicationResizeObserver, [{\n key: \"update\",\n value: function update() {\n var newHeight = this.context.scrollHeight;\n var newWidth = this.context.scrollWidth;\n\n if (this._size.height !== newHeight && this._size.width !== newWidth) {\n this._size.height = newHeight;\n this._size.width = newWidth;\n this.trigger('resize', Object.assign({}, this._size));\n\n for (var _i = 0, _Array$from = Array.from(this._images); _i < _Array$from.length; _i++) {\n var image = _Array$from[_i];\n\n if (!image.complete) {\n image.addEventListener('load', this._updateListener);\n }\n }\n }\n }\n /**\n * Connects observer and adds a listener for resize.\n */\n\n }, {\n key: \"connect\",\n value: function connect() {\n if (this._observer === null) {\n this._observer = new MutationObserver(this._updateListener);\n\n this._observer.observe(this.context, {\n attributes: true,\n childList: true,\n characterData: true,\n subtree: true\n });\n\n window.addEventListener('resize', this._updateListener);\n this.update();\n }\n }\n /**\n * Disconnects observer and removes listener for resize.\n */\n\n }, {\n key: \"disconnect\",\n value: function disconnect() {\n if (this._observer !== null) {\n clearTimeout(this._updateTimeout);\n\n this._observer.disconnect();\n\n this._observer = null;\n window.removeEventListener('resize', this._updateListener);\n }\n }\n }]);\n\n return ApplicationResizeObserver;\n}(_EventHandler2.default);\n\nexports.default = ApplicationResizeObserver;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * This class is used for retireving supported events.\n */\nvar EventSupport = /*#__PURE__*/function () {\n function EventSupport() {\n _classCallCheck(this, EventSupport);\n }\n\n _createClass(EventSupport, null, [{\n key: \"getSupportedPointerEvents\",\n\n /**\n * Returns the supported pointer events.\n *\n * @returns {{start: string, move: string, end: string, leave: string}[]} Supported pointer events.\n */\n value: function getSupportedPointerEvents() {\n if (window.navigator.pointerEnabled) {\n return [{\n start: 'pointerdown',\n move: 'pointermove',\n end: 'pointerup',\n leave: 'pointerleave'\n }];\n } else if (window.navigator.msPointerEnabled) {\n return [{\n start: 'MSPointerDown',\n move: 'MSPointerMove',\n end: 'MSPointerUp',\n leave: 'MSPointerLeave'\n }];\n }\n\n return [{\n start: 'touchstart',\n move: 'touchmove',\n end: 'touchend',\n leave: 'touchleave'\n }, {\n start: 'mousedown',\n move: 'mousemove',\n end: 'mouseup',\n leave: 'mouseleave'\n }];\n }\n }]);\n\n return EventSupport;\n}();\n\nexports.default = EventSupport;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Cache store manager.\n */\nvar CacheStore = /*#__PURE__*/function () {\n /**\n * Class constructor.\n *\n * @param {String} name Store name.\n */\n function CacheStore(name) {\n _classCallCheck(this, CacheStore);\n\n this.constructor.store[name] = this.constructor.store[name] || new Map();\n this.store = this.constructor.store[name];\n }\n /**\n * Sets a cache item.\n *\n * @param {Object} key Cache key.\n * @param {Object} value Cache value.\n */\n\n\n _createClass(CacheStore, [{\n key: \"set\",\n value: function set(key, value) {\n this.store.set(key, value);\n }\n /**\n * Returns a cache item.\n *\n * @param {Object} key Cache key.\n * @return {Object|Null} Cache value.\n */\n\n }, {\n key: \"get\",\n value: function get(key) {\n return this.store.get(key);\n }\n /**\n * Deletes a cache item.\n *\n * @param {Object} key Cache key.\n */\n\n }, {\n key: \"delete\",\n value: function _delete(key) {\n this.store.delete(key);\n }\n /**\n * Clears the cache.\n */\n\n }, {\n key: \"clear\",\n value: function clear() {\n this.store.clear();\n }\n /**\n * Returns all keys.\n *\n * @return {Object[]} Cache keys.\n */\n\n }, {\n key: \"keys\",\n value: function keys() {\n return this.store.keys();\n }\n /**\n * Returns all values.\n *\n * @return {Object[]} Cache values.\n */\n\n }, {\n key: \"values\",\n value: function values() {\n return this.store.values();\n }\n /**\n * Returns the amount of values stored in the cache.\n *\n * @return {Number} Amount of values.\n */\n\n }, {\n key: \"size\",\n get: function get() {\n return this.store.size;\n }\n /**\n * Returns the store.\n *\n * @return {Object} Cache store.\n */\n\n }], [{\n key: \"clearAll\",\n\n /**\n * Clears all cache.\n */\n value: function clearAll() {\n window.IkeaComponent = window.IkeaComponent || {};\n window.IkeaComponent.$cacheStore = {};\n }\n }, {\n key: \"store\",\n get: function get() {\n window.IkeaComponent = window.IkeaComponent || {};\n window.IkeaComponent.$cacheStore = window.IkeaComponent.$cacheStore || {};\n return window.IkeaComponent.$cacheStore;\n }\n }]);\n\n return CacheStore;\n}();\n\nexports.default = CacheStore;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _Exception2 = _interopRequireDefault(require(\"./Exception\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n/**\n * Custom exception.\n */\nvar UnsupportedException = /*#__PURE__*/function (_Exception) {\n _inherits(UnsupportedException, _Exception);\n\n var _super = _createSuper(UnsupportedException);\n\n /**\n * Class constructor.\n *\n * @param {string} message The error message.\n */\n function UnsupportedException(message) {\n _classCallCheck(this, UnsupportedException);\n\n return _super.call(this, message, 'UnsupportedException');\n }\n\n return UnsupportedException;\n}(_Exception2.default);\n\nexports.default = UnsupportedException;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _Exception2 = _interopRequireDefault(require(\"./Exception\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n/**\n * Custom exception.\n */\nvar AbstractMethodException = /*#__PURE__*/function (_Exception) {\n _inherits(AbstractMethodException, _Exception);\n\n var _super = _createSuper(AbstractMethodException);\n\n /**\n * Class constructor.\n *\n * @param {string} [message] The error message.\n */\n function AbstractMethodException() {\n var message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'Class method is abstract cannot be called directly.';\n\n _classCallCheck(this, AbstractMethodException);\n\n return _super.call(this, message, 'AbstractMethodException');\n }\n\n return AbstractMethodException;\n}(_Exception2.default);\n\nexports.default = AbstractMethodException;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _CacheStore = _interopRequireDefault(require(\"../CacheStore\"));\n\nvar _UnsupportedException = _interopRequireDefault(require(\"../exception/UnsupportedException\"));\n\nvar _AbstractMethodException = _interopRequireDefault(require(\"../exception/AbstractMethodException\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _iterableToArrayLimit(arr, i) { if (typeof Symbol === \"undefined\" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === \"undefined\" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === \"number\") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Settings manager.\n */\nvar AbstractSettingsManager = /*#__PURE__*/function () {\n function AbstractSettingsManager() {\n _classCallCheck(this, AbstractSettingsManager);\n }\n\n _createClass(AbstractSettingsManager, null, [{\n key: \"applySettings\",\n\n /**\n * Applies multiple service settings.\n *\n * @param {object} settings Settings object.\n */\n value: function applySettings(settings) {\n var defaultSettings = this.getDefaultSettings();\n\n for (var _i = 0, _Object$keys = Object.keys(settings); _i < _Object$keys.length; _i++) {\n var key = _Object$keys[_i];\n\n if (defaultSettings[key] !== undefined) {\n if (settings[key] !== undefined) {\n this[key] = settings[key];\n }\n } else {\n throw new _UnsupportedException.default('The setting with key \"' + key + '\" is not supported in \"' + this.name + '\".');\n }\n }\n }\n /**\n * Returns all settings as an object.\n *\n * @returns {object} All settings.\n */\n\n }, {\n key: \"getAllSettings\",\n value: function getAllSettings() {\n var settings = {};\n\n var _iterator = _createForOfIteratorHelper(this.settings.store),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var _step$value = _slicedToArray(_step.value, 2),\n key = _step$value[0],\n value = _step$value[1];\n\n settings[key] = value;\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n\n return settings;\n }\n /**\n * Returns the default settings.\n *\n * @abstract\n * @returns {object} Default settings as an object.\n */\n\n }, {\n key: \"getDefaultSettings\",\n value: function getDefaultSettings() {\n throw new _AbstractMethodException.default();\n }\n /**\n * Applies properties for the settings.\n */\n\n }, {\n key: \"setupProperties\",\n value: function setupProperties() {\n var _this = this;\n\n var defaultSettings = this.getDefaultSettings();\n\n var _loop = function _loop() {\n var key = _Object$keys2[_i2];\n\n if (_this[key] === undefined) {\n Object.defineProperty(_this, key, {\n set: function set(value) {\n _this.settings.set(key, value);\n },\n get: function get() {\n return _this.settings.get(key);\n }\n });\n }\n };\n\n for (var _i2 = 0, _Object$keys2 = Object.keys(defaultSettings); _i2 < _Object$keys2.length; _i2++) {\n _loop();\n }\n }\n /**\n * Returns the settings manager name.\n *\n * @abstract\n * @returns {string} Settings manager name.\n */\n\n }, {\n key: \"settingsName\",\n get: function get() {\n throw new _AbstractMethodException.default();\n }\n /**\n * Returns the settings.\n *\n * @returns {CacheStore} Settings cache store.\n */\n\n }, {\n key: \"settings\",\n get: function get() {\n if (!this._cacheStore) {\n this._cacheStore = new _CacheStore.default(this.settingsName);\n\n if (this._cacheStore.size === 0) {\n var defaultSettings = this.getDefaultSettings();\n\n for (var _i3 = 0, _Object$keys3 = Object.keys(defaultSettings); _i3 < _Object$keys3.length; _i3++) {\n var key = _Object$keys3[_i3];\n\n this._cacheStore.set(key, defaultSettings[key]);\n }\n }\n }\n\n return this._cacheStore;\n }\n }]);\n\n return AbstractSettingsManager;\n}();\n\nexports.default = AbstractSettingsManager;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _AbstractSettingsManager = _interopRequireDefault(require(\"./AbstractSettingsManager\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n/**\n * Manages component settings.\n */\nvar ComponentSettings = /*#__PURE__*/function (_AbstractSettingsMana) {\n _inherits(ComponentSettings, _AbstractSettingsMana);\n\n var _super = _createSuper(ComponentSettings);\n\n function ComponentSettings() {\n _classCallCheck(this, ComponentSettings);\n\n return _super.apply(this, arguments);\n }\n\n _createClass(ComponentSettings, null, [{\n key: \"getDefaultSettings\",\n\n /**\n * Returns the default settings.\n *\n * @override\n * @returns {object} Default settings as an object.\n */\n value: function getDefaultSettings() {\n return {\n uiPlatform: null\n };\n }\n /**\n * Returns the settings manager name.\n *\n * @override\n * @returns {string} Settings manager name.\n */\n\n }, {\n key: \"settingsName\",\n get: function get() {\n return 'ComponentSettings';\n }\n }]);\n\n return ComponentSettings;\n}(_AbstractSettingsManager.default);\n\nexports.default = ComponentSettings;\nComponentSettings.setupProperties();","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _IframeUtility = _interopRequireDefault(require(\"./IframeUtility\"));\n\nvar _EasingAnimation = _interopRequireDefault(require(\"../animation/EasingAnimation\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Window scrolling utility\n */\nvar ScrollUtility = /*#__PURE__*/function () {\n function ScrollUtility() {\n _classCallCheck(this, ScrollUtility);\n }\n\n _createClass(ScrollUtility, null, [{\n key: \"scrollToElement\",\n\n /**\n * Scrolls the window to make the element visible.\n *\n * @param {object} options Options object.\n * @param {Element} options.element Element to scroll into view.\n * @param {string} options.platform Platform (nwp, irw, m2, mobile etc.).\n * @param {boolean} [options.animate] TRUE to animate. Default is TRUE.\n * @param {boolean} [options.center] TRUE to center the element. Default is TRUE.\n * @param {number} [options.minDistance] Minimal distance before scroll will be activated. Default is \"200\" (px).\n * @param {number} [options.scrollTopMargin] Scroll top margin that will be offset from the top of the element when the element height is greater than the screen height. Default is \"10\" (px);.\n */\n value: function scrollToElement(options) {\n if (_IframeUtility.default.isInsideIframe()) {\n this._scrollToElement(options);\n } else {\n _IframeUtility.default.scrollToElement(options);\n }\n }\n /**\n * Scrolls the window to make the element visible.\n *\n * @param {object} options Options object.\n * @param {Element} options.element Element to scroll into view.\n * @param {string} options.platform Platform (nwp, irw, m2, mobile etc.).\n * @param {boolean} [options.animate] TRUE to animate. Default is TRUE.\n * @param {boolean} [options.center] TRUE to center the element. Default is TRUE.\n * @param {number} [options.minDistance] Minimal distance before scroll will be activated. Default is \"200\" (px).\n * @param {number} [options.scrollTopMargin] Scroll top margin that will be offset from the top of the element when the element height is greater than the screen height. Default is \"10\" (px);.\n */\n\n }, {\n key: \"_scrollToElement\",\n value: function _scrollToElement(options) {\n var element = options.element,\n scrollTopMargin = options.scrollTopMargin,\n _options$center = options.center,\n center = _options$center === void 0 ? true : _options$center,\n _options$minDistance = options.minDistance,\n minDistance = _options$minDistance === void 0 ? 200 : _options$minDistance,\n _options$animate = options.animate,\n animate = _options$animate === void 0 ? true : _options$animate;\n var screenHeight = window.parent.innerHeight;\n var bodyRect = document.body.getBoundingClientRect();\n var elemRect = element.getBoundingClientRect();\n var elementTopY = elemRect.top - bodyRect.top;\n var elementCenterY = elemRect.height > screenHeight ? elementTopY : elementTopY - screenHeight / 2 + elemRect.height / 2;\n var endPositionY = center ? elementCenterY - scrollTopMargin : elementTopY - scrollTopMargin;\n var startY = window.pageYOffset !== undefined ? window.pageYOffset : window.document.documentElement.scrollTop;\n var currentX = window.pageXOffset !== undefined ? window.pageXOffset : 0;\n var distanceY = Math.abs(startY - endPositionY);\n\n if (distanceY > minDistance) {\n if (animate) {\n var animation = new _EasingAnimation.default();\n animation.on('frame', function (y) {\n return window.parent.scrollTo(0, y);\n });\n animation.startValue = startY;\n animation.endValue = endPositionY;\n var frames = Math.floor(distanceY / 10);\n animation.frames = frames;\n animation.start();\n } else {\n window.scrollTo(currentX, endPositionY);\n }\n }\n }\n }]);\n\n return ScrollUtility;\n}();\n\nexports.default = ScrollUtility;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * ResourceTagLoader\n */\nvar ResourceTagLoader = /*#__PURE__*/function () {\n function ResourceTagLoader() {\n _classCallCheck(this, ResourceTagLoader);\n }\n\n _createClass(ResourceTagLoader, null, [{\n key: \"loadCss\",\n\n /**\n * Load a script by adding a script tag.\n *\n * @param {object} args Args.\n * @param {string} args.url What to load.\n * @param {HTMLElement} args.parent Where to add tag.\n * @returns {Promise} - Resolved when ready.\n */\n value: function loadCss(_ref) {\n var url = _ref.url,\n _ref$parent = _ref.parent,\n parent = _ref$parent === void 0 ? document.head : _ref$parent;\n var element = document.createElement('link');\n var promise = this.waitForTagLoad(element);\n element.href = url;\n element.setAttribute('type', 'text/css');\n element.setAttribute('rel', 'stylesheet');\n parent.appendChild(element);\n return promise;\n }\n /**\n * Load a script by adding a script tag.\n *\n * @param {object} args Args.\n * @param {string} args.url What to load.\n * @param {HTMLElement} args.parent Where to add tag.\n * @returns {Promise} - Resolved when ready.\n */\n\n }, {\n key: \"loadScript\",\n value: function loadScript(_ref2) {\n var url = _ref2.url,\n _ref2$parent = _ref2.parent,\n parent = _ref2$parent === void 0 ? document.head : _ref2$parent;\n var element = document.createElement('script');\n var promise = this.waitForTagLoad(element);\n element.src = url;\n element.async = 1;\n parent.appendChild(element);\n return promise;\n }\n /**\n * Promizify tag load.\n *\n * @param {HTMLElement} htmlElement What to load.\n * @returns {Promise} - Resolved when ready.\n */\n\n }, {\n key: \"waitForTagLoad\",\n value: function waitForTagLoad(htmlElement) {\n return new Promise(function (resolve, reject) {\n htmlElement.addEventListener('load', resolve);\n htmlElement.addEventListener('error', reject);\n });\n }\n }]);\n\n return ResourceTagLoader;\n}();\n\nexports.default = ResourceTagLoader;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Mutex\n */\nvar Mutex = /*#__PURE__*/function () {\n /**\n * Creates a new Mutex.\n *\n * @param {number} maxCount Number of simultaneous locks to allow before other callers must wait.\n */\n function Mutex() {\n var _this = this;\n\n var maxCount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;\n\n _classCallCheck(this, Mutex);\n\n this.queue = [];\n this.count = 0; // Number currently running\n\n this.maxCount = maxCount;\n\n this.addToQueue = function (release) {\n _this.queue.push(release);\n };\n }\n /**\n * Takes a lock, causing execution to wait if number of callers exceeds maxCount.\n *\n * @returns {void|Promise} Promise resolved or not depending on if caller must wait.\n */\n\n\n _createClass(Mutex, [{\n key: \"lock\",\n value: function lock() {\n // Do we event need to wait?\n if (this.count < this.maxCount) {\n // No\n this.count++;\n return Promise.resolve();\n } // Yes, we have to wait for our turn\n\n\n return new Promise(this.addToQueue);\n }\n /**\n * Releases a previously taken lock.\n */\n\n }, {\n key: \"release\",\n value: function release() {\n this.count--;\n\n this._update();\n }\n /**\n * Resolves promises (locks) down to maxCount.\n */\n\n }, {\n key: \"_update\",\n value: function _update() {\n while (this.count < this.maxCount && // We still have space\n this.queue.length !== 0 // We have executers in line\n ) {\n var release = this.queue.shift();\n this.count++;\n release();\n }\n }\n }]);\n\n return Mutex;\n}();\n\nexports.default = Mutex;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar emptyFunction = function emptyFunction() {};\n\nvar returnEmptyFunction = function returnEmptyFunction() {\n return emptyFunction;\n};\n/**\n * Latch\n */\n\n\nvar Latch = /*#__PURE__*/function () {\n /**\n * Creates a new Latch.\n */\n function Latch() {\n _classCallCheck(this, Latch);\n\n this.isFirstRun = true;\n this.isFinished = false;\n this.list = [];\n }\n /**\n * Takes a lock, causing execution to wait if number of callers exceeds maxCount.\n *\n * @returns {Promise} Promise resolved or not depending on if caller must wait.\n */\n\n\n _createClass(Latch, [{\n key: \"aquire\",\n value: function aquire() {\n if (this.isFinished) {\n return Promise.resolve().then(returnEmptyFunction);\n } else if (this.isFirstRun) {\n this.isFirstRun = false;\n return Promise.resolve().then(this._getFirstReleaseFunction.bind(this));\n } else {\n return new Promise(this._addResolveToList.bind(this)).then(returnEmptyFunction);\n }\n }\n /**\n * Add promise resolve to list.\n *\n * @param {Function} resolve Argument from Promise constructor.\n */\n\n }, {\n key: \"_addResolveToList\",\n value: function _addResolveToList(resolve) {\n this.list.push(resolve);\n }\n /**\n *\n * @returns {Function} - A function for release.\n */\n\n }, {\n key: \"_getFirstReleaseFunction\",\n value: function _getFirstReleaseFunction() {\n var _this = this;\n\n return function () {\n return _this._firstRelease();\n };\n }\n /**\n * First release.\n */\n\n }, {\n key: \"_firstRelease\",\n value: function _firstRelease() {\n this.isFinished = true;\n\n this._releaseAll();\n }\n /**\n * Release all promises.\n */\n\n }, {\n key: \"_releaseAll\",\n value: function _releaseAll() {\n this.list.forEach(function (fun) {\n return fun();\n });\n this.list = [];\n }\n }]);\n\n return Latch;\n}();\n\nexports.default = Latch;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nObject.defineProperty(exports, \"DateFormatter\", {\n enumerable: true,\n get: function get() {\n return _DateFormatter.default;\n }\n});\nObject.defineProperty(exports, \"FileUtility\", {\n enumerable: true,\n get: function get() {\n return _FileUtility.default;\n }\n});\nObject.defineProperty(exports, \"IframeUtility\", {\n enumerable: true,\n get: function get() {\n return _IframeUtility.default;\n }\n});\nObject.defineProperty(exports, \"JsonUtility\", {\n enumerable: true,\n get: function get() {\n return _JsonUtility.default;\n }\n});\nObject.defineProperty(exports, \"PriceFormatter\", {\n enumerable: true,\n get: function get() {\n return _PriceFormatter.default;\n }\n});\nObject.defineProperty(exports, \"UrlUtility\", {\n enumerable: true,\n get: function get() {\n return _UrlUtility.default;\n }\n});\nObject.defineProperty(exports, \"StringUtility\", {\n enumerable: true,\n get: function get() {\n return _StringUtility.default;\n }\n});\nObject.defineProperty(exports, \"StyleUtility\", {\n enumerable: true,\n get: function get() {\n return _StyleUtility.default;\n }\n});\nObject.defineProperty(exports, \"ImageUtility\", {\n enumerable: true,\n get: function get() {\n return _ImageUtility.default;\n }\n});\nObject.defineProperty(exports, \"ApplicationResizeObserver\", {\n enumerable: true,\n get: function get() {\n return _ApplicationResizeObserver.default;\n }\n});\nObject.defineProperty(exports, \"EventHandler\", {\n enumerable: true,\n get: function get() {\n return _EventHandler.default;\n }\n});\nObject.defineProperty(exports, \"EventSupport\", {\n enumerable: true,\n get: function get() {\n return _EventSupport.default;\n }\n});\nObject.defineProperty(exports, \"ComponentSettings\", {\n enumerable: true,\n get: function get() {\n return _ComponentSettings.default;\n }\n});\nObject.defineProperty(exports, \"ScrollUtility\", {\n enumerable: true,\n get: function get() {\n return _ScrollUtility.default;\n }\n});\nObject.defineProperty(exports, \"ResourceTagLoader\", {\n enumerable: true,\n get: function get() {\n return _ResourceTagLoader.default;\n }\n});\nObject.defineProperty(exports, \"Mutex\", {\n enumerable: true,\n get: function get() {\n return _Mutex.default;\n }\n});\nObject.defineProperty(exports, \"Latch\", {\n enumerable: true,\n get: function get() {\n return _Latch.default;\n }\n});\n\nvar _DateFormatter = _interopRequireDefault(require(\"./util/DateFormatter\"));\n\nvar _FileUtility = _interopRequireDefault(require(\"./util/FileUtility\"));\n\nvar _IframeUtility = _interopRequireDefault(require(\"./util/IframeUtility\"));\n\nvar _JsonUtility = _interopRequireDefault(require(\"./util/JsonUtility\"));\n\nvar _PriceFormatter = _interopRequireDefault(require(\"./util/PriceFormatter\"));\n\nvar _UrlUtility = _interopRequireDefault(require(\"./util/UrlUtility\"));\n\nvar _StringUtility = _interopRequireDefault(require(\"./util/StringUtility\"));\n\nvar _StyleUtility = _interopRequireDefault(require(\"./util/StyleUtility\"));\n\nvar _ImageUtility = _interopRequireDefault(require(\"./util/ImageUtility\"));\n\nvar _ApplicationResizeObserver = _interopRequireDefault(require(\"./util/ApplicationResizeObserver\"));\n\nvar _EventHandler = _interopRequireDefault(require(\"./event/EventHandler\"));\n\nvar _EventSupport = _interopRequireDefault(require(\"./util/EventSupport\"));\n\nvar _ComponentSettings = _interopRequireDefault(require(\"./settings/ComponentSettings\"));\n\nvar _ScrollUtility = _interopRequireDefault(require(\"./util/ScrollUtility\"));\n\nvar _ResourceTagLoader = _interopRequireDefault(require(\"./util/ResourceTagLoader\"));\n\nvar _Mutex = _interopRequireDefault(require(\"./util/Mutex\"));\n\nvar _Latch = _interopRequireDefault(require(\"./util/Latch\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }","/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\nconst directives = new WeakMap();\n/**\n * Brands a function as a directive factory function so that lit-html will call\n * the function during template rendering, rather than passing as a value.\n *\n * A _directive_ is a function that takes a Part as an argument. It has the\n * signature: `(part: Part) => void`.\n *\n * A directive _factory_ is a function that takes arguments for data and\n * configuration and returns a directive. Users of directive usually refer to\n * the directive factory as the directive. For example, \"The repeat directive\".\n *\n * Usually a template author will invoke a directive factory in their template\n * with relevant arguments, which will then return a directive function.\n *\n * Here's an example of using the `repeat()` directive factory that takes an\n * array and a function to render an item:\n *\n * ```js\n * html`
    <${repeat(items, (item) => html`
  • ${item}
  • `)}
`\n * ```\n *\n * When `repeat` is invoked, it returns a directive function that closes over\n * `items` and the template function. When the outer template is rendered, the\n * return directive function is called with the Part for the expression.\n * `repeat` then performs it's custom logic to render multiple items.\n *\n * @param f The directive factory function. Must be a function that returns a\n * function of the signature `(part: Part) => void`. The returned function will\n * be called with the part object.\n *\n * @example\n *\n * import {directive, html} from 'lit-html';\n *\n * const immutable = directive((v) => (part) => {\n * if (part.value !== v) {\n * part.setValue(v)\n * }\n * });\n */\nexport const directive = (f) => ((...args) => {\n const d = f(...args);\n directives.set(d, true);\n return d;\n});\nexport const isDirective = (o) => {\n return typeof o === 'function' && directives.has(o);\n};\n//# sourceMappingURL=directive.js.map","/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * True if the custom elements polyfill is in use.\n */\nexport const isCEPolyfill = typeof window !== 'undefined' &&\n window.customElements != null &&\n window.customElements.polyfillWrapFlushCallback !==\n undefined;\n/**\n * Reparents nodes, starting from `start` (inclusive) to `end` (exclusive),\n * into another container (could be the same container), before `before`. If\n * `before` is null, it appends the nodes to the container.\n */\nexport const reparentNodes = (container, start, end = null, before = null) => {\n while (start !== end) {\n const n = start.nextSibling;\n container.insertBefore(start, before);\n start = n;\n }\n};\n/**\n * Removes nodes, starting from `start` (inclusive) to `end` (exclusive), from\n * `container`.\n */\nexport const removeNodes = (container, start, end = null) => {\n while (start !== end) {\n const n = start.nextSibling;\n container.removeChild(start);\n start = n;\n }\n};\n//# sourceMappingURL=dom.js.map","/**\n * @license\n * Copyright (c) 2018 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * A sentinel value that signals that a value was handled by a directive and\n * should not be written to the DOM.\n */\nexport const noChange = {};\n/**\n * A sentinel value that signals a NodePart to fully clear its content.\n */\nexport const nothing = {};\n//# sourceMappingURL=part.js.map","/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * An expression marker with embedded unique key to avoid collision with\n * possible text in templates.\n */\nexport const marker = `{{lit-${String(Math.random()).slice(2)}}}`;\n/**\n * An expression marker used text-positions, multi-binding attributes, and\n * attributes with markup-like text values.\n */\nexport const nodeMarker = ``;\nexport const markerRegex = new RegExp(`${marker}|${nodeMarker}`);\n/**\n * Suffix appended to all bound attribute names.\n */\nexport const boundAttributeSuffix = '$lit$';\n/**\n * An updatable Template that tracks the location of dynamic parts.\n */\nexport class Template {\n constructor(result, element) {\n this.parts = [];\n this.element = element;\n const nodesToRemove = [];\n const stack = [];\n // Edge needs all 4 parameters present; IE11 needs 3rd parameter to be null\n const walker = document.createTreeWalker(element.content, 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */, null, false);\n // Keeps track of the last index associated with a part. We try to delete\n // unnecessary nodes, but we never want to associate two different parts\n // to the same index. They must have a constant node between.\n let lastPartIndex = 0;\n let index = -1;\n let partIndex = 0;\n const { strings, values: { length } } = result;\n while (partIndex < length) {\n const node = walker.nextNode();\n if (node === null) {\n // We've exhausted the content inside a nested template element.\n // Because we still have parts (the outer for-loop), we know:\n // - There is a template in the stack\n // - The walker will find a nextNode outside the template\n walker.currentNode = stack.pop();\n continue;\n }\n index++;\n if (node.nodeType === 1 /* Node.ELEMENT_NODE */) {\n if (node.hasAttributes()) {\n const attributes = node.attributes;\n const { length } = attributes;\n // Per\n // https://developer.mozilla.org/en-US/docs/Web/API/NamedNodeMap,\n // attributes are not guaranteed to be returned in document order.\n // In particular, Edge/IE can return them out of order, so we cannot\n // assume a correspondence between part index and attribute index.\n let count = 0;\n for (let i = 0; i < length; i++) {\n if (endsWith(attributes[i].name, boundAttributeSuffix)) {\n count++;\n }\n }\n while (count-- > 0) {\n // Get the template literal section leading up to the first\n // expression in this attribute\n const stringForPart = strings[partIndex];\n // Find the attribute name\n const name = lastAttributeNameRegex.exec(stringForPart)[2];\n // Find the corresponding attribute\n // All bound attributes have had a suffix added in\n // TemplateResult#getHTML to opt out of special attribute\n // handling. To look up the attribute value we also need to add\n // the suffix.\n const attributeLookupName = name.toLowerCase() + boundAttributeSuffix;\n const attributeValue = node.getAttribute(attributeLookupName);\n node.removeAttribute(attributeLookupName);\n const statics = attributeValue.split(markerRegex);\n this.parts.push({ type: 'attribute', index, name, strings: statics });\n partIndex += statics.length - 1;\n }\n }\n if (node.tagName === 'TEMPLATE') {\n stack.push(node);\n walker.currentNode = node.content;\n }\n }\n else if (node.nodeType === 3 /* Node.TEXT_NODE */) {\n const data = node.data;\n if (data.indexOf(marker) >= 0) {\n const parent = node.parentNode;\n const strings = data.split(markerRegex);\n const lastIndex = strings.length - 1;\n // Generate a new text node for each literal section\n // These nodes are also used as the markers for node parts\n for (let i = 0; i < lastIndex; i++) {\n let insert;\n let s = strings[i];\n if (s === '') {\n insert = createMarker();\n }\n else {\n const match = lastAttributeNameRegex.exec(s);\n if (match !== null && endsWith(match[2], boundAttributeSuffix)) {\n s = s.slice(0, match.index) + match[1] +\n match[2].slice(0, -boundAttributeSuffix.length) + match[3];\n }\n insert = document.createTextNode(s);\n }\n parent.insertBefore(insert, node);\n this.parts.push({ type: 'node', index: ++index });\n }\n // If there's no text, we must insert a comment to mark our place.\n // Else, we can trust it will stick around after cloning.\n if (strings[lastIndex] === '') {\n parent.insertBefore(createMarker(), node);\n nodesToRemove.push(node);\n }\n else {\n node.data = strings[lastIndex];\n }\n // We have a part for each match found\n partIndex += lastIndex;\n }\n }\n else if (node.nodeType === 8 /* Node.COMMENT_NODE */) {\n if (node.data === marker) {\n const parent = node.parentNode;\n // Add a new marker node to be the startNode of the Part if any of\n // the following are true:\n // * We don't have a previousSibling\n // * The previousSibling is already the start of a previous part\n if (node.previousSibling === null || index === lastPartIndex) {\n index++;\n parent.insertBefore(createMarker(), node);\n }\n lastPartIndex = index;\n this.parts.push({ type: 'node', index });\n // If we don't have a nextSibling, keep this node so we have an end.\n // Else, we can remove it to save future costs.\n if (node.nextSibling === null) {\n node.data = '';\n }\n else {\n nodesToRemove.push(node);\n index--;\n }\n partIndex++;\n }\n else {\n let i = -1;\n while ((i = node.data.indexOf(marker, i + 1)) !== -1) {\n // Comment node has a binding marker inside, make an inactive part\n // The binding won't work, but subsequent bindings will\n // TODO (justinfagnani): consider whether it's even worth it to\n // make bindings in comments work\n this.parts.push({ type: 'node', index: -1 });\n partIndex++;\n }\n }\n }\n }\n // Remove text binding nodes after the walk to not disturb the TreeWalker\n for (const n of nodesToRemove) {\n n.parentNode.removeChild(n);\n }\n }\n}\nconst endsWith = (str, suffix) => {\n const index = str.length - suffix.length;\n return index >= 0 && str.slice(index) === suffix;\n};\nexport const isTemplatePartActive = (part) => part.index !== -1;\n// Allows `document.createComment('')` to be renamed for a\n// small manual size-savings.\nexport const createMarker = () => document.createComment('');\n/**\n * This regex extracts the attribute name preceding an attribute-position\n * expression. It does this by matching the syntax allowed for attributes\n * against the string literal directly preceding the expression, assuming that\n * the expression is in an attribute-value position.\n *\n * See attributes in the HTML spec:\n * https://www.w3.org/TR/html5/syntax.html#elements-attributes\n *\n * \" \\x09\\x0a\\x0c\\x0d\" are HTML space characters:\n * https://www.w3.org/TR/html5/infrastructure.html#space-characters\n *\n * \"\\0-\\x1F\\x7F-\\x9F\" are Unicode control characters, which includes every\n * space character except \" \".\n *\n * So an attribute is:\n * * The name: any character except a control character, space character, ('),\n * (\"), \">\", \"=\", or \"/\"\n * * Followed by zero or more space characters\n * * Followed by \"=\"\n * * Followed by zero or more space characters\n * * Followed by:\n * * Any character except space, ('), (\"), \"<\", \">\", \"=\", (`), or\n * * (\") then any non-(\"), or\n * * (') then any non-(')\n */\nexport const lastAttributeNameRegex = \n// eslint-disable-next-line no-control-regex\n/([ \\x09\\x0a\\x0c\\x0d])([^\\0-\\x1F\\x7F-\\x9F \"'>=/]+)([ \\x09\\x0a\\x0c\\x0d]*=[ \\x09\\x0a\\x0c\\x0d]*(?:[^ \\x09\\x0a\\x0c\\x0d\"'`<>=]*|\"[^\"]*|'[^']*))$/;\n//# sourceMappingURL=template.js.map","/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\nimport { isCEPolyfill } from './dom.js';\nimport { isTemplatePartActive } from './template.js';\n/**\n * An instance of a `Template` that can be attached to the DOM and updated\n * with new values.\n */\nexport class TemplateInstance {\n constructor(template, processor, options) {\n this.__parts = [];\n this.template = template;\n this.processor = processor;\n this.options = options;\n }\n update(values) {\n let i = 0;\n for (const part of this.__parts) {\n if (part !== undefined) {\n part.setValue(values[i]);\n }\n i++;\n }\n for (const part of this.__parts) {\n if (part !== undefined) {\n part.commit();\n }\n }\n }\n _clone() {\n // There are a number of steps in the lifecycle of a template instance's\n // DOM fragment:\n // 1. Clone - create the instance fragment\n // 2. Adopt - adopt into the main document\n // 3. Process - find part markers and create parts\n // 4. Upgrade - upgrade custom elements\n // 5. Update - set node, attribute, property, etc., values\n // 6. Connect - connect to the document. Optional and outside of this\n // method.\n //\n // We have a few constraints on the ordering of these steps:\n // * We need to upgrade before updating, so that property values will pass\n // through any property setters.\n // * We would like to process before upgrading so that we're sure that the\n // cloned fragment is inert and not disturbed by self-modifying DOM.\n // * We want custom elements to upgrade even in disconnected fragments.\n //\n // Given these constraints, with full custom elements support we would\n // prefer the order: Clone, Process, Adopt, Upgrade, Update, Connect\n //\n // But Safari does not implement CustomElementRegistry#upgrade, so we\n // can not implement that order and still have upgrade-before-update and\n // upgrade disconnected fragments. So we instead sacrifice the\n // process-before-upgrade constraint, since in Custom Elements v1 elements\n // must not modify their light DOM in the constructor. We still have issues\n // when co-existing with CEv0 elements like Polymer 1, and with polyfills\n // that don't strictly adhere to the no-modification rule because shadow\n // DOM, which may be created in the constructor, is emulated by being placed\n // in the light DOM.\n //\n // The resulting order is on native is: Clone, Adopt, Upgrade, Process,\n // Update, Connect. document.importNode() performs Clone, Adopt, and Upgrade\n // in one step.\n //\n // The Custom Elements v1 polyfill supports upgrade(), so the order when\n // polyfilled is the more ideal: Clone, Process, Adopt, Upgrade, Update,\n // Connect.\n const fragment = isCEPolyfill ?\n this.template.element.content.cloneNode(true) :\n document.importNode(this.template.element.content, true);\n const stack = [];\n const parts = this.template.parts;\n // Edge needs all 4 parameters present; IE11 needs 3rd parameter to be null\n const walker = document.createTreeWalker(fragment, 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */, null, false);\n let partIndex = 0;\n let nodeIndex = 0;\n let part;\n let node = walker.nextNode();\n // Loop through all the nodes and parts of a template\n while (partIndex < parts.length) {\n part = parts[partIndex];\n if (!isTemplatePartActive(part)) {\n this.__parts.push(undefined);\n partIndex++;\n continue;\n }\n // Progress the tree walker until we find our next part's node.\n // Note that multiple parts may share the same node (attribute parts\n // on a single element), so this loop may not run at all.\n while (nodeIndex < part.index) {\n nodeIndex++;\n if (node.nodeName === 'TEMPLATE') {\n stack.push(node);\n walker.currentNode = node.content;\n }\n if ((node = walker.nextNode()) === null) {\n // We've exhausted the content inside a nested template element.\n // Because we still have parts (the outer for-loop), we know:\n // - There is a template in the stack\n // - The walker will find a nextNode outside the template\n walker.currentNode = stack.pop();\n node = walker.nextNode();\n }\n }\n // We've arrived at our part's node.\n if (part.type === 'node') {\n const part = this.processor.handleTextExpression(this.options);\n part.insertAfterNode(node.previousSibling);\n this.__parts.push(part);\n }\n else {\n this.__parts.push(...this.processor.handleAttributeExpressions(node, part.name, part.strings, this.options));\n }\n partIndex++;\n }\n if (isCEPolyfill) {\n document.adoptNode(fragment);\n customElements.upgrade(fragment);\n }\n return fragment;\n }\n}\n//# sourceMappingURL=template-instance.js.map","/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * @module lit-html\n */\nimport { reparentNodes } from './dom.js';\nimport { boundAttributeSuffix, lastAttributeNameRegex, marker, nodeMarker } from './template.js';\n/**\n * Our TrustedTypePolicy for HTML which is declared using the html template\n * tag function.\n *\n * That HTML is a developer-authored constant, and is parsed with innerHTML\n * before any untrusted expressions have been mixed in. Therefor it is\n * considered safe by construction.\n */\nconst policy = window.trustedTypes &&\n trustedTypes.createPolicy('lit-html', { createHTML: (s) => s });\nconst commentMarker = ` ${marker} `;\n/**\n * The return type of `html`, which holds a Template and the values from\n * interpolated expressions.\n */\nexport class TemplateResult {\n constructor(strings, values, type, processor) {\n this.strings = strings;\n this.values = values;\n this.type = type;\n this.processor = processor;\n }\n /**\n * Returns a string of HTML used to create a `