{"version":3,"sources":["webpack://widget-subscriptions-add-to-cart/./src/events/selling-plan-changed.ts","webpack://widget-subscriptions-add-to-cart/./src/models/buy-once.ts","webpack://widget-subscriptions-add-to-cart/./src/models/price-adjustments.ts","webpack://widget-subscriptions-add-to-cart/./src/models/selling-plan-allocation.ts","webpack://widget-subscriptions-add-to-cart/./src/services/event-bus/widget-event-bus.ts","webpack://widget-subscriptions-add-to-cart/./src/services/event-bus/event-bus.ts","webpack://widget-subscriptions-add-to-cart/./src/services/hooks.ts","webpack://widget-subscriptions-add-to-cart/./src/store/customizations/index.ts","webpack://widget-subscriptions-add-to-cart/./src/store/product/getters.ts","webpack://widget-subscriptions-add-to-cart/./src/store/product/index.ts","webpack://widget-subscriptions-add-to-cart/./src/store/selling-plans/getters.ts","webpack://widget-subscriptions-add-to-cart/./src/store/selling-plans/index.ts","webpack://widget-subscriptions-add-to-cart/./node_modules/color-name/index.js","webpack://widget-subscriptions-add-to-cart/./node_modules/mustache/mustache.js","webpack://widget-subscriptions-add-to-cart/webpack/bootstrap","webpack://widget-subscriptions-add-to-cart/webpack/runtime/define property getters","webpack://widget-subscriptions-add-to-cart/webpack/runtime/hasOwnProperty shorthand","webpack://widget-subscriptions-add-to-cart/./src/utils/url.ts","webpack://widget-subscriptions-add-to-cart/./src/utils/element.ts","webpack://widget-subscriptions-add-to-cart/./src/customizations/customizations.ts","webpack://widget-subscriptions-add-to-cart/./src/models/dummy-product.ts","webpack://widget-subscriptions-add-to-cart/./src/customizations/widget-customizations.ts","webpack://widget-subscriptions-add-to-cart/./src/render/render.ts","webpack://widget-subscriptions-add-to-cart/./src/utils/ajax.ts","webpack://widget-subscriptions-add-to-cart/./src/container/widgets-container.ts","webpack://widget-subscriptions-add-to-cart/./src/services/shopify.ts","webpack://widget-subscriptions-add-to-cart/./src/render/components/subscription-policy.ts","webpack://widget-subscriptions-add-to-cart/./src/render/components/widgets/template-builder.ts","webpack://widget-subscriptions-add-to-cart/./src/models/price-format.ts","webpack://widget-subscriptions-add-to-cart/./src/render/components/widgets/price-label.ts","webpack://widget-subscriptions-add-to-cart/./src/utils/color.ts","webpack://widget-subscriptions-add-to-cart/./src/utils/colors.ts","webpack://widget-subscriptions-add-to-cart/./src/store/merchant/index.ts","webpack://widget-subscriptions-add-to-cart/./src/store/view/index.ts","webpack://widget-subscriptions-add-to-cart/./src/store/view/actions.ts","webpack://widget-subscriptions-add-to-cart/./src/services/injection/injection.ts","webpack://widget-subscriptions-add-to-cart/./src/utils/retry.ts","webpack://widget-subscriptions-add-to-cart/./src/services/analytics/yotpo-analytics.ts","webpack://widget-subscriptions-add-to-cart/./src/services/analytics/events.ts","webpack://widget-subscriptions-add-to-cart/./src/store/selling-plans/actions.ts","webpack://widget-subscriptions-add-to-cart/./src/render/components/layout.ts","webpack://widget-subscriptions-add-to-cart/./src/render/components/widgets/discount.ts","webpack://widget-subscriptions-add-to-cart/./src/services/sort/frequency.ts","webpack://widget-subscriptions-add-to-cart/./src/services/sort/name.ts","webpack://widget-subscriptions-add-to-cart/./src/services/sort/selling-plans.ts","webpack://widget-subscriptions-add-to-cart/./src/services/sort/price.ts","webpack://widget-subscriptions-add-to-cart/./src/store/view/getters.ts","webpack://widget-subscriptions-add-to-cart/./src/render/components/radio-buttons.ts","webpack://widget-subscriptions-add-to-cart/./src/render/templates/radio-template.ts","webpack://widget-subscriptions-add-to-cart/./src/render/components/widgets/selection-factory.ts","webpack://widget-subscriptions-add-to-cart/./src/render/templates/dropdown-template.ts","webpack://widget-subscriptions-add-to-cart/./src/render/templates/frequency-template.ts","webpack://widget-subscriptions-add-to-cart/./src/render/components/widgets/selection-builder.ts","webpack://widget-subscriptions-add-to-cart/./src/render/components/widgets/tiles-label.ts","webpack://widget-subscriptions-add-to-cart/./src/render/components/tile-buttons.ts","webpack://widget-subscriptions-add-to-cart/./src/store/customizations/getters.ts","webpack://widget-subscriptions-add-to-cart/./src/render/templates/tiles-template.ts","webpack://widget-subscriptions-add-to-cart/./src/render/components/subscription-benefits.ts","webpack://widget-subscriptions-add-to-cart/./src/render/components/product.ts","webpack://widget-subscriptions-add-to-cart/./src/render/components/widgets/template-factory.ts","webpack://widget-subscriptions-add-to-cart/./src/events/product-price-changed.ts","webpack://widget-subscriptions-add-to-cart/./src/services/variants/variants.ts","webpack://widget-subscriptions-add-to-cart/./src/store/product/actions.ts","webpack://widget-subscriptions-add-to-cart/./src/render/components/live-preview.ts","webpack://widget-subscriptions-add-to-cart/./src/widget.ts","webpack://widget-subscriptions-add-to-cart/./src/store/merchant/actions.ts","webpack://widget-subscriptions-add-to-cart/./src/store/customizations/actions.ts","webpack://widget-subscriptions-add-to-cart/./src/index.ts"],"names":["eventName","subscribeToSellingPlanChangedEvent","callback","getOrCreateEventBus","subscribe","publishSellingPlanChangedEvent","args","publish","name","buyOnceId","shouldShowBuyOnce","getProduct","requiresSellingPlan","isBuyOnceId","id","toLowerCase","isBuyOneSellingPlan","getBuyOnceAsSellingPlanGroup","widgetState","options","sellingPlans","getBuyOnceAsSellingPlan","description","priceAdjustments","getPriceAdjustmentLabel","priceAdjustment","currrencySymbol","priceAdjustmentType","currencySymbol","valueType","getPriceAdjustmentValueType","priceAdjustmentValue","value","parseFloat","getPriceAdjustmentValue","toFixed","toString","getPriceAdjustmentValueForDisplay","getLowestDiscountByGroupForVariant","groupId","productState","getProductPrice","defaultVariantAllocation","allocation","price","sort","alloc1","alloc2","getSellingPlanAllocationForVariant","planId","sellingPlanId","WidgetEventBus","logErrors","this","subscriptions","Map","getRandomId","eventSubscriptions","get","set","unsubscribe","delete","publisher","forEach","error","console","Math","random","substr","currentWindow","window","eventBus","yotpoWidgetsContainer","yotpo_event_bus","newEventBus","hooksCustomizatioKeyPrefix","sellingPlanChangedHookInit","isBuyOnce","selectedSellingPlanGroup","getSellingPlanGroup","selectedGroupId","selectedSellingPlan","find","plan","selectedSellingPlanId","eval","fireWidgetReadyHook","customizations","isReadOnly","isPreview","isLaunched","isDresser","allowOutOfForm","livePreview","show","widgetMarkingStrategy","topBar","headerText","helpText","backgroundColor","backgroundOpacity","fontColor","ctaLinkPath","ctaText","closeButtonTextColor","closeButtonBackgroundColor","closeButtonText","isDummy","variantDetection","selector","attribute","autoPickOptionIndex","oneTimeAtLast","productHandle","storefrontTheme","buyOnceText","showGetItText","getItText","showDiscount","strategy","promotionLine","text","loyalty","reward","pointsRatio","tiles","borderColor","borderStyle","borderSize","fullPriceText","suffixText","tileHeight","oddSpread","selectionType","autoInject","enabled","targetSelector","adjacentStrategy","fullFormatProductPrice","priceLabel","prefix","percentSymbolLocation","currency","rate","roundUp","subscriptionPolicy","shouldShow","footer","informationLink","subscriptionBenefits","list","styles","notSelectedRadio","selectedRadio","backgroundImageUrl","dropdownBorderColor","dropdownBackgroundColor","dropdownHoverColor","openByDefault","radioButton","innerColor","outerColor","fontFamily","weight","url","fontSize","primary","colors","hooks","widgetReady","sellingPlanChanged","getCurrentVariant","getDefaultVariant","variants","slice","product","currentVariant","getSellingPlanGroups","variantSellingPlanGroupIds","sellingPlanAllocations","map","s","sellingPlansState","filter","x","indexOf","getSelectedGroupId","getSelectedSellingPlanId","group","getSelectedSellingPlanGroupId","getSelectedSellingPlanGroup","getDiscountedPrice","sellingPlanGroups","selectedSellingPlanGroupId","module","exports","objectToString","Object","prototype","isArray","Array","object","call","isFunction","escapeRegExp","string","replace","hasProperty","obj","propName","regExpTest","RegExp","test","nonSpaceRe","isWhitespace","re","testRegExp","entityMap","whiteRe","spaceRe","equalsRe","curlyRe","tagRe","Scanner","tail","pos","Context","view","parentContext","cache","parent","Writer","templateCache","_cache","key","clear","eos","scan","match","index","substring","length","scanUntil","search","push","lookup","primitive","hasOwnProperty","intermediateValue","names","context","lookupHit","split","clearCache","parse","template","tags","cacheKey","mustache","join","isCacheEnabled","tokens","undefined","openingTagRe","closingTagRe","closingCurlyRe","lineHasNonSpace","sections","spaces","hasTag","nonSpace","indentation","tagIndex","stripSpace","pop","compileTags","tagsToCompile","Error","start","type","chr","token","openSection","scanner","i","valueLength","charAt","nestedTokens","collector","numTokens","nestTokens","lastToken","squashedTokens","squashTokens","parseTemplate","render","partials","config","getConfigTags","renderTokens","originalTemplate","symbol","buffer","renderSection","renderInverted","renderPartial","unescapedValue","escapedValue","rawValue","self","j","indentPartial","partial","filteredIndentation","partialByNl","indentedValue","escape","getConfigEscape","String","version","defaultWriter","TypeError","factory","__webpack_module_cache__","__webpack_require__","moduleId","__webpack_modules__","d","definition","o","defineProperty","enumerable","prop","getQueryParams","queryString","location","params","indexQuery","indexPair","queryKey","decodeURIComponent","queryValue","buildElement","klass","attributes","element","document","createElement","setAttribute","setAttributesOnElement","keys","buildStyle","getHtmlElementByClassName","className","getElementsByClassName","isBlocked","getBoolean","getBooleanWithDefault","defaultValue","getNumber","parseInt","getFloatWithDefault","getFontFamily","values","getPixel","getHook","warn","getTextArrayWithDefault","delimeter","source","sanitizeHtml","renderMainElement","isAdmin","clearStyle","fontStyle","href","rel","getElementsByTagName","appendChild","innerHTML","clearStyles","getPriceAdjustment","getSellingPlan","groupName","dummyPriceAdjustment","position","getSellingPlanAllocations","dummyGroupName","dummyPriceAdjustment1","dummyPriceAdjustment2","dummyPriceAdjustment3","dummySellingPlanAllocations","dummyVariants","title","dummySellingGroups","p","checkStatus","response","status","statusText","parseJSON","json","isContainerDefined","adaptSellingPlan","sellingPlansResponse","resolvePriceAdjustments","price_adjustments","value_type","adaptSellingPlanAllocations","sellingPlanAllocation","selling_plan_group_id","selling_plan_id","getPriceWithCurrency","adaptVariants","variantsResponse","selling_plan_allocations","isYotpoSellingPlanGroup","sellingPlanGroupResponse","app_id","adaptProductResponse","handle","requires_selling_plan","selling_plan_groups","selling_plans","priceVaries","price_varies","isInShopifyDesignMode","Shopify","designMode","getCurrencyRate","roundUpCurrency","getCurrency","ceil","active","openSubscriptionPolicies","style","display","getTextHeader","textHeader","addEventListener","getMainText","textMain","textContent","getTextFooter","defaultInformationLink","origin","textFooter","target","selectedLabel","querySelector","getStyles","buildTemplate","html","Mustache","checkedFn","checked","checkedClassFn","classString","displaySelectedElement","querySelectorAll","isClickedOn","getAttribute","inputEl","pickElement","currnectClass2","getPriceCurrencySymbol","priceFormat","getWithCurrencySymbol","priceWithDecimal","getWithDecimal","priceFormatCurrencyPosition","Number","isInteger","formatPrice","decimalFormat","wrapperElementClass","buildPriceLabel","isSubscription","isSelected","wrapperElement","containerElement","shouldShowPrefix","pricePrefixElement","priceElement","getPrice","fullPriceWithCurrency","getSelectedPriceForGroup","Color","colorString","trim","parts","ColorUtils","getRgbaParts","r","g","b","a","roundedA","colorParts","require","tintRate","calculateTintValue","colorValue","getHexFromRgbParts","hexColor","convertRgbaToHex","getContrastColorFromHex","hexcolor","rgbaColor","color","opacity","c","toRgba","merchantState","guid","viewState","mainElement","formId","setMainElement","formSelector","getFormElement","injectionTargetElement","getInjectionTargetElement","parentNode","nodeName","parentElement","getAutoInjectSelector","isElementExists","findInElement","injectIntoPlaceholder","currentElement","replaceChild","isElementInForm","isForm","parentSelector","selectorsPriority","isTargetSet","formPlace","hostElements","retryWithTimeout","action","interval","retryCount","reject","checker","resolve","do","setTimeout","reportingEndPoints","YotpoAnalytics","event","Promise","doTrack","doGetUniqueUserIdentifier","retryInterval","doGetUserId","isYotpoAnalyticsExists","data","Analytics","getAnalyticsService","trackEvent","category","label","property","userSettings","reporting_end_points","getAnalyticsVersion","getUserSetting","getAppKey","analyticsController","getController","getDomainUserId","dispatchEvent","shouldSendAnalytics","productPageEvent","getDurationStats","performance","getEntriesByName","widgetEnd","now","initStart","durationFromInit","round","startTime","durationFromDomLoadedEvent","timing","domLoaded","domContentLoadedEventStart","navigationStart","time_from_init_start","time_from_dom_loaded","setSellingPlanChange","productId","isDiscountAvailable","sellingPlanGroupId","product_id","selected_group_id","live_preview","getSellingPlansMainElementWrapper","isPreviewClass","isAdminClass","getSellingPlansMainElement","appendElementsInOrder","buyOnceElement","append","getSelectedGroupIndex","groupsHasAnyDiscount","some","getDiscountLabel","firstPriceAdjusment","formatLabelWithDiscount","formatLabelWithoutDiscount","priceAdjustmentLabel","labelSuffix","sortingByFrequency","plan1","plan2","getCountInDays","count","getIntervalDays","countStr","typeStr","intervalCount","intervalType","getIntervalType","getIntervalCountInDays","namePart","sortingByName","sortStrategy","sortingByPrice","getFormId","RadioButtons","sellingPlanGroupElements","buildSellingPlanGroupElement","buildBuyOnce","expandGroupOnAutoSelectedIndex","mainElementWrapper","container","radioElementsWrapper","groupsTemplate","inputAttributes","frequencyTemplate","getWithOpacity","selectionFactory","sortingStrategy","frequencyTemplateElement","innerElement","targetElement","sellingPlanName","classList","add","remove","markSelectedFrequencyLabel","labelForSelection","innerText","buildSelection","getSellingPlanLabel","setElementClassForChangeEvent","registerToElementChangeEvent","dropdownEl","blur","parentInput","radioStyle","buyOnceGroup","selectedIndex","groupByIndex","sellingPlan","discountLabel","buildTilesLabel","hasAnyDiscount","discountPrice","discountElement","discountLabelStyle","TileButtons","sellingPlanElements","sellingPlansCounter","buildSellingPlanElement","variables","loyaltyPoints","promotionLineElement","floor","variable","registerForLabelClick","getOddSpreadCss","getBackgroundColorWithOpacity","buyOncePlan","click","opacityLevel","toHex","benefitsList","benefit","benefitItem","benefitItemText","getWrapperBackgroundColor","isWrapper","renderProduct","selectedTemplate","templateFactory","wrapper","main","getSubscriptionBenefitsElement","containerClass","renderSubscriptionBenefits","getSubscriptionPolicyElement","renderSubscriptionPolicy","replacePrices","groups","buyOnce","priceWrapElement","newPriceElement","replaceWith","replacePriceElementTiles","getVariantIdFromForm","variantIdFormSelector","idElement","getIdValue","elementAttribute","getVariantIdFromUrlParam","queryParams","variant","setProductPrice","setCurrentVariant","variantId","defaultVariant","v","renderLivePreview","topBarElement","topBarStyle","contentContainerElement","yotpoLogo","src","textContainerElement","headerTextElement","buildTextContainer","closeButtonElement","close","buildCloseButtonElement","ctaButtonElement","onClickLink","ctaButtonWrapperElement","previewEvent","buildCtaButtonElement","head","getTopBarElement","renderTopBar","link","cta_link","SubscriptionsAddToCartWidget","widgetOptions","merchantData","instanceId","metadata","instanceVersionId","urlParams","elementAttributes","overridenCustomizations","filterUrlParams","atts","n","nodeValue","getElementAttributes","getWidgetCustomizations","setCustomizations","shouldRenderWidget","isInStore","isOutOfFormAllowed","autoInjectSelector","autoInjectSelectorElement","isButtonOrInput","getAdjacentStrategy","insertAdjacentElement","removeChild","injectWidget","loadedEvent","widget_instance_id","instance_version_id","then","currentVariantId","setProduct","formElement","form","setFormId","initEventsAndHooks","should_be_shown","is_launched","dispatchLoadedEvent","setInterval","initWidgets","clearInterval","ensureWidgetInEditorMode","fetch","addToCartForm","val","mainElementContainer","newMainElement","ex","checkVariantChange","error_msg","inOnPreview","log"],"mappings":"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","file":"app.js","sourcesContent":["import { getOrCreateEventBus, Publisher, Subscription } from '../services/event-bus/event-bus'\n\nexport interface SellingPlanChangedEventArgs {\n selectedGroupId: string\n selectedSellingPlanId: string\n isBuyOnce: boolean\n}\n\ntype SellingPlanChangedCallback = (publisher: Publisher, args: SellingPlanChangedEventArgs) => void;\nconst eventName = 'v1/selling_plan_changed'\n\nexport const subscribeToSellingPlanChangedEvent = (callback: SellingPlanChangedCallback): Subscription => {\n const eventBus = getOrCreateEventBus()\n return eventBus.subscribe(eventName, callback)\n}\nexport const publishSellingPlanChangedEvent = (args: SellingPlanChangedEventArgs): void => {\n const eventBus = getOrCreateEventBus()\n const publisher = { name: 'add-to-cart-widget' }\n return eventBus.publish(eventName, publisher, args)\n}\n","import { SellingPlan } from './selling-plan'\nimport { SellingPlanGroup } from './selling-plan-group'\nimport { widgetState } from '../store/customizations/index'\nimport { getProduct } from '../store/product/getters'\n\nexport const buyOnceId = 'buy-once'\nconst buyOnceSellingPlanId = 0\n\nexport const shouldShowBuyOnce = () => {\n return !getProduct().requiresSellingPlan\n}\n\nexport const isBuyOnceId = (id: string): boolean => {\n if (!id) {\n return false\n }\n return id.toLowerCase() === buyOnceId\n}\n\nexport const isBuyOneSellingPlan = (id: number): boolean => {\n return id === buyOnceSellingPlanId\n}\n\nexport const getBuyOnceAsSellingPlanGroup = (): SellingPlanGroup => {\n return {\n id: buyOnceId,\n name: widgetState.customizations.buyOnceText,\n options: [],\n sellingPlans: []\n }\n}\n\nexport const getBuyOnceAsSellingPlan = (): SellingPlan => {\n return {\n id: buyOnceSellingPlanId,\n name: widgetState.customizations.buyOnceText,\n options: [],\n description: '',\n priceAdjustments: []\n }\n}\n","import { widgetState } from '../store/customizations/index'\nimport { SellingPlanGroup } from './selling-plan-group'\n\nexport type DiscountType = 'percentage' | 'fixed_amount'\n\nexport interface PriceAdjustment {\n valueType: DiscountType\n value: number\n}\n\nexport function getPriceAdjustmentValueType (priceAdjustment: PriceAdjustment, currencySymbol: string): string | undefined {\n if (priceAdjustment) {\n return priceAdjustment.valueType === 'fixed_amount' ? currencySymbol : '%'\n }\n}\n\nexport function getPriceAdjustmentValue (priceAdjustment: PriceAdjustment): number | undefined {\n if (priceAdjustment) {\n const priceAdjustmentValue = priceAdjustment.valueType === 'percentage' ? priceAdjustment.value : priceAdjustment.value * 0.01\n return typeof (priceAdjustmentValue) === 'string' ? parseFloat(priceAdjustmentValue) : priceAdjustmentValue\n }\n}\n\nexport function getPriceAdjustmentValueForDisplay (priceAdjustment: PriceAdjustment): string {\n const priceAdjustmentValue = getPriceAdjustmentValue(priceAdjustment)\n if (priceAdjustmentValue) {\n if (priceAdjustmentValue % 1 !== 0) {\n return priceAdjustmentValue.toFixed(2)\n }\n return priceAdjustmentValue.toString()\n }\n return ''\n}\n\nexport function getPriceAdjustmentLabel (priceAdjustment: PriceAdjustment, currrencySymbol: string): string {\n if (priceAdjustment) {\n const priceAdjustmentType = getPriceAdjustmentValueType(priceAdjustment, currrencySymbol)\n const priceAdjustmentValue = getPriceAdjustmentValueForDisplay(priceAdjustment)\n if (priceAdjustmentType === currrencySymbol) {\n return `${priceAdjustmentType}${priceAdjustmentValue}`\n }\n if (widgetState.customizations.priceLabel.percentSymbolLocation === 'left') {\n return `${priceAdjustmentType}${priceAdjustmentValue}`\n }\n return `${priceAdjustmentValue}${priceAdjustmentType}`\n }\n}\n\nexport function sortPriceAdjustments (sellingPlanGroups: SellingPlanGroup[], selectedGroupId: string, price: number): PriceAdjustment[] {\n const selectedSellingPlanGroup = sellingPlanGroups.find(group => group.id === selectedGroupId)\n\n if (selectedSellingPlanGroup) {\n const priceAdjustments: PriceAdjustment[] = selectedSellingPlanGroup.sellingPlans\n .filter(plan => plan.priceAdjustments && plan.priceAdjustments.length > 0)\n .map(plan => {\n return plan.priceAdjustments[0]\n })\n .sort((plan1, plan2) => {\n return getValue(plan1.value, plan1.valueType, price) - getValue(plan2.value, plan2.valueType, price)\n })\n\n return priceAdjustments.length > 0 ? priceAdjustments : [{ valueType: 'fixed_amount', value: 0 }]\n }\n\n return []\n}\n\nconst getValue = (value: number, type: DiscountType, price: number): number => {\n if (type === 'fixed_amount') {\n return price - value\n }\n return price - (price * (value / 100))\n}\n","import { isBuyOnceId } from './buy-once'\nimport { getProductPrice } from '../store/product/getters'\nimport { productState } from '../store/product/index'\n\nexport interface SellingPlanAllocation {\n groupId: string\n sellingPlanId: number\n price: number\n}\n\nexport const getLowestDiscountByGroupForVariant = (groupId: string): number => {\n if (!productState.currentVariant) {\n return getProductPrice()\n }\n const defaultVariantAllocation = productState.currentVariant.sellingPlanAllocations\n .filter(allocation => allocation.groupId === groupId && allocation.price > 0)\n .sort((alloc1, alloc2) => {\n return alloc1.price - alloc2.price\n })\n return defaultVariantAllocation[0] ? defaultVariantAllocation[0].price : getProductPrice()\n}\n\nexport const getSellingPlanAllocationForVariant = (groupId: string, planId: number): number => {\n if (!productState.currentVariant) {\n return getProductPrice()\n }\n if (isBuyOnceId(groupId)) {\n return productState.currentVariant.price\n }\n const defaultVariantAllocation = productState.currentVariant.sellingPlanAllocations.find(allocation =>\n allocation.groupId === groupId &&\n allocation.sellingPlanId === planId &&\n allocation.price > 0)\n return defaultVariantAllocation ? defaultVariantAllocation.price : getProductPrice()\n}\n","import { EventBus, EventName, Callback, Subscription, Publisher } from './event-bus'\n\ntype SubscriptionId = string;\ntype EventSubscriptions = Map\n\nexport default class WidgetEventBus implements EventBus {\n private subscriptions: Map\n private logErrors: boolean\n\n public constructor (logErrors: boolean) {\n this.subscriptions = new Map()\n this.logErrors = logErrors\n }\n\n public subscribe (eventName: EventName, callback: Callback): Subscription {\n const id = this.getRandomId()\n\n let eventSubscriptions = this.subscriptions.get(eventName)\n if (!eventSubscriptions) {\n eventSubscriptions = new Map()\n this.subscriptions.set(eventName, eventSubscriptions)\n }\n\n eventSubscriptions.set(id, callback)\n\n const subscription: Subscription = {\n eventName: eventName,\n callback: callback,\n unsubscribe: (): void => {\n if (eventSubscriptions) {\n eventSubscriptions.delete(id)\n }\n }\n }\n return subscription\n }\n\n public publish (eventName: EventName, publisher: Publisher, ...args: any[]): void {\n const eventSubscriptions = this.subscriptions.get(eventName)\n if (!eventSubscriptions) {\n return\n }\n\n eventSubscriptions.forEach((callback: Callback): void => {\n try {\n callback(publisher, ...args)\n } catch (error) {\n if (this.logErrors) {\n console.error(error)\n }\n }\n })\n }\n\n private getRandomId (): string {\n return Math.random().toString(36).substr(2, 9)\n }\n}\n","import WidgetEventBus from './widget-event-bus'\n\nexport type EventName = string;\nexport interface Publisher {\n name: string;\n}\nexport type Callback = (publisher: Publisher, ...args: any[]) => void;\nexport interface Subscription {\n eventName: EventName;\n callback: Callback;\n unsubscribe: () => void;\n}\n\nexport interface EventBus {\n subscribe(eventName: EventName, callback: Callback): Subscription;\n publish(eventName: EventName, publisher: Publisher, ...args: any[]): void;\n}\n\n// eslint-disable-next-line import/prefer-default-export\nexport const getOrCreateEventBus = (): EventBus => {\n const currentWindow: any = window\n const eventBus = currentWindow.yotpoWidgetsContainer.yotpo_event_bus\n if (eventBus) {\n return eventBus as EventBus\n }\n\n const newEventBus = new WidgetEventBus(true)\n currentWindow.yotpoWidgetsContainer.yotpo_event_bus = newEventBus\n return newEventBus\n}\n","import { SellingPlanChangedEventArgs, subscribeToSellingPlanChangedEvent } from '../events/selling-plan-changed'\nimport { widgetState } from '../store/customizations/index'\nimport { getSellingPlanGroup } from '../store/selling-plans/getters'\nimport { Publisher } from './event-bus/event-bus'\n\nexport const hooksCustomizatioKeyPrefix = 'hooks-'\n\nexport const sellingPlanChangedHookInit = () => {\n subscribeToSellingPlanChangedEvent((publisher: Publisher, args: SellingPlanChangedEventArgs) => {\n const isBuyOnce = args.isBuyOnce // eslint-disable-line no-unused-vars\n const selectedSellingPlanGroup = getSellingPlanGroup(args.selectedGroupId)\n const selectedSellingPlan = selectedSellingPlanGroup && selectedSellingPlanGroup.sellingPlans // eslint-disable-line no-unused-vars\n ? selectedSellingPlanGroup.sellingPlans.find(plan => plan.id.toString() === args.selectedSellingPlanId) // eslint-disable-line no-unused-vars\n : null\n eval(widgetState.customizations.hooks.sellingPlanChanged) // eslint-disable-line no-eval\n })\n}\n\nexport const fireWidgetReadyHook = () => {\n eval(widgetState.customizations.hooks.widgetReady) // eslint-disable-line no-eval\n}\n","import { WidgetCustomizationsState } from './types'\n\nexport const widgetState: WidgetCustomizationsState = {\n customizations: {\n isReadOnly: false,\n isPreview: false,\n isLaunched: false,\n isDresser: false,\n allowOutOfForm: false,\n livePreview: {\n show: false,\n widgetMarkingStrategy: '',\n topBar: {\n headerText: '',\n helpText: '',\n backgroundColor: '',\n backgroundOpacity: 0,\n fontColor: '',\n ctaLinkPath: '',\n ctaText: '',\n closeButtonTextColor: '',\n closeButtonBackgroundColor: '',\n closeButtonText: ''\n }\n },\n isDummy: false,\n variantDetection: {\n selector: 'form [name=\"id\"]',\n attribute: ''\n },\n autoPickOptionIndex: 0,\n oneTimeAtLast: false,\n productHandle: '',\n storefrontTheme: '',\n buyOnceText: '',\n showGetItText: false,\n getItText: '',\n sellingPlans: {\n showDiscount: true,\n sort: {\n strategy: 'name'\n },\n promotionLine: {\n show: false,\n text: ''\n }\n },\n loyalty: {\n reward: {\n pointsRatio: 1\n }\n },\n tiles: {\n borderColor: '',\n borderStyle: '',\n borderSize: '',\n backgroundColor: '',\n fontColor: '',\n fullPriceText: '',\n suffixText: '',\n tileHeight: '',\n oddSpread: false\n },\n selectionType: '',\n autoInject: {\n enabled: false,\n targetSelector: '',\n adjacentStrategy: 'beforebegin'\n },\n fullFormatProductPrice: '',\n priceLabel: {\n prefix: '',\n strategy: 'starting_and_actual',\n percentSymbolLocation: 'right',\n currency: {\n enabled: false,\n name: '',\n rate: 1.0,\n roundUp: false\n }\n },\n subscriptionPolicy: {\n shouldShow: false,\n description: '',\n footer: '',\n informationLink: ''\n },\n subscriptionBenefits: {\n shouldShow: false,\n list: []\n },\n styles: {\n notSelectedRadio: {\n backgroundColor: ''\n },\n selectedRadio: {\n borderColor: '',\n borderStyle: '',\n borderSize: '',\n backgroundColor: '',\n backgroundImageUrl: '',\n dropdownBorderColor: '',\n dropdownBackgroundColor: '',\n dropdownHoverColor: '',\n openByDefault: true\n },\n radioButton: {\n innerColor: '',\n outerColor: ''\n },\n fontFamily: {\n name: '',\n weight: '',\n url: ''\n },\n fontSize: {\n primary: '',\n sellingPlans: {\n name: '',\n options: ''\n }\n },\n colors: {\n text: {\n primary: ''\n }\n }\n },\n hooks: {\n widgetReady: '',\n sellingPlanChanged: ''\n }\n }\n}\n","import { Product } from '../../models/product'\nimport { Variant } from '../../models/variant'\nimport { productState } from './index'\n\nexport const getProduct = (): Product => {\n return {\n ...productState.product\n }\n}\n\nexport const getVariants = (): Variant[] => {\n const product = getProduct()\n return product.variants.slice(0)\n}\n\nexport const getCurrentVariant = (): Variant => {\n return {\n ...productState.currentVariant\n }\n}\n\nexport const getDefaultVariant = (): Variant => {\n const variants = getVariants()\n return variants[0]\n}\n\nexport const getProductPrice = (): number => {\n return productState.product.price\n}\n\nexport const getVariant = (variantId: number): Variant | undefined => {\n const variant = getProduct().variants.find(v => v.id === variantId)\n return {\n ...variant\n }\n}\n","import { ProductState } from './types'\n\nexport const productState: ProductState = {\n product: null,\n currentVariant: null\n}\n","import { getSellingPlanAllocationForVariant } from '../../models/selling-plan-allocation'\nimport { SellingPlanGroup } from '../../models/selling-plan-group'\nimport { getCurrentVariant, getProductPrice } from '../product/getters'\nimport { sellingPlansState } from './index'\n\nexport const getSellingPlanGroups = (): SellingPlanGroup[] => {\n const variant = getCurrentVariant()\n const variantSellingPlanGroupIds = variant.sellingPlanAllocations.map(s => s.groupId)\n return sellingPlansState.sellingPlanGroups.slice(0).filter(x => variantSellingPlanGroupIds.indexOf(x.id) >= 0)\n}\n\nexport const getSelectedGroupId = (): string => {\n return sellingPlansState.selectedSellingPlanGroupId\n}\n\nexport const getSelectedSellingPlanId = (): string => {\n return sellingPlansState.selectedSellingPlanId\n}\n\nexport const getSellingPlanGroup = (id: string): SellingPlanGroup => {\n const group = sellingPlansState.sellingPlanGroups.find(group => group.id === id)\n return {\n ...group\n }\n}\n\nexport const getSelectedSellingPlanGroupId = (): string => {\n return sellingPlansState.selectedSellingPlanGroupId\n}\n\nexport const getSelectedSellingPlanGroup = (): SellingPlanGroup => {\n return getSellingPlanGroup(sellingPlansState.selectedSellingPlanGroupId)\n}\n\nexport const getDiscountedPrice = (groupId: string, planId: number): number => {\n const discountPrice = getSellingPlanAllocationForVariant(groupId, planId)\n return discountPrice || getProductPrice()\n}\n","import { SellingPlansState } from './types'\n\nexport const sellingPlansState: SellingPlansState = {\n sellingPlanGroups: [],\n selectedSellingPlanGroupId: '',\n selectedSellingPlanId: ''\n}\n","'use strict'\r\n\r\nmodule.exports = {\r\n\t\"aliceblue\": [240, 248, 255],\r\n\t\"antiquewhite\": [250, 235, 215],\r\n\t\"aqua\": [0, 255, 255],\r\n\t\"aquamarine\": [127, 255, 212],\r\n\t\"azure\": [240, 255, 255],\r\n\t\"beige\": [245, 245, 220],\r\n\t\"bisque\": [255, 228, 196],\r\n\t\"black\": [0, 0, 0],\r\n\t\"blanchedalmond\": [255, 235, 205],\r\n\t\"blue\": [0, 0, 255],\r\n\t\"blueviolet\": [138, 43, 226],\r\n\t\"brown\": [165, 42, 42],\r\n\t\"burlywood\": [222, 184, 135],\r\n\t\"cadetblue\": [95, 158, 160],\r\n\t\"chartreuse\": [127, 255, 0],\r\n\t\"chocolate\": [210, 105, 30],\r\n\t\"coral\": [255, 127, 80],\r\n\t\"cornflowerblue\": [100, 149, 237],\r\n\t\"cornsilk\": [255, 248, 220],\r\n\t\"crimson\": [220, 20, 60],\r\n\t\"cyan\": [0, 255, 255],\r\n\t\"darkblue\": [0, 0, 139],\r\n\t\"darkcyan\": [0, 139, 139],\r\n\t\"darkgoldenrod\": [184, 134, 11],\r\n\t\"darkgray\": [169, 169, 169],\r\n\t\"darkgreen\": [0, 100, 0],\r\n\t\"darkgrey\": [169, 169, 169],\r\n\t\"darkkhaki\": [189, 183, 107],\r\n\t\"darkmagenta\": [139, 0, 139],\r\n\t\"darkolivegreen\": [85, 107, 47],\r\n\t\"darkorange\": [255, 140, 0],\r\n\t\"darkorchid\": [153, 50, 204],\r\n\t\"darkred\": [139, 0, 0],\r\n\t\"darksalmon\": [233, 150, 122],\r\n\t\"darkseagreen\": [143, 188, 143],\r\n\t\"darkslateblue\": [72, 61, 139],\r\n\t\"darkslategray\": [47, 79, 79],\r\n\t\"darkslategrey\": [47, 79, 79],\r\n\t\"darkturquoise\": [0, 206, 209],\r\n\t\"darkviolet\": [148, 0, 211],\r\n\t\"deeppink\": [255, 20, 147],\r\n\t\"deepskyblue\": [0, 191, 255],\r\n\t\"dimgray\": [105, 105, 105],\r\n\t\"dimgrey\": [105, 105, 105],\r\n\t\"dodgerblue\": [30, 144, 255],\r\n\t\"firebrick\": [178, 34, 34],\r\n\t\"floralwhite\": [255, 250, 240],\r\n\t\"forestgreen\": [34, 139, 34],\r\n\t\"fuchsia\": [255, 0, 255],\r\n\t\"gainsboro\": [220, 220, 220],\r\n\t\"ghostwhite\": [248, 248, 255],\r\n\t\"gold\": [255, 215, 0],\r\n\t\"goldenrod\": [218, 165, 32],\r\n\t\"gray\": [128, 128, 128],\r\n\t\"green\": [0, 128, 0],\r\n\t\"greenyellow\": [173, 255, 47],\r\n\t\"grey\": [128, 128, 128],\r\n\t\"honeydew\": [240, 255, 240],\r\n\t\"hotpink\": [255, 105, 180],\r\n\t\"indianred\": [205, 92, 92],\r\n\t\"indigo\": [75, 0, 130],\r\n\t\"ivory\": [255, 255, 240],\r\n\t\"khaki\": [240, 230, 140],\r\n\t\"lavender\": [230, 230, 250],\r\n\t\"lavenderblush\": [255, 240, 245],\r\n\t\"lawngreen\": [124, 252, 0],\r\n\t\"lemonchiffon\": [255, 250, 205],\r\n\t\"lightblue\": [173, 216, 230],\r\n\t\"lightcoral\": [240, 128, 128],\r\n\t\"lightcyan\": [224, 255, 255],\r\n\t\"lightgoldenrodyellow\": [250, 250, 210],\r\n\t\"lightgray\": [211, 211, 211],\r\n\t\"lightgreen\": [144, 238, 144],\r\n\t\"lightgrey\": [211, 211, 211],\r\n\t\"lightpink\": [255, 182, 193],\r\n\t\"lightsalmon\": [255, 160, 122],\r\n\t\"lightseagreen\": [32, 178, 170],\r\n\t\"lightskyblue\": [135, 206, 250],\r\n\t\"lightslategray\": [119, 136, 153],\r\n\t\"lightslategrey\": [119, 136, 153],\r\n\t\"lightsteelblue\": [176, 196, 222],\r\n\t\"lightyellow\": [255, 255, 224],\r\n\t\"lime\": [0, 255, 0],\r\n\t\"limegreen\": [50, 205, 50],\r\n\t\"linen\": [250, 240, 230],\r\n\t\"magenta\": [255, 0, 255],\r\n\t\"maroon\": [128, 0, 0],\r\n\t\"mediumaquamarine\": [102, 205, 170],\r\n\t\"mediumblue\": [0, 0, 205],\r\n\t\"mediumorchid\": [186, 85, 211],\r\n\t\"mediumpurple\": [147, 112, 219],\r\n\t\"mediumseagreen\": [60, 179, 113],\r\n\t\"mediumslateblue\": [123, 104, 238],\r\n\t\"mediumspringgreen\": [0, 250, 154],\r\n\t\"mediumturquoise\": [72, 209, 204],\r\n\t\"mediumvioletred\": [199, 21, 133],\r\n\t\"midnightblue\": [25, 25, 112],\r\n\t\"mintcream\": [245, 255, 250],\r\n\t\"mistyrose\": [255, 228, 225],\r\n\t\"moccasin\": [255, 228, 181],\r\n\t\"navajowhite\": [255, 222, 173],\r\n\t\"navy\": [0, 0, 128],\r\n\t\"oldlace\": [253, 245, 230],\r\n\t\"olive\": [128, 128, 0],\r\n\t\"olivedrab\": [107, 142, 35],\r\n\t\"orange\": [255, 165, 0],\r\n\t\"orangered\": [255, 69, 0],\r\n\t\"orchid\": [218, 112, 214],\r\n\t\"palegoldenrod\": [238, 232, 170],\r\n\t\"palegreen\": [152, 251, 152],\r\n\t\"paleturquoise\": [175, 238, 238],\r\n\t\"palevioletred\": [219, 112, 147],\r\n\t\"papayawhip\": [255, 239, 213],\r\n\t\"peachpuff\": [255, 218, 185],\r\n\t\"peru\": [205, 133, 63],\r\n\t\"pink\": [255, 192, 203],\r\n\t\"plum\": [221, 160, 221],\r\n\t\"powderblue\": [176, 224, 230],\r\n\t\"purple\": [128, 0, 128],\r\n\t\"rebeccapurple\": [102, 51, 153],\r\n\t\"red\": [255, 0, 0],\r\n\t\"rosybrown\": [188, 143, 143],\r\n\t\"royalblue\": [65, 105, 225],\r\n\t\"saddlebrown\": [139, 69, 19],\r\n\t\"salmon\": [250, 128, 114],\r\n\t\"sandybrown\": [244, 164, 96],\r\n\t\"seagreen\": [46, 139, 87],\r\n\t\"seashell\": [255, 245, 238],\r\n\t\"sienna\": [160, 82, 45],\r\n\t\"silver\": [192, 192, 192],\r\n\t\"skyblue\": [135, 206, 235],\r\n\t\"slateblue\": [106, 90, 205],\r\n\t\"slategray\": [112, 128, 144],\r\n\t\"slategrey\": [112, 128, 144],\r\n\t\"snow\": [255, 250, 250],\r\n\t\"springgreen\": [0, 255, 127],\r\n\t\"steelblue\": [70, 130, 180],\r\n\t\"tan\": [210, 180, 140],\r\n\t\"teal\": [0, 128, 128],\r\n\t\"thistle\": [216, 191, 216],\r\n\t\"tomato\": [255, 99, 71],\r\n\t\"turquoise\": [64, 224, 208],\r\n\t\"violet\": [238, 130, 238],\r\n\t\"wheat\": [245, 222, 179],\r\n\t\"white\": [255, 255, 255],\r\n\t\"whitesmoke\": [245, 245, 245],\r\n\t\"yellow\": [255, 255, 0],\r\n\t\"yellowgreen\": [154, 205, 50]\r\n};\r\n","// This file has been generated from mustache.mjs\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (global = global || self, global.Mustache = factory());\n}(this, (function () { 'use strict';\n\n /*!\n * mustache.js - Logic-less {{mustache}} templates with JavaScript\n * http://github.com/janl/mustache.js\n */\n\n var objectToString = Object.prototype.toString;\n var isArray = Array.isArray || function isArrayPolyfill (object) {\n return objectToString.call(object) === '[object Array]';\n };\n\n function isFunction (object) {\n return typeof object === 'function';\n }\n\n /**\n * More correct typeof string handling array\n * which normally returns typeof 'object'\n */\n function typeStr (obj) {\n return isArray(obj) ? 'array' : typeof obj;\n }\n\n function escapeRegExp (string) {\n return string.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, '\\\\$&');\n }\n\n /**\n * Null safe way of checking whether or not an object,\n * including its prototype, has a given property\n */\n function hasProperty (obj, propName) {\n return obj != null && typeof obj === 'object' && (propName in obj);\n }\n\n /**\n * Safe way of detecting whether or not the given thing is a primitive and\n * whether it has the given property\n */\n function primitiveHasOwnProperty (primitive, propName) {\n return (\n primitive != null\n && typeof primitive !== 'object'\n && primitive.hasOwnProperty\n && primitive.hasOwnProperty(propName)\n );\n }\n\n // Workaround for https://issues.apache.org/jira/browse/COUCHDB-577\n // See https://github.com/janl/mustache.js/issues/189\n var regExpTest = RegExp.prototype.test;\n function testRegExp (re, string) {\n return regExpTest.call(re, string);\n }\n\n var nonSpaceRe = /\\S/;\n function isWhitespace (string) {\n return !testRegExp(nonSpaceRe, string);\n }\n\n var entityMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n '/': '/',\n '`': '`',\n '=': '='\n };\n\n function escapeHtml (string) {\n return String(string).replace(/[&<>\"'`=\\/]/g, function fromEntityMap (s) {\n return entityMap[s];\n });\n }\n\n var whiteRe = /\\s*/;\n var spaceRe = /\\s+/;\n var equalsRe = /\\s*=/;\n var curlyRe = /\\s*\\}/;\n var tagRe = /#|\\^|\\/|>|\\{|&|=|!/;\n\n /**\n * Breaks up the given `template` string into a tree of tokens. If the `tags`\n * argument is given here it must be an array with two string values: the\n * opening and closing tags used in the template (e.g. [ \"<%\", \"%>\" ]). Of\n * course, the default is to use mustaches (i.e. mustache.tags).\n *\n * A token is an array with at least 4 elements. The first element is the\n * mustache symbol that was used inside the tag, e.g. \"#\" or \"&\". If the tag\n * did not contain a symbol (i.e. {{myValue}}) this element is \"name\". For\n * all text that appears outside a symbol this element is \"text\".\n *\n * The second element of a token is its \"value\". For mustache tags this is\n * whatever else was inside the tag besides the opening symbol. For text tokens\n * this is the text itself.\n *\n * The third and fourth elements of the token are the start and end indices,\n * respectively, of the token in the original template.\n *\n * Tokens that are the root node of a subtree contain two more elements: 1) an\n * array of tokens in the subtree and 2) the index in the original template at\n * which the closing tag for that section begins.\n *\n * Tokens for partials also contain two more elements: 1) a string value of\n * indendation prior to that tag and 2) the index of that tag on that line -\n * eg a value of 2 indicates the partial is the third tag on this line.\n */\n function parseTemplate (template, tags) {\n if (!template)\n return [];\n var lineHasNonSpace = false;\n var sections = []; // Stack to hold section tokens\n var tokens = []; // Buffer to hold the tokens\n var spaces = []; // Indices of whitespace tokens on the current line\n var hasTag = false; // Is there a {{tag}} on the current line?\n var nonSpace = false; // Is there a non-space char on the current line?\n var indentation = ''; // Tracks indentation for tags that use it\n var tagIndex = 0; // Stores a count of number of tags encountered on a line\n\n // Strips all whitespace tokens array for the current line\n // if there was a {{#tag}} on it and otherwise only space.\n function stripSpace () {\n if (hasTag && !nonSpace) {\n while (spaces.length)\n delete tokens[spaces.pop()];\n } else {\n spaces = [];\n }\n\n hasTag = false;\n nonSpace = false;\n }\n\n var openingTagRe, closingTagRe, closingCurlyRe;\n function compileTags (tagsToCompile) {\n if (typeof tagsToCompile === 'string')\n tagsToCompile = tagsToCompile.split(spaceRe, 2);\n\n if (!isArray(tagsToCompile) || tagsToCompile.length !== 2)\n throw new Error('Invalid tags: ' + tagsToCompile);\n\n openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + '\\\\s*');\n closingTagRe = new RegExp('\\\\s*' + escapeRegExp(tagsToCompile[1]));\n closingCurlyRe = new RegExp('\\\\s*' + escapeRegExp('}' + tagsToCompile[1]));\n }\n\n compileTags(tags || mustache.tags);\n\n var scanner = new Scanner(template);\n\n var start, type, value, chr, token, openSection;\n while (!scanner.eos()) {\n start = scanner.pos;\n\n // Match any text between tags.\n value = scanner.scanUntil(openingTagRe);\n\n if (value) {\n for (var i = 0, valueLength = value.length; i < valueLength; ++i) {\n chr = value.charAt(i);\n\n if (isWhitespace(chr)) {\n spaces.push(tokens.length);\n indentation += chr;\n } else {\n nonSpace = true;\n lineHasNonSpace = true;\n indentation += ' ';\n }\n\n tokens.push([ 'text', chr, start, start + 1 ]);\n start += 1;\n\n // Check for whitespace on the current line.\n if (chr === '\\n') {\n stripSpace();\n indentation = '';\n tagIndex = 0;\n lineHasNonSpace = false;\n }\n }\n }\n\n // Match the opening tag.\n if (!scanner.scan(openingTagRe))\n break;\n\n hasTag = true;\n\n // Get the tag type.\n type = scanner.scan(tagRe) || 'name';\n scanner.scan(whiteRe);\n\n // Get the tag value.\n if (type === '=') {\n value = scanner.scanUntil(equalsRe);\n scanner.scan(equalsRe);\n scanner.scanUntil(closingTagRe);\n } else if (type === '{') {\n value = scanner.scanUntil(closingCurlyRe);\n scanner.scan(curlyRe);\n scanner.scanUntil(closingTagRe);\n type = '&';\n } else {\n value = scanner.scanUntil(closingTagRe);\n }\n\n // Match the closing tag.\n if (!scanner.scan(closingTagRe))\n throw new Error('Unclosed tag at ' + scanner.pos);\n\n if (type == '>') {\n token = [ type, value, start, scanner.pos, indentation, tagIndex, lineHasNonSpace ];\n } else {\n token = [ type, value, start, scanner.pos ];\n }\n tagIndex++;\n tokens.push(token);\n\n if (type === '#' || type === '^') {\n sections.push(token);\n } else if (type === '/') {\n // Check section nesting.\n openSection = sections.pop();\n\n if (!openSection)\n throw new Error('Unopened section \"' + value + '\" at ' + start);\n\n if (openSection[1] !== value)\n throw new Error('Unclosed section \"' + openSection[1] + '\" at ' + start);\n } else if (type === 'name' || type === '{' || type === '&') {\n nonSpace = true;\n } else if (type === '=') {\n // Set the tags for the next time around.\n compileTags(value);\n }\n }\n\n stripSpace();\n\n // Make sure there are no open sections when we're done.\n openSection = sections.pop();\n\n if (openSection)\n throw new Error('Unclosed section \"' + openSection[1] + '\" at ' + scanner.pos);\n\n return nestTokens(squashTokens(tokens));\n }\n\n /**\n * Combines the values of consecutive text tokens in the given `tokens` array\n * to a single token.\n */\n function squashTokens (tokens) {\n var squashedTokens = [];\n\n var token, lastToken;\n for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {\n token = tokens[i];\n\n if (token) {\n if (token[0] === 'text' && lastToken && lastToken[0] === 'text') {\n lastToken[1] += token[1];\n lastToken[3] = token[3];\n } else {\n squashedTokens.push(token);\n lastToken = token;\n }\n }\n }\n\n return squashedTokens;\n }\n\n /**\n * Forms the given array of `tokens` into a nested tree structure where\n * tokens that represent a section have two additional items: 1) an array of\n * all tokens that appear in that section and 2) the index in the original\n * template that represents the end of that section.\n */\n function nestTokens (tokens) {\n var nestedTokens = [];\n var collector = nestedTokens;\n var sections = [];\n\n var token, section;\n for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {\n token = tokens[i];\n\n switch (token[0]) {\n case '#':\n case '^':\n collector.push(token);\n sections.push(token);\n collector = token[4] = [];\n break;\n case '/':\n section = sections.pop();\n section[5] = token[2];\n collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens;\n break;\n default:\n collector.push(token);\n }\n }\n\n return nestedTokens;\n }\n\n /**\n * A simple string scanner that is used by the template parser to find\n * tokens in template strings.\n */\n function Scanner (string) {\n this.string = string;\n this.tail = string;\n this.pos = 0;\n }\n\n /**\n * Returns `true` if the tail is empty (end of string).\n */\n Scanner.prototype.eos = function eos () {\n return this.tail === '';\n };\n\n /**\n * Tries to match the given regular expression at the current position.\n * Returns the matched text if it can match, the empty string otherwise.\n */\n Scanner.prototype.scan = function scan (re) {\n var match = this.tail.match(re);\n\n if (!match || match.index !== 0)\n return '';\n\n var string = match[0];\n\n this.tail = this.tail.substring(string.length);\n this.pos += string.length;\n\n return string;\n };\n\n /**\n * Skips all text until the given regular expression can be matched. Returns\n * the skipped string, which is the entire tail if no match can be made.\n */\n Scanner.prototype.scanUntil = function scanUntil (re) {\n var index = this.tail.search(re), match;\n\n switch (index) {\n case -1:\n match = this.tail;\n this.tail = '';\n break;\n case 0:\n match = '';\n break;\n default:\n match = this.tail.substring(0, index);\n this.tail = this.tail.substring(index);\n }\n\n this.pos += match.length;\n\n return match;\n };\n\n /**\n * Represents a rendering context by wrapping a view object and\n * maintaining a reference to the parent context.\n */\n function Context (view, parentContext) {\n this.view = view;\n this.cache = { '.': this.view };\n this.parent = parentContext;\n }\n\n /**\n * Creates a new context using the given view with this context\n * as the parent.\n */\n Context.prototype.push = function push (view) {\n return new Context(view, this);\n };\n\n /**\n * Returns the value of the given name in this context, traversing\n * up the context hierarchy if the value is absent in this context's view.\n */\n Context.prototype.lookup = function lookup (name) {\n var cache = this.cache;\n\n var value;\n if (cache.hasOwnProperty(name)) {\n value = cache[name];\n } else {\n var context = this, intermediateValue, names, index, lookupHit = false;\n\n while (context) {\n if (name.indexOf('.') > 0) {\n intermediateValue = context.view;\n names = name.split('.');\n index = 0;\n\n /**\n * Using the dot notion path in `name`, we descend through the\n * nested objects.\n *\n * To be certain that the lookup has been successful, we have to\n * check if the last object in the path actually has the property\n * we are looking for. We store the result in `lookupHit`.\n *\n * This is specially necessary for when the value has been set to\n * `undefined` and we want to avoid looking up parent contexts.\n *\n * In the case where dot notation is used, we consider the lookup\n * to be successful even if the last \"object\" in the path is\n * not actually an object but a primitive (e.g., a string, or an\n * integer), because it is sometimes useful to access a property\n * of an autoboxed primitive, such as the length of a string.\n **/\n while (intermediateValue != null && index < names.length) {\n if (index === names.length - 1)\n lookupHit = (\n hasProperty(intermediateValue, names[index])\n || primitiveHasOwnProperty(intermediateValue, names[index])\n );\n\n intermediateValue = intermediateValue[names[index++]];\n }\n } else {\n intermediateValue = context.view[name];\n\n /**\n * Only checking against `hasProperty`, which always returns `false` if\n * `context.view` is not an object. Deliberately omitting the check\n * against `primitiveHasOwnProperty` if dot notation is not used.\n *\n * Consider this example:\n * ```\n * Mustache.render(\"The length of a football field is {{#length}}{{length}}{{/length}}.\", {length: \"100 yards\"})\n * ```\n *\n * If we were to check also against `primitiveHasOwnProperty`, as we do\n * in the dot notation case, then render call would return:\n *\n * \"The length of a football field is 9.\"\n *\n * rather than the expected:\n *\n * \"The length of a football field is 100 yards.\"\n **/\n lookupHit = hasProperty(context.view, name);\n }\n\n if (lookupHit) {\n value = intermediateValue;\n break;\n }\n\n context = context.parent;\n }\n\n cache[name] = value;\n }\n\n if (isFunction(value))\n value = value.call(this.view);\n\n return value;\n };\n\n /**\n * A Writer knows how to take a stream of tokens and render them to a\n * string, given a context. It also maintains a cache of templates to\n * avoid the need to parse the same template twice.\n */\n function Writer () {\n this.templateCache = {\n _cache: {},\n set: function set (key, value) {\n this._cache[key] = value;\n },\n get: function get (key) {\n return this._cache[key];\n },\n clear: function clear () {\n this._cache = {};\n }\n };\n }\n\n /**\n * Clears all cached templates in this writer.\n */\n Writer.prototype.clearCache = function clearCache () {\n if (typeof this.templateCache !== 'undefined') {\n this.templateCache.clear();\n }\n };\n\n /**\n * Parses and caches the given `template` according to the given `tags` or\n * `mustache.tags` if `tags` is omitted, and returns the array of tokens\n * that is generated from the parse.\n */\n Writer.prototype.parse = function parse (template, tags) {\n var cache = this.templateCache;\n var cacheKey = template + ':' + (tags || mustache.tags).join(':');\n var isCacheEnabled = typeof cache !== 'undefined';\n var tokens = isCacheEnabled ? cache.get(cacheKey) : undefined;\n\n if (tokens == undefined) {\n tokens = parseTemplate(template, tags);\n isCacheEnabled && cache.set(cacheKey, tokens);\n }\n return tokens;\n };\n\n /**\n * High-level method that is used to render the given `template` with\n * the given `view`.\n *\n * The optional `partials` argument may be an object that contains the\n * names and templates of partials that are used in the template. It may\n * also be a function that is used to load partial templates on the fly\n * that takes a single argument: the name of the partial.\n *\n * If the optional `config` argument is given here, then it should be an\n * object with a `tags` attribute or an `escape` attribute or both.\n * If an array is passed, then it will be interpreted the same way as\n * a `tags` attribute on a `config` object.\n *\n * The `tags` attribute of a `config` object must be an array with two\n * string values: the opening and closing tags used in the template (e.g.\n * [ \"<%\", \"%>\" ]). The default is to mustache.tags.\n *\n * The `escape` attribute of a `config` object must be a function which\n * accepts a string as input and outputs a safely escaped string.\n * If an `escape` function is not provided, then an HTML-safe string\n * escaping function is used as the default.\n */\n Writer.prototype.render = function render (template, view, partials, config) {\n var tags = this.getConfigTags(config);\n var tokens = this.parse(template, tags);\n var context = (view instanceof Context) ? view : new Context(view, undefined);\n return this.renderTokens(tokens, context, partials, template, config);\n };\n\n /**\n * Low-level method that renders the given array of `tokens` using\n * the given `context` and `partials`.\n *\n * Note: The `originalTemplate` is only ever used to extract the portion\n * of the original template that was contained in a higher-order section.\n * If the template doesn't use higher-order sections, this argument may\n * be omitted.\n */\n Writer.prototype.renderTokens = function renderTokens (tokens, context, partials, originalTemplate, config) {\n var buffer = '';\n\n var token, symbol, value;\n for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {\n value = undefined;\n token = tokens[i];\n symbol = token[0];\n\n if (symbol === '#') value = this.renderSection(token, context, partials, originalTemplate, config);\n else if (symbol === '^') value = this.renderInverted(token, context, partials, originalTemplate, config);\n else if (symbol === '>') value = this.renderPartial(token, context, partials, config);\n else if (symbol === '&') value = this.unescapedValue(token, context);\n else if (symbol === 'name') value = this.escapedValue(token, context, config);\n else if (symbol === 'text') value = this.rawValue(token);\n\n if (value !== undefined)\n buffer += value;\n }\n\n return buffer;\n };\n\n Writer.prototype.renderSection = function renderSection (token, context, partials, originalTemplate, config) {\n var self = this;\n var buffer = '';\n var value = context.lookup(token[1]);\n\n // This function is used to render an arbitrary template\n // in the current context by higher-order sections.\n function subRender (template) {\n return self.render(template, context, partials, config);\n }\n\n if (!value) return;\n\n if (isArray(value)) {\n for (var j = 0, valueLength = value.length; j < valueLength; ++j) {\n buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate, config);\n }\n } else if (typeof value === 'object' || typeof value === 'string' || typeof value === 'number') {\n buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate, config);\n } else if (isFunction(value)) {\n if (typeof originalTemplate !== 'string')\n throw new Error('Cannot use higher-order sections without the original template');\n\n // Extract the portion of the original template that the section contains.\n value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender);\n\n if (value != null)\n buffer += value;\n } else {\n buffer += this.renderTokens(token[4], context, partials, originalTemplate, config);\n }\n return buffer;\n };\n\n Writer.prototype.renderInverted = function renderInverted (token, context, partials, originalTemplate, config) {\n var value = context.lookup(token[1]);\n\n // Use JavaScript's definition of falsy. Include empty arrays.\n // See https://github.com/janl/mustache.js/issues/186\n if (!value || (isArray(value) && value.length === 0))\n return this.renderTokens(token[4], context, partials, originalTemplate, config);\n };\n\n Writer.prototype.indentPartial = function indentPartial (partial, indentation, lineHasNonSpace) {\n var filteredIndentation = indentation.replace(/[^ \\t]/g, '');\n var partialByNl = partial.split('\\n');\n for (var i = 0; i < partialByNl.length; i++) {\n if (partialByNl[i].length && (i > 0 || !lineHasNonSpace)) {\n partialByNl[i] = filteredIndentation + partialByNl[i];\n }\n }\n return partialByNl.join('\\n');\n };\n\n Writer.prototype.renderPartial = function renderPartial (token, context, partials, config) {\n if (!partials) return;\n var tags = this.getConfigTags(config);\n\n var value = isFunction(partials) ? partials(token[1]) : partials[token[1]];\n if (value != null) {\n var lineHasNonSpace = token[6];\n var tagIndex = token[5];\n var indentation = token[4];\n var indentedValue = value;\n if (tagIndex == 0 && indentation) {\n indentedValue = this.indentPartial(value, indentation, lineHasNonSpace);\n }\n var tokens = this.parse(indentedValue, tags);\n return this.renderTokens(tokens, context, partials, indentedValue, config);\n }\n };\n\n Writer.prototype.unescapedValue = function unescapedValue (token, context) {\n var value = context.lookup(token[1]);\n if (value != null)\n return value;\n };\n\n Writer.prototype.escapedValue = function escapedValue (token, context, config) {\n var escape = this.getConfigEscape(config) || mustache.escape;\n var value = context.lookup(token[1]);\n if (value != null)\n return (typeof value === 'number' && escape === mustache.escape) ? String(value) : escape(value);\n };\n\n Writer.prototype.rawValue = function rawValue (token) {\n return token[1];\n };\n\n Writer.prototype.getConfigTags = function getConfigTags (config) {\n if (isArray(config)) {\n return config;\n }\n else if (config && typeof config === 'object') {\n return config.tags;\n }\n else {\n return undefined;\n }\n };\n\n Writer.prototype.getConfigEscape = function getConfigEscape (config) {\n if (config && typeof config === 'object' && !isArray(config)) {\n return config.escape;\n }\n else {\n return undefined;\n }\n };\n\n var mustache = {\n name: 'mustache.js',\n version: '4.1.0',\n tags: [ '{{', '}}' ],\n clearCache: undefined,\n escape: undefined,\n parse: undefined,\n render: undefined,\n Scanner: undefined,\n Context: undefined,\n Writer: undefined,\n /**\n * Allows a user to override the default caching strategy, by providing an\n * object with set, get and clear methods. This can also be used to disable\n * the cache by setting it to the literal `undefined`.\n */\n set templateCache (cache) {\n defaultWriter.templateCache = cache;\n },\n /**\n * Gets the default or overridden caching object from the default writer.\n */\n get templateCache () {\n return defaultWriter.templateCache;\n }\n };\n\n // All high-level mustache.* functions use this writer.\n var defaultWriter = new Writer();\n\n /**\n * Clears all cached templates in the default writer.\n */\n mustache.clearCache = function clearCache () {\n return defaultWriter.clearCache();\n };\n\n /**\n * Parses and caches the given template in the default writer and returns the\n * array of tokens it contains. Doing this ahead of time avoids the need to\n * parse templates on the fly as they are rendered.\n */\n mustache.parse = function parse (template, tags) {\n return defaultWriter.parse(template, tags);\n };\n\n /**\n * Renders the `template` with the given `view`, `partials`, and `config`\n * using the default writer.\n */\n mustache.render = function render (template, view, partials, config) {\n if (typeof template !== 'string') {\n throw new TypeError('Invalid template! Template should be a \"string\" ' +\n 'but \"' + typeStr(template) + '\" was given as the first ' +\n 'argument for mustache#render(template, view, partials)');\n }\n\n return defaultWriter.render(template, view, partials, config);\n };\n\n // Export the escaping function so that the user may override it.\n // See https://github.com/janl/mustache.js/issues/244\n mustache.escape = escapeHtml;\n\n // Export these mainly for testing, but also for advanced usage.\n mustache.Scanner = Scanner;\n mustache.Context = Context;\n mustache.Writer = Writer;\n\n return mustache;\n\n})));\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tif(__webpack_module_cache__[moduleId]) {\n\t\treturn __webpack_module_cache__[moduleId].exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","export const getQueryParams = (): Record => {\n const queryString = window.location.search.substring(1)\n const params: Record = {}\n const queries = queryString.split('&')\n queries.forEach((indexQuery) => {\n const indexPair = indexQuery.split('=')\n\n const queryKey = decodeURIComponent(indexPair[0]).toLowerCase()\n const queryValue = decodeURIComponent(indexPair.length > 1 ? indexPair[1] : '')\n\n params[queryKey] = queryValue\n })\n return params\n}\n","export const getElementAttributes = (element: HTMLElement): Record => {\n const attributes: Record = {}\n for (let i = 0, atts = element.attributes, n = atts.length; i < n; i++) {\n const attribueName = atts[i].nodeName\n attributes[attribueName.toLowerCase()] = (atts[i].nodeValue || '').toString()\n }\n return attributes\n}\n\nexport const buildElement = (type: string, klass: string, attributes: Record): HTMLElement => {\n const element = document.createElement(type)\n element.setAttribute('class', klass)\n setAttributesOnElement(element, attributes)\n return element\n}\n\nexport const setAttributesOnElement = (element: HTMLElement, attributes: Record) => {\n const keys = Object.keys(attributes)\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]\n if (typeof attributes[key] !== 'undefined') {\n element.setAttribute(key, attributes[key].toString())\n }\n }\n}\n\nexport const buildStyle = (map: Record): string => {\n const keys = Object.keys(map)\n const styles = []\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]\n styles.push(`${key}:${map[key]}`)\n }\n return styles.join(';')\n}\n\nexport function addAttributeToHtmlElement (element: string, attributeType: string, attributeValue: any) {\n const classElement = getHtmlElementByClassName(element)\n if (classElement) {\n classElement.setAttribute(attributeType, attributeValue)\n return\n }\n console.log(Error('Cannot add attributes to missing HTML element!'))\n}\n\nexport function insertHtmlElement (element: string, insertPosition: any, html: any) {\n const classElement = getHtmlElementByClassName(element)\n if (classElement) {\n classElement.insertAdjacentHTML(insertPosition, html)\n return\n }\n console.log(Error('Cannot insert HTML element, missing class!'))\n}\n\nexport function getHtmlElementById (id: string) {\n const element = document.getElementById(id)\n if (element) {\n return element\n }\n return null\n}\n\nexport function getHtmlElementByClassName (className: string) {\n const element = (document.getElementsByClassName(className)[0])\n if (element) {\n return element\n }\n return null\n}\n\nexport function removeHtmlElementByClassName (className: string) {\n const element = getHtmlElementByClassName(className)\n if (element) {\n element.remove()\n }\n}\n\nexport function getHtmlElementByTagName (tagName: string) {\n const element = (document.getElementsByTagName(tagName)[0])\n if (element) {\n return element\n }\n return null\n}\n\nexport function getHtmlElementValue (...classNames: any[]) {\n const formattedClassNames = classNames.toString().replace(',', ' ')\n const querySelector = (document.querySelector(formattedClassNames))\n if (querySelector) {\n return querySelector.value\n }\n return null\n}\n","import { getQueryParams } from '../utils/url'\nimport { getElementAttributes } from '../utils/element'\nimport { Customizations } from './types'\nimport { hooksCustomizatioKeyPrefix } from '../services/hooks'\n\nexport const getCustomizations = (customizations: Customizations, element: HTMLElement) => {\n const urlParams = filterUrlParams(getQueryParams())\n const elementAttributes = getElementAttributes(element)\n return {\n ...customizations,\n ...elementAttributes,\n ...urlParams\n }\n}\n\nconst filterUrlParams = (params: Record) => {\n for (const key in params) {\n if (isBlocked(key)) {\n delete params[key]\n }\n }\n return params\n}\n\nconst isBlocked = (key: string): boolean => {\n return key.indexOf(hooksCustomizatioKeyPrefix) === 0\n}\n","import { SellingPlan } from './selling-plan'\nimport { SellingPlanGroup } from './selling-plan-group'\nimport { DiscountType, PriceAdjustment } from './price-adjustments'\nimport { Product } from './product'\nimport { Variant } from './variant'\nimport { SellingPlanAllocation } from './selling-plan-allocation'\n\nconst getPriceAdjustment = (valueType: DiscountType, value: number): PriceAdjustment => {\n return {\n valueType: valueType,\n value: value\n }\n}\n\nconst getSellingPlan = (id: number,\n name: string,\n groupId: string,\n groupName: string,\n variants: Variant[],\n dummyPriceAdjustment: PriceAdjustment[]): SellingPlan => {\n return {\n id,\n name,\n description: '',\n options: [\n {\n name: groupName,\n position: 1,\n value: name\n }\n ],\n priceAdjustments: dummyPriceAdjustment\n }\n}\n\nconst getSellingPlanGroup = (id: string,\n name: string,\n sellingPlans: SellingPlan[],\n variants: Variant[],\n position: number): SellingPlanGroup => {\n return {\n id,\n name,\n options: [\n {\n name,\n position: position,\n values: sellingPlans.map(p => p.name)\n }\n ],\n sellingPlans: sellingPlans\n }\n}\n\nconst getSellingPlanAllocations = (groupId: string, sellingPlanId: number, price: number) => {\n return {\n groupId: groupId,\n sellingPlanId: sellingPlanId,\n price: price\n }\n}\n\nconst getVariant = (id: number, title: string, price: number, sellingPlanAllocations: SellingPlanAllocation[]) => {\n return {\n id: id,\n title: title,\n price: price,\n sellingPlanAllocations: sellingPlanAllocations\n }\n}\n\nconst getProduct = (id: number,\n title: string,\n price: number,\n handle: string,\n description: string,\n requiresSellingPlan: boolean,\n variants: Variant[],\n sellingPlanGroups: SellingPlanGroup[]): Product => {\n return {\n id: id,\n title: title,\n price: price,\n handle: handle,\n description: description,\n requiresSellingPlan: requiresSellingPlan,\n variants: variants,\n sellingPlanGroups: sellingPlanGroups,\n priceVaries: false\n }\n}\n\nconst dummyProductPrice = 1699\n\nconst dummyGroupName = 'Subscribe to Save'\n\nconst dummyPriceAdjustment0: PriceAdjustment[] = []\n\nconst dummyPriceAdjustment1: PriceAdjustment[] = [\n getPriceAdjustment('fixed_amount', 500)\n]\n\nconst dummyPriceAdjustment2: PriceAdjustment[] = [\n getPriceAdjustment('fixed_amount', 1500)\n]\n\nconst dummyPriceAdjustment3: PriceAdjustment[] = [\n getPriceAdjustment('percentage', 20)\n]\n\nconst dummySellingPlanAllocations: SellingPlanAllocation[] = [\n getSellingPlanAllocations('12345', 111, 0),\n getSellingPlanAllocations('12345', 112, 999),\n getSellingPlanAllocations('12345', 113, 799),\n getSellingPlanAllocations('12345', 114, 1199)\n]\n\nconst dummyVariants = (): Variant[] => {\n return [getVariant(12345, 'someTitle', dummyProductPrice, dummySellingPlanAllocations)]\n}\n\nconst dummySellingPlans: SellingPlan[] = [\n getSellingPlan(111, 'Every week', '12345', dummyGroupName, dummyVariants(), dummyPriceAdjustment0),\n getSellingPlan(112, 'Every 2 weeks', '12345', dummyGroupName, dummyVariants(), dummyPriceAdjustment2),\n getSellingPlan(113, 'Every 3 weeks', '12345', dummyGroupName, dummyVariants(), dummyPriceAdjustment1),\n getSellingPlan(114, 'Every 4 weeks', '12345', dummyGroupName, dummyVariants(), dummyPriceAdjustment3)\n]\n\nconst dummyGroup1 = getSellingPlanGroup('12345', dummyGroupName, dummySellingPlans, dummyVariants(), 1)\n\nconst dummySellingGroups: SellingPlanGroup[] = [\n dummyGroup1\n]\n\nexport const getDummyProduct = () => {\n return getProduct(\n 1,\n 'Nike pro',\n dummyProductPrice,\n 'nike',\n 'Nice',\n false,\n dummyVariants(),\n dummySellingGroups\n )\n}\n","import { hooksCustomizatioKeyPrefix } from '../services/hooks'\nimport { Customizations, FontFamilyStyle, WidgetCustomizations } from './types'\n\nexport const getWidgetCustomizations = (customizations: Customizations): WidgetCustomizations => {\n return {\n isReadOnly: getBoolean(customizations, 'mode-read-only'),\n isPreview: getBoolean(customizations, 'mode-preview'),\n isLaunched: getBooleanWithDefault(customizations, 'is-launched', false),\n isDresser: getBooleanWithDefault(customizations, 'is-dresser', false),\n allowOutOfForm: getBooleanWithDefault(customizations, 'allow-out-of-form', false),\n livePreview: {\n show: getBooleanWithDefault(customizations, 'show-live-preview', false),\n widgetMarkingStrategy: customizations['live-preview-widget-marking-strategy'] || 'blinking_border',\n topBar: {\n headerText: customizations['top-bar-header-text'] || 'How does it look?',\n helpText: customizations['top-bar-help-text'] || 'This is still a preview. It won’t go live until you launch your subscription.',\n backgroundColor: customizations['top-bar-background-color'] || '#0042E4',\n backgroundOpacity: customizations['top-bar-background-opacity'] || 0.95,\n fontColor: customizations['top-bar-font-color'] || '#ffffff',\n ctaLinkPath: customizations['top-bar-cta-link-path'] || '',\n ctaText: customizations['top-bar-cta-text'] || 'Get live support',\n closeButtonTextColor: customizations['top-bar-cta-text-color'] || '#0042E4',\n closeButtonBackgroundColor: customizations['top-bar-cta-background-color'] || '#ffffff',\n closeButtonText: customizations['top-bar-close-button-text'] || 'Looks good, back to setup'\n }\n },\n isDummy: getBoolean(customizations, 'mode-dummy'),\n variantDetection: {\n selector: customizations['variant-detection-selector'] || 'form [name=\"id\"]',\n attribute: customizations['variant-detection-element-attr'] || ''\n },\n autoPickOptionIndex: getNumber(customizations, 'auto-pick-option-index', 0),\n productHandle: customizations['product-handle'],\n storefrontTheme: customizations['storefront-theme'],\n buyOnceText: customizations['buy-once-text'] || 'Buy once',\n oneTimeAtLast: getBooleanWithDefault(customizations, 'one-time-at-last', false),\n showGetItText: getBoolean(customizations, 'show-get-it-text'),\n getItText: customizations['get-it-text'] || 'Get it',\n sellingPlans: {\n showDiscount: getBooleanWithDefault(customizations, 'selling-plans-show-discount', true),\n sort: {\n strategy: customizations['selling-plans-sort-strategy'] || 'frequency'\n },\n promotionLine: {\n show: getBooleanWithDefault(customizations, 'selling-plans-promotion-line-show', false),\n text: customizations['selling-plans-promotion-line-text'] || ''\n }\n },\n loyalty: {\n reward: {\n pointsRatio: getFloatWithDefault(customizations, 'loyalty-reward-points-ratio', 1)\n }\n },\n tiles: {\n borderStyle: customizations['styles-tile-border-style'] || 'solid',\n borderColor: customizations['styles-tile-border-color'] || '#2CCCD3',\n borderSize: getPixel(customizations, 'styles-tile-border-size', '2px'),\n backgroundColor: customizations['styles-tile-background-color'] || '#2CCCD3',\n fontColor: customizations['styles-tile-font-color'] || '#0042E4',\n fullPriceText: customizations['tiles-label-text'] || 'full price',\n suffixText: customizations['tiles-label-suffix-text'] || ' off',\n tileHeight: getPixel(customizations, 'tiles-tile-height', '70px'),\n oddSpread: getBooleanWithDefault(customizations, 'tiles-odd-spread', false)\n },\n selectionType: customizations['plan-selection-type'] || 'tiles-only',\n autoInject: {\n enabled: getBooleanWithDefault(customizations, 'should-auto-inject', false),\n targetSelector: customizations['auto-inject-target-selector'] || '',\n adjacentStrategy: customizations['auto-inject-adjacent-strategy'] || ''\n },\n fullFormatProductPrice: sanitizeHtml(customizations, 'full-format-product-price', '$16.99'),\n priceLabel: {\n prefix: customizations['price-label-prefix'] || 'From',\n strategy: customizations['price-label-strategy'] || 'starting_and_actual',\n percentSymbolLocation: customizations['price-label-percent-symbol-location'] || 'right',\n currency: {\n enabled: getBooleanWithDefault(customizations, 'price-label-currency-enabled', false),\n name: customizations['price-label-currency-name'] || '',\n rate: getFloatWithDefault(customizations, 'price-label-currency-rate', 1.0),\n roundUp: getBooleanWithDefault(customizations, 'price-label-currency-round-up', true)\n }\n },\n subscriptionPolicy: {\n shouldShow: getBooleanWithDefault(customizations, 'subscription-policy-should-show', false),\n description: customizations['subscription-policy-description'] || 'You\\'re subscribing to receive this item multiple times, on a recurring basis (according to the frequency you select) with a discount on every recurring order. You may cancel or change your subscription at any time.',\n footer: customizations['subscription-policy-footer'] || 'View subscription policy',\n informationLink: customizations['subscription-policy-information-link']\n },\n subscriptionBenefits: {\n shouldShow: getBooleanWithDefault(customizations, 'subscription-benefits-should-show', false),\n list: getTextArrayWithDefault(customizations, 'subscription-benefits-list', ['No commitment, you can cancel or change online anytime.'], '||')\n },\n styles: {\n notSelectedRadio: {\n backgroundColor: customizations['styles-not-selected-radio-background-color'] || '#F1F1F1'\n },\n selectedRadio: {\n borderStyle: customizations['styles-selected-radio-border-style'] || 'solid',\n borderColor: customizations['styles-selected-radio-border-color'] || '#dbd9d4',\n borderSize: getPixel(customizations, 'styles-selected-radio-border-size', '1px'),\n backgroundColor: customizations['styles-selected-radio-background-color'] || 'rgba(0, 66, 228, 10)',\n backgroundImageUrl: customizations['styles-selected-radio-background-image-url'] || 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAALdSURBVDiNfZNNSNNxGMe//9/UOefe/G+Z868z30gTnK+JaVqEqeQoO3WIooxOehBEAukUBR0U6RDYpUt0KMt3i0QJwsq5aepEndp06Zz/uc2XOTd1/w7iNLO+p+fwfL7P88DzpXBEqan52ZERqkr6hCoxMChESgiP87hdTpt9bsI6b36mH+3THe6n9guGYQTJSXlN2TnXi8VSiXzdMQZRKAEAbLopiOk02Fmr7fu35u7FxdEKg8Hg9RswDCNITbnQVaSpKlie76DKryQhPS3+j810eiNaPxgRHqXhulvre03zulKDweDlAUBOdvHLkqvVZW5HF1VXUwqlkj56GZQRNM7nxqG3p406k3n3lMVsjJ6ZHWvhqdUFWQWXbj/ctPcL62pKQQj5C94XIRRyzyags6OLUqryo7Y3lnpIpFJVJZVIFeVlSf+FnzzvwZ0HzfBseaEpiQNNh9N0eGwlCaOZRNfqONLVcQCAwRETuGNgLXcZPsIHRwFZGYlw2vSQyZnTJIgfKhUK9hAr68DjVz9R/ykQK461Q3ARxAutaKwthDAkGAAgFHAQBIukAQDnnxiukCEvgUP/pBfDfV+QoPDhB18D8UIbGmsLIRGHHnoACts7HkK8Hpdzw3WwdHXFReTy++BWlmBIdBOi42AALheHHa/bQVjrvFEkS4FObzwwubdnIpp6cSw8MDgJmSITy8tz0wFLy+ZG56qz6F3HhEKdGgcej/hN/qWV9WhYl8yszbLUQIaHP2u1X99+jFBpuKcNnfD5fP8EAeB18wgs9khOr23p1o/26XgAQIiny2FbPJecdiumvb2TEgs5RCrlfojjOIxP/ILFHosZ80nu/ZtHvTOzAzfsdvuuP0zx8fH82JiMpvSca6VhUrl8zTEMoYDCrm8XHm8AJGFqsKyFHdK2dk9ND9w3mUxbwKE07istpTAzgomqClMwiUGBwTJQFLyeTQfLmmbYRWv90Tj/BluALmoQILjqAAAAAElFTkSuQmCC',\n dropdownBorderColor: customizations['styles-selected-radio-dropdown-border-color'] || '#676A6C',\n dropdownBackgroundColor: customizations['styles-radio-button-dropdown-background-color'] || '#FCFCFC',\n dropdownHoverColor: customizations['styles-radio-button-dropdown-hover-color'] || 'whitesmoke',\n openByDefault: getBooleanWithDefault(customizations, 'styles-delected-radio-open-by-default', true)\n },\n radioButton: {\n innerColor: customizations['styles-radio-button-inner-color'] || '#0042E4',\n outerColor: customizations['styles-radio-button-outer-color'] || '#474747'\n },\n fontFamily: getFontFamily(customizations, 'styles-font-family', 'Nunito Sans@400|https://fonts.googleapis.com/css?family=Nunito+Sans:400&display=swap'),\n fontSize: {\n primary: getPixel(customizations, 'style-primary-font-size', '13px'),\n sellingPlans: {\n name: getPixel(customizations, 'style-selling-plan-name-font-size', '13px'),\n options: getPixel(customizations, 'style-selling-plan-options-font-size', '13px')\n }\n },\n colors: {\n text: {\n primary: customizations['styles-colors-text-primary'] || '#474747'\n }\n }\n },\n hooks: {\n widgetReady: getHook(customizations, 'hooks-widget-ready'),\n sellingPlanChanged: getHook(customizations, 'hooks-selling-plan-changed')\n }\n }\n}\n\nconst getBoolean = (customizations: Customizations, key: string): boolean => {\n const value = customizations[key] && customizations[key].toString() === 'true'\n return value === true\n}\n\nconst getBooleanWithDefault = (customizations: Customizations, key: string, defaultValue: boolean): boolean => {\n if (typeof customizations[key] === 'undefined') {\n return defaultValue\n }\n return getBoolean(customizations, key)\n}\n\nconst getNumber = (customizations: Customizations, key: string, defaultValue: number): number => {\n const value = customizations[key] || defaultValue\n return parseInt(value, 10)\n}\n\nconst getFloatWithDefault = (customizations: Customizations, key: string, defaultValue: number): number => {\n const value = customizations[key] || defaultValue\n return parseFloat(value)\n}\n\nconst getFontFamily = (customizations: Customizations, key: string, defaultValue: string): FontFamilyStyle => {\n const value = customizations[key] || defaultValue\n const values = value.replace('|', '@').split('@')\n return {\n name: values[0],\n weight: values[1],\n url: values[2]\n }\n}\n\nconst getPixel = (customizations: Customizations, key: string, defaultValue: string): string => {\n const value = customizations[key] || defaultValue\n if (value && value.toString() && value.toString().indexOf('px') < 0) {\n return `${value}px`\n }\n\n return value\n}\n\nconst getHook = (customizations: Customizations, key: string): string => {\n if (key.indexOf(hooksCustomizatioKeyPrefix) !== 0) {\n console.warn('hooks key must start with correct prefix')\n return ''\n }\n return customizations[key]\n}\n\nconst getTextArrayWithDefault = (customizations: Customizations, key: string, defaultValue: string[], delimeter: string): string[] => {\n const source = customizations[key]\n if (!source) {\n return defaultValue\n }\n return source.split(delimeter)\n}\n\nconst sanitizeHtml = (customizations: Customizations, key: string, defaultValue: string) => {\n const value = customizations[key] || defaultValue\n return value.replace(/<\\/?[^>]+(>|$)/g, '')\n}\n","import { widgetState } from '../store/customizations/index'\nimport { buildElement, getHtmlElementByTagName } from '../utils/element'\n\nexport const renderMainElement = (): HTMLElement => {\n const isAdmin = widgetState.customizations.isReadOnly ? 'yotpo-admin-preview' : ''\n const element = buildElement('div', `yotpo-widget-subscriptions-add-to-cart yotpo-widget-override-css yotpo-widget-clear ${isAdmin}`, {})\n const clearStyle = buildElement('style', 'yotpo-css-clear', {})\n const fontStyle = buildElement('link', '', {\n href: widgetState.customizations.styles.fontFamily.url,\n rel: 'stylesheet'\n })\n getHtmlElementByTagName('head').appendChild(fontStyle)\n clearStyle.innerHTML = clearStyles()\n element.appendChild(clearStyle)\n return element\n}\n\nconst clearStyles = () => {\n return `\n .yotpo-widget-clear, .yotpo-widget-clear input, .yotpo-widget-clear button, .yotpo-widget-clear span, .yotpo-widget-clear select, .yotpo-widget-clear label {\n animation : none;\n animation-delay : 0;\n animation-direction : normal;\n animation-duration : 0;\n animation-fill-mode : none;\n animation-iteration-count : 1;\n animation-name : none;\n animation-play-state : running;\n animation-timing-function : ease;\n backface-visibility : visible;\n background : 0;\n background-attachment : scroll;\n background-clip : border-box;\n background-color : transparent;\n background-image : none;\n background-origin : padding-box;\n background-position : 0 0;\n background-position-x : 0;\n background-position-y : 0;\n background-repeat : repeat;\n background-size : auto auto;\n border : 0;\n border-style : none;\n border-width : medium;\n border-color : inherit;\n border-bottom : 0;\n border-bottom-color : inherit;\n border-bottom-left-radius : 0;\n border-bottom-right-radius : 0;\n border-bottom-style : none;\n border-bottom-width : medium;\n border-collapse : separate;\n border-image : none;\n border-left : 0;\n border-left-color : inherit;\n border-left-style : none;\n border-left-width : medium;\n border-radius : 0;\n border-right : 0;\n border-right-color : inherit;\n border-right-style : none;\n border-right-width : medium;\n border-spacing : 0;\n border-top : 0;\n border-top-color : inherit;\n border-top-left-radius : 0;\n border-top-right-radius : 0;\n border-top-style : none;\n border-top-width : medium;\n bottom : auto;\n box-shadow : none;\n box-sizing : content-box;\n caption-side : top;\n clear : none;\n clip : auto;\n color : inherit;\n columns : auto;\n column-count : auto;\n column-fill : balance;\n column-gap : normal;\n column-rule : medium none currentColor;\n column-rule-color : currentColor;\n column-rule-style : none;\n column-rule-width : none;\n column-span : 1;\n column-width : auto;\n content : normal;\n counter-increment : none;\n counter-reset : none;\n cursor : auto;\n direction : ltr;\n display : inline;\n empty-cells : show;\n float : none;\n font : normal;\n font-family : inherit;\n font-size : medium;\n font-style : normal;\n font-variant : normal;\n font-weight : normal;\n height : auto;\n hyphens : none;\n left : auto;\n letter-spacing : normal;\n line-height : normal;\n list-style : none;\n list-style-image : none;\n list-style-position : outside;\n list-style-type : disc;\n margin : 0;\n margin-bottom : 0;\n margin-left : 0;\n margin-right : 0;\n margin-top : 0;\n max-height : none;\n max-width : none;\n min-height : 0;\n min-width : 0;\n opacity : 1;\n orphans : 0;\n outline : 0;\n outline-color : invert;\n outline-style : none;\n outline-width : medium;\n overflow : visible;\n overflow-x : visible;\n overflow-y : visible;\n padding : 0;\n padding-bottom : 0;\n padding-left : 0;\n padding-right : 0;\n padding-top : 0;\n page-break-after : auto;\n page-break-before : auto;\n page-break-inside : auto;\n perspective : none;\n perspective-origin : 50% 50%;\n position : static;\n right : auto;\n tab-size : 8;\n table-layout : auto;\n text-align : inherit;\n text-align-last : auto;\n text-decoration : none;\n text-decoration-color : inherit;\n text-decoration-line : none;\n text-decoration-style : solid;\n text-indent : 0;\n text-shadow : none;\n text-transform : none;\n top : auto;\n transform : none;\n transform-style : flat;\n transition : none;\n transition-delay : 0s;\n transition-duration : 0s;\n transition-property : none;\n transition-timing-function : ease;\n unicode-bidi : normal;\n vertical-align : baseline;\n visibility : visible;\n white-space : normal;\n widows : 0;\n width : auto;\n word-spacing : normal;\n word-break: normal;\n z-index : auto;\n }\n `\n}\n","export const checkStatus = (response: any) => {\n if (response.status >= 200 && response.status < 300) {\n return response\n } else {\n throw new Error(response.statusText)\n }\n}\n\nexport const parseJSON = (response: any) => {\n return response.json()\n}\n","/* global yotpoWidgetsContainer */\n\nimport { AnalyticsController, AnalyticsService } from '../services/analytics/types'\n\nexport const isContainerDefined = (): boolean => {\n // @ts-ignore\n return typeof (yotpoWidgetsContainer) !== 'undefined'\n}\n\nexport const registerToContainer = (name: string, constructor: Function): void => {\n // @ts-ignore\n yotpoWidgetsContainer[name] = constructor\n}\n\nexport const initWidgets = () => {\n // @ts-ignore\n yotpoWidgetsContainer.initWidgets()\n}\n\nexport const initAnalytics = (analyticsController: AnalyticsController): AnalyticsService => {\n // @ts-ignore\n return new yotpoWidgetsContainer.Analytics(analyticsController)\n}\nexport const isAnalyticsDefined = (): boolean => {\n // @ts-ignore\n return isContainerDefined() && !!yotpoWidgetsContainer.Analytics\n}\n","/* global Shopify */\nimport { Product } from '../models/product'\nimport { SellingPlan } from '../models/selling-plan'\nimport { SellingPlanGroup } from '../models/selling-plan-group'\nimport { Variant } from '../models/variant'\nimport { checkStatus, parseJSON } from '../utils/ajax'\nimport { PriceAdjustment } from '../models/price-adjustments'\nimport {\n SellingPlanAllocation\n} from '../models/selling-plan-allocation'\nimport { initWidgets } from '../container/widgets-container'\nimport { widgetState } from '../store/customizations/index'\n\ndeclare const SHOPIFY_BASE_URL: string\n\nconst baseUrl = SHOPIFY_BASE_URL || ''\n\nconst adaptSellingPlan = (sellingPlansResponse: any): SellingPlan => {\n return {\n id: sellingPlansResponse.id,\n description: sellingPlansResponse.description,\n name: sellingPlansResponse.name,\n options: sellingPlansResponse,\n priceAdjustments: resolvePriceAdjustments(sellingPlansResponse)\n }\n}\n\nfunction resolvePriceAdjustments (sellingPlansResponse: any): PriceAdjustment[] {\n return sellingPlansResponse.price_adjustments.map((price: any) => {\n return {\n valueType: price.value_type,\n value: price.value\n }\n })\n}\n\nconst adaptSellingPlanGroup = (productPrice: number, variants: Variant[]) => (sellingPlanGroupResponse: any): SellingPlanGroup => {\n return {\n id: sellingPlanGroupResponse.id,\n name: sellingPlanGroupResponse.name,\n sellingPlans: sellingPlanGroupResponse.selling_plans.map(adaptSellingPlan),\n options: sellingPlanGroupResponse.options\n }\n}\n\nconst adaptSellingPlanAllocations = (sellingPlanAllocation: any): SellingPlanAllocation => {\n return {\n groupId: sellingPlanAllocation.selling_plan_group_id,\n sellingPlanId: sellingPlanAllocation.selling_plan_id,\n price: getPriceWithCurrency(sellingPlanAllocation.price)\n }\n}\n\nconst adaptVariants = (variantsResponse: any): Variant => {\n return {\n id: variantsResponse.id,\n title: variantsResponse.title,\n price: getPriceWithCurrency(variantsResponse.price),\n sellingPlanAllocations: variantsResponse.selling_plan_allocations.map(adaptSellingPlanAllocations)\n }\n}\n\nconst isYotpoSellingPlanGroup = (sellingPlanGroupResponse: any): boolean => {\n if (!sellingPlanGroupResponse.app_id) {\n return false\n }\n return sellingPlanGroupResponse.app_id.toLowerCase() === 'yotpo echo'\n}\n\nconst adaptProductResponse = (response: any): Product => {\n const variants = response.variants.map(adaptVariants)\n return {\n id: response.id,\n description: response.description,\n handle: response.handle,\n title: response.title,\n price: getPriceWithCurrency(response.price),\n requiresSellingPlan: response.requires_selling_plan,\n sellingPlanGroups: response.selling_plan_groups.filter(isYotpoSellingPlanGroup).map(adaptSellingPlanGroup(response.price, variants)),\n variants: variants,\n priceVaries: response.price_varies\n }\n}\n\nexport const getProductInfo = (productHandle: string): Promise => {\n return fetch(`${baseUrl}/products/${productHandle}.js`)\n .then(checkStatus)\n .then(parseJSON)\n .then(adaptProductResponse)\n}\n\nexport const isInShopifyDesignMode = (): boolean => {\n // @ts-ignore\n return typeof (Shopify) !== 'undefined' && Shopify.designMode\n}\n\nexport const ensureWidgetInEditorMode = () => {\n if (isInShopifyDesignMode()) {\n const interval = setInterval(() => {\n const widgetElement = document.querySelector('.yotpo-widget-subscriptions-add-to-cart')\n if (!widgetElement) {\n initWidgets()\n clearInterval(interval)\n }\n }, 3000)\n }\n}\n\nconst getPriceWithCurrency = (price: number): number => {\n if (widgetState.customizations.priceLabel.currency.enabled) {\n const rate = getCurrencyRate()\n if (widgetState.customizations.priceLabel.currency.roundUp) {\n return roundUpCurrency(price, rate)\n }\n return price * rate\n }\n return price\n}\n\nconst getCurrencyRate = (): number => {\n if (widgetState.customizations.priceLabel.currency.rate !== 1.0) {\n return widgetState.customizations.priceLabel.currency.rate\n }\n // @ts-ignore\n if (typeof Shopify !== 'undefined' && Shopify.currency && Shopify.currency.rate) {\n // @ts-ignore\n return parseFloat(Shopify.currency.rate)\n }\n return 1.0\n}\n\nconst roundUpCurrency = (price: number, rate: number): number => {\n if (getCurrency() === 'jpy') {\n return Math.ceil(price * rate / 10000) * 10000\n }\n return Math.ceil((price * rate / 100)) * 100\n}\n\nconst getCurrency = (): string => {\n if (widgetState.customizations.priceLabel.currency.name) {\n return widgetState.customizations.priceLabel.currency.name.toLowerCase()\n }\n // @ts-ignore\n if (typeof Shopify !== 'undefined' && Shopify.currency && Shopify.currency.active) {\n // @ts-ignore\n return Shopify.currency.active.toLowerCase()\n }\n return ''\n}\n","import { buildElement, getHtmlElementByClassName } from '../../utils/element'\nimport { isBuyOnceId } from '../../models/buy-once'\nimport { widgetState } from '../../store/customizations/index'\nimport { getSelectedGroupId } from '../../store/selling-plans/getters'\n\nexport const renderSubscriptionPolicy = (mainElement: HTMLElement) => {\n if (!widgetState.customizations.subscriptionPolicy.shouldShow) {\n return\n }\n const subscriptionPolicy = getSubscriptionPolicyElement()\n mainElement.appendChild(subscriptionPolicy)\n addOpenSubscriptionToOnChangeEvent()\n}\n\nexport const openSubscriptionPolicies = () => {\n const selectedGroupId = getSelectedGroupId()\n\n if (isBuyOnceId(selectedGroupId)) {\n getHtmlElementByClassName('yotpo-subscription-policy-wrapper').style.display = 'none'\n return\n }\n\n getHtmlElementByClassName('yotpo-subscription-policy-wrapper').style.display = 'block'\n}\n\nconst addOpenSubscriptionToOnChangeEvent = () => {\n getHtmlElementByClassName('yotpo-selling-plans-wrapper')\n .addEventListener('change', () => openSubscriptionPolicies())\n}\n\nconst getSubscriptionPolicyElement = (): HTMLElement => {\n const wrapper = buildElement('div', 'yotpo-subscription-policy-wrapper', {})\n const container = buildElement('div', `${widgetState.customizations.isReadOnly ? 'yotpo-subscription-policy-container yotpo-admin-preview' : 'yotpo-subscription-policy-container'}`, {})\n const main = buildElement('div', 'yotpo-subscription-policy', {})\n\n const textHeader = getTextHeader()\n main.appendChild(textHeader)\n\n const textMain = getMainText()\n main.appendChild(textMain)\n\n const textFooter = getTextFooter()\n if (textFooter) {\n main.appendChild(textFooter)\n }\n\n const radioStyle = buildElement('style', 'yotpo-subscription-policy-style', {})\n radioStyle.innerHTML = getStyles()\n\n container.appendChild(main)\n wrapper.appendChild(container)\n wrapper.appendChild(radioStyle)\n\n return wrapper\n}\n\nconst getTextHeader = () => {\n const textHeader = buildElement('div', 'yotpo-subscription-policy-text-header', {})\n textHeader.innerHTML = getSelectedSellingPlanGroup()\n getHtmlElementByClassName('yotpo-selling-plans-wrapper').addEventListener('change', () => {\n textHeader.innerHTML = getSelectedSellingPlanGroup()\n })\n return textHeader\n}\n\nconst getMainText = () => {\n const textMain = buildElement('div', 'yotpo-subscription-policy-text-main', {})\n textMain.textContent = widgetState.customizations.subscriptionPolicy.description\n return textMain\n}\n\nconst getTextFooter = () => {\n const informationLink = widgetState.customizations.subscriptionPolicy.informationLink\n if (informationLink) {\n const defaultInformationLink = `${window.location.origin}/policies/subscription-policy.html?locale=en`\n const textFooter = buildElement('a', 'yotpo-subscription-policy-text-footer', {\n target: '_blank',\n href: informationLink || defaultInformationLink\n })\n textFooter.innerHTML = widgetState.customizations.subscriptionPolicy.footer\n return textFooter\n }\n}\n\nconst getSelectedSellingPlanGroup = (): string => {\n const selectedLabel = document.querySelector('.yotpo-selected .yotpo-radio-label-text')\n if (selectedLabel) {\n return selectedLabel.innerHTML\n }\n}\n\nconst getStyles = (): string => {\n return `\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-policy-wrapper {\n display: none;\n margin: 0 0 10px 0;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-policy-container {\n text-align: initial;\n width: 100%;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-policy-container.yotpo-admin-preview {\n margin: auto;\n max-width: 400px;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-policy {\n background: ${widgetState.customizations.styles.notSelectedRadio.backgroundColor};\n border-radius: 8px;\n display: grid;\n padding: 10px 15px;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-policy-text-header, .yotpo-subscription-policy-text-main, .yotpo-subscription-policy-text-footer {\n margin: 5px;\n font-style: normal;\n font-family: ${widgetState.customizations.styles.fontFamily.name};\n font-weight: ${widgetState.customizations.styles.fontFamily.weight || 500};\n line-height: 20px;\n width: 99%;\n color: ${widgetState.customizations.styles.colors.text.primary};\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-policy-text-main, .yotpo-subscription-policy-text-footer {\n color: ${widgetState.customizations.styles.fontSize.primary};\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-policy-text-header {\n color: ${widgetState.customizations.styles.colors.text.primary};\n font-size: ${widgetState.customizations.styles.fontSize.primary};\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-policy-text-main {\n color: ${widgetState.customizations.styles.fontSize.primary};\n font-size: ${widgetState.customizations.styles.fontSize.primary};\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-policy-text-footer {\n text-decoration: underline;\n font-size: ${widgetState.customizations.styles.fontSize.primary};\n }\n `\n}\n","import { buildElement } from '../../../utils/element'\nimport * as Mustache from 'mustache'\nimport { TemplateOptions } from '../../../models/render-options'\nimport { widgetState } from '../../../store/customizations/index'\n\nexport const buildTemplate = (options: TemplateOptions, template: string) => {\n const html = Mustache.render(template, {\n ...options,\n checkedFn: () => {\n return options.checked ? 'checked=true' : ''\n },\n checkedClassFn: () => {\n return options.checked ? 'yotpo-checked' : ''\n }\n })\n\n const element = buildElement('div', options.classString, options.attributes || {})\n element.innerHTML = html\n\n element.addEventListener('click', displaySelectedElement(options.id))\n\n return element\n}\n\nexport const displaySelectedElement = (value: string) => () => {\n document.querySelectorAll('[data-selling-plan-group-frequency-id]')\n .forEach(element => {\n const isClickedOn = element.getAttribute('data-selling-plan-group-frequency-id') === value\n const canClose = widgetState.customizations.selectionType !== 'radio-and-dropdown' || !widgetState.customizations.styles.selectedRadio.openByDefault\n if (canClose) {\n (element as HTMLElement).style.display = isClickedOn ? 'block' : 'none'\n }\n\n const inputEl = document.querySelector(`[data-seling-plan-group-id=\"${value}\"] .yotpo-radio-label-input`)\n pickElement(inputEl as HTMLElement, isClickedOn)\n })\n document.querySelectorAll('.yotpo-radio-container[data-seling-plan-group-id]')\n .forEach(element => {\n const isClickedOn = element.getAttribute('data-seling-plan-group-id') === String(value)\n pickElement(element as HTMLElement, isClickedOn)\n })\n}\n\nconst pickElement = (element: HTMLElement, isClickedOn: boolean): void => {\n const currnectClass2 = element.getAttribute('class')\n .replace('yotpo-not-selected', '')\n .replace('yotpo-selected', '')\n const klass = isClickedOn ? 'yotpo-selected' : 'yotpo-not-selected'\n element.setAttribute('class', `${currnectClass2} ${klass}`)\n}\n","export const getPriceCurrencySymbol = (priceFormat: string) => {\n return priceFormat.replace(/[0-9,.]/g, '')\n}\n\nexport const getWithCurrencySymbol = (priceFormat: string, price: number): string => {\n const priceWithDecimal = getWithDecimal(price)\n const priceFormatCurrencyPosition = Number(priceFormat[0])\n const currencySymbol = getPriceCurrencySymbol(priceFormat)\n return Number.isInteger(priceFormatCurrencyPosition)\n ? formatPrice(priceFormat, priceWithDecimal) + currencySymbol\n : currencySymbol + formatPrice(priceFormat, priceWithDecimal)\n}\n\nexport const formatPrice = (priceFormat: string, price: string): string => {\n const decimalFormat = (/\\B(?=(\\d{3})+(?!\\d))/g)\n const decimalTypeCount = (priceFormat.match(/[.]/g) || []).length\n return decimalTypeCount === 1\n ? price.replace(decimalFormat, ',')\n : price.replace('.', ',')\n .replace(decimalFormat, '.')\n}\n\nexport const getWithDecimal = (price: number): string => {\n return (price / 100).toFixed(2)\n}\n","import { buildElement } from '../../../utils/element'\nimport { SellingPlanGroup } from '../../../models/selling-plan-group'\nimport { getBuyOnceAsSellingPlanGroup, isBuyOnceId, shouldShowBuyOnce } from '../../../models/buy-once'\nimport { widgetState } from '../../../store/customizations/index'\nimport { getLowestDiscountByGroupForVariant, getSellingPlanAllocationForVariant } from '../../../models/selling-plan-allocation'\nimport { getSelectedSellingPlanGroupId, getSelectedSellingPlanId, getSellingPlanGroups } from '../../../store/selling-plans/getters'\nimport { getWithCurrencySymbol } from '../../../models/price-format'\n\nconst wrapperElementClass = 'yotpo-subscription-price-label-wrapper'\n\nexport const buildPriceLabel = (group: SellingPlanGroup, isSubscription: boolean, isSelected: boolean): HTMLElement => {\n const wrapperElement = buildElement('div', wrapperElementClass, {})\n const containerElement = buildElement('div', 'yotpo-subscription-price-label-container', {})\n\n if (isSubscription && shouldShowPrefix(isSelected)) {\n const pricePrefixElement = buildElement('div', 'yotpo-subscription-label-prefix', {})\n pricePrefixElement.textContent = widgetState.customizations.priceLabel.prefix\n wrapperElement.appendChild(pricePrefixElement)\n }\n\n const priceElement = buildElement('div', 'yotpo-subscription-label-price', {})\n\n const price = getPrice(group, isSelected)\n const priceFormat = widgetState.customizations.fullFormatProductPrice\n const fullPriceWithCurrency = getWithCurrencySymbol(priceFormat, price)\n\n priceElement.textContent = fullPriceWithCurrency\n containerElement.appendChild(priceElement)\n\n wrapperElement.appendChild(containerElement)\n\n return wrapperElement\n}\n\nexport const replacePriceElement = () => {\n const groups = getSellingPlanGroups()\n\n if (shouldShowBuyOnce()) {\n groups.push(getBuyOnceAsSellingPlanGroup())\n }\n\n groups.forEach(group => {\n const priceWrapElement = document.querySelector(`[data-seling-plan-group-id=\"${group.id}\"] .${wrapperElementClass}`)\n\n if (priceWrapElement) {\n const newPriceElement = buildPriceLabel(\n group,\n !isBuyOnceId(group.id),\n group.id === getSelectedSellingPlanGroupId()\n )\n priceWrapElement.replaceWith(newPriceElement)\n }\n })\n}\n\nconst shouldShowPrefix = (isSelected: boolean): boolean => {\n if (widgetState.customizations.priceLabel.strategy === 'starting_from') {\n return true\n }\n if (widgetState.customizations.priceLabel.strategy === 'starting_and_actual') {\n return !isSelected\n }\n return false\n}\n\nconst getPrice = (group: SellingPlanGroup, isSelected: boolean): number => {\n if (widgetState.customizations.priceLabel.strategy === 'starting_and_actual' && isSelected) {\n return getSelectedPriceForGroup(group)\n }\n return getLowestDiscountByGroupForVariant(group.id)\n}\n\nconst getSelectedPriceForGroup = (group: SellingPlanGroup): number => {\n const sellingPlans = group.sellingPlans\n const plan = sellingPlans.find(plan => {\n if (!plan.id) {\n return false\n }\n return plan.id.toString() === getSelectedSellingPlanId()\n })\n if (!plan) {\n return getLowestDiscountByGroupForVariant(group.id)\n }\n return getSellingPlanAllocationForVariant(group.id, plan.id)\n}\n","import { ColorUtils } from './colors'\n\nexport class Color {\n public r: number\n public g: number\n public b: number\n public a: number\n\n constructor (colorString: string) {\n colorString = colorString.trim()\n if (colorString.indexOf('rgb') >= 0) {\n const parts = ColorUtils.getRgbaParts(colorString)\n if (!parts) {\n this.r = 0\n this.g = 0\n this.b = 0\n this.a = 1\n return\n }\n this.r = parseInt(parts[1], 10)\n this.g = parseInt(parts[2], 10)\n this.b = parseInt(parts[3], 10)\n this.a = parts[5] ? parseFloat(parts[5]) : 1\n return\n }\n\n if (colorString.indexOf('#') === 0) {\n if (colorString.length >= 4 && colorString.length <= 5) {\n this.r = parseInt(colorString[1] + colorString[1], 16)\n this.g = parseInt(colorString[2] + colorString[2], 16)\n this.b = parseInt(colorString[3] + colorString[3], 16)\n if (colorString.length === 5) {\n const roundedA = parseInt(colorString[4] + colorString[4], 16)\n this.a = +(roundedA / 255).toFixed(3)\n } else {\n this.a = 1\n }\n return\n }\n if (colorString.length >= 7 && colorString.length <= 9) {\n this.r = parseInt(colorString.substring(1, 3), 16)\n this.g = parseInt(colorString.substring(3, 5), 16)\n this.b = parseInt(colorString.substring(5, 7), 16)\n if (colorString.length === 9) {\n const roundedA = parseInt(colorString.substring(7, 9), 16)\n this.a = +(roundedA / 255).toFixed(3)\n } else {\n this.a = 1\n }\n return\n }\n this.r = 0\n this.g = 0\n this.b = 0\n this.a = 1\n return\n }\n\n const colors = require('color-name') // eslint-disable-line @typescript-eslint/no-var-requires\n const colorParts = (colors[colorString.toLowerCase()] as string[])\n this.r = parseInt(colorParts[0], 10)\n this.g = parseInt(colorParts[1], 10)\n this.b = parseInt(colorParts[2], 10)\n this.a = 1\n }\n\n tint (tintRate: number): void {\n this.r = this.calculateTintValue(this.r, tintRate)\n this.g = this.calculateTintValue(this.g, tintRate)\n this.b = this.calculateTintValue(this.b, tintRate)\n }\n\n private calculateTintValue (colorValue: number, tintRate: number): number {\n return ((255 - colorValue) * (1 - tintRate)) + colorValue\n }\n\n toHex (): string {\n return ColorUtils.getHexFromRgbParts([this.r.toString(), this.g.toString(), this.b.toString()])\n }\n\n toRgb (): string {\n return `rgb(${this.r}, ${this.g}, ${this.b})`\n }\n\n toRgba (): string {\n return `rgba(${this.r}, ${this.g}, ${this.b}, ${this.a})`\n }\n}\n","import { Color } from './color'\n\nexport class ColorUtils {\n static getContrastColor (colorString: string): string {\n if (!colorString) {\n return 'black'\n }\n let hexColor = colorString\n if (colorString.indexOf('rgb') >= 0) {\n hexColor = ColorUtils.convertRgbaToHex(colorString)\n }\n if (hexColor.indexOf('#') !== 0 || hexColor.length <= 6) {\n const colors = require('color-name') // eslint-disable-line @typescript-eslint/no-var-requires\n const colorParts = (colors[colorString] as string[])\n if (!colorParts) {\n return 'black'\n }\n hexColor = ColorUtils.getHexFromRgbParts(colorParts)\n }\n return ColorUtils.getContrastColorFromHex(hexColor)\n }\n\n static getContrastColorFromHex (hexcolor: string): string {\n hexcolor = hexcolor.replace('#', '')\n const r = parseInt(hexcolor.substr(0, 2), 16)\n const g = parseInt(hexcolor.substr(2, 2), 16)\n const b = parseInt(hexcolor.substr(4, 2), 16)\n const yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000\n return (yiq >= 128) ? 'black' : 'white'\n }\n\n static convertRgbaToHex (rgbaColor: string): string {\n const parts = this.getRgbaParts(rgbaColor)\n return (parts && parts.length === 4)\n ? ColorUtils.getHexFromRgbParts([parts[1], parts[2], parts[3]])\n : ''\n }\n\n static getRgbaParts (rgbaColor: string): RegExpMatchArray | null {\n return rgbaColor.match(/^rgba?[\\s+]?\\([\\s+]?(\\d+)[\\s+]?,[\\s+]?(\\d+)[\\s+]?,[\\s+]?(\\d+)[\\s+]?/i)\n }\n\n static getHexFromRgbParts (parts: string[]): string {\n return (parts && parts.length === 3)\n ? '#' +\n ('0' + parseInt(parts[0], 10).toString(16)).slice(-2) +\n ('0' + parseInt(parts[1], 10).toString(16)).slice(-2) +\n ('0' + parseInt(parts[2], 10).toString(16)).slice(-2)\n : ''\n }\n\n static getWithOpacity (color: string, opacity: string): string {\n const c = new Color(color)\n c.a = parseFloat(opacity)\n return c.toRgba()\n }\n}\n","import { MerchantState } from './types'\n\nexport const merchantState: MerchantState = {\n guid: ''\n}\n","import { ViewState } from './types'\n\nexport const viewState: ViewState = {\n mainElement: null,\n formId: ''\n}\n","import { viewState } from './index'\n\nexport const setMainElement = (mainElement: HTMLElement) => {\n viewState.mainElement = mainElement\n}\n\nexport const setFormId = (formId: string) => {\n viewState.formId = formId\n}\n","import { widgetState } from '../../store/customizations/index'\nimport { setFormId } from '../../store/view/actions'\n\nconst formSelector = \"form[action^='/cart/add']\"\n\nexport const injectWidget = (currentElement: HTMLElement, mainElement: HTMLElement): void => {\n const isInStore = widgetState.customizations.isDresser || (!widgetState.customizations.isReadOnly && !widgetState.customizations.isPreview)\n const isOutOfFormAllowed = widgetState.customizations.allowOutOfForm\n const autoInjectEnabled = isInStore &&\n widgetState.customizations.autoInject.enabled\n if (!autoInjectEnabled) {\n injectIntoPlaceholder(currentElement, mainElement)\n return\n }\n if (isOutOfFormAllowed) {\n const formElement = getFormElement()\n if (formElement) {\n injectIntoPlaceholder(currentElement, mainElement)\n return\n }\n }\n const adjacentStrategy = widgetState.customizations.autoInject.adjacentStrategy || getAdjacentStrategy()\n const targetElement = getInjectionTargetElement()\n if (isElementInForm(targetElement)) {\n targetElement.insertAdjacentElement(adjacentStrategy, mainElement)\n removePlaceholder(currentElement)\n return\n }\n if (!targetElement && isElementInForm(currentElement)) {\n injectIntoPlaceholder(currentElement, mainElement)\n return\n }\n throw new Error('element is not within a form')\n}\n\nexport const getFormElement = (): Element | null => {\n let injectionTargetElement = getInjectionTargetElement()\n while (injectionTargetElement && injectionTargetElement.parentNode && injectionTargetElement.nodeName.toLowerCase() !== 'form') {\n injectionTargetElement = injectionTargetElement.parentElement\n }\n if (injectionTargetElement) {\n return injectionTargetElement.nodeName.toLowerCase() === 'form' ? injectionTargetElement : null\n }\n return null\n}\n\nexport const getAutoInjectSelector = (): string => {\n if (!isElementExists(formSelector)) {\n return ''\n }\n const buttonSelector = \"button[type^='submit']\"\n const inputSelector = \"input[type^='submit']\"\n const selectorPriorities = [buttonSelector, inputSelector]\n return findInElement(formSelector, selectorPriorities)\n}\n\nexport const getAdjacentStrategy = (): 'beforebegin' | 'afterbegin' | 'beforeend' | 'afterend' => {\n const autoInjectSelector = getAutoInjectSelector().toString()\n if (autoInjectSelector) {\n const autoInjectSelectorElement = document.querySelectorAll(autoInjectSelector)\n const isButtonOrInput = autoInjectSelectorElement[autoInjectSelectorElement.length - 1].nodeName.toLowerCase()\n if (isButtonOrInput === 'button' || isButtonOrInput === 'input') {\n return 'beforebegin'\n }\n }\n return 'afterbegin'\n}\n\nconst isElementExists = (selector: string): boolean => {\n return document.querySelectorAll(selector).length > 0\n}\n\nconst injectIntoPlaceholder = (currentElement: HTMLElement, mainElement: HTMLElement) => {\n currentElement.parentNode.replaceChild(mainElement, currentElement)\n}\n\nconst isElementInForm = (element: Element): boolean => {\n if (!element) {\n return false\n }\n let isForm = element\n while (isForm && isForm.parentNode && isForm.nodeName.toLowerCase() !== 'form') {\n isForm = isForm.parentElement\n }\n if (isForm) {\n return isForm.nodeName.toLowerCase() === 'form'\n }\n return false\n}\n\nconst findInElement = (parentSelector: string, selectorsPriority: string[]): string => {\n for (let i = 0; i < selectorsPriority.length; i++) {\n const selector = `${parentSelector} ${selectorsPriority[i]}`\n if (isElementExists(selector)) {\n return selector\n }\n }\n return parentSelector\n}\n\nconst getInjectionTargetElement = (): Element | null => {\n const isTargetSet = !!widgetState.customizations.autoInject.targetSelector\n const selector = widgetState.customizations.autoInject.targetSelector || getAutoInjectSelector()\n\n if (!selector) {\n return null\n }\n\n let formPlace = 'last'\n if (!isTargetSet) {\n const hasMoreThan3Forms = document.querySelectorAll(formSelector).length >= 3\n if (hasMoreThan3Forms) {\n formPlace = 'first'\n }\n }\n\n const hostElements = document.querySelectorAll(selector)\n if (hostElements.length === 0) {\n return null\n }\n if (formPlace === 'first') {\n return hostElements[0]\n }\n return hostElements[hostElements.length - 1]\n}\n\nconst removePlaceholder = (element: HTMLElement): void => {\n if (element && element.parentElement) {\n element.parentElement.removeChild(element)\n }\n}\n\nexport const bindWidgetToFormId = (form: HTMLElement): void => {\n let formId = form.getAttribute('id')\n if (!formId) {\n formId = 'yotpo-add-to-cart-form-id'\n form.setAttribute('id', formId)\n }\n setFormId(formId)\n}\n","export interface Promiseable {\n do (): any\n checker(): boolean\n resolve (data: any): void\n reject (): void\n}\n\nexport const retryWithTimeout = (action: Promiseable, interval: number, retryCount: number) => {\n if (retryCount <= 0) {\n action.reject()\n return\n }\n if (!action.checker()) {\n setTimeout(() => {\n retryCount -= 1\n retryWithTimeout(action, interval, retryCount)\n }, interval)\n return\n }\n\n action.resolve(action.do())\n}\n","import { initAnalytics, isAnalyticsDefined } from '../../container/widgets-container'\nimport { Promiseable, retryWithTimeout } from '../../utils/retry'\nimport { AnalyticsController, AnalyticsService, PixelEvent } from './types'\n\nconst trackRetries = 10\nconst trackRetriesIntervalMs = 50\nconst reportingEndPoints = ['p.yotpo.com']\nconst apiId = 'onsite_v3'\n\nexport class YotpoAnalytics {\n static track (guid: string, event: PixelEvent): Promise {\n return new Promise((resolve, reject) => {\n YotpoAnalytics.doTrack(guid, event, trackRetries, trackRetriesIntervalMs, resolve, reject)\n })\n }\n\n static getUniqueUserIdentifier (guid: string): Promise {\n return new Promise((resolve, reject) => {\n YotpoAnalytics.doGetUniqueUserIdentifier(guid, trackRetries, trackRetriesIntervalMs, resolve, reject)\n })\n }\n\n private static doGetUniqueUserIdentifier (guid: string, retryCount: number, retryInterval: number, resolve: any, reject: any): void {\n const action: Promiseable = {\n do: () => {\n return YotpoAnalytics.doGetUserId(guid)\n },\n checker: (): boolean => {\n return YotpoAnalytics.isYotpoAnalyticsExists()\n },\n resolve: (data: any) => {\n resolve(data)\n },\n reject: () => {\n reject('timeout waiting for analytics')\n }\n }\n retryWithTimeout(action, retryInterval, retryCount)\n }\n\n private static isYotpoAnalyticsExists (): boolean {\n return isAnalyticsDefined()\n }\n\n private static doTrack (guid: string, event: PixelEvent, retryCount: number, retryInterval: number, resolve: any, reject: any) {\n const action: Promiseable = {\n do: () => {\n const service = YotpoAnalytics.getAnalyticsService(guid)\n service.trackEvent(event.category, event.action, event.label, event.property, event.context)\n return true\n },\n checker: (): boolean => {\n return YotpoAnalytics.isYotpoAnalyticsExists()\n },\n resolve: (data: any) => {\n resolve(data)\n },\n reject: () => {\n reject('timeout waiting for analytics')\n }\n }\n retryWithTimeout(action, retryInterval, retryCount)\n }\n\n private static getController (guid: string): AnalyticsController {\n const userSettings: any = {\n reporting_end_points: reportingEndPoints\n }\n return {\n getAnalyticsVersion (): string {\n return apiId\n },\n getUserSetting (key: string): string {\n return userSettings[key]\n },\n getAppKey (): string {\n return guid\n }\n }\n }\n\n private static getAnalyticsService (guid: string): AnalyticsService {\n const analyticsController = YotpoAnalytics.getController(guid)\n return initAnalytics(analyticsController)\n }\n\n private static doGetUserId (guid: string) {\n const service = YotpoAnalytics.getAnalyticsService(guid)\n return service.getDomainUserId()\n }\n}\n","import { widgetState } from '../../store/customizations/index'\nimport { merchantState } from '../../store/merchant/index'\nimport { getProduct } from '../../store/product/getters'\nimport { getSelectedSellingPlanGroup, getSelectedSellingPlanId, getSellingPlanGroups } from '../../store/selling-plans/getters'\nimport { getFormElement } from '../injection/injection'\nimport { DurationStats, PixelEvent } from './types'\nimport { YotpoAnalytics } from './yotpo-analytics'\n\nexport const dispatchEvent = (event: PixelEvent): void => {\n if (!shouldSendAnalytics()) {\n return\n }\n const productPageEvent = {\n ...event,\n category: 'product-page-widget'\n }\n YotpoAnalytics.track(merchantState.guid, productPageEvent)\n}\n\nexport const getLoadedEvent = (instanceId: number, instanceVersionId: number): PixelEvent => {\n return {\n action: 'loaded',\n context: {\n widget_instance_id: instanceId,\n instance_version_id: instanceVersionId,\n ...getDurationStats()\n }\n }\n}\n\nexport const dispatchLoadedEvent = (loadedEvent: PixelEvent): void => {\n loadedEvent.context = {\n ...loadedEvent.context,\n should_be_shown: widgetState.customizations.isLaunched && getSellingPlanGroups().length > 0,\n is_launched: widgetState.customizations.isLaunched,\n live_preview: widgetState.customizations.livePreview.show\n }\n dispatchEvent(loadedEvent)\n}\n\nconst shouldSendAnalytics = () => {\n return !(widgetState.customizations.isReadOnly || widgetState.customizations.isPreview)\n}\n\nexport const initAddToCartAnalytics = (): void => {\n const addToCartForm = getFormElement()\n if (addToCartForm) {\n addToCartForm.addEventListener('submit', () => {\n try {\n addToCartSuccess()\n } catch (error) {\n console.error(error)\n }\n })\n } else {\n dispatchEvent({\n action: 'error',\n label: 'add_to_cart',\n context: {\n error_msg: 'missing add to cart form'\n }\n })\n }\n}\n\nconst addToCartSuccess = (): void => {\n const selectedSellingPlanGroup = getSelectedSellingPlanGroup()\n if (selectedSellingPlanGroup && selectedSellingPlanGroup.id !== 'buy-once') {\n dispatchEvent({\n action: 'clicked_on',\n label: 'add_to_cart',\n context: {\n product_id: getProduct().id.toString(),\n selling_plan_id: getSelectedSellingPlanId(),\n selected_group_id: selectedSellingPlanGroup.id,\n live_preview: widgetState.customizations.livePreview.show\n }\n })\n }\n}\n\nconst getDurationStats = (): DurationStats|null => {\n if (typeof (window) !== 'undefined' && window.performance && window.performance.getEntriesByName) {\n const widgetEnd = window.performance.now()\n const initStart = window.performance.getEntriesByName('yotpo:initializer:loaded')\n if (initStart.length > 0) {\n const durationFromInit = Math.round(widgetEnd - initStart[0].startTime)\n let durationFromDomLoadedEvent = 0\n if (window.performance.timing) {\n const domLoaded = (window.performance.timing.domContentLoadedEventStart - window.performance.timing.navigationStart)\n durationFromDomLoadedEvent = Math.round(widgetEnd - domLoaded)\n }\n return {\n time_from_init_start: durationFromInit,\n time_from_dom_loaded: durationFromDomLoadedEvent\n }\n }\n }\n return null\n}\n","import { publishSellingPlanChangedEvent } from '../../events/selling-plan-changed'\nimport { SellingPlanGroup } from '../../models/selling-plan-group'\nimport { dispatchEvent } from '../../services/analytics/events'\nimport { widgetState } from '../customizations/index'\nimport { sellingPlansState } from './index'\n\nexport const setSellingPlanGroups = (sellingPlanGroups: SellingPlanGroup[]) => {\n sellingPlansState.sellingPlanGroups = sellingPlanGroups.slice(0)\n}\n\nexport const setSelectedSellingPlan = (sellingPlanGroupId: string, sellingPlanId: string) => {\n sellingPlansState.selectedSellingPlanGroupId = sellingPlanGroupId\n sellingPlansState.selectedSellingPlanId = sellingPlanId\n}\n\nexport const setSellingPlanChange = (groupId: string, selectedSellingPlanId: string, isSubscription: boolean, productId: string, isDiscountAvailable: boolean) => {\n setSelectedSellingPlan(groupId, selectedSellingPlanId)\n publishSellingPlanChangedEvent({\n selectedGroupId: groupId,\n selectedSellingPlanId,\n isBuyOnce: !isSubscription\n })\n if (groupId !== 'buy-once') {\n dispatchEvent({\n action: 'clicked_on',\n context: {\n product_id: productId,\n selling_plan_id: selectedSellingPlanId,\n selected_group_id: groupId,\n live_preview: widgetState.customizations.livePreview.show\n }\n })\n }\n}\n","import { shouldShowBuyOnce } from '../../models/buy-once'\nimport { widgetState } from '../../store/customizations/index'\nimport { buildElement } from '../../utils/element'\n\nexport const getSellingPlansMainElementWrapper = () => {\n const isPreviewClass = widgetState.customizations.isPreview && !widgetState.customizations.livePreview.show ? 'yotpo-is-preview' : ''\n const isAdminClass = widgetState.customizations.isReadOnly ? 'yotpo-admin-preview' : ''\n return buildElement('div', `yotpo-selling-plans-wrapper ${isAdminClass} ${isPreviewClass}`, {})\n}\n\nexport const getSellingPlansMainElement = () => {\n return buildElement('div', 'yotpo-selling-plans', {})\n}\n\nexport const appendElementsInOrder = (element: HTMLElement, sellingPlanGroups: HTMLElement[], buyOnceElement: HTMLElement): void => {\n if (!shouldShowBuyOnce()) {\n element.append(...sellingPlanGroups)\n return\n }\n if (widgetState.customizations.oneTimeAtLast) {\n element.append(...sellingPlanGroups, buyOnceElement)\n return\n }\n element.append(buyOnceElement, ...sellingPlanGroups)\n}\n\nexport const getSelectedGroupIndex = (): number => {\n const autoPickOptionIndex = widgetState.customizations.autoPickOptionIndex\n return !shouldShowBuyOnce() && autoPickOptionIndex === 0 ? 1 : autoPickOptionIndex\n}\n","import { getPriceAdjustmentLabel, PriceAdjustment } from '../../../models/price-adjustments'\nimport { getPriceCurrencySymbol } from '../../../models/price-format'\nimport { widgetState } from '../../../store/customizations/index'\nimport { getSellingPlanGroup, getSellingPlanGroups } from '../../../store/selling-plans/getters'\n\nexport const groupsHasAnyDiscount = () => {\n return getSellingPlanGroups().some(group => group.sellingPlans.some(plan => {\n return plan.priceAdjustments.length && plan.priceAdjustments[0].value > 0\n }))\n}\nexport const getDiscountLabel = (priceAdjustments: PriceAdjustment[], groupId: string): string => {\n const group = getSellingPlanGroup(groupId)\n if (group.sellingPlans) {\n const hasAtLeastOneDiscount = group.sellingPlans.some(plan => {\n return plan.priceAdjustments.length && plan.priceAdjustments[0].value > 0\n })\n if (!hasAtLeastOneDiscount) {\n return ''\n }\n }\n if (priceAdjustments) {\n const firstPriceAdjusment = priceAdjustments[0]\n if (firstPriceAdjusment && firstPriceAdjusment.value) {\n return formatLabelWithDiscount(firstPriceAdjusment)\n }\n }\n return formatLabelWithoutDiscount()\n}\n\nconst formatLabelWithoutDiscount = () => {\n return `(${widgetState.customizations.tiles.fullPriceText})`\n}\n\nconst formatLabelWithDiscount = (firstPriceAdjusment: PriceAdjustment) => {\n const currency = getPriceCurrencySymbol(widgetState.customizations.fullFormatProductPrice)\n const priceAdjustmentLabel = getPriceAdjustmentLabel(firstPriceAdjusment, currency)\n const labelSuffix = widgetState.customizations.tiles.suffixText\n return `(${priceAdjustmentLabel}${labelSuffix})`\n}\n","import { SellingPlan } from '../../models/selling-plan'\n\ntype intervalType = 'day' | 'week' | 'month' | 'year'\n\nexport const sortingByFrequency = (plan1: SellingPlan, plan2: SellingPlan) => {\n const plan1Count = getCountInDays(plan1)\n const plan2Count = getCountInDays(plan2)\n return plan1Count - plan2Count\n}\n\nconst getCountInDays = (plan: SellingPlan) => {\n if (!plan.name) {\n return 0\n }\n const parts = plan.name.split(' ')\n const has2PartsAtLeast = parts.length >= 2\n if (!has2PartsAtLeast) {\n return 0\n }\n const startsWithEvery = parts[0].toLowerCase() === 'every'\n if (!startsWithEvery) {\n return 0\n }\n const count = parts.length === 2 ? '1' : parts[1]\n const type = parts.length === 2 ? parts[1] : parts[2]\n return getIntervalDays(count, type)\n}\n\nconst getIntervalDays = (countStr: string, typeStr: string): number => {\n const intervalCount = parseInt(countStr, 10)\n if (!intervalCount) {\n return 0\n }\n const intervalType = getIntervalType(typeStr)\n if (!intervalType) {\n return 0\n }\n return getIntervalCountInDays(intervalType, intervalCount)\n}\n\nconst getIntervalCountInDays = (type: intervalType, intervalCount: number): number => {\n switch (type) {\n case 'day':\n return intervalCount\n case 'week':\n return 7 * intervalCount\n case 'month':\n return 30 * intervalCount\n case 'year':\n return 365 * intervalCount\n }\n}\n\nconst getIntervalType = (namePart: string): intervalType | '' => {\n switch (namePart.toLowerCase()) {\n case 'day':\n case 'days':\n return 'day'\n case 'week':\n case 'weeks':\n return 'week'\n case 'month':\n case 'months':\n return 'month'\n case 'year':\n case 'years':\n return 'year'\n }\n return ''\n}\n","import { SellingPlan } from '../../models/selling-plan'\n\nexport const sortingByName = (plan1: SellingPlan, plan2: SellingPlan) => {\n if (plan1.name > plan2.name) {\n return 1\n } else if (plan1.name < plan2.name) {\n return -1\n }\n return 0\n}\n","import { SellingPlan } from '../../models/selling-plan'\nimport { widgetState } from '../../store/customizations/index'\nimport { sortingByFrequency } from './frequency'\nimport { sortingByName } from './name'\nimport { sortingByPrice } from './price'\n\nexport const sortStrategy = (groupId: string): (a: SellingPlan, b: SellingPlan) => number => {\n switch (widgetState.customizations.sellingPlans.sort.strategy) {\n case 'name':\n return sortingByName\n case 'price':\n return sortingByPrice(groupId)\n case 'frequency':\n return sortingByFrequency\n }\n}\n","import { SellingPlan } from '../../models/selling-plan'\nimport { getSellingPlanAllocationForVariant } from '../../models/selling-plan-allocation'\n\nexport const sortingByPrice = (groupId: string) => (plan1: SellingPlan, plan2: SellingPlan) => {\n const pricePlan1 = getSellingPlanAllocationForVariant(groupId, plan1.id)\n const pricePlan2 = getSellingPlanAllocationForVariant(groupId, plan2.id)\n return pricePlan1 - pricePlan2\n}\n","import { viewState } from './index'\n\nexport const getMainElement = (): HTMLElement => {\n return viewState.mainElement\n}\n\nexport const getFormId = (): string => {\n return viewState.formId\n}\n","import { getBuyOnceAsSellingPlanGroup } from '../../models/buy-once'\nimport { buildElement } from '../../utils/element'\nimport { widgetState } from '../../store/customizations/index'\nimport { buildTemplate, displaySelectedElement } from './widgets/template-builder'\nimport { radioTemplate } from '../templates/radio-template'\nimport { buildPriceLabel } from './widgets/price-label'\nimport { buildSelection } from './widgets/selection-builder'\nimport { selectionFactory } from './widgets/selection-factory'\nimport { Template } from '../../models/template'\nimport { SellingPlanGroup } from '../../models/selling-plan-group'\nimport { setSellingPlanChange } from '../../store/selling-plans/actions'\nimport { getProduct, getProductPrice } from '../../store/product/getters'\nimport { getSellingPlanGroups } from '../../store/selling-plans/getters'\nimport { appendElementsInOrder, getSelectedGroupIndex, getSellingPlansMainElement, getSellingPlansMainElementWrapper } from './layout'\nimport { PlanSelectionLayout } from '../../models/layout'\nimport { getLowestDiscountByGroupForVariant } from '../../models/selling-plan-allocation'\nimport { getDiscountLabel } from './widgets/discount'\nimport { SellingPlan } from '../../models/selling-plan'\nimport { sortStrategy } from '../../services/sort/selling-plans'\nimport { getFormId } from '../../store/view/getters'\n\nexport class RadioButtons implements PlanSelectionLayout {\n render (): HTMLElement {\n const sellingPlanGroupElements = getSellingPlanGroups().map((group, index) => {\n const isSelected = getSelectedGroupIndex() === (1 + index)\n return this.buildSellingPlanGroupElement(group, isSelected, true)\n })\n\n const mainElement = getSellingPlansMainElement()\n appendElementsInOrder(mainElement, sellingPlanGroupElements, this.buildBuyOnce())\n this.expandGroupOnAutoSelectedIndex()\n\n const mainElementWrapper = getSellingPlansMainElementWrapper()\n mainElementWrapper.appendChild(mainElement)\n mainElementWrapper.appendChild(this.styles())\n\n return mainElementWrapper\n }\n\n private buildSellingPlanGroupElement (group: SellingPlanGroup, checked: boolean, isSubscription: boolean): HTMLElement {\n const container = buildElement('div', `yotpo-radio-container ${checked ? 'yotpo-selected' : ''}`, {\n 'data-seling-plan-group-id': group.id\n })\n const radioElementsWrapper = buildElement('div', 'yotpo-radio-button-text-wrapper', {\n 'data-seling-plan-group-id': group.id\n })\n\n const template = widgetState.customizations.selectionType.split('-')[2]\n const formId = getFormId()\n const groupsTemplate = buildTemplate({\n id: group.id,\n value: group.sellingPlans[0] ? group.sellingPlans[0].id : '',\n text: group.name,\n checked,\n formId,\n classString: 'yotpo-radio-buttons',\n inputAttributes: {\n data: group.sellingPlans[0] ? group.sellingPlans[0].name : '',\n name: 'selling_plan'\n }\n },\n radioTemplate()\n )\n\n const priceLabel = buildPriceLabel(group, isSubscription, checked)\n\n const frequencyTemplate = selectionFactory(template as Template)\n const sortingStrategy = sortStrategy(group.id)\n const frequencyTemplateElement = buildSelection({\n values: group.sellingPlans.sort(sortingStrategy).map((x, index) => {\n const label = this.getSellingPlanLabel(x, group.id)\n return {\n id: x.id,\n label: label,\n value: x.id.toString(),\n checked: index === 0\n }\n }),\n attributes: {},\n classString: 'yotpo-select-wrapper',\n id: group.id,\n groupId: group.id\n },\n frequencyTemplate\n )\n\n radioElementsWrapper.appendChild(groupsTemplate)\n radioElementsWrapper.appendChild(priceLabel)\n container.appendChild(radioElementsWrapper)\n\n this.setElementClassForChangeEvent(group, container, frequencyTemplateElement, isSubscription)\n this.registerToElementChangeEvent(group, container, frequencyTemplateElement, isSubscription)\n\n return container\n }\n\n private registerToElementChangeEvent (group: SellingPlanGroup, element: HTMLElement, container: HTMLElement, isSubscription: boolean) {\n element.addEventListener('change', (event: Event) => {\n const selectedSellingPlanId = (event.target as HTMLInputElement).value\n const price = getProductPrice()\n const isDiscountAvailable = price !== getLowestDiscountByGroupForVariant(group.id) && price > 0\n setSellingPlanChange(group.id, selectedSellingPlanId, isSubscription, getProduct().id.toString(), isDiscountAvailable)\n if (widgetState.customizations.selectionType === 'radio-and-dropdown') {\n const dropdownEl = document.querySelector('.yotpo-widget-subscriptions-add-to-cart .yotpo-frequency-options')\n if (dropdownEl) {\n (dropdownEl as HTMLElement).blur()\n }\n if (widgetState.customizations.styles.selectedRadio.openByDefault) {\n const parentInput = document.querySelector(`.yotpo-radio-button-text-wrapper[data-seling-plan-group-id=\"${group.id}\"] .yotpo-radio-label-input`)\n if (parentInput) {\n (parentInput as HTMLInputElement).checked = true\n }\n }\n }\n })\n }\n\n private styles (): any {\n const radioStyle = buildElement('style', 'yotpo-radio-style', {})\n radioStyle.innerHTML = `\n .yotpo-widget-subscriptions-add-to-cart {\n -webkit-appearance: none;\n -moz-appearance: none;\n background-repeat: no-repeat;\n background-position-x: 96%;\n background-position-y: 50%;\n background-size: 10%;\n border-radius: 3px;\n margin-right: 2rem;\n padding: 10px 20px 10px 10px;\n display: contents;\n border: 1px solid transparent;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-selling-plans-wrapper {\n display: block;\n margin: 20px 0 4px 0;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-selling-plans-wrapper.yotpo-admin-preview {\n text-align: center;\n min-height: auto;\n display: block;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-plans-and-policy-wrapper {\n max-width: 500px;\n }\n\n .yotpo-widget-subscriptions-add-to-cart.yotpo-admin-preview .yotpo-plans-and-policy-wrapper {\n min-height:300px;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-selling-plans {\n width: 100%;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-is-preview .yotpo-selling-plans {\n max-width: 400px;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-admin-preview .yotpo-selling-plans {\n text-align: left;\n display: inline-block;\n min-width: 150px;\n width: 100%;\n max-width: 400px;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-radio-container {\n background-color: ${widgetState.customizations.styles.notSelectedRadio.backgroundColor};\n border-radius: 8px;\n padding: 10px 15px;\n margin: 5px 0;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-widget-subscriptions-add-to-cart .yotpo-radio-container {\n border: 1px solid transparent;\n border-radius: 3px;\n min-width: 230px;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-radio-container.yotpo-selected {\n border-style: ${widgetState.customizations.styles.selectedRadio.borderStyle};\n border-width: ${widgetState.customizations.styles.selectedRadio.borderSize};\n border-color: ${widgetState.customizations.styles.selectedRadio.borderColor};\n background-color: ${widgetState.customizations.styles.selectedRadio.backgroundColor};\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-radio-button-text-wrapper {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-price-label-wrapper {\n display: flex;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-price-label-container {\n display: flex;\n justify-content: left;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-label-prefix {\n font-style: normal;\n font-family: ${widgetState.customizations.styles.fontFamily.name};\n font-size: ${widgetState.customizations.styles.fontSize.sellingPlans.name};\n font-weight: ${widgetState.customizations.styles.fontFamily.weight || 600};\n color: ${widgetState.customizations.styles.colors.text.primary};\n margin-right: 10px;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-selected .yotpo-subscription-label-prefix {\n color: ${widgetState.customizations.tiles.fontColor};\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-label-price {\n font-style: normal;\n font-family: ${widgetState.customizations.styles.fontFamily.name};\n font-size: ${widgetState.customizations.styles.fontSize.sellingPlans.name};\n font-weight: ${widgetState.customizations.styles.fontFamily.weight || 600};\n color: ${widgetState.customizations.styles.colors.text.primary};\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-selected .yotpo-subscription-label-price {\n color: ${widgetState.customizations.tiles.fontColor};\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-label-for-select-type {\n display: inline-block;\n margin-right: 5px;\n }`\n return radioStyle\n }\n\n private buildBuyOnce () {\n const buyOnceGroup = getBuyOnceAsSellingPlanGroup()\n const isSelected = widgetState.customizations.autoPickOptionIndex === 0\n return this.buildSellingPlanGroupElement(buyOnceGroup, isSelected, false)\n }\n\n private setElementClassForChangeEvent (group: SellingPlanGroup, element: HTMLElement, container: HTMLElement, isSubscription: boolean) {\n if (group.sellingPlans.length > 0) {\n element.appendChild(container)\n }\n\n const klass = isSubscription ? 'yotpo-radio-subscription-container' : 'yotpo-radio-buy-once-container'\n element.classList.add(klass)\n }\n\n private expandGroupOnAutoSelectedIndex () {\n const selectedIndex = getSelectedGroupIndex()\n if (selectedIndex >= 1) {\n const groupByIndex = getSellingPlanGroups()[selectedIndex - 1]\n setTimeout(displaySelectedElement(groupByIndex.id), 0)\n }\n }\n\n private getSellingPlanLabel (sellingPlan: SellingPlan, groupId: string): string {\n if (!widgetState.customizations.sellingPlans.showDiscount) {\n return sellingPlan.name\n }\n const discountLabel = getDiscountLabel(sellingPlan.priceAdjustments, groupId)\n const label = `${sellingPlan.name} ${discountLabel}`\n return label.trim()\n }\n}\n","import { widgetState } from '../../store/customizations/index'\n\nexport const radioTemplate = () => {\n return `\n \n `\n}\n","import { dropdownTemplate } from '../../templates/dropdown-template'\nimport { frequencyTemplate } from '../../templates/frequency-template'\nimport { Template } from '../../../models/template'\n\nexport const selectionFactory = (template: Template) => {\n switch (template) {\n case 'dropdown':\n return dropdownTemplate()\n case 'frequency':\n default:\n return frequencyTemplate()\n }\n}\n","import { widgetState } from '../../store/customizations/index'\n\nexport const dropdownTemplate = () => {\n return `\n
\n {{#values}}\n \n \n {{/values}}\n
\n `\n}\n","import { widgetState } from '../../store/customizations/index'\nimport { ColorUtils } from '../../utils/colors'\n\nexport const frequencyTemplate = () => {\n return `\n
\n {{#values}}\n \n {{/values}}\n
\n `\n}\n","import { buildElement, buildStyle } from '../../../utils/element'\nimport * as Mustache from 'mustache'\nimport { widgetState } from '../../../store/customizations/index'\nimport { SelectionOptions } from '../../../models/render-options'\n\nexport const buildSelection = (options: SelectionOptions, template: string) => {\n const element = buildElement('div', 'yotpo-selling-plan-select-container', {\n style: buildStyle({ display: shouldOpenByDefault() ? 'block' : 'none' }),\n 'data-selling-plan-group-frequency-id': options.id\n })\n\n const html = Mustache.render(template, options)\n\n const innerElement = buildElement('div', options.classString, options.attributes || {})\n innerElement.innerHTML = html\n\n const selectEl = innerElement.querySelector('.yotpo-frequency-options')\n selectEl.addEventListener('change', (event) => {\n bindSelectionToInput(options.id)(event)\n markSelectedFrequencyLabel(event)\n })\n if (widgetState.customizations.showGetItText) {\n const labelForSelection = buildElement('label', 'yotpo-label-for-select-type', {})\n labelForSelection.innerText = widgetState.customizations.getItText\n element.appendChild(labelForSelection)\n }\n\n element.appendChild(innerElement)\n\n return element\n}\nconst shouldOpenByDefault = (): boolean => {\n if (widgetState.customizations.selectionType === 'radio-and-dropdown') {\n return widgetState.customizations.styles.selectedRadio.openByDefault\n }\n return false\n}\nconst bindSelectionToInput = (groupId: string) => (event: Event) => {\n const targetElement = event.target\n const sellingPlanId = targetElement.value\n const sellingPlanName = targetElement.getAttribute('data-label')\n const inputEl = document.querySelector(`.yotpo-radio-container[data-seling-plan-group-id=\"${groupId}\"] .yotpo-radio-label-input`)\n inputEl.setAttribute('value', sellingPlanId)\n inputEl.setAttribute('data-selling-plan-name', sellingPlanName)\n}\n\nconst markSelectedFrequencyLabel = (event: Event) => {\n const targetElement = event.target\n const sellingPlanId = targetElement.value\n document.querySelectorAll('.yotpo-frequency-label')\n .forEach(element => {\n const id = element.getAttribute('value')\n if (sellingPlanId === id) {\n element.classList.add('yotpo-frequency-selected')\n } else {\n element.classList.remove('yotpo-frequency-selected')\n }\n })\n}\n","import { widgetState } from '../../../store/customizations/index'\nimport { buildElement } from '../../../utils/element'\nimport { PriceAdjustment } from '../../../models/price-adjustments'\nimport { buyOnceId, getBuyOnceAsSellingPlan, getBuyOnceAsSellingPlanGroup, isBuyOneSellingPlan, shouldShowBuyOnce } from '../../../models/buy-once'\nimport { getDiscountedPrice, getSellingPlanGroups } from '../../../store/selling-plans/getters'\nimport { getWithCurrencySymbol } from '../../../models/price-format'\nimport { getDiscountLabel, groupsHasAnyDiscount } from './discount'\n\nconst wrapperElementClassTiles = 'yotpo-subscription-discount-label-container'\nexport const buildTilesLabel = (groupId: string, priceAdjustments: PriceAdjustment[], hasAnyDiscount: boolean, discountPrice: number): HTMLElement => {\n const containerElement = buildElement('div', 'yotpo-subscription-discount-label-container', {})\n\n const priceFormat = widgetState.customizations.fullFormatProductPrice\n const priceElement = buildElement('div', 'yotpo-tile-option-price', {})\n priceElement.textContent = getWithCurrencySymbol(priceFormat, discountPrice)\n containerElement.appendChild(priceElement)\n\n if (widgetState.customizations.sellingPlans.showDiscount && hasAnyDiscount) {\n const discountElement = buildElement('div', 'yotpo-tile-option-discount', {})\n discountElement.textContent = getDiscountLabel(priceAdjustments, groupId)\n containerElement.appendChild(discountElement)\n }\n\n containerElement.appendChild(getStyles())\n\n return containerElement\n}\n\nexport const replacePriceElementTiles = () => {\n const groups = getSellingPlanGroups()\n\n if (shouldShowBuyOnce()) {\n const buyOnce = getBuyOnceAsSellingPlanGroup()\n buyOnce.sellingPlans = [getBuyOnceAsSellingPlan()]\n groups.push(buyOnce)\n }\n\n const hasAnyDiscount = groupsHasAnyDiscount()\n groups.forEach(group => {\n group.sellingPlans.forEach(plan => {\n const planId = isBuyOneSellingPlan(plan.id) ? buyOnceId : plan.id\n const priceWrapElement = document.querySelector(`[data-seling-plan-group-id=\"${planId}\"] .${wrapperElementClassTiles}`)\n const discountPrice = getDiscountedPrice(group.id, plan.id)\n if (priceWrapElement) {\n const newPriceElement = buildTilesLabel(group.id, plan.priceAdjustments, hasAnyDiscount, discountPrice)\n priceWrapElement.replaceWith(newPriceElement)\n }\n })\n })\n}\n\nconst getStyles = (): any => {\n const discountLabelStyle = buildElement('style', 'yotpo-discount-label-style', {})\n discountLabelStyle.innerHTML = `\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-discount-label-container {\n display: flex;\n margin: auto;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-tile-option-price, .yotpo-tile-option-discount {\n font-style: normal;\n font-family: ${widgetState.customizations.styles.fontFamily.name};\n font-size: ${widgetState.customizations.styles.fontSize.sellingPlans.options};\n font-weight: ${widgetState.customizations.styles.fontFamily.weight || 500};\n color: ${widgetState.customizations.tiles.fontColor};\n margin: 2px;\n }\n `\n return discountLabelStyle\n}\n","import { getBuyOnceAsSellingPlan, getBuyOnceAsSellingPlanGroup, isBuyOnceId } from '../../models/buy-once'\nimport { buildElement } from '../../utils/element'\nimport { widgetState } from '../../store/customizations/index'\nimport { buildTemplate } from './widgets/template-builder'\nimport { setSellingPlanChange } from '../../store/selling-plans/actions'\nimport { tilesTemplate } from '../templates/tiles-template'\nimport { SellingPlan } from '../../models/selling-plan'\nimport { buildTilesLabel } from './widgets/tiles-label'\nimport { Color } from '../../utils/color'\nimport { appendElementsInOrder, getSelectedGroupIndex, getSellingPlansMainElement, getSellingPlansMainElementWrapper } from './layout'\nimport { getDiscountedPrice, getSellingPlanGroups } from '../../store/selling-plans/getters'\nimport { getProduct } from '../../store/product/getters'\nimport { PlanSelectionLayout } from '../../models/layout'\nimport { groupsHasAnyDiscount } from './widgets/discount'\nimport { sortStrategy } from '../../services/sort/selling-plans'\nimport { getFormId } from '../../store/view/getters'\nimport { getPromotionLine } from '../../store/customizations/getters'\n\nexport class TileButtons implements PlanSelectionLayout {\n render (): HTMLElement {\n const sellingPlanElements: HTMLElement[] = []\n\n const hasAnyDiscount = groupsHasAnyDiscount()\n let sellingPlansCounter = 0\n getSellingPlanGroups().forEach(group => {\n const sortingStrategy = sortStrategy(group.id)\n group.sellingPlans\n .sort(sortingStrategy)\n .forEach(plan => {\n const isSelected = getSelectedGroupIndex() === (1 + sellingPlansCounter++)\n sellingPlanElements.push(this.buildSellingPlanElement(plan, isSelected, true, group.id, hasAnyDiscount))\n })\n })\n const mainElement = getSellingPlansMainElement()\n appendElementsInOrder(mainElement, sellingPlanElements, this.buildBuyOnce(hasAnyDiscount))\n\n const mainElementWrapper = getSellingPlansMainElementWrapper()\n mainElementWrapper.appendChild(mainElement)\n mainElementWrapper.appendChild(this.styles())\n\n return mainElementWrapper\n }\n\n private buildSellingPlanElement (plan: SellingPlan, checked: boolean, isSubscription: boolean, groupId: string, hasAnyDiscount: boolean): HTMLElement {\n const planId = (isBuyOnceId(groupId) ? groupId : plan.id).toString()\n const container = buildElement('div', `yotpo-radio-container ${checked ? 'yotpo-selected' : ''}`, {\n 'data-seling-plan-group-id': planId\n })\n const radioElementsWrapper = buildElement('div', 'yotpo-radio-button-text-wrapper', {\n 'data-seling-plan-group-id': planId\n })\n const formId = getFormId()\n const groupsTemplate = buildTemplate({\n id: planId,\n value: plan && !isBuyOnceId(planId) ? plan.id : '',\n text: plan.name,\n formId,\n checked,\n classString: 'yotpo-tile-buttons',\n inputAttributes: {\n data: plan ? plan.name : '',\n name: 'selling_plan'\n }\n },\n tilesTemplate()\n )\n\n const discountPrice = getDiscountedPrice(groupId, plan.id)\n const discountLabel = buildTilesLabel(groupId, plan.priceAdjustments, hasAnyDiscount, discountPrice)\n\n radioElementsWrapper.appendChild(groupsTemplate)\n radioElementsWrapper.appendChild(discountLabel)\n if (widgetState.customizations.sellingPlans.promotionLine.show) {\n const promotionLineElement = buildElement('div', 'yotpo-tile-promotion-line', {})\n promotionLineElement.textContent = getPromotionLine(discountPrice)\n radioElementsWrapper.appendChild(promotionLineElement)\n }\n container.appendChild(radioElementsWrapper)\n\n this.registerForLabelClick(container, plan, groupId)\n this.registerToElementChangeEvent(plan, container, groupsTemplate, isSubscription, groupId)\n\n return container\n }\n\n private registerToElementChangeEvent (plan: SellingPlan, element: HTMLElement, container: HTMLElement, isSubscription: boolean, groupId: string): void {\n element.addEventListener('change', (event: Event) => {\n const selectedSellingPlanId = (event.target as HTMLInputElement).value\n const isDiscountAvailable = plan.priceAdjustments ? plan.priceAdjustments.length > 0 : false\n setSellingPlanChange(groupId, selectedSellingPlanId, isSubscription, getProduct().id.toString(), isDiscountAvailable)\n })\n }\n\n private styles (): any {\n const radioStyle = buildElement('style', 'yotpo-radio-style', {})\n radioStyle.innerHTML = `\n .yotpo-widget-subscriptions-add-to-cart .yotpo-selling-plans {\n width: 100%;\n grid-gap: 10px;\n display: grid;\n color: #444;\n grid-template-columns: 2fr 2fr;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-is-preview .yotpo-selling-plans {\n max-width: 400px;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-selling-plans-wrapper {\n display: block;\n margin: 20px 0 10px 0;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-selling-plans-wrapper.yotpo-admin-preview {\n text-align: center;\n min-height: auto;\n display: block;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-admin-preview .yotpo-selling-plans {\n grid-gap: 10px;\n display: grid;\n color: #444;\n grid-template-columns: 2fr 2fr;\n margin: auto;\n max-width: 400px;\n }\n .yotpo-widget-subscriptions-add-to-cart {\n -webkit-appearance: none;\n -moz-appearance: none;\n background-repeat: no-repeat;\n background-position-x: 96%;\n background-position-y: 50%;\n background-size: 10%;\n border-radius: 3px;\n margin-right: 2rem;\n padding: 10px;\n padding-right: 20px;\n display: contents;\n border: 1px solid transparent;\n }\n ${widgetState.customizations.tiles.oddSpread ? this.getOddSpreadCss() : ''}\n .yotpo-widget-subscriptions-add-to-cart .yotpo-radio-container {\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-radio-container {\n padding: 10px;\n border: 1px solid #B4B8C7;\n background-color: ${widgetState.customizations.styles.notSelectedRadio.backgroundColor};\n border-radius: 8px;\n height: ${widgetState.customizations.tiles.tileHeight};\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-radio-container.yotpo-selected {\n border-style: ${widgetState.customizations.tiles.borderStyle};\n border-width: ${widgetState.customizations.tiles.borderSize};\n border-color: ${widgetState.customizations.styles.radioButton.innerColor};\n background-color: ${this.getBackgroundColorWithOpacity('20')};\n pointer-events: none;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-radio-button-text-wrapper {\n display: flex;\n flex-direction: column;\n align-items: baseline;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-tile-buttons {\n margin: auto;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-tile-promotion-line {\n margin: auto;\n font-size: ${widgetState.customizations.styles.fontSize.sellingPlans.name};\n font-family: ${widgetState.customizations.styles.fontFamily.name};\n font-style: normal;\n font-weight: ${widgetState.customizations.styles.fontFamily.weight || 500};\n color: ${widgetState.customizations.styles.colors.text.primary};\n display: table-cell;\n vertical-align: middle;\n text-align: center;\n }`\n return radioStyle\n }\n\n private getOddSpreadCss (): string {\n return `.yotpo-widget-subscriptions-add-to-cart .yotpo-radio-container:first-child:nth-last-child(odd) {\n grid-column: auto / span 2;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-radio-container:first-child:nth-last-child(even),\n .yotpo-widget-subscriptions-add-to-cart .yotpo-radio-container:first-child:nth-last-child(even) ~\n .yotpo-widget-subscriptions-add-to-cart .yotpo-radio-container {\n grid-column: auto / span 1;\n }`\n }\n\n private buildBuyOnce (hasAnyDiscount: boolean): HTMLElement {\n const buyOnceGroup = getBuyOnceAsSellingPlanGroup()\n const buyOncePlan = getBuyOnceAsSellingPlan()\n const isSelected = widgetState.customizations.autoPickOptionIndex === 0\n return this.buildSellingPlanElement(buyOncePlan, isSelected, false, buyOnceGroup.id, hasAnyDiscount)\n }\n\n private registerForLabelClick (container: HTMLElement, plan: SellingPlan, groupId: string): void {\n container.addEventListener('click', () => {\n document.querySelectorAll('.yotpo-radio-label-input')\n .forEach(element => {\n const value = element.getAttribute('value')\n const isBuyOnce = (!value && isBuyOnceId(groupId))\n if (isBuyOnce || value === plan.id.toString()) {\n (element).click()\n }\n })\n })\n }\n\n private getBackgroundColorWithOpacity (opacityLevel: string): string {\n const color = new Color(widgetState.customizations.styles.selectedRadio.backgroundColor)\n return `${color.toHex()}${opacityLevel}`\n }\n}\n","import { widgetState } from './index'\n\nexport const isTilesLayout = (): boolean => {\n return widgetState.customizations.selectionType === 'tiles-only'\n}\n\nexport const renderText = (template: string, variables: Record): string => {\n Object.keys(variables).forEach(variable => {\n template = template.replace(variable, variables[variable])\n })\n return template\n}\n\nexport const getPromotionLine = (price: number) => {\n const loyaltyPoints = Math.floor((price / 100) * widgetState.customizations.loyalty.reward.pointsRatio)\n return renderText(widgetState.customizations.sellingPlans.promotionLine.text, {\n '{{loyalty_points}}': loyaltyPoints.toString()\n })\n}\n","import { widgetState } from '../../store/customizations/index'\n\nexport const tilesTemplate = () => {\n return `\n \n `\n}\n","import { buildElement, getHtmlElementByClassName } from '../../utils/element'\nimport { isBuyOnceId } from '../../models/buy-once'\nimport { widgetState } from '../../store/customizations/index'\nimport { getSelectedGroupId } from '../../store/selling-plans/getters'\n\nexport const renderSubscriptionBenefits = (mainElement: HTMLElement) => {\n if (!widgetState.customizations.subscriptionBenefits.shouldShow) {\n return\n }\n const subscriptionBenefits = getSubscriptionBenefitsElement()\n mainElement.appendChild(subscriptionBenefits)\n addOpenSubscriptionToOnChangeEvent()\n}\n\nexport const repaintSubscriptionBenefits = () => {\n const selectedGroupId = getSelectedGroupId()\n\n let containerClass = 'yotpo-subscription-benefits-wrapper'\n if (widgetState.customizations.isReadOnly) {\n containerClass = 'yotpo-subscription-benefits-container'\n }\n\n if (isBuyOnceId(selectedGroupId)) {\n getHtmlElementByClassName(containerClass).style.backgroundColor = widgetState.customizations.styles.notSelectedRadio.backgroundColor\n return\n }\n\n getHtmlElementByClassName(containerClass).style.backgroundColor = widgetState.customizations.styles.selectedRadio.backgroundColor\n}\n\nconst addOpenSubscriptionToOnChangeEvent = () => {\n getHtmlElementByClassName('yotpo-selling-plans-wrapper')\n .addEventListener('change', () => repaintSubscriptionBenefits())\n}\n\nconst getSubscriptionBenefitsElement = (): HTMLElement => {\n const wrapper = buildElement('div', 'yotpo-subscription-benefits-wrapper', {})\n const container = buildElement('div', `${widgetState.customizations.isReadOnly ? 'yotpo-subscription-benefits-container yotpo-admin-preview' : 'yotpo-subscription-benefits-container'}`, {})\n const main = buildElement('div', 'yotpo-subscription-benefits', {})\n\n const textMain = getMainText()\n main.appendChild(textMain)\n\n const radioStyle = buildElement('style', 'yotpo-subscription-benefits-style', {})\n radioStyle.innerHTML = getStyles()\n\n container.appendChild(main)\n wrapper.appendChild(container)\n wrapper.appendChild(radioStyle)\n\n return wrapper\n}\n\nconst getMainText = () => {\n const benefitsList = buildElement('ul', 'yotpo-subscription-benefits-list', {})\n widgetState.customizations.subscriptionBenefits.list.forEach((benefit) => {\n const benefitItem = buildElement('li', 'yotpo-subscription-benefits-list-bullet', {})\n const benefitItemText = buildElement('span', 'yotpo-subscription-benefits-list-bullet-text', {})\n benefitItemText.textContent = benefit\n benefitItem.appendChild(benefitItemText)\n benefitsList.appendChild(benefitItem)\n })\n return benefitsList\n}\n\nconst getStyles = (): string => {\n return `\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-benefits-wrapper {\n display: block;\n margin: 0 0 10px 0;\n padding: 8px;\n border-radius: 5px;\n background-color: ${getWrapperBackgroundColor(true)};\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-benefits-container {\n text-align: initial;\n width: 100%;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-benefits-container.yotpo-admin-preview {\n margin: auto;\n max-width: 400px;\n background-color: ${getWrapperBackgroundColor(false)};\n border-radius: 5px;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-benefits {\n display: grid;\n padding: 2px;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-benefits-list {\n padding-inline-start: 15px;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-benefits-list .yotpo-subscription-benefits-list-bullet {\n margin-bottom: 8px;\n margin-left: 10px;\n list-style: disc;\n color: ${widgetState.customizations.styles.colors.text.primary};\n font-size: ${widgetState.customizations.styles.fontSize.primary};\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-subscription-benefits-list .yotpo-subscription-benefits-list-bullet .yotpo-subscription-benefits-list-bullet-text {\n position: relative;\n left: -5px;\n color: ${widgetState.customizations.styles.colors.text.primary};\n font-size: ${widgetState.customizations.styles.fontSize.primary};\n padding-bottom: 5px;\n }\n `\n}\n\nconst getWrapperBackgroundColor = (isWrapper: boolean): string => {\n if (isWrapper) {\n return widgetState.customizations.isReadOnly\n ? 'unset'\n : widgetState.customizations.autoPickOptionIndex === 1\n ? widgetState.customizations.styles.selectedRadio.backgroundColor\n : widgetState.customizations.styles.notSelectedRadio.backgroundColor\n } else {\n return widgetState.customizations.isReadOnly\n ? widgetState.customizations.autoPickOptionIndex === 1\n ? widgetState.customizations.styles.selectedRadio.backgroundColor\n : widgetState.customizations.styles.notSelectedRadio.backgroundColor\n : 'unset'\n }\n}\n","import { openSubscriptionPolicies, renderSubscriptionPolicy } from './subscription-policy'\nimport { widgetState } from '../../store/customizations/index'\nimport { templateFactory } from './widgets/template-factory'\nimport { getSellingPlanGroups } from '../../store/selling-plans/getters'\nimport { getProduct } from '../../store/product/getters'\nimport { isTilesLayout } from '../../store/customizations/getters'\nimport { replacePriceElementTiles } from './widgets/tiles-label'\nimport { replacePriceElement } from './widgets/price-label'\nimport { buildElement } from '../../utils/element'\nimport { renderSubscriptionBenefits } from './subscription-benefits'\n\nexport const renderProduct = (mainElement: HTMLElement): void => {\n if (getSellingPlanGroups().length === 0) {\n return\n }\n const product = getProduct()\n const template = widgetState.customizations.selectionType.split('-')[0]\n const selectedTemplate = templateFactory(template, product).render()\n const element = buildElement('div', 'yotpo-plans-and-policy-wrapper', {})\n mainElement.appendChild(element)\n element.appendChild(selectedTemplate)\n renderSubscriptionBenefits(element)\n renderSubscriptionPolicy(element)\n if (product.requiresSellingPlan || (widgetState.customizations.autoPickOptionIndex > 0 && !widgetState.customizations.oneTimeAtLast)) {\n if (widgetState.customizations.subscriptionPolicy.shouldShow) {\n openSubscriptionPolicies()\n }\n }\n}\n\nexport const replacePrices = () => {\n if (isTilesLayout()) {\n replacePriceElementTiles()\n } else {\n replacePriceElement()\n }\n}\n","import { PlanSelectionLayout } from '../../../models/layout'\nimport { Product } from '../../../models/product'\nimport { RadioButtons } from '../radio-buttons'\nimport { TileButtons } from '../tile-buttons'\n\nexport const templateFactory = (template: string, product: Product): PlanSelectionLayout => {\n switch (template) {\n case 'tiles':\n return new TileButtons()\n case 'radio':\n default:\n return new RadioButtons()\n }\n}\n","import { getOrCreateEventBus, Publisher, Subscription } from '../services/event-bus/event-bus'\n\nexport interface ProductPriceChangedEventArgs {\n price: number\n}\n\ntype ProductPriceChangedCallback = (publisher: Publisher, args: ProductPriceChangedEventArgs) => void;\nconst eventName = 'v1/product_price_changed'\n\nexport const subscribeToProductPriceChangedEvent = (callback: ProductPriceChangedCallback): Subscription => {\n const eventBus = getOrCreateEventBus()\n return eventBus.subscribe(eventName, callback)\n}\n\nexport const publishProductPriceChangedEvent = (args: ProductPriceChangedEventArgs): void => {\n const eventBus = getOrCreateEventBus()\n const publisher = { name: 'add-to-cart-widget' }\n return eventBus.publish(eventName, publisher, args)\n}\n","import { publishProductPriceChangedEvent } from '../../events/product-price-changed'\nimport { renderProduct } from '../../render/components/product'\nimport { renderMainElement } from '../../render/render'\nimport { widgetState } from '../../store/customizations/index'\nimport { setCurrentVariant } from '../../store/product/actions'\nimport { productState } from '../../store/product/index'\nimport { setMainElement } from '../../store/view/actions'\nimport { getMainElement } from '../../store/view/getters'\nimport { getQueryParams } from '../../utils/url'\n\nconst checkVariantChange = () => {\n try {\n const val = getVariantIdFromUrlParam() || getVariantIdFromForm()\n if (val && productState.currentVariant && val !== productState.currentVariant.id) {\n setCurrentVariant(val)\n if (productState.currentVariant && productState.currentVariant.id !== val) {\n return\n }\n const mainElementContainer = getMainElement()\n if (mainElementContainer) {\n const newMainElement = renderMainElement()\n renderProduct(newMainElement)\n mainElementContainer.replaceWith(newMainElement)\n setMainElement(newMainElement)\n }\n if (productState.currentVariant) {\n publishProductPriceChangedEvent({\n price: productState.currentVariant.price\n })\n }\n }\n } catch (ex) {\n console.error('faild to act on possible variant change', ex)\n }\n}\n\nconst getVariantIdFromForm = (): number | null => {\n const variantIdFormSelector = widgetState.customizations.variantDetection.selector\n const idElement = document.querySelector(variantIdFormSelector)\n return idElement\n ? getIdValue(idElement as HTMLInputElement, widgetState.customizations.variantDetection.attribute)\n : null\n}\n\nconst getIdValue = (idElement: HTMLInputElement, elementAttribute: string): number => {\n return elementAttribute\n ? parseInt((idElement).getAttribute(elementAttribute))\n : parseInt((idElement).value)\n}\n\nexport const getVariantIdFromUrlParam = (): number | null => {\n const queryParams = getQueryParams()\n if (queryParams.variant) {\n return parseInt(queryParams.variant)\n }\n return null\n}\n\nexport const getCurrentVariantId = (): number | null => {\n const idFromUrl = getVariantIdFromUrlParam()\n if (idFromUrl) {\n return idFromUrl\n }\n return getVariantIdFromForm()\n}\n\nexport const registerToVariantChange = () => {\n setInterval(() => {\n checkVariantChange()\n }, 500)\n}\n","import { productState } from './index'\nimport { Product } from '../../models/product'\nimport { getDefaultVariant } from './getters'\nimport { getCurrentVariantId } from '../../services/variants/variants'\nimport { setSellingPlanGroups } from '../selling-plans/actions'\n\nexport const setProductPrice = (price: number) => {\n productState.product.price = price\n}\n\nexport const setProduct = (product: Product) => {\n productState.product = product\n const currentVariantId = getCurrentVariantId()\n setCurrentVariant(currentVariantId)\n if (productState.currentVariant && productState.currentVariant.price) {\n setProductPrice(productState.currentVariant.price)\n }\n setSellingPlanGroups(product.sellingPlanGroups)\n}\n\nexport const setCurrentVariant = (variantId: number) => {\n const defaultVariant = getDefaultVariant()\n if (!variantId && !productState.currentVariant && defaultVariant) {\n productState.currentVariant = defaultVariant\n return\n }\n const variant = productState.product.variants.find(v => v.id === variantId)\n if (variant) {\n productState.currentVariant = variant\n return\n }\n\n if (defaultVariant) {\n productState.currentVariant = defaultVariant\n }\n}\n","import { dispatchEvent } from '../../services/analytics/events'\nimport { widgetState } from '../../store/customizations/index'\nimport { buildElement } from '../../utils/element'\n\nconst renderTopBar = (mainElement: HTMLElement) => {\n const topBarElement = getTopBarElement()\n mainElement.appendChild(topBarElement)\n return topBarElement\n}\nexport const getTopBarElement = () => {\n const topBarElement = buildElement('div', 'yotpo-live-preview-bar', {})\n const topBarStyle = buildElement('style', 'yotpo-live-preview-bar-style', {})\n topBarStyle.innerHTML = getStyles()\n topBarElement.appendChild(topBarStyle)\n const contentContainerElement = buildElement('div', 'yotpo-live-preview-bar-content-container', {})\n const yotpoLogo = buildYotpoLogoElement()\n const textContainerElement = buildTextContainer()\n const closeButtonElement = buildCloseButtonElement()\n const ctaButtonElement = buildCtaButtonElement()\n contentContainerElement.appendChild(yotpoLogo)\n contentContainerElement.appendChild(textContainerElement)\n contentContainerElement.appendChild(closeButtonElement)\n contentContainerElement.appendChild(ctaButtonElement)\n topBarElement.appendChild(contentContainerElement)\n\n const fontStyle = buildElement('link', '', {\n href: 'https://fonts.googleapis.com/css?family=Inter:400&display=swap',\n rel: 'stylesheet'\n })\n document.head.appendChild(fontStyle)\n\n return topBarElement\n}\n\nexport const renderLivePreview = (mainElement: HTMLElement): HTMLElement => {\n return renderTopBar(mainElement)\n}\n\nexport const getStyles = (): string => {\n return `\n .yotpo-widget-subscriptions-add-to-cart .yotpo-live-preview-bar {\n box-sizing: border-box;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-live-preview-bar {\n position: fixed;\n top: 260px;\n left: 0;\n width: 245px;\n height: 315px;\n background: ${widgetState.customizations.livePreview.topBar.backgroundColor};\n opacity: ${widgetState.customizations.livePreview.topBar.backgroundOpacity};\n color: ${widgetState.customizations.livePreview.topBar.fontColor};\n line-height: 20px;\n font-family: Inter;\n z-index: 9999;\n padding: 20px;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-live-preview-bar .yotpo-live-preview-bar-content-container {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n text-align: left;\n height: 100%\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-live-preview-bar .yotpo-live-preview-bar-content-container .yotpo-live-preview-bar-logo {\n max-width: 66px;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-live-preview-bar .yotpo-live-preview-bar-content-container .yotpo-live-preview-bar-text-container .yotpo-live-preview-bar-header-text {\n font-size: 20px;\n line-height: 28px;\n margin-bottom: 14px;\n }\n .yotpo-widget-subscriptions-add-to-cart .yotpo-live-preview-bar .yotpo-live-preview-bar-content-container .yotpo-live-preview-bar-text-container .yotpo-live-preview-bar-help-text {\n font-size: 14px;\n line-height: 24px;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-live-preview-bar .yotpo-live-preview-bar-content-container .yotpo-live-preview-bar-close-button {\n background: ${widgetState.customizations.livePreview.topBar.closeButtonBackgroundColor};\n color: ${widgetState.customizations.livePreview.topBar.closeButtonTextColor};\n text-align: center;\n text-decoration: none;\n border-radius: 3px;\n padding: 8px 16px;\n font-family: Inter;\n font-weight: 600;\n font-size: 13px;\n line-height: 20px;\n cursor: pointer;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-live-preview-bar .yotpo-live-preview-bar-content-container .yotpo-live-preview-bar-cta-text {\n color: ${widgetState.customizations.livePreview.topBar.fontColor};\n text-align: center;\n font-family: Inter;\n font-size: 14px;\n line-height: 20px;\n }\n\n .yotpo-widget-subscriptions-add-to-cart .yotpo-live-preview-bar .yotpo-live-preview-bar-content-container .yotpo-live-preview-bar-cta-trigger {\n text-decoration: underline;\n }\n\n ${getWidgetMarking()}`\n}\n\nfunction buildTextContainer (): HTMLElement {\n const textContainerElement = buildElement('div', 'yotpo-live-preview-bar-text-container', {})\n const headerTextElement = buildElement('div', 'yotpo-live-preview-bar-header-text', {})\n headerTextElement.innerText = widgetState.customizations.livePreview.topBar.headerText\n textContainerElement.appendChild(headerTextElement)\n const helpText = buildElement('div', 'yotpo-live-preview-bar-help-text', {})\n helpText.innerText = widgetState.customizations.livePreview.topBar.helpText\n textContainerElement.appendChild(helpText)\n\n return textContainerElement\n}\n\nfunction buildYotpoLogoElement () {\n return buildElement('img', 'yotpo-live-preview-bar-logo', {\n src: 'https://cdn-widget-assets.yotpo.com/SubscriptionsAddToCartWidget/assets/1.1.9/assets/images/yotpo-logo.png'\n })\n}\n\nfunction buildCtaButtonElement (): HTMLElement {\n const onClickLink = `https://subscriptions.yotpo.com/#/on-boarding/${widgetState.customizations.livePreview.topBar.ctaLinkPath}?open_chat=true`\n const ctaButtonWrapperElement = buildElement('span', 'yotpo-live-preview-bar-cta-text', {})\n ctaButtonWrapperElement.innerText = 'Need help? '\n const ctaButtonElement = buildElement('a', 'yotpo-live-preview-bar-cta-text yotpo-live-preview-bar-cta-trigger', {\n href: onClickLink,\n target: '_blank'\n })\n ctaButtonElement.innerText = widgetState.customizations.livePreview.topBar.ctaText\n ctaButtonElement.addEventListener('click', () => previewEvent(onClickLink))\n ctaButtonWrapperElement.appendChild(ctaButtonElement)\n return ctaButtonWrapperElement\n}\n\nfunction buildCloseButtonElement (): HTMLElement {\n const closeButtonElement = buildElement('button', 'yotpo-live-preview-bar-close-button', {})\n closeButtonElement.innerText = widgetState.customizations.livePreview.topBar.closeButtonText\n closeButtonElement.addEventListener('click', () => window.close())\n return closeButtonElement\n}\n\nconst previewEvent = (link: string): void => {\n dispatchEvent({\n action: 'clicked_on',\n label: 'get_live_support',\n context: {\n cta_link: link\n }\n })\n}\n\nfunction getWidgetMarking (): string {\n const widgetMarkingStrategy = widgetState.customizations.livePreview.widgetMarkingStrategy\n if (widgetMarkingStrategy === 'blinking_border') {\n return `.yotpo-widget-subscriptions-add-to-cart .yotpo-selling-plans-wrapper {\n outline: 3px solid transparent;\n animation: yotpo-blink 1s;\n animation-iteration-count: 5;\n }\n\n @keyframes yotpo-blink {\n 50% {\n border-radius: 5px;\n outline-color:${widgetState.customizations.livePreview.topBar.backgroundColor};\n }\n }`\n }\n\n if (widgetMarkingStrategy === 'stable_border') {\n return `.yotpo-widget-subscriptions-add-to-cart .yotpo-selling-plans-wrapper {\n border: 3px solid ${widgetState.customizations.livePreview.topBar.backgroundColor};\n border-radius: 5px;\n }`\n }\n}\n","import { WidgetOptions } from './types'\nimport { getCustomizations } from './customizations/customizations'\nimport { getWidgetCustomizations } from './customizations/widget-customizations'\nimport { renderMainElement } from './render/render'\nimport { WidgetCustomizations } from './customizations/types'\nimport { getDummyProduct } from './models/dummy-product'\nimport { ensureWidgetInEditorMode, getProductInfo, isInShopifyDesignMode } from './services/shopify'\nimport { Product } from './models/product'\nimport { renderProduct, replacePrices } from './render/components/product'\nimport { fireWidgetReadyHook, sellingPlanChangedHookInit } from './services/hooks'\nimport { Publisher } from './services/event-bus/event-bus'\nimport { ProductPriceChangedEventArgs, subscribeToProductPriceChangedEvent } from './events/product-price-changed'\nimport { SellingPlanChangedEventArgs, subscribeToSellingPlanChangedEvent } from './events/selling-plan-changed'\nimport { setProduct, setProductPrice } from './store/product/actions'\nimport { setCustomizations } from './store/customizations/actions'\nimport { renderLivePreview } from './render/components/live-preview'\nimport { setMerchantAttributes } from './store/merchant/actions'\nimport { registerToVariantChange } from './services/variants/variants'\nimport { injectWidget, bindWidgetToFormId, getFormElement } from './services/injection/injection'\nimport { dispatchLoadedEvent, getLoadedEvent, initAddToCartAnalytics } from './services/analytics/events'\nimport { setMainElement } from './store/view/actions'\n\nexport class SubscriptionsAddToCartWidget {\n private element: HTMLElement\n private customizations: WidgetCustomizations\n private guid: string\n private instanceId: number\n private instanceVersionId: number\n\n init (widgetOptions: WidgetOptions) {\n this.element = widgetOptions.element\n this.guid = widgetOptions.merchantData.guid\n this.instanceId = widgetOptions.metadata.instanceId\n this.instanceVersionId = widgetOptions.metadata.instanceVersionId\n const overridenCustomizations = getCustomizations(widgetOptions.metadata.customizations, this.element)\n this.customizations = getWidgetCustomizations(overridenCustomizations)\n setCustomizations(this.customizations)\n setMerchantAttributes(this.guid)\n }\n\n run () {\n if (!this.shouldRenderWidget()) {\n return\n }\n const mainElement = renderMainElement()\n setMainElement(mainElement)\n injectWidget(this.element, mainElement)\n const loadedEvent = getLoadedEvent(this.instanceId, this.instanceVersionId)\n\n this.getProduct().then((product: Product) => {\n setProduct(product)\n if (this.customizations.allowOutOfForm) {\n const formElement = getFormElement()\n if (formElement) {\n bindWidgetToFormId(formElement as HTMLElement)\n }\n }\n renderProduct(mainElement)\n if (product.sellingPlanGroups.length > 0) {\n this.initEventsAndHooks()\n dispatchLoadedEvent(loadedEvent)\n }\n })\n\n ensureWidgetInEditorMode()\n\n if (this.customizations.livePreview.show) {\n renderLivePreview(mainElement)\n }\n\n if (this.customizations.hooks.widgetReady) {\n fireWidgetReadyHook()\n }\n }\n\n private getProduct (): Promise {\n if (this.customizations.productHandle) {\n return getProductInfo(this.customizations.productHandle)\n }\n return new Promise((resolve) => {\n resolve(getDummyProduct())\n })\n }\n\n private initEventsAndHooks () {\n if (this.customizations.hooks.sellingPlanChanged) {\n sellingPlanChangedHookInit()\n }\n if (this.customizations.priceLabel.strategy === 'starting_and_actual') {\n subscribeToSellingPlanChangedEvent((publisher: Publisher, args: SellingPlanChangedEventArgs) => {\n replacePrices()\n })\n }\n subscribeToProductPriceChangedEvent((publisher: Publisher, args: ProductPriceChangedEventArgs) => {\n setProductPrice(args.price)\n replacePrices()\n })\n registerToVariantChange()\n initAddToCartAnalytics()\n }\n\n private shouldRenderWidget () {\n const inOnPreview = this.customizations.isPreview || this.customizations.isReadOnly\n const isOnSite = this.customizations.productHandle && (this.customizations.isLaunched || this.customizations.livePreview.show || isInShopifyDesignMode())\n return isOnSite || inOnPreview\n }\n}\n","import { merchantState } from './index'\n\nexport const setMerchantAttributes = (guid: string) => {\n merchantState.guid = guid\n}\n","import { widgetState } from './index'\nimport { WidgetCustomizations } from '../../customizations/types'\n\nexport const setCustomizations = (customizations: WidgetCustomizations) => {\n widgetState.customizations = customizations\n}\n","import { SubscriptionsAddToCartWidget } from './widget'\nimport { isContainerDefined, registerToContainer } from './container/widgets-container'\n\nif (isContainerDefined()) {\n registerToContainer('SubscriptionsAddToCartWidget', () => {\n return new SubscriptionsAddToCartWidget()\n })\n} else {\n console.log('yotpoWidgetsContainer is not defined')\n}\n"],"sourceRoot":""}