{"version":3,"file":"564.min.js?t=1747159542749","mappings":"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","sources":["webpack://@hero-digital/masonite/./src/components/foundation/Image/Image.template.js","webpack://@hero-digital/masonite/./src/components/modules/ColorPicker/ColorPicker.js","webpack://@hero-digital/masonite/./src/components/modules/ColorPicker/ColorPicker.template.js","webpack://@hero-digital/masonite/./src/components/modules/PlayIcon/PlayIcon.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductInfo/ProductInfo.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductInfo/ProductInfo.template.js","webpack://@hero-digital/masonite/./src/components/modules/Tabs/Tabs.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionGroup/ProductOptionGroup.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionCategory/ProductOptionCategory.template.js","webpack://@hero-digital/masonite/./src/components/modules/Modal/Modal.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionsCustomColor/ProductOptionCustomColor.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionsCustomColor/ProductOptionsCustomColor.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionCategory/ProductOptionCategory.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionGroup/ProductOptionGroup.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionFilters/ProductOptionFilters.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionFilters/ProductOptionFilters.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptions/ProductOptions.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptions/ProductOptions.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/components/ProductShare/ProductShare.template.js","webpack://@hero-digital/masonite/./src/js/utilities/scriptLoader.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/components/ProductShare/ProductShare.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/ProductTools.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/ProductTools.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaThumbnails/ProductMediaThumbnails.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaThumbnails/ProductMediaThumbnails.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaImage/ProductMediaImage.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaImage/ProductMediaImage.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaVideo/ProductMediaVideo.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaVideo/ProductMediaVideo.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaVisualizer/ProductMediaVisualizer.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaVisualizer/ProductMediaVisualizer.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaGallery/ProductMediaGallery.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaGallery/ProductMediaGallery.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductFeatures/ProductFeatures.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductDetails/ProductDetails.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductSpecifications/ProductSpecifications.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMeasurement/ProductMeasurement.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductDocuments/ProductDocuments.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductDetails/ProductDetails.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductRelatedContent/ProductRelatedContent.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductRelatedContent/ProductRelatedContent.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/models/ProductInformationModel/ProductInformationModel.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/services/ProductInformationRouter/ProductInformationRouter.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/ProductInformation.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/ProductInformation.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/components/Notification/Notification.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/components/Notification/Notification.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/components/ProductSave/ProductSave.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/components/ProductSave/ProductSave.template.js","webpack://@hero-digital/masonite/./src/components/modules/Tabs/index.js","webpack://@hero-digital/masonite/./src/components/modules/VideoPlayer/VideoPlayer.js","webpack://@hero-digital/masonite/./src/components/modules/VideoPlayer/VideoPlayer.template.js"],"sourcesContent":["import classNames from 'utilities/classnames'\n\n/**\n *\n * @param {Object} args Template arguments\n * @param {String} args.addClassName Additional class name\n * @param {String} args.altText Image alt text\n * @param {String} args.defaultAspectRatio default aspect ratio\n * @param {String} args.defaultSrc Desktop src\n * @param {String} args.loading Image loading style\n * @param {String} args.mobileSrc Mobile srcset\n * @param {String} args.mobileAspectRatio mobile view aspect ratio\n * @returns\n */\nconst ImageTemplate = ({\n\taddClassName,\n\taltText,\n\tdefaultAspectRatio,\n\tdefaultSrc,\n\tloading = 'lazy',\n\tmobileAspectRatio,\n\tmobileSrc\n}) => `\n \n ${\n\t\t\tmobileSrc\n\t\t\t\t? ``\n\t\t\t\t: ''\n\t\t}\n \n \n`\n\nexport default ImageTemplate\n","import { insert } from 'utilities/renderer'\nimport { noop } from 'utilities/utilities'\nimport iro from '@jaames/iro'\nimport Services from 'services'\nimport template from './ColorPicker.template.js'\n\n/**\n * ColorPicker component responsible for rendering a color picker\n * and providing a callback for when the color changes\n * @param {HTMLElement} element - the element to render the component in\n * @param {Object} options - the options for the component\n * @param {number} options.height - the height of the color picker\n * @param {string} options.initialColor - the initial color for the color picker\n * @param {Function} options.onChange - the callback for when the color changes\n * @param {string} options.theme - the theme for the color picker\n */\nexport default class ColorPicker {\n\tstatic SELECTORS = {\n\t\tWHEEL: '[data-cmp-hook=\"color-picker-wheel\"]',\n\t\tINPUT_HEX: '[data-cmp-hook=\"color-input-hex\"]',\n\t\tINPUT_RGB: '[data-cmp-hook=\"color-input-rgb\"]'\n\t}\n\n\tconstructor(\n\t\telement,\n\t\t{ height = 242, onChange = noop, initialColor = '', theme = 'light' } = {}\n\t) {\n\t\tthis.element = element\n\t\tthis.onChange = onChange\n\t\tthis.services = Services.getInstance()\n\t\tthis.initialColor = initialColor\n\t\tthis.height = height\n\t\tthis.theme = theme\n\t\tthis.resizeService = this.services.ResizeService\n\t\tthis.init()\n\t}\n\n\t/**\n\t * Initialize the component\n\t */\n\tinit() {\n\t\tthis.template = template({\n\t\t\ttheme: this.theme\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\t\tthis.cacheDom()\n\t\tthis.createWheel()\n\t\tthis.attachEvents()\n\t\tthis.render()\n\t\tthis.setPickerWidth()\n\t}\n\n\t/**\n\t * Cache the DOM elements\n\t */\n\tcacheDom() {\n\t\tthis.wheelEl = this.template.querySelector(ColorPicker.SELECTORS.WHEEL)\n\t\tthis.inputHex = this.template.querySelector(\n\t\t\tColorPicker.SELECTORS.INPUT_HEX\n\t\t)\n\t\tthis.inputsRgb = this.template.querySelectorAll(\n\t\t\tColorPicker.SELECTORS.INPUT_RGB\n\t\t)\n\t}\n\n\t/**\n\t * Attach the events\n\t */\n\tattachEvents() {\n\t\tthis.inputHex.addEventListener('change', this.onHexChange)\n\t\tthis.inputsRgb.forEach((input) => {\n\t\t\tinput.addEventListener('change', this.onRgbChange)\n\t\t})\n\t\tthis.wheel.on(['color:init', 'color:change'], this.onWheelChange)\n\t\tthis.resizeService.addCallback(this.setPickerWidth)\n\t}\n\n\t/**\n\t * Detach the events\n\t */\n\tdetachEvents() {\n\t\tthis.inputHex.removeEventListener('change', this.onHexChange)\n\t\tthis.inputsRgb.forEach((input) => {\n\t\t\tinput.removeEventListener('change', this.onRgbChange)\n\t\t})\n\t\tthis.wheel.off(['color:init', 'color:change'], this.onWheelChange)\n\t\tthis.resizeService.removeCallback(this.setPickerWidth)\n\t}\n\n\t/**\n\t * Destroy the component\n\t */\n\tdestroy() {\n\t\tthis.detachEvents()\n\t}\n\n\t/**\n\t * Create the color wheel picker\n\t */\n\tcreateWheel() {\n\t\tthis.wheel = new iro.ColorPicker(this.wheelEl, {\n\t\t\tdisplay: 'block',\n\t\t\twidth: 200,\n\t\t\tboxHeight: this.height,\n\t\t\tcolor: this.initialColor,\n\t\t\tlayout: [\n\t\t\t\t{\n\t\t\t\t\tcomponent: iro.ui.Box\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tcomponent: iro.ui.Slider,\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tid: 'hue-slider',\n\t\t\t\t\t\tsliderType: 'hue',\n\t\t\t\t\t\tsliderSize: 12\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t})\n\t}\n\n\t/**\n\t * Set the hex input value\n\t */\n\tsetHexInput(hex) {\n\t\tthis.inputHex.value = hex\n\t}\n\n\t/**\n\t * Set the rbg input values\n\t */\n\tsetRgbInputs(rgb) {\n\t\tthis.inputsRgb.forEach((input) => {\n\t\t\tif (rgb[input.dataset.color]) {\n\t\t\t\tinput.value = rgb[input.dataset.color]\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Set the width of the color picker to the width of the parent element\n\t */\n\tsetPickerWidth = () => {\n\t\tconst width = this.wheelEl.offsetWidth\n\t\tthis.wheel.resize(width)\n\t}\n\n\t/**\n\t * Callback for when the color wheel changes to set the inputs and apply the onChange callback\n\t * @param {Object} color - the color object\n\t */\n\tonWheelChange = (color) => {\n\t\tconst hex = color.hexString\n\t\tconst rgb = color.rgb\n\n\t\tthis.setHexInput(hex)\n\t\tthis.setRgbInputs(rgb)\n\t\tthis.onChange(hex)\n\t}\n\n\t/**\n\t * Callback for when the hex input changes to set hex to the color wheel and apply the onChange callback\n\t * @param {Event} event - input change event\n\t */\n\tonHexChange = (event) => {\n\t\ttry {\n\t\t\tthis.wheel.color.set(event.currentTarget.value)\n\t\t} catch (e) {\n\t\t\tthis.setHexInput(this.wheel.color.hexString)\n\t\t}\n\n\t\t// fallback to previous color if the active color doesn't match the input color\n\t\t// this is to prevent the color from changing if the input is invalid\n\t\tif (this.wheel.color.hexString !== this.inputHex.value) {\n\t\t\tthis.setHexInput(this.wheel.color.hexString)\n\t\t}\n\n\t\tthis.onChange(this.wheel.color.hexString)\n\t}\n\n\t/**\n\t * Callback for when a rgb input changes to set rgb values to the color wheel and apply the onChange callback\n\t * @param {Event} event - input change event\n\t */\n\tonRgbChange = (event) => {\n\t\tconst colorType = event.currentTarget.dataset.color\n\t\ttry {\n\t\t\tconst rgb = {}\n\t\t\tthis.inputsRgb.forEach((input) => {\n\t\t\t\trgb[input.dataset.color] = input.value\n\t\t\t})\n\n\t\t\tthis.wheel.color.set(`rgb(${rgb.r}, ${rgb.g}, ${rgb.b}`)\n\t\t} catch (e) {\n\t\t\tthis.setRgbInputs(this.wheel.color.rgb)\n\t\t}\n\n\t\t// fallback to previous color if the active color doesn't match the input color\n\t\t// this is to prevent the color from changing if the input is invalid\n\t\tif (\n\t\t\tthis.wheel.color.rgb[colorType].toString() !==\n\t\t\tevent.currentTarget.value\n\t\t) {\n\t\t\tthis.setRgbInputs(this.wheel.color.rgb)\n\t\t}\n\n\t\tthis.onChange(this.wheel.color.hexString)\n\t}\n\n\t/**\n\t * Render the component\n\t */\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import html from 'utilities/html'\nimport inputTemplate from 'foundation/Input/Input.template'\n\n/**\n * Template for the color picker component\n * @param {Object} args\n * @param {string} args.theme - The theme of the color picker\n * @returns {Function} - The template function\n */\nexport default ({ theme = 'light' }) => html`\n\t
\n\t\t
\n\t\t
\n\t\t\t\n\t\t\t\t${inputTemplate({\n\t\t\t\t\taddClassName:\n\t\t\t\t\t\t'mod-color-picker__input-group mod-color-picker__input-group--hex',\n\t\t\t\t\taccessibilityLabel: 'Hex',\n\t\t\t\t\tdataAttributes: [\n\t\t\t\t\t\t'data-cmp-hook=\"color-input-hex\"',\n\t\t\t\t\t\t'data-color=\"hex\"'\n\t\t\t\t\t],\n\t\t\t\t\tid: 'hex',\n\t\t\t\t\tlabel: 'Hex',\n\t\t\t\t\tname: 'hex',\n\t\t\t\t\ttheme\n\t\t\t\t})}\n\t\t\t\n\t\t\t\n\t\t\t\t${inputTemplate({\n\t\t\t\t\taddClassName:\n\t\t\t\t\t\t'mod-color-picker__input-group mod-color-picker__input-group--rgb',\n\t\t\t\t\taccessibilityLabel: 'R',\n\t\t\t\t\tdataAttributes: [\n\t\t\t\t\t\t'data-cmp-hook=\"color-input-rgb\"',\n\t\t\t\t\t\t'data-color=\"r\"'\n\t\t\t\t\t],\n\t\t\t\t\tid: 'rgb-r',\n\t\t\t\t\tlabel: 'R',\n\t\t\t\t\tname: 'rgb-r',\n\t\t\t\t\ttheme\n\t\t\t\t})}\n\t\t\t\t${inputTemplate({\n\t\t\t\t\taddClassName:\n\t\t\t\t\t\t'mod-color-picker__input-group mod-color-picker__input-group--rgb',\n\t\t\t\t\taccessibilityLabel: 'G',\n\t\t\t\t\tdataAttributes: [\n\t\t\t\t\t\t'data-cmp-hook=\"color-input-rgb\"',\n\t\t\t\t\t\t'data-color=\"g\"'\n\t\t\t\t\t],\n\t\t\t\t\tid: 'rgb-g',\n\t\t\t\t\tlabel: 'G',\n\t\t\t\t\tname: 'rgb-g',\n\t\t\t\t\ttheme\n\t\t\t\t})}\n\t\t\t\t${inputTemplate({\n\t\t\t\t\taddClassName:\n\t\t\t\t\t\t'mod-color-picker__input-group mod-color-picker__input-group--rgb',\n\t\t\t\t\taccessibilityLabel: 'B',\n\t\t\t\t\tdataAttributes: [\n\t\t\t\t\t\t'data-cmp-hook=\"color-input-rgb\"',\n\t\t\t\t\t\t'data-color=\"b\"'\n\t\t\t\t\t],\n\t\t\t\t\tid: 'rgb-b',\n\t\t\t\t\tlabel: 'B',\n\t\t\t\t\tname: 'rgb-b',\n\t\t\t\t\ttheme\n\t\t\t\t})}\n\t\t\t\n\t\t\n\t\t\n\t\n`\n","import Icon from 'foundation/Icon/Icon.template.js'\nimport classNames from 'utilities/classnames'\n\n/**\n * Play Icon Positions\n */\nexport const POSITIONS = {\n\tBOTTOM_LEFT: 'bottom-left',\n\tBOTTOM_RIGHT: 'bottom-right',\n\tCENTER: 'center',\n\tTOP_LEFT: 'top-left',\n\tTOP_RIGHT: 'top-right'\n}\n\n/**\n * Play Icon Sizes\n */\nexport const SIZES = {\n\tLARGE: 'large',\n\tSMALL: 'small'\n}\n\n/**\n * Render Video Play Icon template\n * @param {String} addClassName Additional class name to component\n * @param {Object} a11y Accessibility labels\n * @param {String} a11y.buttonLabel Accessibility label for button\n * @param {String} a11y.playLabel Accessibility label for play icon\n * @param {String} a11y.pauseLabel Accessibility label for pause icon\n * @param {Array} dataAttributes Data attributes to add to component\n * @param {String} id ID to add to component\n * @param {Boolean} isButton If true, component will render as a button\n * @param {Boolean} isInline If true, component will render inline vs the full contents of the parent\n * @param {String} position Position of play icon\n * @param {String} size Size of play icon (small or large)\n */\nconst PlayIcon = ({\n\taddClassName,\n\ta11y: { buttonLabel = '', playLabel = 'Play', pauseLabel = 'Pause' } = {},\n\tdataAttributes,\n\tid,\n\tisButton,\n\tisInline,\n\tposition,\n\tsize,\n\tisBlackAndWhite = false\n} = {}) => {\n\tconst tag = isButton ? 'button' : 'div'\n\n\treturn /* HTML */ `\n <${tag}\n class=\"${classNames(\n\t\t\t'mod-play-icon',\n\t\t\taddClassName,\n\t\t\tisBlackAndWhite && `mod-play-icon--black-white`,\n\t\t\tisInline && `mod-play-icon--inline`,\n\t\t\tposition && `mod-play-icon--position`,\n\t\t\tposition && `mod-play-icon--position-${position}`,\n\t\t\tsize && `mod-play-icon--size-${size}`\n\t\t)}\"\n ${id ? `id=\"${id}\"` : ''}\n ${buttonLabel ? `aria-label=\"${buttonLabel}\"` : ''}\n ${dataAttributes ? dataAttributes.join(' ') : ''}\n data-is-paused=\"true\"\n >\n
\n
\n ${Icon({\n\t\t\t\ticon: 'play'\n\t\t\t})}\n
\n
\n ${Icon({\n\t\t\t\ticon: 'pause'\n\t\t\t})}\n
\n
\n \n`\n}\n\nexport default PlayIcon\n","import { insert } from 'utilities/renderer'\nimport template from './ProductInfo.template'\n\nexport default class ProductInfo {\n\tconstructor(\n\t\telement,\n\t\t{\n\t\t\tcollection,\n\t\t\tglassAvailable,\n\t\t\tbenefits,\n\t\t\tcta,\n\t\t\tconstructionEyebrow,\n\t\t\tfeaturedInEyebrow,\n\t\t\tcomingSoonEyebrow\n\t\t} = {}\n\t) {\n\t\tthis.element = element\n\t\tthis.collection = collection\n\t\tthis.glassAvailable = glassAvailable\n\t\tthis.benefits = benefits\n\t\tthis.cta = cta\n\t\tthis.constructionEyebrow = constructionEyebrow\n\t\tthis.featuredInEyebrow = featuredInEyebrow\n\t\tthis.comingSoonEyebrow = comingSoonEyebrow\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tthis.template = template({\n\t\t\tcollection: this.collection,\n\t\t\tglassAvailable: this.glassAvailable,\n\t\t\tbenefits: this.benefits,\n\t\t\tcta: this.cta,\n\t\t\tconstructionEyebrow: this.constructionEyebrow,\n\t\t\tfeaturedInEyebrow: this.featuredInEyebrow,\n\t\t\tcomingSoonEyebrow: this.comingSoonEyebrow\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\t\tthis.render()\n\t}\n\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import html from 'utilities/html'\nimport textTemplate, {\n\tTYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\nimport linkTemplate from 'foundation/Link/Link.template'\nimport titleTemplate, {\n\tTYPES as TITLE_TYPES\n} from 'foundation/Title/Title.template'\n\n/**\n * Template for the Product Information component\n * @param {Object} args\n * @param {string} args.collection - The name of the collection\n * @param {Object} args.glassAvailable - The glass available object\n * @param {Array} args.benefits - The benefits of the collection\n * @param {Object} args.cta - The CTA of the collection\n * @param {string} args.cta.label - The label of the CTA\n * @param {string} args.cta.url - The url of the CTA\n * @param {string} args.cta.target - The target of the CTA\n * @returns {Function} - The template function\n */\nconst template = ({\n\tcollection = '',\n\tglassAvailable = null,\n\tbenefits = '',\n\tcta = {},\n\tconstructionEyebrow = '',\n\tfeaturedInEyebrow = null,\n\tcomingSoonEyebrow = null\n} = {}) => html`\n\t
\n\t\t
\n\t\t\t${titleTemplate({\n\t\t\t\ttext: collection,\n\t\t\t\theadingElement: 'h1',\n\t\t\t\theadingType: TITLE_TYPES.H4\n\t\t\t})}\n\t\t
\n\n\t\t${glassAvailable !== null\n\t\t\t? /* html */ `\n \n ${textTemplate({\n\t\t\t\t\ttext: glassAvailable.label,\n\t\t\t\t\ttextElement: 'span',\n\t\t\t\t\ttextType: TEXT_TYPES.BODY_XSM\n\t\t\t\t})}\n
\n `\n\t\t\t: ''}\n\t\t${featuredInEyebrow !== null\n\t\t\t? /* html */ `\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t${textTemplate({\n\t\t\t\t\t\t\t\ttext: featuredInEyebrow,\n\t\t\t\t\t\t\t\ttextElement: 'span',\n\t\t\t\t\t\t\t\ttextType: TEXT_TYPES.BODY_XSM\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\n\t\t\t\t\t`\n\t\t\t: ''}\n\t\t${comingSoonEyebrow !== null\n\t\t\t? /* html */ `\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t${textTemplate({\n\t\t\t\t\t\t\t\t\ttext: comingSoonEyebrow,\n\t\t\t\t\t\t\t\t\ttextElement: 'span',\n\t\t\t\t\t\t\t\t\ttextType: TEXT_TYPES.BODY_XSM\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t`\n\t\t\t: ''}\n\n\t\t\n\t\t\t${textTemplate({\n\t\t\t\ttext: constructionEyebrow,\n\t\t\t\ttextElement: 'span',\n\t\t\t\ttextType: TEXT_TYPES.BODY_XSM\n\t\t\t})}\n\t\t\n\n\t\t
    \n\t\t\t${Array.isArray(benefits)\n\t\t\t\t? benefits\n\t\t\t\t\t\t.map((benefit) =>\n\t\t\t\t\t\t\thtml`\n\t\t\t\t\t\t\t\t
  • \n\t\t\t\t\t\t\t\t\t${textTemplate({\n\t\t\t\t\t\t\t\t\t\ttext: benefit,\n\t\t\t\t\t\t\t\t\t\ttextElement: 'span'\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t
  • \n\t\t\t\t\t\t\t`()\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.join('')\n\t\t\t\t: ''}\n\t\t
\n\t\t
\n\t\t\t${linkTemplate({\n\t\t\t\taccessibilityLabel: cta?.text,\n\t\t\t\thref: cta?.url,\n\t\t\t\ttarget: cta?.target,\n\t\t\t\tlabel: cta?.text,\n\t\t\t\tlinkStyle: 'link-style-primary',\n\t\t\t\tlinkButtonStyle: 'link-style-primary',\n\t\t\t\tlinkTextStyle: 'link-style-primary',\n\t\t\t\tlinkSize: 'link-large',\n\t\t\t\tshowAsButtonLink: false,\n\t\t\t\tstartIcon: 'map-pin',\n\t\t\t\tanalytics: {\n\t\t\t\t\tevent: 'cta_link',\n\t\t\t\t\tcta_text: cta?.text,\n\t\t\t\t\tcta_title: collection\n\t\t\t\t}\n\t\t\t})}\n\t\t
\n\t\n`\n\nexport default template\n","// import html from 'utilities/html'\nimport classNames from 'utilities/classnames'\n\n/**\n * Single Tab Template\n * @param {Object} tab - Tab details\n * @param {String} id - Unique identifier for the tab\n * @param {String} accessibilityLabel - Accessibility label for the tab\n * @param {String} title - Title of the tab\n * @param {String} theme - Theme class for the tab\n * @param {Boolean} disabled - Whether the tab is disabled\n * @param {Boolean} isActive - Whether the tab is active\n */\nconst Tab = ({ id, accessibilityLabel, title, theme, disabled, isActive }) => `\n \n
\n \n ${title}\n \n
\n \n`\n\n/**\n * Display the tabs\n * @param {String} id - ID of the tabs component\n * @param {Array} tabs - Array of tab objects\n * @param {String} theme - Theme class\n * @returns {String} - HTML string for tabs\n */\nconst displayTabs = (id, tabs, theme) =>\n\ttabs\n\t\t? tabs\n\t\t\t\t.map((tab, index) =>\n\t\t\t\t\tTab({\n\t\t\t\t\t\tid: `${id}-tab-${tab.id || index}`,\n\t\t\t\t\t\taccessibilityLabel: tab.title || '',\n\t\t\t\t\t\ttitle: tab.title || '',\n\t\t\t\t\t\ttheme,\n\t\t\t\t\t\tdisabled: tab.disabled || false,\n\t\t\t\t\t\tisActive: tab.isActive || false\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t\t.join('')\n\t\t: ''\n\n/**\n * Display the content\n * @param {String} id - ID of the tabs component\n * @param {Array} tabs - Array of tab objects\n * @param {String} theme - Theme class\n * @returns {String} - HTML string for tab contents\n */\nconst displayContent = (id, tabs, theme) => `\n
\n ${\n\t\t\ttabs\n\t\t\t\t? tabs\n\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t(tab, index) => `\n
\n ${tab.content || ''}\n
\n `\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.join('')\n\t\t\t\t: ''\n\t\t}\n
\n`\n\n/**\n * Display the select dropdown\n * @param {Array} tabs - Array of tab objects\n * @param {String} id - ID of the tabs component\n * @returns {String} - HTML string for the dropdown select\n */\nconst displaySelect = (tabs, id) => `\n
\n \n ${tabs.find((tab) => tab.isActive)?.title || 'Select a tab'}\n \n\n \n ${tabs\n\t\t\t.map(\n\t\t\t\t(tab, index) => `\n
  • \n \n \n ${tab.title}\n \n \n
  • \n `\n\t\t\t)\n\t\t\t.join('')}\n \n
    \n`\n\n/**\n * Tabs Template\n * @param {Object} args - Template arguments\n * @param {String} args.alignment - Alignment class for the tabs\n * @param {String} args.id - ID of the tabs component\n * @param {String} args.moduleSpacing - Spacing class for the module\n * @param {Array} args.tabs - Array of tab objects\n * @param {String} args.theme - Theme class\n * @returns {String} - Complete HTML for the Tabs component\n */\nconst TabsTemplate = ({\n\taddClassName,\n\tid,\n\talignment,\n\tfullWidth = false,\n\tmoduleSpacing,\n\ttabs,\n\ttheme = 'theme-light'\n}) => `\n \n \n ${displaySelect(tabs, id)}\n\n \n
    \n
    \n
    \n ${displayTabs(id, tabs, theme)}\n \n
    \n ${displayContent(id, tabs, theme)}\n
    \n
    \n \n`\n\nexport default TabsTemplate\n","import html from 'utilities/html'\nimport classNames from 'utilities/classnames'\nimport imageTemplate from 'foundation/Image/Image.template'\nimport linkTemplate from 'foundation/Link/Link.template'\nimport textTemplate, {\n\tTYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\nimport iconTemplate from 'foundation/Icon/Icon.template'\nimport tabsTemplate from '../../../Tabs/Tabs.template'\nimport { Default as buttonTemplate } from 'foundation/Button/Button.stories'\n\n/**\n * Utility function to get the custom color from the option value\n */\nfunction getCustomColor(option) {\n\tconst customColorPrefix = 'custom-color-'\n\tconst isCustomColor = option?.value.includes(customColorPrefix)\n\tconst customColor = isCustomColor\n\t\t? option.value.split(customColorPrefix)[1]\n\t\t: ''\n\treturn customColor\n}\n\n/**\n * Template for the option image\n * @param {Object} args\n * @param {Object} args.option - The option object\n * @param {Object} args.selectedOption - The selected option object\n * @param {Boolean} args.displayDarkImage - Whether to display the dark image\n */\nconst activeOptionImageTemplate = ({\n\toption,\n\tselectedOption,\n\tdisplayDarkImage\n} = {}) => {\n\tconst customColor = getCustomColor(selectedOption)\n\n\tif (customColor) {\n\t\treturn html``\n\t}\n\n\treturn selectedOption?.imageDark && displayDarkImage\n\t\t? html` ${imageTemplate({\n\t\t\t\taddClassName:\n\t\t\t\t\t'mod-product-option-group__active-image mod-product-option-group__active-image--light',\n\t\t\t\tdefaultAspectRatio: '1/1',\n\t\t\t\tmobileAspectRatio: '1/1',\n\t\t\t\tdefaultSrc: selectedOption?.image,\n\t\t\t\tmobileSrc: selectedOption?.image,\n\t\t\t\taltText: selectedOption?.label,\n\t\t\t\tloading: 'eager'\n\t\t })}\n\t\t ${imageTemplate({\n\t\t\t\taddClassName:\n\t\t\t\t\t'mod-product-option-group__active-image mod-product-option-group__active-image--dark',\n\t\t\t\tdefaultAspectRatio: '1/1',\n\t\t\t\tmobileAspectRatio: '1/1',\n\t\t\t\tdefaultSrc: selectedOption?.imageDark,\n\t\t\t\tmobileSrc: selectedOption?.imageDark,\n\t\t\t\taltText: selectedOption?.label,\n\t\t\t\tloading: 'eager'\n\t\t })}`\n\t\t: html` ${imageTemplate({\n\t\t\t\taddClassName: 'mod-product-option-group__active-image',\n\t\t\t\tdefaultAspectRatio: '1/1',\n\t\t\t\tmobileAspectRatio: '1/1',\n\t\t\t\tdefaultSrc: selectedOption?.image,\n\t\t\t\tmobileSrc: selectedOption?.image,\n\t\t\t\taltText: selectedOption?.label,\n\t\t\t\tloading: 'eager'\n\t\t })}`\n}\n\n/**\n * Template for a single product option category. This is the element that each option input will be rendered into.\n * @param {*} category\n * @returns\n */\nconst categoryTemplate = ({ category = {} }) => html`\n\t
    \n\t\t
    \n\t
    \n`\n\n/**\n * Template for the product option tabs\n * @param {Array} categories - The categories of the product option group\n * @returns\n */\nconst categoryTabsTemplate = ({ breakpoint, categories = [], groupValue }) =>\n\thtml`\n\t\t
    \n\t\t\t${tabsTemplate({\n\t\t\t\taddClassName: 'mod-product-option-group__tabs',\n\t\t\t\tdisableTabsScrollIntoView: true,\n\t\t\t\tid: `product-option-tabs-${groupValue}`,\n\t\t\t\ttabs: categories.map((category) => ({\n\t\t\t\t\ttitle: category.label,\n\t\t\t\t\tcontent: categoryTemplate({\n\t\t\t\t\t\tbreakpoint,\n\t\t\t\t\t\tcategory\n\t\t\t\t\t})()\n\t\t\t\t})),\n\t\t\t\ttheme: breakpoint.MEDIUM_LARGE ? 'theme-light' : 'theme-dark'\n\t\t\t})}\n\t\t
    \n\t`\n\nexport const rangeTemplate = ({\n\trangeLabel,\n\trangeMax,\n\trangeMin,\n\trangeValue\n} = {}) => html`\n\t
    \n\t\t
    \n\t\t\t${textTemplate({\n\t\t\t\ttextType: TEXT_TYPES.CAPTION,\n\t\t\t\ttext: `${rangeLabel}:`\n\t\t\t})}\n\t\t
    \n\t\t
    \n\t\t\t${Array.from({ length: rangeMax - rangeMin + 1 }, (_, i) => i + 1)\n\t\t\t\t.map((_, i) =>\n\t\t\t\t\thtml`\n\t\t\t\t\t\t\n\t\t\t\t\t`()\n\t\t\t\t)\n\t\t\t\t.join('')}\n\t\t
    \n\t\t
    \n\t\t\t${textTemplate({\n\t\t\t\ttextType: TEXT_TYPES.CAPTION,\n\t\t\t\ttext: `${rangeValue}/${rangeMax}`\n\t\t\t})}\n\t\t
    \n\t
    \n`\n\nconst optionInfoTemplate = ({ option, selectedOption } = {}) => {\n\tconst isColor = option.type === 'color'\n\tconst customColor = getCustomColor(selectedOption)\n\n\treturn html`\n\t\t
    \n\t\t\t\n\t\t\t\t${activeOptionImageTemplate({ option, selectedOption })()}\n\t\t\t
    \n\t\t\t
    \n\t\t\t\t${textTemplate({\n\t\t\t\t\ttextType: TEXT_TYPES.CALLOUT,\n\t\t\t\t\ttext: selectedOption?.label || ''\n\t\t\t\t})}\n\t\t\t
    \n\t\t\n\t`\n}\n\n/**\n *\n * @param {args} {Object}\n * @param {args.option} {Object} - The option object\n * @param {args.selectedOption} {Object} - The selected option object\n * @param {args.isToggleButton} {Boolean} - Whether the option is a toggle button\n * @returns\n */\nexport const optionDetailsTemplate = ({\n\toption,\n\toption: { label, tooltip, rangeLabel, rangeMax, rangeMin },\n\tselectedOption,\n\tisToggleButton\n} = {}) => {\n\tconst isColor = option.type === 'color'\n\tconst customColor = getCustomColor(selectedOption)\n\n\treturn html`\n\t\t\n\t\t\t\n\t\t\t\t${activeOptionImageTemplate({\n\t\t\t\t\toption,\n\t\t\t\t\tselectedOption,\n\t\t\t\t\tdisplayDarkImage: isToggleButton\n\t\t\t\t})()}\n\t\t\t\n\t\t\t
    \n\t\t\t\t
    \n\t\t\t\t\t${textTemplate({\n\t\t\t\t\t\ttextType: TEXT_TYPES.CTA_LG,\n\t\t\t\t\t\ttext: label\n\t\t\t\t\t})}\n\t\t\t\t
    \n\t\t\t\t${tooltip !== ''\n\t\t\t\t\t? /* HTML */ `\n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t${tooltip}\n\t\t\t\t\t\t\t\t\t\t${iconTemplate({\n\t\t\t\t\t\t\t\t\t\t\taddClassName: 'cmp-tooltip__svg',\n\t\t\t\t\t\t\t\t\t\t\ticon: 'info'\n\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t${textTemplate({\n\t\t\t\t\t\t\t\t\t\t\ttext: tooltip,\n\t\t\t\t\t\t\t\t\t\t\ttextElement: 'p',\n\t\t\t\t\t\t\t\t\t\t\ttextType: TEXT_TYPES.BODY_SM,\n\t\t\t\t\t\t\t\t\t\t\taddClassName: 'cmp-tooltip__text'\n\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t `\n\t\t\t\t\t: ''}\n\t\t\t\t
    \n\t\t\t\t\t${textTemplate({\n\t\t\t\t\t\ttextType: TEXT_TYPES.CALLOUT,\n\t\t\t\t\t\ttext: selectedOption?.label || ''\n\t\t\t\t\t})}\n\t\t\t\t
    \n\t\t\t\t${rangeLabel\n\t\t\t\t\t? rangeTemplate({\n\t\t\t\t\t\t\trangeLabel,\n\t\t\t\t\t\t\trangeMax,\n\t\t\t\t\t\t\trangeMin,\n\t\t\t\t\t\t\trangeValue: selectedOption?.range || ''\n\t\t\t\t\t })()\n\t\t\t\t\t: ''}\n\t\t\t\n\t\t\n\t`\n}\n\nexport const toggleButtonTemplate = ({\n\toption,\n\tselectedOption,\n\tbreakpoint\n}) => html`\n\t
    \n\t\t${breakpoint?.MEDIUM_LARGE\n\t\t\t? optionDetailsTemplate({ option, selectedOption })()\n\t\t\t: optionInfoTemplate({ option, selectedOption })()}\n\t
    \n`\n\n/**\n * Template for the more details link\n * @param {Object} args\n * @param {Object} args.moreDetails\n * @param {string} args.moreDetails.detailsId - The id of the details element\n * @param {string} args.moreDetails.label - The label for the more details link\n * @returns\n */\nconst moreDetailsTemplate = ({ moreDetails } = {}) => html`\n\t
    \n\t\t${linkTemplate({\n\t\t\tlinkStyle: 'link-style-text',\n\t\t\tdataAttributes: ['data-cmp-hook=\"product-option-group-more-details\"'],\n\t\t\thref: `#product-details-categories-tab-${moreDetails.detailsId}`,\n\t\t\tlabel: moreDetails.label,\n\t\t\tlinkSize: 'link-large',\n\t\t\tshowAsButtonLink: false,\n\t\t\tshowAsTextLink: true\n\t\t})}\n\t
    \n`\n\n/**\n *\n * @param {Object} productOptionGroup\n * @param {string} productOptionGroup.label - The label for the product option group\n * @param {string} productOptionGroup.rangeLabel - The label for the range of the product option group\n * @param {string} productOptionGroup.rangeMax - The maximum value for the range of the product option group\n * @param {string} productOptionGroup.rangeMin - The minimum value for the range of the product option group\n * @param {string} productOptionGroup.type - The type of the product option group\n * @param {string} productOptionGroup.value - The value of the product option group\n * @param {Array} productOptionGroup.categories - The categories of the product option group\n * @returns\n */\nconst template = ({\n\thasSingleOption,\n\toption,\n\toption: {\n\t\tlabel = '',\n\t\ttooltip = '',\n\t\trangeLabel = '',\n\t\trangeMax = '',\n\t\trangeMin = '',\n\t\ttype = '',\n\t\tvalue = '',\n\t\tcategories = []\n\t} = {},\n\toptionTools: { select, cancel } = {},\n\tselectedOption,\n\tbreakpoint\n} = {}) => html`\n\t
    \n\t\t
    \n\t\t\t${textTemplate({\n\t\t\t\ttextType: TEXT_TYPES.CALLOUT,\n\t\t\t\ttext: label\n\t\t\t})}\n\t\t
    \n\n\t\t\n\t\t\t
    \n\n\t\t\t${hasSingleOption\n\t\t\t\t? ''\n\t\t\t\t: /* HTML */ `\n\t\t\t\t\t\t${iconTemplate({\n\t\t\t\t\t\t\ticon: 'chevron-down',\n\t\t\t\t\t\t\taddClassName:\n\t\t\t\t\t\t\t\t'mod-product-option-group__toggle-button-indicator-icon'\n\t\t\t\t\t\t})}\n\t\t\t\t `}\n\t\t\n\t\t\n\t\t\t
    \n\t\t\t\t
    \n\t\t\t\t\t${optionDetailsTemplate({\n\t\t\t\t\t\toption,\n\t\t\t\t\t\tselectedOption,\n\t\t\t\t\t\tisToggleButton: true\n\t\t\t\t\t})()}\n\t\t\t\t
    \n\t\t\t\t${Array.isArray(categories) && categories.length > 1\n\t\t\t\t\t? categoryTabsTemplate({\n\t\t\t\t\t\t\tbreakpoint,\n\t\t\t\t\t\t\tcategories,\n\t\t\t\t\t\t\tgroupValue: value,\n\t\t\t\t\t\t\toption,\n\t\t\t\t\t\t\tselectedOption\n\t\t\t\t\t })()\n\t\t\t\t\t: ''}\n\t\t\t\t${Array.isArray(categories) && categories.length === 1\n\t\t\t\t\t? categoryTemplate({\n\t\t\t\t\t\t\tbreakpoint,\n\t\t\t\t\t\t\tcategory: categories[0],\n\t\t\t\t\t\t\toption,\n\t\t\t\t\t\t\tselectedOption\n\t\t\t\t\t })()\n\t\t\t\t\t: ''}\n\t\t\t\t${option.moreDetails\n\t\t\t\t\t? moreDetailsTemplate({ moreDetails: option.moreDetails })()\n\t\t\t\t\t: ''}\n\t\t\t\t
    \n\t\t\t\t\t${buttonTemplate({\n\t\t\t\t\t\tbuttonSize: 'button-large',\n\t\t\t\t\t\tbuttonStyle: 'button-style-primary-reversed',\n\t\t\t\t\t\tdataAttributes: [\n\t\t\t\t\t\t\t'data-cmp-hook=\"product-option-group-submit\"'\n\t\t\t\t\t\t],\n\t\t\t\t\t\tlabel: select?.label || '',\n\t\t\t\t\t\taccessibilityLabel: select?.accessibilityLabel || ''\n\t\t\t\t\t})}\n\t\t\t\t\t${buttonTemplate({\n\t\t\t\t\t\tbuttonSize: 'button-large',\n\t\t\t\t\t\tbuttonStyle: 'button-style-tertiary-reversed',\n\t\t\t\t\t\tdataAttributes: [\n\t\t\t\t\t\t\t'data-cmp-hook=\"product-option-group-cancel\"'\n\t\t\t\t\t\t],\n\t\t\t\t\t\tlabel: cancel?.label || '',\n\t\t\t\t\t\taccessibilityLabel: cancel?.accessibilityLabel || ''\n\t\t\t\t\t})}\n\t\t\t\t
    \n\t\t\t
    \n\t\t\n\t\n`\n\nexport default template\n","import html from 'utilities/html'\nimport classNames from 'utilities/classnames'\nimport textTemplate, {\n\tTYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\nimport imageTemplate from 'foundation/Image/Image.template'\nimport iconTemplate from 'foundation/Icon/Icon.template'\n\n/**\n * Tile option input template\n * @param {Object} args\n * @param {Object} args.option - The option object\n * @param {String} args.optionId - The id of the option\n * @param {String} args.categoryValue - The value of the category\n * @param {String} args.groupValue - The value of the group\n * @param {String} args.groupType - The type of the group\n * @param {String} args.groupType - The type of the group\n * @returns {Function} - html template function\n */\nconst tileOptionTemplate = ({\n\toption,\n\toptionId,\n\tcategoryValue,\n\tgroupValue,\n\tgroupType\n}) => html`\n\t\n\t\t\n\t\t\n\t\n`\n\n/**\n * Custom Color option input template\n * @param {Object} args\n * @param {Object} args.option - The option object\n * @param {String} args.optionId - The id of the option\n * @param {String} args.categoryValue - The value of the category\n * @param {String} args.groupValue - The value of the group\n * @param {String} args.groupType - The type of the group\n * @returns {Function} - html template function\n */\nconst customColorTemplate = ({\n\toption,\n\toptionId,\n\tcategoryValue,\n\tgroupValue,\n\tgroupType\n}) => html`\n\t
    \n\t\t\n\t\t\t\n\t\t\t\n\t\t\t\t${imageTemplate({\n\t\t\t\t\taddClassName: 'mod-product-option-category__image',\n\t\t\t\t\tdefaultAspectRatio: '1/1',\n\t\t\t\t\tmobileAspectRatio: '1/1',\n\t\t\t\t\tdefaultSrc: option.image,\n\t\t\t\t\tmobileSrc: option.image,\n\t\t\t\t\taltText: option.label\n\t\t\t\t})}\n\t\t\t\n\t\t
    \n\t\t
    \n\t\n`\n\n/**\n * Text option input template\n * @param {Object} args\n * @param {Object} args.option - The option object\n * @param {String} args.optionId - The id of the option\n * @param {String} args.categoryValue - The value of the category\n * @param {String} args.groupValue - The value of the group\n * @param {String} args.groupType - The type of the group\n * @param {String} args.groupType - The type of the group\n * @returns {Function} - html template function\n */\nconst textOptionTemplate = ({\n\toption,\n\toptionId,\n\tcategoryValue,\n\tgroupValue,\n\tgroupType\n}) => html`\n\t\n\t\t\n\t\t\n\t\n`\n/**\n * Tile Text option input template\n * Note: this template is unique in that is displays the value of the option instead of the label\n * @param {Object} args\n * @param {Object} args.option - The option object\n * @param {String} args.optionId - The id of the option\n * @param {String} args.categoryValue - The value of the category\n * @param {String} args.groupValue - The value of the group\n * @param {String} args.groupType - The type of the group\n * @param {String} args.groupType - The type of the group\n * @returns {Function} - html template function\n */\nconst tileTextOptionTemplate = ({\n\toption,\n\toptionId,\n\tcategoryValue,\n\tgroupValue,\n\tgroupType\n}) => html`\n\t\n\t\t\n\t\t\n\t\n`\n\n/**\n * Template for rendering a single option\n * @param {Object} option\n * @returns\n */\nconst categoryOptionTemplate = ({\n\toption = {},\n\tcategoryValue = '',\n\tgroupValue = '',\n\tgroupType = ''\n}) => {\n\tconst optionId = `${groupValue}-${categoryValue}-${option.value}`\n\n\tif (groupType === 'color' && categoryValue === 'Custom') {\n\t\treturn customColorTemplate({\n\t\t\toption,\n\t\t\toptionId,\n\t\t\tcategoryValue,\n\t\t\tgroupValue,\n\t\t\tgroupType\n\t\t})\n\t} else if (groupType === 'color' || groupType === 'tile') {\n\t\treturn tileOptionTemplate({\n\t\t\toption,\n\t\t\toptionId,\n\t\t\tcategoryValue,\n\t\t\tgroupValue,\n\t\t\tgroupType\n\t\t})\n\t} else if (groupType === 'tileText') {\n\t\treturn tileTextOptionTemplate({\n\t\t\toption,\n\t\t\toptionId,\n\t\t\tcategoryValue,\n\t\t\tgroupValue,\n\t\t\tgroupType\n\t\t})\n\t} else if (groupType === 'text') {\n\t\treturn textOptionTemplate({\n\t\t\toption,\n\t\t\toptionId,\n\t\t\tcategoryValue,\n\t\t\tgroupValue,\n\t\t\tgroupType\n\t\t})\n\t}\n\n\treturn html``\n}\n\nconst viewMoreButton = ({ isLargeBreakpoint, optionsWrapperId }) => html`\n\t\n\t\t\n\t\t\n\t\t\t${iconTemplate({\n\t\t\t\ticon: 'chevron-down',\n\t\t\t\taddClassName: 'mod-product-option-category__view-more-svg'\n\t\t\t})}\n\t\t\n\t\n`\n\nconst viewMoreTemplate = ({ optionsWrapperId }) => html`\n\t
    \n\t\t${viewMoreButton({ isLargeBreakpoint: true, optionsWrapperId })()}\n\t\t${viewMoreButton({ isLargeBreakpoint: false, optionsWrapperId })()}\n\t
    \n`\n\nconst noteTemplate = ({ note }) => html`\n\t
    \n\t\t${textTemplate({\n\t\t\ttext: note,\n\t\t\ttextType: TEXT_TYPES.CALLOUT,\n\t\t\ttextElement: 'p'\n\t\t})}\n\t
    \n`\n\n/**\n * ProductOptionCategory template responsible for rendering a category of options\n * @param {Object} args\n * @param {Object} args.category - Option category object\n * @param {String} args.groupValue - the value of the group\n * @param {String} args.groupType - the type of the group\n * @param {Number} args.maxOptions - the maximum number of options to show before collapsing\n * @returns {Function} - html template function\n */\nconst template = ({ category, groupValue, groupType, maxOptions }) => {\n\tconst optionModifiers = {\n\t\ttile: 'mod-product-option-category--tile',\n\t\ttileText: 'mod-product-option-category--tile-text',\n\t\tcolor: 'mod-product-option-category--tile-color',\n\t\ttext: 'mod-product-option-category--text'\n\t}\n\tconst hasOptions =\n\t\tArray.isArray(category.options) && category.options.length > 0\n\tconst optionsWrapperId = `${groupValue}-${category.value}-category-options`\n\n\treturn html`\n\t\t\n\t\t\t
    \n\t\t\t\t\n\t\t\t\t\t${textTemplate({\n\t\t\t\t\t\ttext: category.helperLabel || category.labelAccessibility,\n\t\t\t\t\t\ttextType: TEXT_TYPES.BODY_SM\n\t\t\t\t\t})}\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t${hasOptions\n\t\t\t\t\t\t? category.options\n\t\t\t\t\t\t\t\t.map((option, index) =>\n\t\t\t\t\t\t\t\t\tcategoryOptionTemplate({\n\t\t\t\t\t\t\t\t\t\toption,\n\t\t\t\t\t\t\t\t\t\tcategoryValue: category.value,\n\t\t\t\t\t\t\t\t\t\tgroupValue,\n\t\t\t\t\t\t\t\t\t\tgroupType\n\t\t\t\t\t\t\t\t\t})()\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.join('')\n\t\t\t\t\t\t: ''}\n\t\t\t\t\n\t\t\t
    \n\t\t\t${category.note ? noteTemplate({ note: category.note })() : ''}\n\t\t\t${hasOptions && category.options.length > maxOptions\n\t\t\t\t? viewMoreTemplate({\n\t\t\t\t\t\toptionsWrapperId\n\t\t\t\t })()\n\t\t\t\t: ''}\n\t\t\n\t`\n}\nexport default template\n","import classNames from 'utilities/classnames'\n\n/**\n * @param {Object} icon SVG icon to display\n * @returns\n */\nconst displayCloseIcon = (icon) =>\n\ticon\n\t\t? `\n \n \n \n `\n\t\t: ''\n\n/**\n * Render Modal template\n * @param {Object} options Component options\n * @param {String} options.id Component ID\n * @param {Boolean} options.defaultOpen Whether the modal is open by default\n * @param {String} options.children Content to be rendered within the modal\n * @param {String} options.closeButtonAriaLabel Aria label for the close button\n * @param {String} options.closeButtonClass CSS class for the close button\n * @param {String} options.fullScreen CSS class for the modal to go full screen\n * @param {String} options.hasHeader CSS class to add a header to the modal\n * @param {String} options.modalClass CSS class for the modal\n * @param {String} options.transition CSS class for the modal transition\n * @param {String} options.headerTitle Header title text\n */\nconst ModalOverlayTemplate = ({\n\tid,\n\tdefaultOpen = false,\n\tchildren = '',\n\tcloseButtonAriaLabel = '',\n\tcloseButtonClass = '',\n\tfullScreen = false,\n\thasHeader = false,\n\tmodalClass = '',\n\ttransition = 'fade',\n\theaderTitle = ''\n}) => /* HTML */ `\n\t\n\t\t
    \n\t\t\t\n\t\t\t\t${displayCloseIcon('close-x')}\n\t\t\t\n\t\t\t${hasHeader\n\t\t\t\t? `

    ${headerTitle}

    `\n\t\t\t\t: ''}\n\t\t\t${children}\n\t\t
    \n\t\n`\n\nexport default ModalOverlayTemplate\n","import html from 'utilities/html'\nimport classNames from 'utilities/classnames'\nimport modalTemplate from 'modules/Modal/Modal.template'\nimport textTemplate, {\n\tTYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\nimport titleTemplate, {\n\tTYPES as TITLE_TYPES\n} from 'foundation/Title/Title.template'\nimport { Default as buttonTemplate } from 'foundation/Button/Button.stories'\n\n/**\n * Template for the ProductOptionCustomColor select and cancel buttons for mobile breakpoints\n * @param {Object} arg\n * @param {Object} args.optionTools - The option tools object with the select and cancel labels\n * @returns {Function} - The template function\n */\nconst mobileButtons = ({ optionTools = {} }) => html`\n\t
    \n\t\t${buttonTemplate({\n\t\t\taddClassName: 'mod-product-option-custom-color__button',\n\t\t\tbuttonSize: 'button-large',\n\t\t\tbuttonStyle: 'button-style-primary-reversed',\n\t\t\tdataAttributes: ['data-cmp-hook=\"color-picker-select-button\"'],\n\t\t\tlabel: optionTools.select?.label || '',\n\t\t\taccessibilityLabel: optionTools.select?.accessibilityLabel || ''\n\t\t})}\n\t\t${buttonTemplate({\n\t\t\taddClassName: 'mod-product-option-custom-color__button',\n\t\t\tbuttonSize: 'button-large',\n\t\t\tbuttonStyle: 'button-style-tertiary-reversed',\n\t\t\tdataAttributes: ['data-cmp-hook=\"color-picker-cancel-button\"'],\n\t\t\tlabel: optionTools.cancel?.label || '',\n\t\t\taccessibilityLabel: optionTools.cancel?.accessibilityLabel || ''\n\t\t})}\n\t
    \n`\n\n/**\n * Template for the ProductOptionCustomColor select and cancel buttons for desktop breakpoints\n * @param {Object} arg\n * @param {Object} args.optionTools - The option tools object with the select and cancel labels\n * @returns {Function} - The template function\n */\nconst desktopButtons = ({ optionTools = {} }) => html`\n\t
    \n\t\t${buttonTemplate({\n\t\t\taddClassName: 'mod-product-option-custom-color__button',\n\t\t\tbuttonSize: 'button-large',\n\t\t\tbuttonStyle: 'button-style-tertiary',\n\t\t\tdataAttributes: ['data-cmp-hook=\"color-picker-cancel-button\"'],\n\t\t\tlabel: optionTools.cancel?.label || '',\n\t\t\taccessibilityLabel: optionTools?.accessibilityLabel || ''\n\t\t})}\n\t\t${buttonTemplate({\n\t\t\taddClassName: 'mod-product-option-custom-color__button',\n\t\t\tbuttonSize: 'button-large',\n\t\t\tbuttonStyle: 'button-style-primary',\n\t\t\tdataAttributes: ['data-cmp-hook=\"color-picker-select-button\"'],\n\t\t\tlabel: optionTools.select?.label || '',\n\t\t\taccessibilityLabel: optionTools.select?.accessibilityLabel || ''\n\t\t})}\n\t
    \n`\n\n/**\n * Template for the ProductOptionCustomColor content\n * @param {Object} args\n * @param {Object} args.content - The content object for the component\n * @param {Object} args.content.title - The title to display\n * @param {Object} args.content.description - The description to display\n * @param {Object} args.content.optionTools - The option tools object with the select and cancel labels\n * @param {Boolean} args.isMediumLarge - Whether the breakpoint is medium-large\n * @returns {Function} - The template function\n */\nconst modalContent = ({\n\tcontent: { title, description, optionTools } = {},\n\tisMediumLarge\n}) => html`\n\t
    \n\t\t${titleTemplate({\n\t\t\taddClassName: 'mod-product-option-custom-color__title',\n\t\t\theadingType: TITLE_TYPES.H4,\n\t\t\ttext: title || '',\n\t\t\theadingElement: 'h2'\n\t\t})}\n\t\t${textTemplate({\n\t\t\taddClassName: 'mod-product-option-custom-color__description',\n\t\t\ttextType: TEXT_TYPES.BODY_MEDIUM,\n\t\t\ttext: description || ''\n\t\t})}\n\t\t
    \n\t\t${isMediumLarge\n\t\t\t? desktopButtons({ optionTools })()\n\t\t\t: mobileButtons({ optionTools })()}\n\t\n`\n\n/**\n * Template for the ProductOptionCustomColor component\n * @param {Object} args\n * @param {Object} args.content - The content object for the component\n * @param {Object} args.content.title - The title to display\n * @param {Object} args.content.description - The description to display\n * @param {Object} args.content.optionTools - The option tools object with the select and cancel labels\n * @param {Boolean} args.isMediumLarge - Whether the breakpoint is medium-large\n * @returns {Function} - The template function\n */\nconst template = ({\n\tcontent,\n\tcontent: { title, description, optionTools } = {},\n\tisMediumLarge\n}) => html`\n\t\n\t\t${modalTemplate({\n\t\t\tcloseButtonAriaLabel: optionTools.cancelAccessibility,\n\t\t\theaderTitle: title || '',\n\t\t\tid: 'custom-color-modal',\n\t\t\tmodalClass: 'mod-product-option-custom-color__modal',\n\t\t\tchildren: modalContent({ content, isMediumLarge })()\n\t\t})}\n\t\n`\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport { noop } from 'utilities/utilities'\nimport Services from 'services'\nimport ColorPicker from 'modules/ColorPicker/ColorPicker'\nimport template from './ProductOptionCustomColor.template'\nimport Modal from 'modules/Modal/Modal'\n\n/**\n * ProductOptionCustomColor component responsible for rendering a custom color picker in a modal\n * @param {HTMLElement} element - the element to render the component in\n * @param {Object} options - the options for the component\n * @param {Object} options.content - the content for the component\n * @param {string} options.content.title - the title for the color picker modal\n * @param {string} options.content.description - the description for the color picker modal\n * @param {Object} options.content.optionTools - the option tools for the color picker modal (e.g. \"Select\" and \"Cancel\" buttons)\n * @param {string} options.initialColor - the initial color for the color picker\n * @param {Function} options.onSelect - the callback for when the color changes\n * @param {Function} options.onCancel - the callback for when the color picker is cancelled\n */\nexport default class ProductOptionCustomColor {\n\tstatic SELECTORS = {\n\t\tBUTTON_CANCEL: '[data-cmp-hook=\"color-picker-cancel-button\"]',\n\t\tBUTTON_SELECT: '[data-cmp-hook=\"color-picker-select-button\"]',\n\t\tCOLOR_PICKER_BUTTON: '[data-cmp-hook=\"color-picker-button\"]',\n\t\tCOLOR_PICKER: '[data-cmp-hook=\"color-picker\"]',\n\t\tMODAL: '[data-cmp-is=\"modal\"]'\n\t}\n\n\tconstructor(\n\t\telement,\n\t\t{ content = {}, initialColor = null, onSelect = noop, onCancel } = {}\n\t) {\n\t\tthis.element = element\n\t\tthis.services = Services.getInstance()\n\t\tthis.EventEmitterService = this.services.EventEmitterService\n\t\tthis.mediaQuery = this.services.BreakpointListener.queryMatch\n\t\tthis.content = content\n\t\tthis.onSelect = onSelect\n\t\tthis.onCancel = onCancel\n\t\tthis.color = initialColor\n\t\tthis.pendingColor = initialColor\n\t\tthis.init()\n\t}\n\n\t/**\n\t * Initializes the component\n\t */\n\tinit() {\n\t\tif (this.template) {\n\t\t\tthis.detachEvents()\n\t\t}\n\n\t\tthis.template = template({\n\t\t\tcontent: this.content,\n\t\t\tisMediumLarge: this.mediaQuery.MEDIUM_LARGE\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.cacheDom()\n\t\tthis.attachEvents()\n\t\tthis.render()\n\t}\n\n\t/**\n\t * Cache the DOM elements\n\t */\n\tcacheDom() {\n\t\tthis.colorPickerButtonEl = this.template.querySelector(\n\t\t\tProductOptionCustomColor.SELECTORS.COLOR_PICKER_BUTTON\n\t\t)\n\n\t\tthis.colorPickerEl = this.template.querySelector(\n\t\t\tProductOptionCustomColor.SELECTORS.COLOR_PICKER\n\t\t)\n\n\t\tthis.modalEl = this.template.querySelector(\n\t\t\tProductOptionCustomColor.SELECTORS.MODAL\n\t\t)\n\n\t\tthis.buttonSelect = this.template.querySelector(\n\t\t\tProductOptionCustomColor.SELECTORS.BUTTON_SELECT\n\t\t)\n\n\t\tthis.buttonCancel = this.template.querySelector(\n\t\t\tProductOptionCustomColor.SELECTORS.BUTTON_CANCEL\n\t\t)\n\t}\n\n\t/**\n\t * Attach the events\n\t */\n\tattachEvents() {\n\t\tthis.EventEmitterService.on(Modal.EVENTS.CLOSE_MODAL, this.onModalClose)\n\n\t\tthis.buttonSelect.addEventListener('click', this.onSelectHandler)\n\t\tthis.buttonCancel.addEventListener('click', this.onCancelHandler)\n\n\t\tthis.services.BreakpointListener.addListener(this.onBreakpointChange)\n\t}\n\n\t/**\n\t * Detach the events\n\t */\n\tdetachEvents() {\n\t\tthis.services.BreakpointListener.removeListener(this.onBreakpointChange)\n\t}\n\n\t/**\n\t * Destroy the component\n\t */\n\tdestroy() {\n\t\tthis.detachEvents()\n\t}\n\n\t/**\n\t * Store the active color picker color\n\t * @param {string} color - hex color value\n\t */\n\tsetColor = (color) => {\n\t\tthis.pendingColor = color\n\t}\n\n\t/**\n\t * Open the color picker modal and initialize the color picker\n\t */\n\topenColorPicker = () => {\n\t\tthis.modal = new Modal(this.modalEl)\n\n\t\t// fix for a race condition with the keydown event + Enter key\n\t\t// forcing the modal to close when opened\n\t\trequestAnimationFrame(() => {\n\t\t\tthis.modal.open()\n\t\t})\n\n\t\t// Large breakpoints, show ColorPicker in a modal\n\t\tthis.colorPicker = new ColorPicker(this.colorPickerEl, {\n\t\t\ttheme: this.mediaQuery.MEDIUM_LARGE ? 'light' : 'dark',\n\t\t\tonChange: this.setColor,\n\t\t\tinitialColor: this.color\n\t\t})\n\t}\n\n\t/**\n\t * Callback for when a modal is closed to destroy the modal and color picker\n\t * @param {string} modalId - The id of the modal that was closed\n\t */\n\tonModalClose = (modalId) => {\n\t\tif (modalId === this.modalEl.id) {\n\t\t\tthis.modal?.destroy()\n\t\t\tthis.colorPicker?.destroy()\n\t\t}\n\t}\n\n\t/**\n\t * Callback for when the color picker select button is clicked to update the color and trigger the onSelect callback\n\t */\n\tonSelectHandler = () => {\n\t\tthis.color = this.pendingColor\n\t\tthis.onSelect(this.pendingColor)\n\t\tthis.modal.close()\n\t}\n\n\t/**\n\t * Callback for when the color picker cancel button is clicked to reset the color and trigger the onCancel callback\n\t */\n\tonCancelHandler = () => {\n\t\tthis.pendingColor = this.color\n\n\t\tif (this.modal) {\n\t\t\tthis.modal.close()\n\t\t}\n\t}\n\n\t/**\n\t * Callback for when the breakpoint changes to re-render the component and close the modal\n\t * @param {Object} breakpoint - the mediaQuery breakpoint object\n\t */\n\tonBreakpointChange = (breakpoint) => {\n\t\tconst hasChanged =\n\t\t\tbreakpoint.MEDIUM_LARGE !== this.mediaQuery.MEDIUM_LARGE\n\n\t\tthis.mediaQuery = breakpoint\n\n\t\tif (hasChanged) {\n\t\t\tthis.onCancelHandler()\n\t\t\tthis.init()\n\t\t}\n\t}\n\n\t/**\n\t * Render the component\n\t */\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import { insert } from 'utilities/renderer'\nimport template from './ProductOptionCategory.template'\nimport ProductOptionCustomColor from '../ProductOptionsCustomColor/ProductOptionsCustomColor'\n\n/**\n * ProductOptionCategory component responsible for rendering a category of options\n * @param {HTMLElement} element - the element to render the component in\n * @param {Object} options - the options for the component\n * @param {String} options.groupValue - the value of the group\n * @param {Object} options.category - the category object\n * @param {Object} options.optionTools - the option tools object\n */\nexport default class ProductOptionCategory {\n\t/**\n\t * Selectors used by the component\n\t */\n\tstatic SELECTORS = {\n\t\tINPUT: '[data-cmp-hook=\"product-option-input\"]',\n\t\tOPTIONS: '[data-cmp-hook=\"product-option-category-options\"]',\n\t\tOPTION: '[data-cmp-hook=\"product-option\"]',\n\t\tOPTION_CUSTOM_COLOR_INPUT: '[data-custom-input=\"custom-color\"]',\n\t\tOPTION_CUSTOM_COLOR_LABEL: '[data-custom-label=\"custom-color\"]',\n\t\tCUSTOM_COLOR: '[data-cmp-hook=\"product-option-custom-color\"]',\n\t\tVIEW_MORE: '[data-cmp-hook=\"product-options-view-more\"]',\n\t\tVIEW_MORE_LABEL: '[data-cmp-hook=\"product-options-view-more-label\"]'\n\t}\n\n\t/**\n\t * Classes used by the component\n\t */\n\tstatic CLASSES = {\n\t\tOPTION_HIDE: 'mod-product-option-category__option--hide',\n\t\tVIEW_MORE_EXPANDED:\n\t\t\t'mod-product-option-category__view-more-button--expanded'\n\t}\n\n\t/**\n\t * The maximum number of options to show before collapsing\n\t */\n\tstatic MAX_OPTIONS = {\n\t\ttile: 10,\n\t\tcolor: 12,\n\t\ttext: 6\n\t}\n\n\tconstructor(\n\t\telement,\n\t\t{ groupValue, groupType, category = {}, optionTools = {} } = {}\n\t) {\n\t\tthis.element = element\n\t\tthis.groupValue = groupValue\n\t\tthis.groupType = groupType\n\t\tthis.category = category\n\t\tthis.optionTools = optionTools\n\t\tthis.maxOptions = ProductOptionCategory.MAX_OPTIONS[this.groupType]\n\t\tthis.isExpanded = false\n\n\t\tthis.init()\n\t}\n\n\t/**\n\t * Initialize the component\n\t */\n\tinit() {\n\t\tthis.template = template({\n\t\t\tcategory: this.category,\n\t\t\tgroupValue: this.groupValue,\n\t\t\tgroupType: this.groupType,\n\t\t\tmaxOptions: this.maxOptions,\n\t\t\toptionTools: this.optionTools\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.cacheDom()\n\t\tthis.createCustomColor()\n\t\tthis.attachEvents()\n\t\tthis.checkViewMore()\n\t\tthis.render()\n\t}\n\n\t/**\n\t * Cache DOM elements\n\t */\n\tcacheDom() {\n\t\tthis.optionsEl = this.template.querySelector(\n\t\t\tProductOptionCategory.SELECTORS.OPTIONS\n\t\t)\n\n\t\tthis.optionEls = this.template.querySelectorAll(\n\t\t\tProductOptionCategory.SELECTORS.OPTION\n\t\t)\n\n\t\tthis.optionCustomColorInput = this.template.querySelector(\n\t\t\tProductOptionCategory.SELECTORS.OPTION_CUSTOM_COLOR_INPUT\n\t\t)\n\n\t\tthis.optionCustomColorLabel = this.template.querySelector(\n\t\t\tProductOptionCategory.SELECTORS.OPTION_CUSTOM_COLOR_LABEL\n\t\t)\n\n\t\tthis.customColorEl = this.template.querySelector(\n\t\t\tProductOptionCategory.SELECTORS.CUSTOM_COLOR\n\t\t)\n\n\t\tthis.viewMoreButtonEls = this.template.querySelectorAll(\n\t\t\tProductOptionCategory.SELECTORS.VIEW_MORE\n\t\t)\n\n\t\tthis.viewMoreLabelEls = this.template.querySelectorAll(\n\t\t\tProductOptionCategory.SELECTORS.VIEW_MORE_LABEL\n\t\t)\n\t}\n\n\t/**\n\t * Attach events\n\t */\n\tattachEvents() {\n\t\tif (this.viewMoreButtonEls.length > 0) {\n\t\t\tthis.viewMoreButtonEls.forEach((viewMoreButtonEl) => {\n\t\t\t\tviewMoreButtonEl.addEventListener('click', this.toggleViewMore)\n\t\t\t})\n\t\t}\n\n\t\tif (this.optionCustomColorLabel && this.optionCustomColorInput) {\n\t\t\tthis.optionCustomColorInput.addEventListener(\n\t\t\t\t'click',\n\t\t\t\tthis.onCustomColorInputSelect\n\t\t\t)\n\n\t\t\tthis.optionCustomColorInput.addEventListener(\n\t\t\t\t'keydown',\n\t\t\t\tthis.onCustomColorInputSelect\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Detach events\n\t */\n\tdetachEvents() {\n\t\tif (this.viewMoreButtonEls.length > 0) {\n\t\t\tthis.viewMoreButtonEls.forEach((viewMoreButtonEl) => {\n\t\t\t\tviewMoreButtonEl.removeEventListener('click', this.toggleViewMore)\n\t\t\t})\n\t\t}\n\n\t\tif (this.optionCustomColorLabel && this.optionCustomColorInput) {\n\t\t\tthis.optionCustomColorInput.removeEventListener(\n\t\t\t\t'click',\n\t\t\t\tthis.onCustomColorInputSelect\n\t\t\t)\n\n\t\t\tthis.optionCustomColorInput.removeEventListener(\n\t\t\t\t'keydown',\n\t\t\t\tthis.onCustomColorInputSelect\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Destroy the component\n\t */\n\tdestroy() {\n\t\tthis.detachEvents()\n\t}\n\n\t/**\n\t * Create the custom color picker\n\t */\n\tcreateCustomColor() {\n\t\tif (this.customColorEl) {\n\t\t\tconst colorPrefix = 'custom-color-'\n\t\t\tconst customColorOption = this.category.options.find(\n\t\t\t\t(option) => option.value.indexOf(colorPrefix) > -1\n\t\t\t)\n\t\t\tconst initialColor = customColorOption\n\t\t\t\t? `#${customColorOption.value.split(colorPrefix)[1]}`\n\t\t\t\t: null\n\n\t\t\tthis.productOptionCustomColor = new ProductOptionCustomColor(\n\t\t\t\tthis.customColorEl,\n\t\t\t\t{\n\t\t\t\t\tinitialColor,\n\t\t\t\t\tcontent: {\n\t\t\t\t\t\ttitle: this.category.helperLabel,\n\t\t\t\t\t\tdescription: this.category.helperText,\n\t\t\t\t\t\toptionTools: this.optionTools\n\t\t\t\t\t},\n\t\t\t\t\tonSelect: this.onCustomColorSelect\n\t\t\t\t}\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Callback for when the custom color input is selected (e.g. click or enter) to open the color picker\n\t * @param {Event} e - the event object\n\t */\n\tonCustomColorInputSelect = (e) => {\n\t\tif (\n\t\t\t(e.type === 'keydown' && (e.key === 'Enter' || e.key === ' ')) ||\n\t\t\te.type === 'click'\n\t\t) {\n\t\t\te.stopImmediatePropagation()\n\t\t\tthis.productOptionCustomColor.openColorPicker()\n\t\t}\n\t}\n\n\t/**\n\t * Callback for when a custom color is selected to update the custom color input as selected and trigger a change event\n\t * @param {string} color - the color hex that was selected\n\t */\n\tonCustomColorSelect = (color) => {\n\t\tthis.optionCustomColorInput.value = `custom-color-${color.replace(\n\t\t\t'#',\n\t\t\t''\n\t\t)}`\n\n\t\tthis.optionCustomColorInput.checked = true\n\t\tthis.optionCustomColorInput.dispatchEvent(new Event('change'))\n\t}\n\n\t/**\n\t * Check if the view more button should be expanded, collapsed, or hidden\n\t */\n\tcheckViewMore() {\n\t\tconst selectedOptionIdx = Array.isArray(this.category.options)\n\t\t\t? this.category.options.findIndex((option) => {\n\t\t\t\t\treturn option.isSelected\n\t\t\t })\n\t\t\t: -1\n\n\t\tif (selectedOptionIdx && selectedOptionIdx + 1 > this.maxOptions) {\n\t\t\tthis.expandViewMore()\n\t\t} else {\n\t\t\tthis.collapseViewMore()\n\t\t}\n\t}\n\n\t/**\n\t * Expand the view more button to show all options\n\t */\n\texpandViewMore() {\n\t\tthis.isExpanded = true\n\n\t\tthis.optionEls.forEach((optionEl) => {\n\t\t\toptionEl.classList.remove(ProductOptionCategory.CLASSES.OPTION_HIDE)\n\t\t\toptionEl.setAttribute('aria-hidden', false)\n\t\t\toptionEl.removeAttribute('tabindex')\n\t\t})\n\n\t\tthis.viewMoreButtonEls.forEach((viewMoreButtonEl) => {\n\t\t\tviewMoreButtonEl.classList.add(\n\t\t\t\tProductOptionCategory.CLASSES.VIEW_MORE_EXPANDED\n\t\t\t)\n\n\t\t\tviewMoreButtonEl.setAttribute('aria-expanded', true)\n\n\t\t\tviewMoreButtonEl.setAttribute(\n\t\t\t\t'aria-label',\n\t\t\t\tthis.optionTools.seeLessAccessibility\n\t\t\t)\n\t\t})\n\n\t\tthis.viewMoreLabelEls.forEach((viewMoreLabelEl) => {\n\t\t\tviewMoreLabelEl.innerHTML = this.optionTools.seeLess\n\t\t})\n\t}\n\n\t/**\n\t * Collapse the view more button to hide options\n\t */\n\tcollapseViewMore() {\n\t\tthis.isExpanded = false\n\n\t\tthis.optionEls.forEach((optionEl, index) => {\n\t\t\tif (index + 1 > this.maxOptions) {\n\t\t\t\toptionEl.classList.add(ProductOptionCategory.CLASSES.OPTION_HIDE)\n\t\t\t\toptionEl.setAttribute('aria-hidden', true)\n\t\t\t\toptionEl.setAttribute('tabindex', -1)\n\t\t\t}\n\t\t})\n\n\t\tthis.viewMoreButtonEls.forEach((viewMoreButtonEl) => {\n\t\t\tviewMoreButtonEl.classList.remove(\n\t\t\t\tProductOptionCategory.CLASSES.VIEW_MORE_EXPANDED\n\t\t\t)\n\t\t\tviewMoreButtonEl.setAttribute('aria-expanded', false)\n\n\t\t\tviewMoreButtonEl.setAttribute(\n\t\t\t\t'aria-label',\n\t\t\t\tthis.optionTools.seeAllAccessibility\n\t\t\t)\n\t\t})\n\n\t\tthis.viewMoreLabelEls.forEach((viewMoreLabelEl) => {\n\t\t\tviewMoreLabelEl.innerHTML = this.optionTools.seeAll\n\t\t})\n\t}\n\n\t/**\n\t * Toggle the view more button to show or hide options\n\t */\n\ttoggleViewMore = () => {\n\t\tif (this.isExpanded) {\n\t\t\tthis.collapseViewMore()\n\t\t} else {\n\t\t\tthis.expandViewMore()\n\t\t}\n\t}\n\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import { insert } from 'utilities/renderer'\nimport {\n\tnoop,\n\tactionOnClickOutside,\n\tlimitKeyboardAccessibility\n} from 'utilities/utilities'\nimport template, {\n\ttoggleButtonTemplate,\n\toptionDetailsTemplate\n} from './ProductOptionGroup.template'\nimport ProductOptionCategory from '../ProductOptionCategory/ProductOptionCategory'\nimport Services from 'services'\nimport Tabs from 'modules/Tabs'\nimport Analytics from 'services/Analytics/Analytics'\nimport tippy from 'tippy.js'\n\n/**\n * ProductOptionGroup component responsible for rendering a single product option group, eg. Glass, Color, Size, etc.\n * @param {HTMLElement} element - the root element for this component\n * @param {Object} option - the product option group object\n * @param {Object} optionTools - the product option tools object\n * @param {Function} onProductSelect - callback function for when a product option is selected\n * @param {Function} onProductSubmit - callback function for when the product option group is submitted\n * @param {Function} onProductCancel - callback function for when the product option group is cancelled\n */\nexport default class ProductOptionGroup {\n\tstatic SELECTORS = {\n\t\tTABS: '[data-cmp-is=\"tabs\"]',\n\t\tINPUT: '[data-cmp-hook=\"product-option-input\"]',\n\t\tDRAWER: '[data-cmp-hook=\"product-option-group-drawer\"]',\n\t\tTOGGLE: '[data-cmp-hook=\"product-option-group-toggle\"]',\n\t\tTOGGLE_CONTENT: '[data-cmp-hook=\"product-option-group-toggle-content\"]',\n\t\tDETAILS: '[data-cmp-hook=\"product-option-details\"]',\n\t\tSUBMIT_BUTTON: '[data-cmp-hook=\"product-option-group-submit\"]',\n\t\tCANCEL_BUTTON: '[data-cmp-hook=\"product-option-group-cancel\"]',\n\t\tMORE_DETAILS: '[data-cmp-hook=\"product-option-group-more-details\"]',\n\t\tTOOLTIP_TOGGLE_BUTTON: '[data-cmp-hook=\"tooltip-toggle-button\"]',\n\t\tTOOLTIP_DRAWER_INFO: '[data-cmp-hook=\"tooltip-drawer-info\"]'\n\t}\n\n\tstatic CLASSES = {\n\t\tACTIVE_GROUP: 'mod-product-option-group--active',\n\t\tDISABLED_GROUP: 'mod-product-option-group--disabled',\n\t\tTHEME_LIGHT: 'theme-light',\n\t\tTHEME_DARK: 'theme-dark'\n\t}\n\n\tconstructor(\n\t\telement,\n\t\t{\n\t\t\toption = {},\n\t\t\toptionTools = {},\n\t\t\tonProductSelect = noop,\n\t\t\tonProductSubmit = noop,\n\t\t\tonProductCancel = noop\n\t\t} = {}\n\t) {\n\t\tthis.element = element\n\t\tthis.option = option\n\t\tthis.optionTools = optionTools\n\t\tthis.categories = {}\n\t\tthis.tabs = null // reference to tabs component\n\t\tthis.tooltipsToggleButtons = []\n\t\tthis.onProductSelect = onProductSelect\n\t\tthis.onProductSubmit = onProductSubmit\n\t\tthis.onProductCancel = onProductCancel\n\t\tthis.isDrawerOpen = false\n\t\tthis.services = Services.getInstance()\n\t\tthis.eventEmitterService = this.services.EventEmitterService\n\t\tthis.mediaQuery = this.services.BreakpointListener.queryMatch\n\t\tthis.analyticsService = Analytics.getInstance()\n\t\tthis.init()\n\t}\n\n\t/**\n\t * Initialize the component and create all of the product option categories\n\t */\n\tinit() {\n\t\tconst hasSingleOption =\n\t\t\tthis.option?.categories?.reduce(\n\t\t\t\t(acc, category) => acc.concat(category.options),\n\t\t\t\t[]\n\t\t\t).length === 1\n\n\t\tthis.template = template({\n\t\t\thasSingleOption,\n\t\t\toption: this.option,\n\t\t\toptionTools: this.optionTools,\n\t\t\tselectedOption: this.getSelectedOption(),\n\t\t\tbreakpoint: this.mediaQuery\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.createCategories()\n\t\tthis.cacheDom()\n\t\tthis.attachEvents()\n\t\tthis.createToggleButton()\n\t\tthis.createDrawerTooltips()\n\t\tthis.createTabs()\n\t\tthis.setTheme()\n\t\tthis.setDisabledDrawer()\n\t\tthis.render()\n\t}\n\n\t/**\n\t * Cache all DOM elements\n\t */\n\tcacheDom() {\n\t\tthis.tabsEl = this.template.querySelector(\n\t\t\tProductOptionGroup.SELECTORS.TABS\n\t\t)\n\n\t\tthis.optionInputs = Array.from(\n\t\t\tthis.template.querySelectorAll(ProductOptionCategory.SELECTORS.INPUT)\n\t\t)\n\n\t\tthis.optionDrawer = this.template.querySelector(\n\t\t\tProductOptionGroup.SELECTORS.DRAWER\n\t\t)\n\n\t\tthis.optionToggleButton = this.template.querySelector(\n\t\t\tProductOptionGroup.SELECTORS.TOGGLE\n\t\t)\n\n\t\tthis.optionToggleButtonContent = this.template.querySelector(\n\t\t\tProductOptionGroup.SELECTORS.TOGGLE_CONTENT\n\t\t)\n\n\t\tthis.submitButton = this.template.querySelector(\n\t\t\tProductOptionGroup.SELECTORS.SUBMIT_BUTTON\n\t\t)\n\n\t\tthis.cancelButton = this.template.querySelector(\n\t\t\tProductOptionGroup.SELECTORS.CANCEL_BUTTON\n\t\t)\n\n\t\tthis.moreDetails = this.template.querySelector(\n\t\t\tProductOptionGroup.SELECTORS.MORE_DETAILS\n\t\t)\n\t}\n\n\t/**\n\t * Attach all events\n\t */\n\tattachEvents() {\n\t\tthis.optionInputs.forEach((input) => {\n\t\t\tinput.addEventListener('change', this.onProductSelectHandler)\n\t\t})\n\n\t\tthis.optionToggleButton.addEventListener('focus', this.onToggleFocus)\n\t\tthis.optionToggleButton.addEventListener('keydown', this.onToggleKeydown)\n\t\tthis.optionToggleButton.addEventListener('click', this.toggleDrawer)\n\t\tthis.submitButton.addEventListener('click', this.onSubmit)\n\t\tthis.cancelButton.addEventListener('click', this.onCancel)\n\t\tthis.services.BreakpointListener.addListener(this.onBreakpointChange)\n\n\t\tif (this.moreDetails) {\n\t\t\tthis.moreDetails.addEventListener('click', this.onMoreDetails)\n\t\t}\n\t}\n\n\t/**\n\t * Detach all events\n\t */\n\tdetachEvents() {\n\t\tthis.optionInputs.forEach((input) => {\n\t\t\tinput.removeEventListener('change', this.onProductSelectHandler)\n\t\t})\n\n\t\tif (this.moreDetails) {\n\t\t\tthis.moreDetails.removeEventListener('click', this.onMoreDetails)\n\t\t}\n\t}\n\n\t/**\n\t * Destroy the component\n\t */\n\tdestroy() {\n\t\tif (this.tabs) {\n\t\t\tthis.tabs.destroy()\n\t\t}\n\n\t\tthis.detachEvents()\n\t}\n\n\t/**\n\t * Callback for when the breakpoint changes to close the drawer if it's open and the breakpoint changes between LARGE and SMALL/MEDIUM\n\t * @param {Object} breakpoint - The breakpoint object\n\t */\n\tonBreakpointChange = (breakpoint) => {\n\t\tconst hasChanged =\n\t\t\tbreakpoint.MEDIUM_LARGE !== this.mediaQuery.MEDIUM_LARGE\n\n\t\tthis.mediaQuery = breakpoint\n\n\t\tif (hasChanged) {\n\t\t\tthis.closeDrawer()\n\t\t\tthis.createToggleButton()\n\t\t\tthis.setTheme()\n\t\t}\n\t}\n\n\t/**\n\t * Event handler for when a product option is selected to invoke the\n\t * onProductSelect callback with selected product option data\n\t * @param {Event} event - Change event object\n\t */\n\tonProductSelectHandler = (event) => {\n\t\tconst { target } = event\n\t\tconst { dataset, value, checked } = target\n\n\t\tif (typeof this.onProductSelect === 'function') {\n\t\t\tthis.onProductSelect({\n\t\t\t\tgroupValue: dataset.group,\n\t\t\t\tcategoryValue: dataset.category,\n\t\t\t\toptionValue: value,\n\t\t\t\tisSelected: checked\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Event handler for when the submit button is clicked to invoke the\n\t * onProductSubmit callback and close the drawer\n\t */\n\tonSubmit = () => {\n\t\tthis.onProductSubmit()\n\t\tthis.closeDrawer()\n\t}\n\n\t/**\n\t * Event handler for when the cancel button is clicked to invoke the\n\t * onProductCancel callback and close the drawer\n\t */\n\tonCancel = () => {\n\t\tthis.onProductCancel()\n\t\tthis.closeDrawer()\n\t}\n\n\t/**\n\t * Event handler for when the more details button is clicked to switch to the details tab\n\t * @param {*} event\n\t */\n\tonMoreDetails = (event) => {\n\t\tevent.preventDefault()\n\n\t\tconst detailsId = this.option?.moreDetails?.detailsId\n\n\t\tif (detailsId) {\n\t\t\tif (!this.mediaQuery.MEDIUM_LARGE) {\n\t\t\t\t// close the drawer if it's open on mobile/tablet\n\t\t\t\tthis.onCancel()\n\t\t\t}\n\t\t\tthis.eventEmitterService.emit(Tabs.EVENTS.SWITCH_TAB, {\n\t\t\t\ttabsId: 'product-details-categories',\n\t\t\t\ttabId: `product-details-categories-tab-${detailsId}`\n\t\t\t})\n\t\t}\n\n\t\tsetTimeout(() => {\n\t\t\tconst tabNav = document.getElementById(`product-details-categories`)\n\t\t\tif (tabNav) {\n\t\t\t\ttabNav.scrollIntoView({\n\t\t\t\t\tbehavior: 'smooth'\n\t\t\t\t})\n\t\t\t}\n\t\t}, 500)\n\t}\n\n\t/**\n\t * Create the toggle button for the product option group to set the\n\t * text of the button based on the breakpoint and selected option\n\t */\n\tcreateToggleButton() {\n\t\tconst toggleButton = toggleButtonTemplate({\n\t\t\toption: this.option,\n\t\t\tselectedOption: this.getSelectedOption(),\n\t\t\tbreakpoint: this.mediaQuery\n\t\t})({ getNode: true })\n\n\t\tinsert(toggleButton, this.optionToggleButtonContent)\n\t\tthis.createTooltipToggleButtons()\n\t}\n\n\t/**\n\t * Create all of the product option categories\n\t */\n\tcreateCategories() {\n\t\tconst { categories } = this.option\n\n\t\tif (categories) {\n\t\t\tcategories.forEach((category) => {\n\t\t\t\tconst categoryEl = this.template.querySelector(\n\t\t\t\t\t`[data-cpm-hook=\"product-option-category-${category.value}\"]`\n\t\t\t\t)\n\t\t\t\tconst el = document.createElement('div')\n\n\t\t\t\tif (categoryEl) {\n\t\t\t\t\tcategoryEl.appendChild(el)\n\t\t\t\t}\n\n\t\t\t\tthis.categories[category.value] = new ProductOptionCategory(el, {\n\t\t\t\t\tgroupValue: this.option.value,\n\t\t\t\t\tgroupType: this.option.type,\n\t\t\t\t\tcategory,\n\t\t\t\t\toptionTools: this.optionTools\n\t\t\t\t})\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Create the tabs for the product option group if there are more than one category\n\t */\n\tcreateTabs() {\n\t\tconst { categories } = this.option\n\t\tif (this.tabsEl && categories.length > 1) {\n\t\t\tthis.tabs = new Tabs(this.tabsEl)\n\t\t}\n\t}\n\n\t/**\n\t * Create the tooltips for the product option group toggle button\n\t */\n\tcreateTooltipToggleButtons() {\n\t\tif (this.tooltipsToggleButtons.length > 0) {\n\t\t\tthis.tooltipsToggleButtons.forEach((tooltip) => {\n\t\t\t\ttooltip.destroy()\n\t\t\t})\n\t\t}\n\n\t\tthis.tooltipsToggleButtons = []\n\n\t\tthis.tooltipToggleButtonsEls = this.template.querySelectorAll(\n\t\t\tProductOptionGroup.SELECTORS.TOOLTIP_TOGGLE_BUTTON\n\t\t)\n\n\t\tthis.tooltipToggleButtonsEls.forEach((tooltipEl, i) => {\n\t\t\tconst tooltipContent = tooltipEl.querySelector('.js-tooltip-content')\n\t\t\tconst tooltip = this.createTooltip(tooltipEl, tooltipContent)\n\t\t\tthis.tooltipsToggleButtons.push(tooltip)\n\t\t})\n\t}\n\n\t/**\n\t * Create the tooltips for the product option group drawer info\n\t */\n\tcreateDrawerTooltips() {\n\t\tthis.tooltipsDrawers = []\n\n\t\tthis.tooltipDrawerEls = this.template.querySelectorAll(\n\t\t\tProductOptionGroup.SELECTORS.TOOLTIP_DRAWER_INFO\n\t\t)\n\n\t\tthis.tooltipDrawerEls.forEach((tooltipEl, i) => {\n\t\t\tconst tooltipContent = tooltipEl.querySelector('.js-tooltip-content')\n\t\t\tconst tooltip = this.createTooltip(tooltipEl, tooltipContent)\n\n\t\t\tthis.tooltipsDrawers.push(tooltip)\n\t\t})\n\t}\n\n\t/**\n\t * Create an instance of tippy for the tooltip\n\t * @param {Element} tooltipEl - The tooltip element\n\t * @param {Element} tooltipContent - The tooltip content element\n\t * @returns\n\t */\n\tcreateTooltip(tooltipEl, tooltipContent) {\n\t\treturn tippy(tooltipEl, {\n\t\t\tallowHTML: true,\n\t\t\tcontent: tooltipContent,\n\t\t\tanimateFill: true,\n\t\t\tinteractive: true,\n\t\t\tplacement: 'auto',\n\t\t\ttrigger: 'click',\n\t\t\tflipOnUpdate: true,\n\t\t\tonTrigger: (instance, e) => {\n\t\t\t\te.stopImmediatePropagation()\n\t\t\t},\n\t\t\tonUntrigger: (instance, e) => {\n\t\t\t\te.stopImmediatePropagation()\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Get the index of the selected category\n\t * @returns {Number} - The index of the selected category\n\t */\n\tgetSelectedCategoryIndex = () => {\n\t\treturn this.option.categories.findIndex((category) => {\n\t\t\treturn category.options.find((option) => option.isSelected)\n\t\t})\n\t}\n\n\t/**\n\t * Get the selected option for this product option group\n\t * @returns {Object} - The selected option for this product option group\n\t */\n\tgetSelectedOption = () => {\n\t\treturn this.option.categories\n\t\t\t.reduce((acc, category) => acc.concat(category.options), [])\n\t\t\t.find((option) => option?.isSelected)\n\t}\n\n\t/**\n\t * Get all of the options for this product option group\n\t * @returns {Array} - All of the options for this product option group\n\t */\n\tgetAllOptions = () => {\n\t\treturn this.option.categories.reduce((acc, category) => {\n\t\t\treturn acc.concat(category.options)\n\t\t}, [])\n\t}\n\n\t/**\n\t * Set the theme based on the breakpoint\n\t */\n\tsetTheme() {\n\t\tthis.optionDrawer.classList.remove(\n\t\t\tthis.mediaQuery.MEDIUM_LARGE\n\t\t\t\t? ProductOptionGroup.CLASSES.THEME_DARK\n\t\t\t\t: ProductOptionGroup.CLASSES.THEME_LIGHT\n\t\t)\n\t\tthis.optionDrawer.classList.add(\n\t\t\tthis.mediaQuery.MEDIUM_LARGE\n\t\t\t\t? ProductOptionGroup.CLASSES.THEME_LIGHT\n\t\t\t\t: ProductOptionGroup.CLASSES.THEME_DARK\n\t\t)\n\n\t\tif (this.tabs) {\n\t\t\tthis.tabs.setTheme(\n\t\t\t\tthis.mediaQuery.MEDIUM_LARGE ? Tabs.THEMES.LIGHT : Tabs.THEMES.DARK\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Set the active tab based on the selected option\n\t */\n\tsetActiveTab = () => {\n\t\tconst activeCatIdx = this.getSelectedCategoryIndex()\n\t\tconst activeTabId = this.tabs\n\t\t\t? Object.keys(this.tabs.tabIds)[activeCatIdx]\n\t\t\t: null\n\n\t\tif (activeTabId) {\n\t\t\tthis.tabs.switchTab(activeTabId)\n\t\t}\n\t}\n\n\t/**\n\t * Set the selected options for this product option group based on the options passed in\n\t * @param {Object} options - Object containing the selected options for this product option group\n\t * @param {Array} options.categories - Array of categories containing the selected options for each category\n\t * @param {String} options.categories[].value - Value of the category\n\t * @param {Array} options.categories[].options - Array of options for the category\n\t * @param {String} options.categories[].options[].value - Value of the option\n\t * @param {Boolean} options.categories[].options[].isSelected - Whether or not the option is selected\n\t */\n\tsetSelectedOptions = (options, optionsApplied) => {\n\t\tconst prevSelectedOption = this.getSelectedOption()\n\t\tconst hasDisabledChanged = this.option?.isDisabled !== options?.isDisabled\n\t\tthis.option = options\n\t\tconst selectedOption = this.getSelectedOption()\n\t\tconst allOptions = this.getAllOptions()\n\t\tconst hasOptionChanged =\n\t\t\tprevSelectedOption?.value !== selectedOption?.value || optionsApplied\n\t\tconst customColorIdx = (val) => val.includes('custom-color')\n\n\t\tif (hasDisabledChanged) {\n\t\t\tthis.setDisabledDrawer()\n\t\t}\n\n\t\tif (hasOptionChanged) {\n\t\t\tthis.optionInputs.forEach((input) => {\n\t\t\t\tconst { value, checked } = input\n\t\t\t\tconst option = allOptions.find(\n\t\t\t\t\t(option) =>\n\t\t\t\t\t\t(customColorIdx(option.value) && customColorIdx(value)) ||\n\t\t\t\t\t\toption.value === value\n\t\t\t\t)\n\n\t\t\t\tif (!!option?.isSelected !== checked) {\n\t\t\t\t\tinput.checked = option.isSelected\n\t\t\t\t}\n\n\t\t\t\tif (option?.isDisabled) {\n\t\t\t\t\tinput.setAttribute('disabled', true)\n\t\t\t\t} else {\n\t\t\t\t\tinput.removeAttribute('disabled')\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tif (optionsApplied) {\n\t\t\t\tthis.createToggleButton()\n\t\t\t}\n\t\t\tthis.setOptionDetails()\n\t\t}\n\t}\n\n\t/**\n\t * Set the option details based on the selected option\n\t */\n\tsetOptionDetails = () => {\n\t\tconst optionDetails = this.template.querySelectorAll(\n\t\t\tProductOptionGroup.SELECTORS.DETAILS\n\t\t)\n\t\tconst selectedOption = this.getSelectedOption()\n\t\tconst updatedOptionDetails = optionDetailsTemplate({\n\t\t\toption: this.option,\n\t\t\tselectedOption\n\t\t})({ getNode: true })\n\n\t\toptionDetails.forEach((optionDetail) => {\n\t\t\toptionDetail.replaceWith(updatedOptionDetails.cloneNode(true))\n\t\t})\n\n\t\tthis.createTooltipToggleButtons()\n\t}\n\n\t/**\n\t * When the toggle button is focused, scroll it into view\n\t */\n\tonToggleFocus = (event) => {\n\t\tif (!this.mediaQuery.MEDIUM_LARGE) {\n\t\t\t// scroll the button into view after the drawer is open\n\t\t\t// this solves an where the scoll is prevent by the drawer animating in\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tthis.optionToggleButton.scrollIntoView({\n\t\t\t\t\tbehavior: 'smooth',\n\t\t\t\t\tinline: 'nearest',\n\t\t\t\t\tblock: 'nearest'\n\t\t\t\t})\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Callback to close the drawer when the user selects the escape key when the button is focused\n\t * @param {Event} event\n\t */\n\tonToggleKeydown = (event) => {\n\t\tif (\n\t\t\t(event.key === 'Escape' || event.eyCode === 27) &&\n\t\t\t!this.mediaQuery.MEDIUM_LARGE\n\t\t) {\n\t\t\tthis.closeDrawer()\n\t\t}\n\t}\n\n\t/**\n\t * Toggles the drawer open and close. If the drawer is open,\n\t * it calls closeDrawer. Otherwise, it calls openDrawer.\n\t * @param {Event} event - The click event that triggers the toggle\n\t */\n\ttoggleDrawer = (event) => {\n\t\tevent.stopImmediatePropagation()\n\n\t\tif (this.isDrawerOpen) {\n\t\t\tthis.closeDrawer()\n\t\t} else {\n\t\t\tthis.openDrawer()\n\t\t}\n\t}\n\n\t/**\n\t * Open the drawer for this product option group, wire up the events\n\t * for closing the drawer, set focus trap, and set the active tab\n\t */\n\topenDrawer = () => {\n\t\tthis.isDrawerOpen = true\n\n\t\tthis.optionToggleButton.setAttribute('aria-expanded', true)\n\t\tthis.template.classList.add(ProductOptionGroup.CLASSES.ACTIVE_GROUP)\n\n\t\tif (!this.mediaQuery.MEDIUM_LARGE) {\n\t\t\tactionOnClickOutside(this.optionDrawer, this.onCancel)\n\t\t\tlimitKeyboardAccessibility(this.optionDrawer, this.onCancel)\n\t\t}\n\n\t\tif (this.tabs) {\n\t\t\tthis.setActiveTab()\n\t\t}\n\n\t\tthis.trackDrawer()\n\t}\n\n\t/**\n\t * Close the drawer for this product option group and remove focus from the drawer\n\t */\n\tcloseDrawer = () => {\n\t\tthis.isDrawerOpen = false\n\n\t\tthis.optionToggleButton.setAttribute('aria-expanded', false)\n\t\tthis.optionToggleButton.focus()\n\t\tthis.template.classList.remove(ProductOptionGroup.CLASSES.ACTIVE_GROUP)\n\n\t\tif (typeof this.optionDrawer.clearListener === 'function') {\n\t\t\tthis.optionDrawer.clearListener()\n\t\t}\n\n\t\tif (typeof this.optionDrawer.clearKeyHandler === 'function') {\n\t\t\tthis.optionDrawer.clearKeyHandler()\n\t\t}\n\n\t\tthis.trackDrawer()\n\t}\n\n\t/**\n\t * Set the disabled state of the drawer based on the option.isDisabled property\n\t */\n\tsetDisabledDrawer = () => {\n\t\tconst action = this.option?.isDisabled ? 'add' : 'remove'\n\t\tthis.template.classList[action](ProductOptionGroup.CLASSES.DISABLED_GROUP)\n\t}\n\n\t/**\n\t * Track the drawer open/close event\n\t */\n\ttrackDrawer = () => {\n\t\tthis.analyticsService.trackInteraction('product_option_drawer', {\n\t\t\tstate: this.isDrawerOpen ? 'open' : 'close',\n\t\t\toption: this.option?.label?.toLowerCase()\n\t\t})\n\t}\n\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import { noop } from 'utilities/utilities'\n\nimport template from './ProductOptionFilters.template'\n\n/**\n * ProductOptionFilters component responsible for rendering filters to filter product options\n * @param {HTMLElement} element - the root element for this component\n * @param {Object} filters - the product filters group object\n * @param {Function} onFilterSelect - callback function for when a filter option is selected\n *\n */\nexport default class ProductOptionFilters {\n\tstatic SELECTORS = {\n\t\tOPTION: '[data-cmp-hook=\"checkbox-filter-input\"]'\n\t}\n\n\tconstructor(element, { filters = {}, onFilterSelect = noop }) {\n\t\tthis.element = element\n\t\tthis.filters = filters\n\t\tthis.onFilterSelect = onFilterSelect\n\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tthis.template = template({\n\t\t\tfilters: this.filters\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.cacheDom()\n\t\tthis.attachEvents()\n\t\tthis.render()\n\t}\n\n\t/**\n\t * Cache DOM elements\n\t */\n\tcacheDom() {\n\t\tthis.optionEls = this.template.querySelectorAll(\n\t\t\tProductOptionFilters.SELECTORS.OPTION\n\t\t)\n\t}\n\n\t/**\n\t * Attach events to the component\n\t */\n\tattachEvents() {\n\t\tthis.optionEls.forEach((optionEl) => {\n\t\t\toptionEl.addEventListener('change', this.onFilterSelectHandler)\n\t\t})\n\t}\n\n\t/**\n\t * Detach events from the component\n\t */\n\tdetachEvents() {\n\t\tthis.optionEls.forEach((optionEl) => {\n\t\t\toptionEl.removeEventListener('change', this.onFilterSelectHandler)\n\t\t})\n\t}\n\n\t/**\n\t * Event handler for when a filter option is selected to invoke the\n\t * onFilterSelect callback with selected filter option data\n\t * @param {Event} event - Change event object\n\t */\n\tonFilterSelectHandler = (event) => {\n\t\tconst { target } = event\n\t\tconst { dataset, value, checked } = target\n\n\t\tif (typeof this.onFilterSelect === 'function') {\n\t\t\tthis.onFilterSelect({\n\t\t\t\tfilterId: dataset?.filterId,\n\t\t\t\toptionValue: value,\n\t\t\t\tisSelected: checked\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Render the component\n\t */\n\trender() {\n\t\tthis.element.appendChild(this.template)\n\t}\n}\n","import html from 'utilities/html'\n\n/**\n * Template for the checkbox item\n * @param {Object} param\n * @param {Object} param.filter - The filter object\n * @returns\n */\nconst checkboxItemTemplate = ({ filter }) => {\n\treturn html`\n\t\t
    \n\t\t\t\n\t\t\t\n\t\t
    \n\t`()\n}\n\n/**\n * Template for the ProductOptionFilters component that renders a groupd of filters\n * @param {Object} param\n * @param {Object} param.option - The option group object to display\n */\nconst template = ({ filters }) => {\n\treturn html`\n\t\t
    \n\t\t\t
    \n\t\t\t\t\n\t\t\t\t\t${filters.label}\n\t\t\t\t\n\t\t\t\t${filters?.filterOptions.map((filter) => {\n\t\t\t\t\tswitch (filter.type) {\n\t\t\t\t\t\tcase 'checkbox':\n\t\t\t\t\t\t\treturn checkboxItemTemplate({ filter })\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn ''\n\t\t\t\t\t}\n\t\t\t\t})}\n\t\t\t
    \n\t\t
    \n\t`\n}\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport template from './ProductOptions.template'\nimport ProductOptionGroup from '../ProductOptionGroup/ProductOptionGroup'\nimport ProductOptionFilters from '../ProductOptionFilters/ProductOptionFilters'\nimport Services from 'services'\n\n/**\n * ProductOptions component responsible for rendering all of the product options for a product,eg. Glass, Color, Size, etc.\n * @param {HTMLElement} element - the element to render the component in\n * @param {Object} options - the options for the component\n * @param {Array} options.options - the options for the product\n * @param {Object} options.productModel - the product model\n */\nexport default class ProductOptions {\n\tstatic SELECTORS = {\n\t\tPRODUCT_OPTION_FILTERS: '[data-cmp-hook=\"product-option-filters\"]',\n\t\tPRODUCT_OPTION_WRAPPER: '[data-cmp-hook=\"product-option-wrapper\"]',\n\t\tPRODUCT_OPTION_MESSAGE: '.mod-product-options__message',\n\t\tPRODUCT_OPTION_MESSAGE_ICON: '.mod-product-options__message-icon',\n\t\tPRODUCT_OPTION_MESSAGE_TEXT: '.mod-product-options__message-text'\n\t}\n\n\tstatic CLASSES = {\n\t\tOPTION: 'mod-product-options__item',\n\t\tFILTER_OPTION: 'mod-product-options__filter-item',\n\t\tMESSAGE_ACTIVE: 'mod-product-options__message--active'\n\t}\n\n\tconstructor(element, { filters = {}, options = [], productModel } = {}) {\n\t\tthis.element = element\n\t\tthis.productOptions = {}\n\t\tthis.productModel = productModel\n\t\tthis.options = options\n\t\tthis.filters = filters\n\t\tthis.services = Services.getInstance()\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tthis.template = template()({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.cacheDom()\n\t\tthis.createProductOptions()\n\t\tthis.createOptionFilters()\n\t\tthis.attachEvents()\n\t\tthis.render()\n\t}\n\n\t/**\n\t * Cache the DOM elements for the ProductOptions component.\n\t */\n\tcacheDom() {\n\t\tthis.productOptionFilterItemsEl = this.template.querySelector(\n\t\t\tProductOptions.SELECTORS.PRODUCT_OPTION_FILTERS\n\t\t)\n\n\t\tthis.productOptionWrapperEl = this.template.querySelector(\n\t\t\tProductOptions.SELECTORS.PRODUCT_OPTION_WRAPPER\n\t\t)\n\n\t\tthis.productOptionMessageTextEl = this.template.querySelector(\n\t\t\tProductOptions.SELECTORS.PRODUCT_OPTION_MESSAGE_TEXT\n\t\t)\n\n\t\tthis.productOptionMessageEl = this.template.querySelector(\n\t\t\tProductOptions.SELECTORS.PRODUCT_OPTION_MESSAGE\n\t\t)\n\t}\n\n\t/**\n\t * Attach events to the ProductOptions component.\n\t */\n\tattachEvents() {\n\t\tthis.productModel.addEventListener(this.onModelUpdate)\n\t}\n\n\t/**\n\t * Detach events from the ProductOptions component.\n\t */\n\tdetachEvents() {\n\t\tthis.productModel.removeEventListener(this.onModelUpdate)\n\t}\n\n\t/**\n\t * Destroy ProductOptions component.\n\t */\n\tdestroy() {\n\t\tthis.detachEvents()\n\t}\n\n\t/**\n\t * Create all of the product option filters\n\t */\n\tcreateOptionFilters() {\n\t\tconst { context: { filters = {} } = {} } = this.productModel.getState()\n\n\t\tif (filters?.filterOptions?.length > 0) {\n\t\t\tconst el = document.createElement('div')\n\n\t\t\tthis.productOptionFilterItemsEl.appendChild(el)\n\t\t\tel.classList.add(ProductOptions.CLASSES.FILTER_OPTION)\n\t\t\tthis.productFilterOptions = new ProductOptionFilters(el, {\n\t\t\t\tfilters,\n\t\t\t\tonFilterSelect: this.onFilterSelect\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Create all of the product options\n\t */\n\tcreateProductOptions() {\n\t\tconst { context: { pendingOptions = [], optionTools } = {} } =\n\t\t\tthis.productModel.getState()\n\n\t\tpendingOptions.forEach((option) => {\n\t\t\tconst el = document.createElement('div')\n\n\t\t\tthis.productOptionWrapperEl.appendChild(el)\n\t\t\tel.classList.add(ProductOptions.CLASSES.OPTION)\n\t\t\tthis.productOptions[option.value] = new ProductOptionGroup(el, {\n\t\t\t\toption,\n\t\t\t\toptionTools,\n\t\t\t\tonProductSelect: this.onProductSelect,\n\t\t\t\tonProductSubmit: this.onProductSubmit,\n\t\t\t\tonProductCancel: this.onProductCancel\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Set the product option message based on if the product options have been modified\n\t */\n\tsetProductOptionMessage() {\n\t\tconst {\n\t\t\tcontext: { hasModifiedSelectedOption, optionMessages }\n\t\t} = this.productModel.getState()\n\t\tconst message =\n\t\t\thasModifiedSelectedOption && optionMessages?.modifiedOption\n\t\t\t\t? optionMessages.modifiedOption\n\t\t\t\t: ''\n\n\t\tif (hasModifiedSelectedOption) {\n\t\t\tthis.productOptionMessageEl.classList.add(\n\t\t\t\tProductOptions.CLASSES.MESSAGE_ACTIVE\n\t\t\t)\n\t\t} else {\n\t\t\tthis.productOptionMessageEl.classList.remove(\n\t\t\t\tProductOptions.CLASSES.MESSAGE_ACTIVE\n\t\t\t)\n\t\t}\n\n\t\tthis.productOptionMessageTextEl.innerHTML = message\n\t}\n\n\t/**\n\t * Event handler for when a product option filter is selected\n\t * @param {Object} event\n\t * @param {String} event.filterId - The id of the filter\n\t * @param {String} event.optionValue - The value of the filter option\n\t * @param {Boolean} event.isSelected - Whether or not the filter option is selected\n\t */\n\tonFilterSelect = (event) => {\n\t\tconst { filterId, optionValue, isSelected } = event\n\n\t\tthis.productModel.setFilter({\n\t\t\tfilter: {\n\t\t\t\tfilterId,\n\t\t\t\toptionValue,\n\t\t\t\tisSelected\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Event handler for when a product option is selected\n\t * @param {Object} event\n\t * @param {String} event.groupValue - The value of the product option group\n\t * @param {String} event.categoryValue - The value of the product option category\n\t * @param {String} event.optionValue - The value of the product option\n\t * @param {Boolean} event.isSelected - Whether or not the product option is selected\n\t */\n\tonProductSelect = (event) => {\n\t\tconst { groupValue, categoryValue, optionValue, isSelected } = event\n\t\tconst autoApply =\n\t\t\tthis.services.BreakpointListener.getCurrentBreakpoint().MEDIUM_LARGE\n\n\t\t// Note: this is where we would update the product model if the product options changed\n\t\tthis.productModel.setOption(\n\t\t\t{\n\t\t\t\tgroupValue,\n\t\t\t\tcategoryValue,\n\t\t\t\toptionValue,\n\t\t\t\tisSelected\n\t\t\t},\n\t\t\tautoApply\n\t\t)\n\t}\n\n\t/**\n\t * Event handler for when a product option selection is submitted to\n\t * apply the product options to the product model\n\t */\n\tonProductSubmit = () => {\n\t\tthis.productModel.applyOptions()\n\t}\n\n\t/**\n\t * Event handler for when a product option selection is cancelled to\n\t * reset the product model to the last applied state\n\t */\n\tonProductCancel = () => {\n\t\tthis.productModel.cancelOptions()\n\t}\n\n\t/**\n\t * Event handler for when the product model is updated\n\t * @param {Object} state - The state object from XState\n\t * @param {Object} event - The event object from XState\n\t */\n\tonModelUpdate = (state, event) => {\n\t\tif (\n\t\t\tevent.type === 'UPDATE_OPTIONS' ||\n\t\t\tevent.type === 'APPLY_OPTIONS' ||\n\t\t\tevent.type === 'CANCEL_OPTIONS'\n\t\t) {\n\t\t\tconst { context: { pendingOptions = [] } = {} } = state\n\t\t\tconst autoApply =\n\t\t\t\tevent?.data?.autoApply || event.type === 'APPLY_OPTIONS'\n\n\t\t\tObject.keys(this.productOptions).forEach((key) => {\n\t\t\t\tconst optionGroup = pendingOptions.find(\n\t\t\t\t\t(option) => option.value === key\n\t\t\t\t)\n\n\t\t\t\tthis.productOptions[key].setSelectedOptions(optionGroup, autoApply)\n\t\t\t})\n\t\t}\n\n\t\tif (\n\t\t\tevent.type === 'APPLY_OPTIONS' ||\n\t\t\t(event.type === 'UPDATE_OPTIONS' && event?.data?.autoApply)\n\t\t) {\n\t\t\tthis.setProductOptionMessage()\n\t\t}\n\t}\n\n\t/**\n\t * Render the ProductOptions component in the DOM.\n\t */\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import html from 'utilities/html'\nimport textTemplate, {\n\tTYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\nimport iconTemplate from 'foundation/Icon/Icon.template'\n\nconst template = () =>\n\thtml`\n\t\t
    \n\t\t\t
    \n\t\t\t\t${iconTemplate({\n\t\t\t\t\ticon: 'alert-circle',\n\t\t\t\t\taddClassName: 'mod-product-options__message-icon'\n\t\t\t\t})}\n\t\t\t\t${textTemplate({\n\t\t\t\t\taddClassName: 'mod-product-options__message-text',\n\t\t\t\t\ttag: 'p',\n\t\t\t\t\ttext: '',\n\t\t\t\t\ttextType: TEXT_TYPES.CALLOUT\n\t\t\t\t})}\n\t\t\t
    \n\t\t\t
    \n\t\t\t\n\t\t\n\t`\n\nexport default template\n","import html from 'utilities/html'\nimport Icon from 'foundation/Icon/Icon.template'\n\nconst template = ({ product, share, pinterest, copy, copySuccess } = {}) =>\n\thtml`\n\t\t
    \n\t\t\t
    \n\t\t\t\t\n\t\t\t\t\t${Icon({\n\t\t\t\t\t\taddClassName: 'mod-product-share__tooltip-icon',\n\t\t\t\t\t\ticon: 'share'\n\t\t\t\t\t})}\n\t\t\t\t\t${share.label}\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t
      \n\t\t\t\t\t\t
    • \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t${Icon({\n\t\t\t\t\t\t\t\t\taddClassName:\n\t\t\t\t\t\t\t\t\t\t'mod-product-share__item-icon mod-product-share__item-icon--pinterest',\n\t\t\t\t\t\t\t\t\ticon: 'social-pinterest'\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t${pinterest.label}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
    • \n\t\t\t\t\t\t
    • \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t${Icon({\n\t\t\t\t\t\t\t\t\taddClassName: 'mod-product-share__item-icon',\n\t\t\t\t\t\t\t\t\ticon: 'link'\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t${copy.label}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t${Icon({\n\t\t\t\t\t\t\t\t\taddClassName:\n\t\t\t\t\t\t\t\t\t\t'mod-product-share__item-icon mod-product-share__item-icon--success',\n\t\t\t\t\t\t\t\t\ticon: 'check-circle'\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t${copySuccess.label}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t
    \n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
    \n\t\t\t\n\t\t\n\t`\n\nexport default template\n","/*\n * Load Dependency: Load a dependency script and call a callback when it's loaded\n * @param {string} urlPath\n * @param {function} onComplete\n */\nconst scripts = []\n\nexport function loadDependency(urlPath, onComplete) {\n\tif (scripts.includes(urlPath)) {\n\t\tonComplete(true)\n\t\treturn\n\t}\n\n\tconst headElm = document.querySelector('head')\n\tconst script = document.createElement('script')\n\tscript.src = urlPath\n\tscript.defer = true\n\n\tscript.onload = function onDependencyLoad() {\n\t\tonComplete(true)\n\t\tscripts.push(urlPath)\n\t}\n\tscript.onerror = function onDependencyError() {\n\t\tonComplete(false)\n\t}\n\n\theadElm.appendChild(script)\n}\n","import { insert } from 'utilities/renderer'\nimport template from './ProductShare.template'\nimport tippy from 'tippy.js'\nimport { loadDependency } from 'utilities/scriptLoader'\nimport Analytics from 'services/Analytics/Analytics'\n\n/**\n * ProductShare component responsible for sharing a product\n * Note: sub-components should be created for each share method (e.g. copy link, pinterest, etc.)\n */\nexport default class ProductShare {\n\tstatic SELECTORS = {\n\t\tshareTooltip: '[data-cmp-hook=\"share-tooltip\"]',\n\t\tshareCopy: '[data-cmp-hook=\"share-copy\"]',\n\t\tsharePinterest: '[data-cmp-hook=\"share-pinterest\"]',\n\t\tsuccessMessage: '[data-cmp-hook=\"share-success-message\"]'\n\t}\n\n\t/**\n\t *\n\t * @param {*} element\n\t * @param {Object} props\n\t * @param {Object} props.product\n\t * @param {Object} props.product.sku - Product sku\n\t * @param {Object} props.product.collection - Product collection name\n\t * @param {Object} props.product.media - Product media\n\t * @param {Object} props.product.media.src - Product media url\n\t * @param {Object} props.product.media.alt - Product media alt\n\t * @param {Object} props.product.url - Product url\n\t * @param {Object} props.content - Product tools content\n\t * @param {Object} props.content.share - Product share content\n\t * @param {Object} props.content.pinterest - Product Pinterest content\n\t * @param {Object} props.content.copy - Product copy content\n\t * @param {Object} props.content.copySuccess - Product copy success content\n\t */\n\tconstructor(element, { product = {}, content = {} } = {}) {\n\t\tthis.element = element\n\t\tthis.product = product\n\t\tthis.content = content\n\t\tthis.analyticsService = Analytics.getInstance()\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tthis.template = template({\n\t\t\tproduct: this.product,\n\t\t\tshare: this.content.share,\n\t\t\tpinterest: this.content.pinterest,\n\t\t\tcopy: this.content.copy,\n\t\t\tcopySuccess: this.content.copySuccess\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\t\tthis.cacheDom()\n\t\tthis.attachEvents()\n\t\tthis.createTooltip()\n\t\tthis.loadPinterestScript()\n\t\tthis.render()\n\t}\n\n\t/**\n\t * Cache the dom refs needed for the component\n\t */\n\tcacheDom() {\n\t\tthis.shareTooltip = this.template.querySelectorAll(\n\t\t\tProductShare.SELECTORS.shareTooltip\n\t\t)\n\n\t\tthis.shareCopy = this.template.querySelector(\n\t\t\tProductShare.SELECTORS.shareCopy\n\t\t)\n\n\t\tthis.sharePinterest = this.template.querySelector(\n\t\t\tProductShare.SELECTORS.sharePinterest\n\t\t)\n\n\t\tthis.successMessage = this.template.querySelector(\n\t\t\tProductShare.SELECTORS.successMessage\n\t\t)\n\t}\n\n\t/**\n\t * Attach the events needed for the component\n\t */\n\tattachEvents() {\n\t\tthis.shareCopy.addEventListener('click', this.copyHandler)\n\t}\n\n\t/**\n\t * Detach the events needed for the component\n\t */\n\tdetachEvents() {\n\t\tthis.shareCopy.removeEventListener('click', this.copyHandler)\n\n\t\tif (this.isPinterestLoaded && window.PinUtils) {\n\t\t\tthis.sharePinterest.removeEventListener('click', this.onPinterestClick)\n\t\t}\n\t}\n\n\t/**\n\t * Destroy the carousel instance and remove event listeners\n\t */\n\tdestroy() {\n\t\tthis.detachEvents()\n\t}\n\n\t/**\n\t * Copy URL from data-uri attribute for product\n\t * After copying link and showing a success message,\n\t * set a timeout to re-show the copy link\n\t */\n\tcopyHandler = () => {\n\t\tconst url = this.shareCopy.dataset.url\n\n\t\tnavigator.clipboard.writeText(url).then(() => {\n\t\t\tif (this.successMessage.hasAttribute('hidden')) {\n\t\t\t\tthis.showSuccessMessage()\n\t\t\t\tthis.trackShare('copy')\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tthis.showShareCopy()\n\t\t\t\t}, 5000)\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Show the copy link and hide the success message\n\t */\n\tshowShareCopy() {\n\t\tthis.shareCopy.removeAttribute('hidden')\n\t\tthis.successMessage.setAttribute('hidden', '')\n\t}\n\n\t/**\n\t * Show the success message and hide the copy link\n\t */\n\tshowSuccessMessage() {\n\t\tthis.shareCopy.setAttribute('hidden', '')\n\t\tthis.successMessage.removeAttribute('hidden')\n\t}\n\n\t/**\n\t * Create the tooltip to house the share options\n\t */\n\tcreateTooltip() {\n\t\tthis.shareTooltip.forEach((tooltipEl, i) => {\n\t\t\tconst tooltipContent = this.template.querySelector(\n\t\t\t\t'.js-tooltip-share-content'\n\t\t\t)\n\n\t\t\ttippy(tooltipEl, {\n\t\t\t\tallowHTML: true,\n\t\t\t\tcontent: tooltipContent,\n\t\t\t\tanimateFill: true,\n\t\t\t\tinteractive: true,\n\t\t\t\tplacement: 'bottom',\n\t\t\t\ttrigger: 'click'\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Load Pinterest script using the loadDependency utility\n\t */\n\tloadPinterestScript() {\n\t\tloadDependency(\n\t\t\t'//assets.pinterest.com/js/pinit_main.js',\n\t\t\tthis.onPinterestLoaded\n\t\t)\n\t}\n\n\t/*\n\t * If the dependency is loaded and the window.PinUtils is available call onPinterestClick\n\t */\n\tonPinterestLoaded = (isLoaded) => {\n\t\tthis.isPinterestLoaded = isLoaded\n\n\t\tif (this.isPinterestLoaded && window.PinUtils) {\n\t\t\tthis.sharePinterest.addEventListener('click', this.onPinterestClick)\n\t\t}\n\t}\n\n\t/**\n\t * Call the PinUtils.pinOne method to share the product to Pinterest\n\t */\n\tonPinterestClick = (event) => {\n\t\tevent.preventDefault()\n\n\t\twindow.PinUtils.pinOne({\n\t\t\turl: this.product.url,\n\t\t\tmedia: this.product.media.src,\n\t\t\tdescription: this.product.collection\n\t\t})\n\n\t\tthis.trackShare('pinterest')\n\t}\n\n\t/**\n\t * Track sharing clicks\n\t * @param {String} type - Sharing action type\n\t */\n\ttrackShare = (type) => {\n\t\tthis.analyticsService.trackInteraction('product_shares', {\n\t\t\tproduct_name: this.product.collection,\n\t\t\tproduct_share_type: type\n\t\t})\n\t}\n\n\t/**\n\t * Render the component\n\t */\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import { insert } from 'utilities/renderer'\nimport template from './ProductTools.template'\nimport ProductSave from './components/ProductSave/ProductSave'\nimport ProductShare from './components/ProductShare/ProductShare'\n\n/**\n * ProductTools component responsible for rendering the ProductSave and ProductShare components\n */\nexport default class ProductTools {\n\tstatic SELECTORS = {\n\t\tPRODUCT_SAVE: '[data-cmp-hook=\"product-save\"]',\n\t\tPRODUCT_SHARE: '[data-cmp-hook=\"product-share\"]'\n\t}\n\n\t/**\n\t *\n\t * @param {Element} element - DOM element to render the component in\n\t * @param {Object} props\n\t * @param {Object} props.product\n\t * @param {Object} props.product.sku - Product sku\n\t * @param {Object} props.product.collection - Product collection name\n\t * @param {Object} props.product.media - Product media\n\t * @param {Object} props.product.media.src - Product media url\n\t * @param {Object} props.product.media.alt - Product media alt)\n\t * @param {Object} props.product.url - Product url\n\t * @param {Object} props.product.customOptions - Product options\n\t * @param {Object} props.content - Product tools content\n\t * @param {Object} props.content.save - Product save content\n\t * @param {Object} props.content.saved - Product saved content\n\t * @param {Object} props.content.savedSuccess - Product saved success content\n\t * @param {Object} props.content.share - Product share content\n\t * @param {Object} props.content.pinterest - Product pinterest content\n\t * @param {Object} props.content.copy - Product copy content\n\t * @param {Object} props.content.copySuccess - Product copu success content\n\t */\n\tconstructor(element, { product = {}, content = {} } = {}) {\n\t\tthis.element = element\n\t\tthis.product = product\n\t\tthis.content = content\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tthis.template = template({\n\t\t\tproduct: this.product\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.cacheDom()\n\t\tthis.createProductSave()\n\t\tthis.createProductShare()\n\t\tthis.render()\n\t}\n\n\t/**\n\t * Cache the DOM elements for the ProductSave component.\n\t */\n\tcacheDom() {\n\t\tthis.productSaveEl = this.template.querySelector(\n\t\t\tProductTools.SELECTORS.PRODUCT_SAVE\n\t\t)\n\n\t\tthis.productShareEl = this.template.querySelector(\n\t\t\tProductTools.SELECTORS.PRODUCT_SHARE\n\t\t)\n\t}\n\n\t/**\n\t * Create the ProductSave component\n\t */\n\tcreateProductSave() {\n\t\tthis.productSave = new ProductSave(this.productSaveEl, {\n\t\t\tproduct: this.product,\n\t\t\tcontent: this.content,\n\t\t\tisButton: true,\n\t\t\tshowCta: true\n\t\t})\n\t}\n\n\t/**\n\t * Create the ProductShare component\n\t */\n\tcreateProductShare() {\n\t\tthis.productShare = new ProductShare(this.productShareEl, {\n\t\t\tproduct: this.product,\n\t\t\tcontent: {\n\t\t\t\tshare: this.content.share,\n\t\t\t\tpinterest: this.content.pinterest,\n\t\t\t\tcopy: this.content.copy,\n\t\t\t\tcopySuccess: this.content.copySuccess\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Render the ProductTools component\n\t */\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import html from 'utilities/html'\n\nconst template = () => html`
    \n\t
    \n\t
    \n
    `\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport template from './ProductMediaThumbnails.template'\n\n/**\n * Product Media Thumbnails responsible for rendering the thumbnails and handling the click event\n * @param {HTMLElement} element - DOM element to render the thumbnails\n * @param {Object} args\n * @param {Array} args.mediaGallery\n * @param {Function} args.onSelect - Callback function to be called when a thumbnail is selected with the index of the selected thumbnail\n */\nexport default class ProductMediaThumbnails {\n\tstatic SELECTORS = {\n\t\tTHUMBAIL_BUTTON: '[data-cmp-hook=\"mod-product-media-thumbnail-button\"]'\n\t}\n\n\tstatic CLASSES = {\n\t\tTHUMBNAIL_ACTIVE: 'mod-product-media-thumbnails__button--active'\n\t}\n\n\tconstructor(element, { mediaGallery, onSelect } = {}) {\n\t\tthis.element = element\n\t\tthis.mediaGallery = mediaGallery\n\t\tthis.onSelect = onSelect\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tthis.template = template({\n\t\t\tmediaGallery: this.mediaGallery\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.cacheDom()\n\t\tthis.attachEvents()\n\t\tthis.render()\n\t}\n\n\tcacheDom() {\n\t\tthis.thumbnailButtons = Array.from(\n\t\t\tthis.template.querySelectorAll(\n\t\t\t\tProductMediaThumbnails.SELECTORS.THUMBAIL_BUTTON\n\t\t\t)\n\t\t)\n\t}\n\n\tattachEvents() {\n\t\tthis.thumbnailButtons.forEach((button, index) => {\n\t\t\tbutton.addEventListener('click', this.setActiveThumbnail)\n\t\t})\n\t}\n\n\tdetachEvents() {\n\t\tthis.thumbnailButtons.forEach((button, index) => {\n\t\t\tbutton.removeEventListener('click', this.setActiveThumbnail)\n\t\t})\n\t}\n\n\t/**\n\t * Set the active thumbnail and call the onSelect callback with the index of the selected thumbnail\n\t * @param {Event} event - Click event\n\t */\n\tsetActiveThumbnail = (event) => {\n\t\tconst { currentTarget } = event\n\n\t\tif (\n\t\t\tcurrentTarget.classList.contains(\n\t\t\t\tProductMediaThumbnails.CLASSES.THUMBNAIL_ACTIVE\n\t\t\t)\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.thumbnailButtons.forEach((button, index) => {\n\t\t\tbutton.classList.remove(\n\t\t\t\tProductMediaThumbnails.CLASSES.THUMBNAIL_ACTIVE\n\t\t\t)\n\n\t\t\tif (button === currentTarget) {\n\t\t\t\tbutton.classList.add(\n\t\t\t\t\tProductMediaThumbnails.CLASSES.THUMBNAIL_ACTIVE\n\t\t\t\t)\n\n\t\t\t\tif (typeof this.onSelect === 'function') {\n\t\t\t\t\tthis.onSelect(index)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import html from 'utilities/html'\nimport classNames from 'utilities/classnames'\nimport imageTemplate from 'foundation/Image/Image.template'\nimport playIconTemplate, {\n\tPOSITIONS as PLAY_BUTTON_POSITIONS,\n\tSIZES as PLAY_BUTTON_SIZES\n} from 'modules/PlayIcon/PlayIcon.template'\n\n/**\n * Product Media Thumbnails Template\n * @param {Object} args\n * @param {Array} args.mediaGallery\n * @param {String} args.mediaGallery[].alt - Alt text for the image\n * @param {String} args.mediaGallery[].poster - Poster image for the video\n * @param {String} args.mediaGallery[].src - Image or video src\n * @param {String} args.mediaGallery[].type - Media type (expected: 'image' or 'video')\n * @returns\n */\nconst template = ({ mediaGallery }) => html`\n\t
    \n\t\t
      \n\t\t\t${mediaGallery\n\t\t\t\t.map((mediaItem, index) =>\n\t\t\t\t\thtml`
    • \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t${mediaItem.type === 'video'\n\t\t\t\t\t\t\t\t? playIconTemplate({\n\t\t\t\t\t\t\t\t\t\taddClassName:\n\t\t\t\t\t\t\t\t\t\t\t'mod-product-media-thumbnails__play-icon',\n\t\t\t\t\t\t\t\t\t\tposition: PLAY_BUTTON_POSITIONS.CENTER,\n\t\t\t\t\t\t\t\t\t\tsize: PLAY_BUTTON_SIZES.SMALL\n\t\t\t\t\t\t\t\t })\n\t\t\t\t\t\t\t\t: ''}\n\t\t\t\t\t\t\t${imageTemplate({\n\t\t\t\t\t\t\t\taddClassName: 'mod-product-media-thumbnails__image',\n\t\t\t\t\t\t\t\tdefaultSrc:\n\t\t\t\t\t\t\t\t\tmediaItem.type === 'video'\n\t\t\t\t\t\t\t\t\t\t? mediaItem.poster\n\t\t\t\t\t\t\t\t\t\t: mediaItem.src,\n\t\t\t\t\t\t\t\tmobileSrc:\n\t\t\t\t\t\t\t\t\tmediaItem.type === 'video'\n\t\t\t\t\t\t\t\t\t\t? mediaItem.poster\n\t\t\t\t\t\t\t\t\t\t: mediaItem.src,\n\t\t\t\t\t\t\t\taltText: mediaItem.alt\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\n\t\t\t\t\t
    • `()\n\t\t\t\t)\n\t\t\t\t.join('')}\n\t\t
    \n\t
    \n`\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport template from './ProductMediaImage.template'\n\n/**\n * Product Media Image responsible for rendering a product image\n * @param {HTMLElement} element - DOM element to render the image to\n * @param {Object} args\n * @param {Object} args.media\n */\nexport default class ProductMediaImage {\n\tconstructor(element, { media } = {}) {\n\t\tthis.element = element\n\t\tthis.media = media\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tthis.template = template({\n\t\t\tmedia: this.media\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.render()\n\t}\n\n\tdestroy() {\n\t\tthis.template.remove()\n\t}\n\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import html from 'utilities/html'\nimport classNames from 'utilities/classnames'\nimport imageTemplate from 'foundation/Image/Image.template'\n\n/**\n * Product Media Thumbnails Template\n * @param {Object} args\n * @param {Object} args.media\n * @param {String} args.media.alt - Alt text for the image\n * @param {String} args.media.poster - Poster image for the video\n * @param {String} args.media.src - Image or video src\n * @param {String} args.media.type - Media type (expected: 'image' or 'video')\n * @returns\n */\nconst template = ({ media }) => html`\n\t\n\t\t${imageTemplate({\n\t\t\taddClassName: 'mod-product-media-image__asset',\n\t\t\tdefaultSrc: media.src,\n\t\t\tmobileSrc: media.src,\n\t\t\taltText: media.alt,\n\t\t\tloading: 'eager'\n\t\t})}\n\t\n`\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport template from './ProductMediaVideo.template'\nimport VideoPlayer from 'modules/VideoPlayer/VideoPlayer'\n\n/**\n * Product Media Video component resonible for rendering video player\n */\nexport default class ProductMediaVideo {\n\tstatic SELECTORS = {\n\t\tVIDEO_PLAYER: '[data-cmp-is=\"video-player\"]'\n\t}\n\n\tconstructor(element, { media }) {\n\t\tthis.element = element\n\t\tthis.media = media\n\t\tthis.videoPlayer = null\n\n\t\tthis.init()\n\t\tthis.render()\n\t}\n\n\tinit() {\n\t\tthis.template = template({\n\t\t\tmedia: this.media\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tconst videoPlayerEl = this.template.querySelector(\n\t\t\tProductMediaVideo.SELECTORS.VIDEO_PLAYER\n\t\t)\n\n\t\tthis.videoPlayer = new VideoPlayer(videoPlayerEl, {\n\t\t\t...this.media,\n\t\t\tid: 'product-media-video'\n\t\t})\n\t}\n\n\tdestroy() {\n\t\tthis.videoPlayer.destroy()\n\t}\n\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import html from 'utilities/html'\nimport videoPlayerTemplate, {\n\tPLAY_BUTTON_POSITIONS\n} from 'modules/VideoPlayer/VideoPlayer.template'\n\n/**\n * Product Media Video Template\n * @param {Object} args\n * @param {Object} args.media\n * @param {String} args.media.alt - Alt text for the image\n * @param {String} args.media.poster - Poster image for the video\n * @param {String} args.media.src - Image or video src\n * @param {String} args.media.type - Media type (expected: 'image' or 'video')\n * @returns\n */\nconst template = ({ media }) => html`\n\t
    \n\t\t${videoPlayerTemplate({\n\t\t\thidePlayButtonAfterPlay: true,\n\t\t\tplayButtonPosition: PLAY_BUTTON_POSITIONS.CENTER,\n\t\t\tplaysInline: true,\n\t\t\tposterSrc: media.poster,\n\t\t\tshowPlayButton: true,\n\t\t\tvideoSrc: media.src\n\t\t})}\n\t
    \n`\n\nexport default template\n","import html from 'utilities/html'\nimport modalTemplate from 'modules/Modal/Modal.template'\n\n// eslint-disable-next-line no-unused-vars\n\nconst modalContent = (data) => html`\n\t
    \n\t\t${data?.visualizer?.arModalMessage\n\t\t\t? data?.visualizer?.arModalMessage\n\t\t\t: ''}\n\t\t
    \n\t\t\t\n\t\t\t\tView Door\n\t\t\t\n\t\t
    \n\t
    \n`\n\n/**\n * Product Media Visualizer Template\n * @returns\n */\nconst template = (data) => html`
    \n\t${modalTemplate({\n\t\tdefaultOpen: false,\n\t\thasHeader: false,\n\t\tid: 'custom-visualizer-modal',\n\t\tmodalClass: 'mod-product-media-visualizer__modal',\n\t\tchildren: modalContent(data)()\n\t})}\n
    `\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport template from './ProductMediaVisualizer.template'\nimport Analytics from 'services/Analytics/Analytics'\nimport Services from 'services'\nimport Modal from '../../../Modal/Modal'\n\n/**\n * Product Media Visualizer responsible for rendering a ThreeKit visualizer player\n * and methods to set the door configuration and backplate scene\n * @param {HTMLElement} element - DOM element to render the image to\n * @param {Object} args\n * @param {Object} args.productModel - Product model\n */\nexport default class ProductMediaVisualizer {\n\tstatic CLASSES = {\n\t\tHIDE: 'mod-product-media-visualizer--hidden',\n\t\tVISUALIZER_BUTTON: 'mod-product-media-visualizer__ar-button'\n\t}\n\n\tstatic SELECTORS = {\n\t\tMODAL: '[data-cmp-is=\"modal\"]'\n\t}\n\n\tconstructor(element, { productModel } = {}) {\n\t\tthis.element = element\n\t\tthis.productModel = productModel\n\t\tthis.initialData = this.getInitialData()\n\t\tthis.hasDependency = false\n\t\tthis.focusableElements = []\n\t\tthis.services = Services.getInstance()\n\t\tthis.EventEmitterService = this.services.EventEmitterService\n\t\tthis.analyticsService = Analytics.getInstance()\n\n\t\tthis.loadDependency().then(() => {\n\t\t\tthis.init()\n\t\t})\n\t}\n\n\t/**\n\t * Initialize the component by creating the template, attaching events and rendering the component\n\t */\n\tinit() {\n\t\tthis.template = template(this.initialData)({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.cacheDom()\n\t\tthis.createPlayer()\n\t\tthis.attachEvents()\n\t\tthis.render()\n\t\tthis.setupButtonClone()\n\t}\n\n\tisMobileDevice() {\n\t\tconst userAgent = navigator.userAgent || window.opera\n\n\t\t// Regular expressions to match common mobile and tablet devices\n\t\tconst phonePattern =\n\t\t\t/Mobi|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Windows Phone/i\n\t\tconst tabletPattern =\n\t\t\t/Tablet|iPad|PlayBook|Silk|Kindle|KFTT|KFOT|KFJWI|KFJWA|KFOT/i\n\n\t\treturn phonePattern.test(userAgent) || tabletPattern.test(userAgent)\n\t}\n\n\tsetupButtonClone() {\n\t\tconst checkForButton = () => {\n\t\t\tconst arButton = this.template.querySelector(\n\t\t\t\t'button[data-id=\"arButton\"]'\n\t\t\t)\n\n\t\t\tif (arButton) {\n\t\t\t\tlet newButton = this.template.querySelector(\n\t\t\t\t\t'button[data-id=\"arButtonClone\"]'\n\t\t\t\t)\n\n\t\t\t\t// Only create and insert the newButton if it doesn't already exist\n\t\t\t\tif (!newButton) {\n\t\t\t\t\tnewButton = arButton.cloneNode(true)\n\t\t\t\t\tnewButton.setAttribute('data-id', 'arButtonClone') // Add an ID to the newButton\n\t\t\t\t\tif (this.isMobileDevice()) {\n\t\t\t\t\t\tnewButton.addEventListener('click', () => {\n\t\t\t\t\t\t\tthis.setupModal()\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tarButton.parentNode.insertBefore(newButton, arButton)\n\t\t\t\t\t\tarButton.style.display = 'none'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\trequestAnimationFrame(checkForButton)\n\t\t\t}\n\t\t}\n\n\t\t// Start checking for the button\n\t\trequestAnimationFrame(checkForButton)\n\t}\n\n\taddEventListeners() {\n\t\tconst viewDoorButton = document.querySelector(\n\t\t\t'.mod-product-media-visualizer__button'\n\t\t)\n\t\tconst arButton = this.template.querySelector('button[data-id=\"arButton\"]')\n\n\t\tif (viewDoorButton) {\n\t\t\tviewDoorButton.addEventListener('click', (e) => {\n\t\t\t\tif (this.isMobileDevice()) {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\tarButton.click()\n\t\t\t\t\tthis.onVisualizerButtonClick()\n\t\t\t\t\tthis.onModalClose(this.modalEl.id)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\n\tcacheDom() {\n\t\tthis.modalEl = this.template.querySelector(\n\t\t\tProductMediaVisualizer.SELECTORS.MODAL\n\t\t)\n\t}\n\n\tgetInitialData() {\n\t\tif (!window.masonite?.pip) {\n\t\t\tconsole.error(\n\t\t\t\t'No initial data was found for the ProductInformation component. Please add the data to the window.masonite.pip object.'\n\t\t\t)\n\t\t\treturn {}\n\t\t}\n\n\t\treturn typeof window.masonite.pip === 'string'\n\t\t\t? JSON.parse(window.masonite.pip)\n\t\t\t: window.masonite.pip\n\t}\n\n\tonModalClose = (modalId) => {\n\t\tif (modalId === this.modalEl.id) {\n\t\t\tthis.modal?.destroy()\n\t\t}\n\n\t\tif (document.body.classList.contains('no-scroll')) {\n\t\t\tdocument.body.classList.remove('no-scroll')\n\t\t}\n\t}\n\n\tonModalOpen = (modalId) => {\n\t\tif (modalId === this.modalEl.id) {\n\t\t\tthis.addEventListeners()\n\t\t}\n\t}\n\n\t/**\n\t * Attach events to the component.\n\t */\n\tattachEvents() {\n\t\tthis.EventEmitterService.on(Modal.EVENTS.CLOSE_MODAL, this.onModalClose)\n\t\tthis.productModel.addEventListener(this.onModelUpdate)\n\t}\n\n\t/**\n\t * Detach events from the component.\n\t */\n\tdetachEvents() {\n\t\tthis.productModel.removeEventListener(this.onModelUpdate)\n\t}\n\n\t/**\n\t * Attach the visualizer button events\n\t */\n\tattachVisualizerButtonEvents = () => {\n\t\tthis.visualizerButton = this.template.querySelector(\n\t\t\t`.${ProductMediaVisualizer.CLASSES.VISUALIZER_BUTTON}`\n\t\t)\n\n\t\tif (this.visualizerButton) {\n\t\t\tthis.visualizerButton.addEventListener(\n\t\t\t\t'click',\n\t\t\t\tthis.onVisualizerButtonClick\n\t\t\t)\n\n\t\t\tif (this.productModel.getState().context.showARModal) {\n\t\t\t\tif (this.isMobileDevice() === true) {\n\t\t\t\t\tthis.setupModal()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tsetupModal() {\n\t\tthis.modal = new Modal(this.modalEl)\n\t\tthis.modal.open()\n\t\tthis.EventEmitterService.on(Modal.EVENTS.OPEN_MODAL, this.onModalOpen)\n\t}\n\n\t/**\n\t * Detach the visualizer button events\n\t */\n\tdetachVisualizerButtonEvents = () => {\n\t\tif (this.visualizerButton) {\n\t\t\tthis.visualizerButton.removeEventListener(\n\t\t\t\t'click',\n\t\t\t\tthis.onVisualizerButtonClick\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Destroy the component\n\t */\n\tdestroy() {\n\t\tthis.detachEvents()\n\t\tthis.detachVisualizerButtonEvents()\n\t\tthis.template.remove()\n\t}\n\n\t/**\n\t * Load the ThreeKit dependency and resolve when loaded\n\t * @returns {Promise}\n\t */\n\tloadDependency() {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tif (this.hasDependency) {\n\t\t\t\tresolve()\n\t\t\t} else {\n\t\t\t\tconst visualizer = this.productModel.getState().context.visualizer\n\t\t\t\tconst headElm = document.querySelector('head')\n\t\t\t\tconst script = document.createElement('script')\n\t\t\t\tscript.src = visualizer.library\n\t\t\t\tscript.defer = true\n\n\t\t\t\tscript.onload = function onDependencyLoad() {\n\t\t\t\t\tresolve()\n\t\t\t\t\tthis.hasDependency = true\n\t\t\t\t}\n\t\t\t\tscript.onerror = function onDependencyError() {\n\t\t\t\t\treject(new Error('Failed to threekit load dependency'))\n\t\t\t\t\tthis.hasDependency = false\n\t\t\t\t}\n\n\t\t\t\theadElm.appendChild(script)\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Create the ThreeKit player with the initial configuration\n\t *\n\t * Currently, the following doors can be tested (in the whitesweep scene only):\n\t * DR-SM-WIN-80\n\t * DR-SM-RIV-80\n\t * DR-SM-MEL-80\n\t * DR-SM-LOG-80\n\t * DR-SM-LIV-80\n\t * DR-SM-LNP-80\n\t * DR-SM-CHE-80\n\t * DR-SM-BER-80\n\t * DR-SM-6P-80\n\t * DR-SM-4P-80\n\t * DR-SM-2P-80\n\t * DR-SM-2PR-80\n\t * DR-TX-2PAT-80\n\t */\n\tcreatePlayer() {\n\t\tconst { visualizer, isInterior } =\n\t\t\tthis.productModel.getState().context || {}\n\n\t\twindow\n\t\t\t.threekitPlayer({\n\t\t\t\tauthToken: visualizer.authToken,\n\t\t\t\tel: this.template,\n\t\t\t\tcustomId: isInterior\n\t\t\t\t\t? 'InteriorDoorTemplate'\n\t\t\t\t\t: 'ExteriorDoorTemplate', // \"InteriorDoorTemplate\" or \"ExteriorDoorTemplate\"\n\t\t\t\tdisplay: 'image',\n\t\t\t\tinitialConfiguration: this.getConfiguration(), // Catalog Code of door (salsify:id)\n\t\t\t\t// configurationId:'',// set when loading Favorites. Use this instead of initialConfiguration. Alternatively Favorites can also be loaded through URL paramater tkcsid\n\t\t\t\tcache: {\n\t\t\t\t\tmaxAge: visualizer.cacheMaxAge, // milliseconds\n\t\t\t\t\tscope: visualizer.cacheScope // version\n\t\t\t\t}, // Best practice is to not use cached during development, but to enable at go live\n\t\t\t\tshowConfigurator: false, // No need to show Threekit attributes\n\t\t\t\tshowAR: true, // Show standard visualize button. see below for css\n\t\t\t\tshowShare: false, // this is for standard button. see documentation on custom AR button\n\t\t\t\tclassnames: {\n\t\t\t\t\tloading: 'loadingBar', // override css on player loading component\n\t\t\t\t\tmobile: 'mobilePlayer', // override css on player in moblie view\n\t\t\t\t\tshare: { button: 'ShareButton', popup: 'SharePopup' }, // override css on share button and share popup\n\t\t\t\t\tar: {\n\t\t\t\t\t\tbutton: ProductMediaVisualizer.CLASSES.VISUALIZER_BUTTON,\n\t\t\t\t\t\tpopup: 'arPopup'\n\t\t\t\t\t}, // override css on Visualize button and Visualize popup\n\t\t\t\t\tfullscreen: 'mod-product-media-visualizer__fullscreen-button', // override css on fullscreen button\n\t\t\t\t\thelp: 'helpButton' // override css on help button\n\t\t\t\t},\n\t\t\t\tshowLoadingThumbnail: false, // not needed for 2D Player\n\t\t\t\tshowLoadingProgress: false, // Will most likely not be needed for 2D Player. see https://community.threekit.com/hc/en-us/articles/4410044862107-2021-23-0-November-10-2021 for details\n\t\t\t\t// allowMobileVerticalOrbit // Not needed for 2D player\n\t\t\t\t// compression //Can be handled at Org level, no need to override\n\t\t\t\tpublishStage: 'published' // prevents unpublished items/options from appearing on front end\n\t\t\t})\n\t\t\t.then(async (player) => {\n\t\t\t\tthis.player = player\n\n\t\t\t\t// wait for the player to be rendered before setting the configuration\n\t\t\t\tawait player.when('rendered')\n\n\t\t\t\tthis.configurator = await player.getConfigurator() // This configurator will be used to set the door configuration\n\t\t\t\tthis.stageConfigurator = await player.getStageConfigurator() // This configurator will be needed to set the Backplate Attribute\n\n\t\t\t\t// get a snapshot of the player when the player renders a new image\n\t\t\t\tthis.player.on('rendered', this.getSnapshot)\n\n\t\t\t\t// give the player a second to render before attaching events to the Visualizer AR button\n\t\t\t\tsetTimeout(this.attachVisualizerButtonEvents, 1000)\n\t\t\t})\n\t}\n\n\t/**\n\t * Convert a hex value to an RGB scale\n\t * @param {String} hexValue - The hex value to convert\n\t * @returns {Object} - The RGB scale\n\t * @example\n\t * convertHexToRgbScale('808080')\n\t * // returns { r: 0.5, g: 0.5, b: 0.5 }\n\t */\n\tconvertHexToRgbScale(hexValue) {\n\t\tconst r = parseInt(hexValue.substring(0, 2), 16) / 255\n\t\tconst g = parseInt(hexValue.substring(2, 4), 16) / 255\n\t\tconst b = parseInt(hexValue.substring(4, 6), 16) / 255\n\n\t\treturn { r, g, b }\n\t}\n\n\t/**\n\t * Get the configuration values of the door for the visualizer configurator\n\t */\n\tgetConfiguration() {\n\t\tconst { sku } = this.productModel.getState().context || {}\n\t\tconst options = this.productModel.getOptions()\n\t\tconst disabledOptions = options.filter((option) => option.isDisabled)\n\t\tconst optionParams = this.productModel.getOptionParams()\n\n\t\tconst configuration = {\n\t\t\tDoor: { customId: sku }\n\t\t}\n\n\t\tObject.keys(optionParams).forEach((key) => {\n\t\t\tconst isDisabledOption = disabledOptions.some(\n\t\t\t\t(option) => option.value === key\n\t\t\t)\n\n\t\t\tif (optionParams[key].includes('custom-color-')) {\n\t\t\t\tconfiguration.Color = { customId: 'CustomColor' }\n\t\t\t\tconfiguration.PaintColorPicker = this.convertHexToRgbScale(\n\t\t\t\t\toptionParams[key].replace('custom-color-', '')\n\t\t\t\t)\n\t\t\t} else if (!isDisabledOption) {\n\t\t\t\tconfiguration[key] = { customId: optionParams[key] }\n\t\t\t}\n\t\t})\n\n\t\tconsole.log('Visualizer configuration: ', configuration)\n\n\t\treturn configuration\n\t}\n\n\t/**\n\t * Set the configuration values of the door to the visualizer configurator\n\t */\n\tasync setConfiguration() {\n\t\tawait this.configurator.setConfiguration(this.getConfiguration())\n\t}\n\n\t/**\n\t * Set the backplate scene\n\t * @param {String} sceneId - The scene id to set\n\t */\n\tasync setScene(sceneId) {\n\t\tawait this.stageConfigurator.setConfiguration({\n\t\t\tBackplate: { customId: sceneId }\n\t\t})\n\t}\n\n\t/**\n\t * Get the snapshot base64 image from the player and set it to the product model\n\t */\n\tgetSnapshot = async () => {\n\t\tconst savedScene = await this.player.snapshotAsync({\n\t\t\tmimeType: 'image/webp'\n\t\t})\n\n\t\tthis.productModel.setVisualizerSnapshot(savedScene)\n\t}\n\n\t/**\n\t * Event handler for when the product model is updated to set the door configuration\n\t */\n\tonModelUpdate = (state, event) => {\n\t\tif (\n\t\t\tevent.type === 'APPLY_OPTIONS' ||\n\t\t\t(event.type === 'UPDATE_OPTIONS' && event.data.autoApply)\n\t\t) {\n\t\t\tthis.setConfiguration()\n\t\t}\n\t}\n\n\t/**\n\t * Visually hide the visualizer and set the focusable elements to be hidden\n\t */\n\thideVisualizer = () => {\n\t\tif (!this?.template) {\n\t\t\treturn\n\t\t}\n\n\t\tconst focusableElements = this.getFocusableElements()\n\t\tthis.template.classList.add(ProductMediaVisualizer.CLASSES.HIDE)\n\t\tthis.template.setAttribute('aria-hidden', true)\n\n\t\tfocusableElements.forEach((el) => {\n\t\t\tel.setAttribute('tabIndex', -1)\n\t\t\tel.setAttribute('aria-hidden', true)\n\t\t\tel.setAttribute('hiddenTabIndex', true)\n\t\t})\n\n\t\t// set the scene to the default hero so that when changes are made\n\t\t// and saved, the default scene is shown\n\t\tthis.setScene('hero')\n\t}\n\n\t/**\n\t * Visually show the visualizer and set the focusable elements to be visible\n\t */\n\tshowVisualizer = () => {\n\t\tif (!this?.template) {\n\t\t\treturn\n\t\t}\n\n\t\tconst focusableElements = this.getFocusableElements()\n\t\tthis.template.classList.remove(ProductMediaVisualizer.CLASSES.HIDE)\n\t\tthis.template.removeAttribute('aria-hidden')\n\n\t\tfocusableElements.forEach((el) => {\n\t\t\tif (el.hasAttribute('hiddenTabIndex')) {\n\t\t\t\tel.removeAttribute('tabIndex')\n\t\t\t\tel.removeAttribute('aria-hidden')\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Track the click event on the visualizer button\n\t */\n\tonVisualizerButtonClick = () => {\n\t\tthis.analyticsService.trackInteraction('click_visualize')\n\t}\n\n\t/**\n\t * Get all focusable elements in the visualizer\n\t * @returns\n\t */\n\tgetFocusableElements() {\n\t\treturn this.template.querySelectorAll(\n\t\t\t'a[href], button, input, textarea, select, details, [tabindex]'\n\t\t)\n\t}\n\n\t/**\n\t * Render the component\n\t */\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import { insert, empty } from 'utilities/renderer'\nimport template from './ProductMediaGallery.template'\nimport ProductTools from 'modules/ProductTools'\nimport ProductMediaThumbnails from './../ProductMediaThumbnails/ProductMediaThumbnails'\nimport ProductMediaImage from './../ProductMediaImage/ProductMediaImage'\nimport ProductMediaVideo from './../ProductMediaVideo/ProductMediaVideo'\nimport ProductMediaVisualizer from './../ProductMediaVisualizer/ProductMediaVisualizer'\nimport Services from 'services'\nimport Analytics from 'services/Analytics/Analytics'\n\n/**\n * ProductMediaGallery component responsible for rendering the ProductMediaThumbnails, ProductMediaImage and ProductMediaVideo components\n */\nexport default class ProductMediaGallery {\n\tstatic SELECTORS = {\n\t\tTHUMBNAILS: '[data-cmp-hook=\"product-media-thumbnails\"]',\n\t\tMEDIA: '[data-cmp-hook=\"product-media\"]',\n\t\tMEDIA_VISUALIZER: '[data-cmp-hook=\"product-media-visualizer\"]',\n\t\tMEDIA_WRAPPER: '[data-cmp-hook=\"product-media-wrapper\"]',\n\t\tTOOLS: '[data-cmp-hook=\"product-tools\"]',\n\t\tSLOT_1: '[data-cmp-hook=\"product-media-slot-1\"]',\n\t\tSLOT_2: '[data-cmp-hook=\"product-media-slot-2\"]'\n\t}\n\n\t/**\n\t *\n\t * @param {Element} element - DOM element to render the component in\n\t * @param {Object} props\n\t * @param {Object} props.productModel - Product model\n\t */\n\tconstructor(element, { productModel } = {}) {\n\t\tthis.element = element\n\t\tthis.productModel = productModel\n\t\tthis.services = Services.getInstance()\n\t\tthis.analyticsService = Analytics.getInstance()\n\t\tthis.mediaQuery = this.services.BreakpointListener.queryMatch\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tconst { context } = this.productModel.getState()\n\t\tconst { mediaGallery } = context\n\n\t\tthis.template = template()({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.cacheDom()\n\t\tthis.createProductTools()\n\t\tthis.createThumbnails(mediaGallery)\n\t\tthis.createMediaPlayer(mediaGallery[0])\n\t\tthis.attachEvents()\n\t\tthis.setContentOrder()\n\t\tthis.render()\n\t}\n\n\t/**\n\t * Cache the DOM elements for the ProductSave component.\n\t */\n\tcacheDom() {\n\t\tthis.thumbnailsEl = this.template.querySelector(\n\t\t\tProductMediaGallery.SELECTORS.THUMBNAILS\n\t\t)\n\n\t\tthis.mediaEl = this.template.querySelector(\n\t\t\tProductMediaGallery.SELECTORS.MEDIA\n\t\t)\n\n\t\tthis.mediaVisualizerEl = this.template.querySelector(\n\t\t\tProductMediaGallery.SELECTORS.MEDIA_VISUALIZER\n\t\t)\n\n\t\tthis.productToolsEl = this.template.querySelector(\n\t\t\tProductMediaGallery.SELECTORS.TOOLS\n\t\t)\n\n\t\tthis.productMediaWrapperEl = this.template.querySelector(\n\t\t\tProductMediaGallery.SELECTORS.MEDIA_WRAPPER\n\t\t)\n\n\t\tthis.productMediaSlot1El = this.template.querySelector(\n\t\t\tProductMediaGallery.SELECTORS.SLOT_1\n\t\t)\n\n\t\tthis.productMediaSlot2El = this.template.querySelector(\n\t\t\tProductMediaGallery.SELECTORS.SLOT_2\n\t\t)\n\t}\n\n\t/**\n\t * Attach events to the product media gallery component.\n\t */\n\tattachEvents() {\n\t\tthis.services.BreakpointListener.addListener(this.onBreakpointChange)\n\n\t\tthis.productModel.addEventListener(this.onModelUpdate)\n\t}\n\n\t/**\n\t * Create the thumbnails component\n\t */\n\tcreateThumbnails(mediaGallery) {\n\t\tthis.productMediaThumbnails = new ProductMediaThumbnails(\n\t\t\tthis.thumbnailsEl,\n\t\t\t{\n\t\t\t\tmediaGallery,\n\t\t\t\tonSelect: this.onThumbnailSelect\n\t\t\t}\n\t\t)\n\t}\n\n\t/**\n\t * Create the media player component based on the media type\n\t * @param {Object} media - Media object\n\t * @param {String} media.alt - Alt text for the image\n\t * @param {String} media.poster - Poster image for the video\n\t * @param {String} media.src - Image or video src\n\t * @param {String} media.type - Media type (expected: 'image' or 'video')\n\t *\n\t */\n\tcreateMediaPlayer(media) {\n\t\tconst { context } = this.productModel.getState()\n\t\tconst { isVisualizerEnabled } = context\n\n\t\t// clean up the media player by removing the current media\n\t\t// and hiding the visualizer if it is enabled\n\t\tempty(this.mediaEl)\n\t\tif (this.mediaVisualizer) {\n\t\t\tthis.mediaVisualizer.hideVisualizer()\n\t\t}\n\n\t\tif (\n\t\t\tmedia.type === 'image' &&\n\t\t\t(!isVisualizerEnabled || !media.isVisualizer)\n\t\t) {\n\t\t\tthis.createMediaImage(media)\n\t\t} else if (\n\t\t\tmedia.type === 'image' &&\n\t\t\tisVisualizerEnabled &&\n\t\t\tmedia.isVisualizer\n\t\t) {\n\t\t\tthis.createMediaVisualizer(media)\n\t\t\tthis.mediaVisualizer.showVisualizer()\n\t\t} else if (media.type === 'video') {\n\t\t\tthis.createMediaVideo(media)\n\t\t}\n\t}\n\n\t/**\n\t * Create the media image component\n\t * @param {Object} media\n\t */\n\tcreateMediaImage(media) {\n\t\tif (this.mediaImage) {\n\t\t\tthis.mediaImage.destroy()\n\t\t}\n\n\t\tthis.mediaImage = new ProductMediaImage(this.mediaEl, { media })\n\t}\n\n\t/**\n\t * Create the media video component\n\t * @param {Object} media - Media object\n\t */\n\tcreateMediaVideo(media) {\n\t\tif (this.mediaVideo) {\n\t\t\tthis.mediaVideo.destroy()\n\t\t}\n\t\tthis.mediaVideo = new ProductMediaVideo(this.mediaEl, { media })\n\t}\n\n\t/**\n\t * Create the media video component\n\t * @param {Object} media - Media object\n\t */\n\tcreateMediaVisualizer(media) {\n\t\tif (this.mediaVisualizer) {\n\t\t\tthis.mediaVisualizer.render()\n\t\t\tthis.mediaVisualizer.setScene(media?.backplateScene)\n\t\t} else {\n\t\t\tthis.mediaVisualizer = new ProductMediaVisualizer(\n\t\t\t\tthis.mediaVisualizerEl,\n\t\t\t\t{\n\t\t\t\t\tproductModel: this.productModel\n\t\t\t\t}\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Create the product tools component\n\t */\n\tcreateProductTools() {\n\t\tconst { context } = this.productModel.getState()\n\t\tconst customOptions = this.productModel.getOptionParams()\n\t\tconst { collection, mediaGallery, sku, tools, visualizerSnapshot } =\n\t\t\tcontext\n\n\t\tthis.productTools = new ProductTools(this.productToolsEl, {\n\t\t\tproduct: {\n\t\t\t\tsku,\n\t\t\t\tcollection,\n\t\t\t\tmedia: {\n\t\t\t\t\tsrc: {\n\t\t\t\t\t\tdefaultSrc: visualizerSnapshot || mediaGallery[0]?.src || ''\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\turl: window.location.href,\n\t\t\t\tcustomOptions\n\t\t\t},\n\t\t\tcontent: tools\n\t\t})\n\t}\n\n\t/**\n\t * Set the content order of the product media component based on the current breakpoint\n\t * to maintain the proper tab order as the layout reorders.\n\t */\n\tsetContentOrder() {\n\t\tif (this.mediaQuery.MEDIUM) {\n\t\t\tthis.productMediaSlot1El.appendChild(this.thumbnailsEl)\n\t\t\tthis.productMediaSlot2El.appendChild(this.productMediaWrapperEl)\n\t\t} else {\n\t\t\tthis.productMediaSlot1El.appendChild(this.productMediaWrapperEl)\n\t\t\tthis.productMediaSlot2El.appendChild(this.thumbnailsEl)\n\t\t}\n\t}\n\n\t/**\n\t * Update the media query state and set the content order if the breakpoint has changed.\n\t * @param {*} breakpoint\n\t */\n\tonBreakpointChange = (breakpoint) => {\n\t\tconst hasChanged = breakpoint.MEDIUM !== this.mediaQuery.MEDIUM\n\n\t\tthis.mediaQuery = breakpoint\n\n\t\tif (hasChanged) {\n\t\t\tthis.setContentOrder()\n\t\t}\n\t}\n\n\t/**\n\t * Handler for when a thumbail is selected\n\t * @param {*} index\n\t */\n\tonThumbnailSelect = (index) => {\n\t\tconst { context } = this.productModel.getState()\n\t\tconst { mediaGallery } = context\n\n\t\tthis.createMediaPlayer(mediaGallery[index])\n\t\tthis.trackThumbnailClick(mediaGallery[index])\n\t}\n\n\t/**\n\t * Track the thumbnail click\n\t * @param {Object} media - Media object\n\t */\n\ttrackThumbnailClick = (media) => {\n\t\tif (media && media?.alt) {\n\t\t\tthis.analyticsService.trackInteraction('product_gallery', {\n\t\t\t\timage_title: media?.alt\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Event handler for when the product model is updated\n\t * @param {Object} state - The state object from XState\n\t * @param {Object} event - The event object from XState\n\t */\n\tonModelUpdate = (_state, _event) => {\n\t\tthis.createProductTools()\n\t}\n\n\t/**\n\t * Render the product media gallery component\n\t */\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import html from 'utilities/html'\n\n/**\n * Product Media Gallery Template\n */\nconst template = () => html`\n\t
    \n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t
    \n\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t\n\t\n`\n\nexport default template\n","import textTemplate, {\n\tTYPES as TEXT_TYPES,\n\tTHEMES as TEXT_THEMES\n} from 'foundation/Text/Text.template'\n\n/**\n * Display features\n * @param {array} features The features to display\n */\nconst displayFeatures = (features) =>\n\tfeatures && features.length\n\t\t? `\n ${features\n\t\t\t.map(\n\t\t\t\t(feature) => `\n
  • \n ${textTemplate({\n\t\t\t\t\taddClassName: 'mod-product-feature__list-text',\n\t\t\t\t\ttext: feature,\n\t\t\t\t\ttextElement: 'p',\n\t\t\t\t\ttextType: TEXT_TYPES.BODY_LG,\n\t\t\t\t\ttheme: TEXT_THEMES.LIGHT\n\t\t\t\t})}\n
  • \n `\n\t\t\t)\n\t\t\t.join('')}\n `\n\t\t: ''\n\n/**\n * Display additional features\n * @param {array} features The additional features to display\n */\nconst displayAdditionalFeatures = (features) =>\n\tfeatures && features.length\n\t\t? `\n ${features\n\t\t\t.map(\n\t\t\t\t(feature) => `\n
  • \n \n \n \n ${textTemplate({\n\t\t\t\t\taddClassName: 'mod-product-feature__additional-element-text',\n\t\t\t\t\ttext: feature,\n\t\t\t\t\ttextElement: 'p',\n\t\t\t\t\ttextType: TEXT_TYPES.BODY_MD,\n\t\t\t\t\ttheme: TEXT_THEMES.LIGHT\n\t\t\t\t})}\n
  • \n `\n\t\t\t)\n\t\t\t.join('')}\n `\n\t\t: ''\n\nconst productFeaturesTemplate = ({\n\tdescription,\n\tfeatures,\n\tadditionalFeaturesLabel,\n\tadditionalFeatures\n}) => {\n\treturn `\n
    \n
    \n ${textTemplate({\n\t\t\t\taddClassName: 'mod-product-feature__description-text',\n\t\t\t\ttext: description,\n\t\t\t\ttextElement: 'p',\n\t\t\t\ttextType: TEXT_TYPES.BODY_LG,\n\t\t\t\ttheme: TEXT_THEMES.LIGHT\n\t\t\t})}\n
    \n
      \n ${displayFeatures(features)}\n
    \n
    \n ${\n\t\t\tadditionalFeatures && additionalFeatures.length\n\t\t\t\t? `\n
    \n ${textTemplate({\n\t\t\t\t\t\taddClassName: 'mod-product-feature__additional-text',\n\t\t\t\t\t\ttext: `${additionalFeaturesLabel}:`,\n\t\t\t\t\t\ttextElement: 'p',\n\t\t\t\t\t\ttextType: TEXT_TYPES.BODY_MD_INLINE,\n\t\t\t\t\t\ttheme: TEXT_THEMES.LIGHT\n\t\t\t\t\t})}\n
    \n
      \n ${displayAdditionalFeatures(additionalFeatures)}\n
    `\n\t\t\t\t: ''\n\t\t}\n
    \n
    \n `\n\t// return value\n}\n\nexport default productFeaturesTemplate\n","import html from 'utilities/html'\nimport tabsTemplate from '../../../Tabs/Tabs.template'\nimport productFeaturesTemplate from '../ProductFeatures/ProductFeatures.template'\nimport productSpecificationsTemplate from '../ProductSpecifications/ProductSpecifications.template'\nimport productMeasurementTemplate from '../ProductMeasurement/ProductMeasurement.template'\nimport productDocumentsTemplate from '../ProductDocuments/ProductDocuments.template'\n\n// Map of content templates for each category\nconst contentMap = {\n\tdoorFeatures: productFeaturesTemplate, // Template for door features\n\tproductSpecifications: productSpecificationsTemplate, // Template for product specifications\n\tmeasurements: productMeasurementTemplate, // Template for measurements\n\ttechnicalDocuments: productDocumentsTemplate // Template for technical documents\n}\n\n// Function to convert the JSON content into an array of product details\nconst generateProductDetails = (details) => {\n\treturn Object.entries(details).map(([key, value]) => {\n\t\tconst contentFunc = contentMap[key]\n\t\tconst content = contentFunc ? contentFunc(value) : ''\n\t\tconst { label } = value\n\n\t\treturn {\n\t\t\tid: key,\n\t\t\ttitle: label,\n\t\t\tcontent\n\t\t}\n\t})\n}\n\nconst template = ({ details = {} }) => {\n\tconst productDetails = generateProductDetails(details)\n\n\treturn html`\n
    \n
    \n ${\n\t\t\t\t\tArray.isArray(productDetails) && productDetails.length > 1\n\t\t\t\t\t\t? tabsTemplate({\n\t\t\t\t\t\t\t\tid: 'product-details-categories',\n\t\t\t\t\t\t\t\tfullWidth: true,\n\t\t\t\t\t\t\t\ttabs: productDetails\n\t\t\t\t\t\t })\n\t\t\t\t\t\t: ''\n\t\t\t\t}\n
    \n
    \n \n `\n}\nexport default template\n","import textTemplate, {\n\tTYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\nimport Icon from 'foundation/Icon/Icon.template'\n\nconst productSpecificationsTemplate = ({ specs }) => {\n\treturn `\n
    \n \n ${specs\n\t\t\t\t.map(\n\t\t\t\t\t({ label, value, tooltip }) => `\n \n \n \n \n `\n\t\t\t\t)\n\t\t\t\t.join('')}\n
    \n
    \n ${textTemplate({\n\t\t\t\t\t\t\ttext: label,\n\t\t\t\t\t\t\ttextElement: 'p',\n\t\t\t\t\t\t\ttextType: TEXT_TYPES.BODY_MD_INLINE,\n\t\t\t\t\t\t\taddClassName: 'mod-product-specs__label'\n\t\t\t\t\t\t})}\n ${\n\t\t\t\t\t\t\ttooltip && label !== ''\n\t\t\t\t\t\t\t\t? `\n \n \n ${tooltip}\n ${Icon({\n\t\t\t\t\t\t\t\t\t\t\taddClassName: 'cmp-tooltip__svg',\n\t\t\t\t\t\t\t\t\t\t\ticon: 'info'\n\t\t\t\t\t\t\t\t\t\t})}\n \n \n ${textTemplate({\n\t\t\t\t\t\t\t\t\t\t\ttext: tooltip,\n\t\t\t\t\t\t\t\t\t\t\ttextElement: 'p',\n\t\t\t\t\t\t\t\t\t\t\ttextType: TEXT_TYPES.BODY_SM,\n\t\t\t\t\t\t\t\t\t\t\taddClassName: 'cmp-tooltip__text'\n\t\t\t\t\t\t\t\t\t\t})}\n
    \n \n `\n\t\t\t\t\t\t\t\t: ''\n\t\t\t\t\t\t}\n \n
    \n ${textTemplate({\n\t\t\t\t\t\t\ttext: value,\n\t\t\t\t\t\t\ttextElement: 'p',\n\t\t\t\t\t\t\ttextType: TEXT_TYPES.BODY_MD,\n\t\t\t\t\t\t\taddClassName: 'mod-product-specs__value'\n\t\t\t\t\t\t})}\n
    \n
    \n `\n}\n\nexport default productSpecificationsTemplate\n","import textTemplate, {\n\tTYPES as TEXT_TYPES,\n\tTHEMES as TEXT_THEMES\n} from 'foundation/Text/Text.template'\nimport linkTemplate from 'foundation/Link/Link.template'\n\nconst productMeasurementTemplate = ({\n\tmeasurementText,\n\tmeasurementLink,\n\tmeasurementLinkText,\n\twidthLabel,\n\theightLabel,\n\twidths,\n\theights,\n\tavailable\n}) => {\n\treturn /* HTML */ `\n\t\t
    \n\t\t\t${measurementText && measurementText !== ''\n\t\t\t\t? `\n
    \n ${textTemplate({\n\t\t\t\taddClassName: 'mod-product-measurement__description-text',\n\t\t\t\ttext: measurementText,\n\t\t\t\ttextElement: 'p',\n\t\t\t\ttextType: TEXT_TYPES.BODY_LG\n\t\t\t})}\n ${\n\t\t\t\tmeasurementLink && measurementLink !== ''\n\t\t\t\t\t? `\n
    \n ${linkTemplate({\n\t\t\t\t\thref: measurementLink,\n\t\t\t\t\tlabel: measurementLinkText,\n\t\t\t\t\tlinkSize: 'link-small',\n\t\t\t\t\tlinkStyle: 'link-style-text',\n\t\t\t\t\tshowAsButtonLink: false,\n\t\t\t\t\tshowAsTextLink: true\n\t\t\t\t})}\n
    `\n\t\t\t\t\t: ''\n\t\t\t}\n
    `\n\t\t\t\t: ''}\n\t\t\t
    \n\t\t\t\t${textTemplate({\n\t\t\t\t\taddClassName: 'mod-product-measurement__legend-height-text',\n\t\t\t\t\ttext: heightLabel,\n\t\t\t\t\ttextElement: 'p',\n\t\t\t\t\ttextType: TEXT_TYPES.EYEBROW,\n\t\t\t\t\ttheme: TEXT_THEMES.LIGHT\n\t\t\t\t})}\n\t\t\t
    \n\n\t\t\t
    \n\t\t\t\t
    \n\t\t\t\t\t${textTemplate({\n\t\t\t\t\t\taddClassName: 'mod-product-measurement__legend-width-text',\n\t\t\t\t\t\ttext: widthLabel,\n\t\t\t\t\t\ttextElement: 'p',\n\t\t\t\t\t\ttextType: TEXT_TYPES.EYEBROW,\n\t\t\t\t\t\ttheme: TEXT_THEMES.LIGHT\n\t\t\t\t\t})}\n\t\t\t\t
    \n\t\t\t\t
    \n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t${heights\n\t\t\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t\t\t(height) =>\n\t\t\t\t\t\t\t\t\t\t\t``\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t${widths\n\t\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t\t(width) => `\n \n \n ${heights\n\t\t\t\t\t\t\t.map((height) => {\n\t\t\t\t\t\t\t\tconst cell = available.includes(\n\t\t\t\t\t\t\t\t\t`${width.replace(/\"/g, '')}-x-${height.replace(\n\t\t\t\t\t\t\t\t\t\t/\"/g,\n\t\t\t\t\t\t\t\t\t\t''\n\t\t\t\t\t\t\t\t\t)}`\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t? `
    \n
    \n
    \n `\n\t\t\t\t\t\t\t\t\t: `
    \n
    \n
    `\n\t\t\t\t\t\t\t\treturn ``\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.join('')}\n \n `\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t\t\n\t\t\t\t\t
    \n ${textTemplate({\n\t\t\t\t\t\t\t\t\ttext: height,\n\t\t\t\t\t\t\t\t\ttextElement: 'p',\n\t\t\t\t\t\t\t\t\ttextType: TEXT_TYPES.BODY_MD,\n\t\t\t\t\t\t\t\t\ttheme: TEXT_THEMES.LIGHT\n\t\t\t\t\t\t\t\t})}\n
    \n ${textTemplate({\n\t\t\t\t\t\t\t\t\ttext: width,\n\t\t\t\t\t\t\t\t\ttextElement: 'p',\n\t\t\t\t\t\t\t\t\ttextType: TEXT_TYPES.BODY_MD,\n\t\t\t\t\t\t\t\t\ttheme: TEXT_THEMES.LIGHT\n\t\t\t\t\t\t\t\t})}\n ${cell}
    \n\t\t\t\t
    \n\t\t\t
    \n\t\t
    \n\t`\n}\n\nexport default productMeasurementTemplate\n","import linkTemplate from 'foundation/Link/Link.template'\n/**\n * Display additional documents\n * @param {array} documents The additional documents to display\n */\nconst displayDocumentsLinks = (documents) =>\n\tdocuments && documents.length\n\t\t? `\n ${documents\n\t\t\t.map(\n\t\t\t\t({ label, url }) => `\n
  • \n ${linkTemplate({\n\t\t\t\t\taccessibilityLabel: label,\n\t\t\t\t\thref: url,\n\t\t\t\t\tlabel,\n\t\t\t\t\tlinkSize: 'link-large',\n\t\t\t\t\tlinkStyle: 'link-style-text',\n\t\t\t\t\tshowAsButtonLink: false,\n\t\t\t\t\tshowAsTextLink: false,\n\t\t\t\t\tshowAsDownloadLink: true,\n\t\t\t\t\ttarget: '_blank',\n\t\t\t\t\tanalytics: {\n\t\t\t\t\t\tevent: 'file_download',\n\t\t\t\t\t\tfile_extension: 'pdf',\n\t\t\t\t\t\tfile_name: label,\n\t\t\t\t\t\tclick_url: url\n\t\t\t\t\t}\n\t\t\t\t})}\n
  • \n `\n\t\t\t)\n\t\t\t.join('')}\n `\n\t\t: ''\n\nconst productDocumentsTemplate = ({ documents }) => {\n\treturn `\n
      \n ${displayDocumentsLinks(documents)}\n
    `\n}\n\nexport default productDocumentsTemplate\n","import { insert } from 'utilities/renderer'\nimport template from './ProductDetails.template'\nimport Tabs from 'modules/Tabs'\nimport tippy from 'tippy.js'\n\nexport default class ProductDetails {\n\tstatic SELECTORS = {\n\t\tTABS: '[data-cmp-hook=\"product-details-tabs\"]',\n\t\tTABS_CMP: '[data-cmp-is=\"tabs\"]',\n\t\tDOOR_FEATURES: '[data-cmp-hook=\"product-door-features\"]',\n\t\tPRODUCT_SPECIFICATIONS: '[data-cmp-hook=\"product-specifications\"]',\n\t\tMEASUREMENTS: '[data-cmp-hook=\"product-measurements\"]',\n\t\tTECHNICAL_DOCUMENTS: '[data-cmp-hook=\"product-technical-documents\"]',\n\t\tTOOLTIP: '[data-cmp-hook=\"tooltip\"]'\n\t}\n\n\tconstructor(element, { details = {} } = {}) {\n\t\tthis.tabs = null // reference to tabs component\n\t\tthis.element = element\n\t\tthis.details = details\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tthis.template = template({\n\t\t\tdetails: this.details\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\t\tthis.cacheDom()\n\t\tthis.render()\n\t\tthis.createTabs()\n\t\tthis.createTooltips()\n\t}\n\n\tcacheDom() {\n\t\tthis.tabsEl = this.template.querySelector(ProductDetails.SELECTORS.TABS)\n\t\tthis.doorFeaturesEl = this.template.querySelector(\n\t\t\tProductDetails.SELECTORS.DOOR_FEATURES\n\t\t)\n\t\tthis.productSpecificationsEl = this.template.querySelector(\n\t\t\tProductDetails.SELECTORS.PRODUCT_SPECIFICATIONS\n\t\t)\n\t\tthis.measurementsEl = this.template.querySelector(\n\t\t\tProductDetails.SELECTORS.MEASUREMENTS\n\t\t)\n\t\tthis.technicalDocumentsEl = this.template.querySelector(\n\t\t\tProductDetails.SELECTORS.TECHNICAL_DOCUMENTS\n\t\t)\n\t\tthis.tooltip = this.template.querySelectorAll(\n\t\t\tProductDetails.SELECTORS.TOOLTIP\n\t\t)\n\t}\n\n\t/**\n\t * @todo Implement this method\n\t */\n\tcreateTabs() {\n\t\tconst productDetailsCategories = Object.keys(this.details)\n\t\tconst tabsCmpEl = this.tabsEl.querySelector(\n\t\t\tProductDetails.SELECTORS.TABS_CMP\n\t\t)\n\t\tif (tabsCmpEl && productDetailsCategories.length > 1) {\n\t\t\tthis.tabs = new Tabs(tabsCmpEl)\n\t\t}\n\t}\n\n\tcreateTooltips() {\n\t\tthis.tooltip.forEach((tooltipEl, i) => {\n\t\t\tconst tooltipContent = tooltipEl.querySelector('.js-tooltip-content')\n\n\t\t\ttippy(tooltipEl, {\n\t\t\t\tallowHTML: true,\n\t\t\t\tcontent: tooltipContent,\n\t\t\t\tanimateFill: true,\n\t\t\t\tinteractive: true,\n\t\t\t\tplacement: 'auto',\n\t\t\t\ttrigger: 'click'\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Destroy the component\n\t */\n\tdestroy() {\n\t\tif (this.tabs) {\n\t\t\tthis.tabs.destroy()\n\t\t}\n\t}\n\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import { insert } from 'utilities/renderer'\nimport template from './ProductRelatedContent.template'\n\n/**\n * Component for the Product Related Articles Content\n */\nexport default class ProductRelatedContent {\n\t/**\n\t * @param {Element} element - The element to render the component in\n\t * @param {Object} props\n\t * @param {string} props.content - The content markup to display in the component\n\t */\n\tconstructor(element, { content = '' } = {}) {\n\t\tthis.element = element\n\t\tthis.content = content\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tthis.template = template({\n\t\t\tid: this.id\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.template.innerHTML = this.content\n\t\tthis.render()\n\t}\n\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import html from 'utilities/html'\n\nconst template = () =>\n\thtml` `\n\nexport default template\n","import { createMachine, assign, interpret } from 'xstate'\n\n/**\n * ProductInformationModel responsible for managing the state of the ProductInformation module\n */\nexport default class ProductInformationModel {\n\t/**\n\t *\n\t * @param {Object} props\n\t * @param {Object} props.initialState - The initial state of the state machine\n\t * @param {Object} props.queryFilters - The url query param filters to parse\n\t * @param {Object} props.queryOptions - The url query param options to parse\n\t */\n\tconstructor({ initialState, queryFilters = {}, queryOptions = {} }) {\n\t\tthis.listeners = []\n\t\tthis.initialState = this.parseInitialData({\n\t\t\tinitialState,\n\t\t\tqueryFilters,\n\t\t\tqueryOptions\n\t\t})\n\n\t\tconsole.log('initialState', this.initialState)\n\n\t\tthis.machine = createMachine(\n\t\t\t{\n\t\t\t\tid: 'productInformation',\n\t\t\t\tinitial: 'idle',\n\t\t\t\tcontext: {\n\t\t\t\t\t...this.initialState,\n\t\t\t\t\tvisualizerSnapshot: null,\n\t\t\t\t\tpendingOptions: [...this.initialState.options]\n\t\t\t\t},\n\t\t\t\tstates: {\n\t\t\t\t\tidle: {\n\t\t\t\t\t\ton: {\n\t\t\t\t\t\t\tUPDATE_FILTERS: {\n\t\t\t\t\t\t\t\tactions: 'updateFilters'\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tUPDATE_OPTIONS: {\n\t\t\t\t\t\t\t\tactions: 'updateOptions'\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tAPPLY_OPTIONS: {\n\t\t\t\t\t\t\t\tactions: 'applyOptions'\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tCANCEL_OPTIONS: {\n\t\t\t\t\t\t\t\tactions: 'cancelOptions'\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tSET_VISUALIZER_SNAPSHOT: {\n\t\t\t\t\t\t\t\tactions: 'setVisualizerSnapshot'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tactions: {\n\t\t\t\t\tupdateFilters: assign((context, event) => ({\n\t\t\t\t\t\t...context,\n\t\t\t\t\t\tfilters: event.data.updatedFilters\n\t\t\t\t\t})),\n\t\t\t\t\tupdateOptions: assign((context, event) => ({\n\t\t\t\t\t\t...context,\n\t\t\t\t\t\thasModifiedSelectedOption:\n\t\t\t\t\t\t\tevent.data.updatedOptions.meta.hasModifiedSelectedOption,\n\t\t\t\t\t\toptions: event.data.autoApply\n\t\t\t\t\t\t\t? event.data.updatedOptions.options\n\t\t\t\t\t\t\t: context.options,\n\t\t\t\t\t\tpendingOptions: event.data.updatedOptions.options\n\t\t\t\t\t})),\n\t\t\t\t\tapplyOptions: assign((context, event) => ({\n\t\t\t\t\t\t...context,\n\t\t\t\t\t\toptions: [...context.pendingOptions]\n\t\t\t\t\t})),\n\t\t\t\t\tcancelOptions: assign((context, event) => ({\n\t\t\t\t\t\t...context,\n\t\t\t\t\t\tpendingOptions: [...context.options]\n\t\t\t\t\t})),\n\t\t\t\t\tsetVisualizerSnapshot: assign((context, event) => ({\n\t\t\t\t\t\t...context,\n\t\t\t\t\t\tvisualizerSnapshot: event.data.snapshot || null\n\t\t\t\t\t}))\n\t\t\t\t}\n\t\t\t}\n\t\t)\n\n\t\tthis.machineService = interpret(this.machine).start()\n\n\t\tthis.machineService.subscribe(this.onUpdate)\n\t}\n\n\t/**\n\t * Add a listener to the model to be called when the state changes\n\t * @param {Function} listener - Callback function to be called when the state changes\n\t */\n\taddEventListener(listener) {\n\t\tif (typeof listener === 'function') {\n\t\t\tthis.listeners.push(listener)\n\t\t}\n\t}\n\n\t/**\n\t * Remove a listener from the callbacks\n\t * @param {Function} listener - Callback function to remove from the listeners\n\t */\n\tremoveEventListener(listener) {\n\t\tthis.listeners = this.listeners.filter((l) => l !== listener)\n\t}\n\n\t/**\n\t * Parse initial model data to set the initial state\n\t * @param {*} initialData - The initial data to parse\n\t * @param {*} queryOptions - The query options to parse\n\t * @returns {Object} - The parsed initial data\n\t */\n\tparseInitialData({ initialState, queryFilters, queryOptions }) {\n\t\tlet filters = initialState?.filters || {}\n\t\tlet options = initialState?.options || []\n\n\t\t// Set initial selected filters from query params\n\t\tif (Object.keys(queryFilters).length > 0) {\n\t\t\tfilters = {\n\t\t\t\t...filters,\n\t\t\t\tfilterOptions: filters.filterOptions.map((filterOption) => {\n\t\t\t\t\tif (queryFilters[filterOption.id]) {\n\t\t\t\t\t\tswitch (filterOption.type) {\n\t\t\t\t\t\t\tcase 'checkbox':\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\t...filterOption,\n\t\t\t\t\t\t\t\t\toption: {\n\t\t\t\t\t\t\t\t\t\t...filterOption.option,\n\t\t\t\t\t\t\t\t\t\tisSelected:\n\t\t\t\t\t\t\t\t\t\t\tqueryFilters[filterOption.id] ===\n\t\t\t\t\t\t\t\t\t\t\tfilterOption.option.value\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\treturn filterOption\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn filterOption\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\t// Set initial selected options from query params\n\t\tif (Object.keys(queryOptions).length > 0) {\n\t\t\toptions = initialState.options.map((optionGroup, idx) => {\n\t\t\t\tif (queryOptions[optionGroup.value]) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...optionGroup,\n\t\t\t\t\t\tcategories: optionGroup.categories.map((category, idx) => {\n\t\t\t\t\t\t\tif (category.options) {\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\t...category,\n\t\t\t\t\t\t\t\t\toptions: category.options.map((option, idx) => {\n\t\t\t\t\t\t\t\t\t\tconst customColorPrefix = 'custom-color-'\n\t\t\t\t\t\t\t\t\t\tconst isCustomColorOption =\n\t\t\t\t\t\t\t\t\t\t\toption.value.includes(customColorPrefix)\n\t\t\t\t\t\t\t\t\t\tconst isCustomColorQuery =\n\t\t\t\t\t\t\t\t\t\t\tqueryOptions[optionGroup.value].includes(\n\t\t\t\t\t\t\t\t\t\t\t\tcustomColorPrefix\n\t\t\t\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\t\t\t...option,\n\t\t\t\t\t\t\t\t\t\t\tisSelected:\n\t\t\t\t\t\t\t\t\t\t\t\t(isCustomColorOption &&\n\t\t\t\t\t\t\t\t\t\t\t\t\tisCustomColorQuery) ||\n\t\t\t\t\t\t\t\t\t\t\t\tqueryOptions[optionGroup.value] ===\n\t\t\t\t\t\t\t\t\t\t\t\t\toption.value,\n\t\t\t\t\t\t\t\t\t\t\tvalue:\n\t\t\t\t\t\t\t\t\t\t\t\tisCustomColorOption && isCustomColorQuery\n\t\t\t\t\t\t\t\t\t\t\t\t\t? queryOptions[optionGroup.value]\n\t\t\t\t\t\t\t\t\t\t\t\t\t: option.value\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn category\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn optionGroup\n\t\t\t})\n\t\t}\n\n\t\tconst parsedOptions = this.parseOptions({ filters, options })\n\n\t\treturn {\n\t\t\t...initialState,\n\t\t\thasModifiedSelectedOption:\n\t\t\t\tparsedOptions.meta.hasModifiedSelectedOption,\n\t\t\tfilters,\n\t\t\toptions: parsedOptions.options\n\t\t}\n\t}\n\n\t/**\n\t * Parses the options and applies business logic to select/deselect options and disable groups based on the association with other selected options and filters.\n\t *\n\t * @param {Object} param\n\t * @param {Object} param.filters - The filters to apply to the options\n\t * @param {Object} param.options - The options to parse\n\t * @returns {Object} - The parsed options and meta data related to the options\n\t */\n\tparseOptions({ filters, options }) {\n\t\tconst controlledOptions = {}\n\t\tlet hasModifiedSelectedOption = false\n\t\t// extract the selected options to compare against mustHaveOne options\n\t\tconst selectedOptionValues =\n\t\t\tObject.values(this.parseSelectedOptions(options)).map(\n\t\t\t\t(option) => option.value\n\t\t\t) || []\n\n\t\t// Create a map of controlledOptions for filters\n\t\tif (Array.isArray(filters?.filterOptions)) {\n\t\t\tfilters?.filterOptions.forEach((filter) => {\n\t\t\t\tfilter.controls.forEach((control) => {\n\t\t\t\t\tswitch (filter.type) {\n\t\t\t\t\t\tcase 'checkbox':\n\t\t\t\t\t\t\tcontrolledOptions[control] = filter?.option?.isSelected\n\t\t\t\t\t\t\t\t? true\n\t\t\t\t\t\t\t\t: !!controlledOptions[control]\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t}\n\n\t\tconst updatedOptions = options.map((optionGroup) => {\n\t\t\t// store a flag to determine if a selected option has been disabled\n\t\t\tlet hasDisabledSelectedOption = false\n\n\t\t\t// update the option group with the isDisabled property based on the controlledOptions\n\t\t\tconst updatedOptionGroup = {\n\t\t\t\t...optionGroup,\n\t\t\t\tisDisabled: Object.hasOwn(controlledOptions, optionGroup.value)\n\t\t\t\t\t? !controlledOptions[optionGroup.value]\n\t\t\t\t\t: false,\n\t\t\t\tcategories: optionGroup.categories.map((category) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...category,\n\t\t\t\t\t\toptions: category.options.map((option) => {\n\t\t\t\t\t\t\t// if the option has a mustHaveOne property and it is not selected, disable the option\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tArray.isArray(option.mustHaveOne) &&\n\t\t\t\t\t\t\t\toption.mustHaveOne.length > 0\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tconst hasMustHave = option.mustHaveOne.some(\n\t\t\t\t\t\t\t\t\t(mustHave) => selectedOptionValues.includes(mustHave)\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tif (option.isSelected && !hasMustHave) {\n\t\t\t\t\t\t\t\t\thasDisabledSelectedOption = true\n\t\t\t\t\t\t\t\t\thasModifiedSelectedOption = true\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\t...option,\n\t\t\t\t\t\t\t\t\tisDisabled: !hasMustHave,\n\t\t\t\t\t\t\t\t\tisSelected: !hasMustHave ? false : option.isSelected\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t...option\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// if a selected option has been disabled, select the first non-disabled option as selected\n\t\t\tif (hasDisabledSelectedOption) {\n\t\t\t\tlet isDefaultSelected = false\n\t\t\t\tfor (let i = 0; i < updatedOptionGroup.categories.length; i++) {\n\t\t\t\t\tif (isDefaultSelected) {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (\n\t\t\t\t\t\tlet j = 0;\n\t\t\t\t\t\tj < updatedOptionGroup.categories[i].options.length;\n\t\t\t\t\t\tj++\n\t\t\t\t\t) {\n\t\t\t\t\t\tif (!updatedOptionGroup.categories[i].options[j].isDisabled) {\n\t\t\t\t\t\t\tupdatedOptionGroup.categories[i].options[\n\t\t\t\t\t\t\t\tj\n\t\t\t\t\t\t\t].isSelected = true\n\t\t\t\t\t\t\tisDefaultSelected = true\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn updatedOptionGroup\n\t\t})\n\n\t\treturn {\n\t\t\toptions: updatedOptions,\n\t\t\tmeta: {\n\t\t\t\thasModifiedSelectedOption: hasModifiedSelectedOption || false\n\t\t\t}\n\t\t}\n\t}\n\n\t/***\n\t * Callback function to be called when the state changes\n\t * @param {Object} state - The current state of the state machine\n\t */\n\tonUpdate = (state, event) => {\n\t\tthis.listeners.forEach((listener) => listener(state, event))\n\t}\n\n\t/**\n\t * Event emitter to send events to the state machine\n\t * @param {Object} event - The event to send to the state machine\n\t * @param {string} event.type - The type of event to send to the state machine\n\t * @param {Object} event.data - The payload of the event to send to the state machine\n\t */\n\tsend(event) {\n\t\tthis.machineService.send(event)\n\t}\n\n\t/**\n\t * Set a filter selection state in filters context and send an event to the state machine with the updated filters and updated options based on the selected filters\n\t * @param {Object} param\n\t * @param {Object} param.filter - The filter to update\n\t */\n\tsetFilter({ filter }) {\n\t\tconst { filters, pendingOptions } = this.getState().context\n\n\t\tconst updatedFilters = {\n\t\t\t...filters,\n\t\t\tfilterOptions: filters.filterOptions.map((filterOption) => {\n\t\t\t\tif (filterOption.id === filter.filterId) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...filterOption,\n\t\t\t\t\t\toption: {\n\t\t\t\t\t\t\t...filterOption.option,\n\t\t\t\t\t\t\tisSelected: filter.isSelected\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn filterOption\n\t\t\t})\n\t\t}\n\n\t\tconst updatedOptions = this.parseOptions({\n\t\t\tfilters: updatedFilters,\n\t\t\toptions: pendingOptions\n\t\t})\n\n\t\tthis.send({ type: 'UPDATE_FILTERS', data: { updatedFilters } })\n\t\tthis.send({\n\t\t\ttype: 'UPDATE_OPTIONS',\n\t\t\tdata: { updatedOptions, autoApply: true }\n\t\t})\n\t}\n\n\t/**\n\t * Set an option selection state in options context and send an event to the state machine with the updated options\n\t * @param {Object} option - The option to update\n\t */\n\tsetOption(option, autoApply = false) {\n\t\tconst { filters, pendingOptions } = this.getState().context\n\t\tconst customColorIdx = (val) => val.indexOf('custom-color')\n\n\t\tlet updatedOptions = pendingOptions.map((o, idx) => {\n\t\t\tif (o.value === option.groupValue) {\n\t\t\t\treturn {\n\t\t\t\t\t...o,\n\t\t\t\t\tcategories: o.categories.map((c, idx) => {\n\t\t\t\t\t\tif (c.options) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t...c,\n\t\t\t\t\t\t\t\toptions: c.options.map((o, idx) => {\n\t\t\t\t\t\t\t\t\tconst isCustomColor =\n\t\t\t\t\t\t\t\t\t\tcustomColorIdx(o.value) > -1 &&\n\t\t\t\t\t\t\t\t\t\tcustomColorIdx(option.optionValue) > -1\n\n\t\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\t\t...o,\n\t\t\t\t\t\t\t\t\t\tisSelected:\n\t\t\t\t\t\t\t\t\t\t\to.value === option.optionValue || isCustomColor\n\t\t\t\t\t\t\t\t\t\t\t\t? option.isSelected\n\t\t\t\t\t\t\t\t\t\t\t\t: false,\n\t\t\t\t\t\t\t\t\t\tvalue: isCustomColor\n\t\t\t\t\t\t\t\t\t\t\t? option.optionValue\n\t\t\t\t\t\t\t\t\t\t\t: o.value\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn c\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn o\n\t\t})\n\n\t\tupdatedOptions = this.parseOptions({ filters, options: updatedOptions })\n\n\t\tthis.send({ type: 'UPDATE_OPTIONS', data: { updatedOptions, autoApply } })\n\t}\n\n\t/**\n\t * Send an event to the state machine to apply the current pendingOptions\n\t */\n\tapplyOptions() {\n\t\tthis.send({\n\t\t\ttype: 'APPLY_OPTIONS'\n\t\t})\n\t}\n\n\t/**\n\t * Send an event to the state machine to reset the current pendingOptions to the applied options\n\t */\n\tcancelOptions() {\n\t\tthis.send({\n\t\t\ttype: 'CANCEL_OPTIONS'\n\t\t})\n\t}\n\n\t/**\n\t * Get option parameters\n\t * @returns {Object} - The option parameters\n\t */\n\tgetOptionParams() {\n\t\tconst { options } = this.getState().context\n\t\tconst params = {}\n\n\t\toptions.forEach((optionGroup) => {\n\t\t\toptionGroup.categories.forEach((category) => {\n\t\t\t\tif (category.options) {\n\t\t\t\t\tcategory.options.forEach((option) => {\n\t\t\t\t\t\tif (option.isSelected) {\n\t\t\t\t\t\t\tparams[optionGroup.value] = option.value\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\n\t\treturn params\n\t}\n\n\t/**\n\t * Parse the options and return a trimmed down object with only the selected options\n\t * @param {Object} options - The options to parse\n\t * @returns {Object} - The selected options\n\t */\n\tparseSelectedOptions(options) {\n\t\tconst selectedOptions = {}\n\n\t\toptions.forEach((optionGroup) => {\n\t\t\toptionGroup.categories.forEach((category) => {\n\t\t\t\tif (category.options) {\n\t\t\t\t\tcategory.options.forEach((option) => {\n\t\t\t\t\t\tif (option.isSelected) {\n\t\t\t\t\t\t\tselectedOptions[optionGroup.value] = option\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\n\t\treturn selectedOptions\n\t}\n\n\t/**\n\t * Get a trimmed down options object with only the selected options\n\t * @returns {Object} - The selected options\n\t */\n\tgetSelectedOptions() {\n\t\tconst { options } = this.getState().context\n\t\treturn this.parseSelectedOptions(options)\n\t}\n\n\t/**\n\t * Get the options from the state machine context\n\t * @returns\n\t */\n\tgetOptions() {\n\t\tconst { options } = this.getState().context\n\t\treturn options\n\t}\n\n\t/**\n\t * Set the visualizer snapshot image\n\t * @param {String} snapshot - The base64 encoded image string\n\t */\n\tsetVisualizerSnapshot(snapshot) {\n\t\tthis.machineService.send({\n\t\t\ttype: 'SET_VISUALIZER_SNAPSHOT',\n\t\t\tdata: { snapshot }\n\t\t})\n\t}\n\n\t/**\n\t * Get current state\n\t */\n\tgetState = () => {\n\t\tconst state = this.machineService.getSnapshot()\n\t\tconst { value, context } = state\n\t\treturn { value, context }\n\t}\n}\n","import History from 'services/History/History'\n\n/**\n * ProductInformationRouter responsible for managing the routing and history state of the product information page\n */\nexport default class ProductInformationRouter extends History {\n\t/**\n\t * Set the selected options in the url\n\t * @param {Array} options - The configured product options\n\t * @example [{ value: 'color', categories: [{ value: 'red', options: [{ value: 'red', isSelected: true }] }] }]\n\t * // Url = https://www.masonite.com/product-information?color=red\n\t */\n\tsetOptions({ filters = {}, options = [] }) {\n\t\tconst url = `${window.location.origin}${window.location.pathname}`\n\t\tconst searchParams = new URLSearchParams(window.location.search)\n\n\t\t// Set the selected filters to the url\n\t\tif (Array.isArray(filters?.filterOptions)) {\n\t\t\tfilters.filterOptions.forEach((filter) => {\n\t\t\t\tswitch (filter.type) {\n\t\t\t\t\tcase 'checkbox':\n\t\t\t\t\t\tif (filter.option.isSelected) {\n\t\t\t\t\t\t\tsearchParams.set(filter.id, filter.option.value)\n\t\t\t\t\t\t} else if (searchParams.has(filter.id)) {\n\t\t\t\t\t\t\tsearchParams.delete(filter.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\t// Set the selected options to the url\n\t\tif (Array.isArray(options)) {\n\t\t\toptions.forEach((option) => {\n\t\t\t\tconst key = option.value\n\t\t\t\tconst allOptions = option.categories.reduce((acc, category) => {\n\t\t\t\t\treturn acc.concat(category.options)\n\t\t\t\t}, [])\n\t\t\t\tconst selectedOption = allOptions.find(\n\t\t\t\t\t(o) => o?.isSelected && !option.isDisabled\n\t\t\t\t)\n\n\t\t\t\tif (searchParams.has(key) && !selectedOption) {\n\t\t\t\t\tsearchParams.delete(key)\n\t\t\t\t} else if (selectedOption) {\n\t\t\t\t\tsearchParams.set(key, selectedOption.value)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\tthis.replaceState(\n\t\t\toptions,\n\t\t\tdocument.title,\n\t\t\t`${url}?${searchParams.toString()}`\n\t\t)\n\t}\n\n\t/**\n\t * Parse and return the valid options from the url\n\t * @param {Object} param\n\t * @param {Object} param.filters - The valid filters to parse from the url\n\t * @param {Object} param.options - The valid options to parse from the url\n\t * @returns {Object} - The valid options and filters parsed from the url\n\t * @example getOptions({ options: { categories: [{ value: 'color', options: [{ value: 'red' }] }] }})\n\t * // Url = https://www.masonite.com/product-information?color=red&invalidOption=blue\n\t * // { color: 'red' }\n\t * @example getOptions({ options: { categories: [{ value: 'color', options: [{ value: 'red' }] }, { value: 'size', options: [{ value: 'small' }] }] })\n\t * // Url = https://www.masonite.com/product-information?color=red&size=small\n\t * // { color: 'red', size: 'small' }\n\t *\n\t */\n\tgetOptions({ filters, options }) {\n\t\tconst searchParams = new URLSearchParams(window.location.search)\n\n\t\tconst queryFilters = {}\n\t\tif (Array.isArray(filters?.filterOptions)) {\n\t\t\tfilters.filterOptions.forEach((filter) => {\n\t\t\t\tswitch (filter.type) {\n\t\t\t\t\tcase 'checkbox':\n\t\t\t\t\t\tif (searchParams.has(filter.id)) {\n\t\t\t\t\t\t\tqueryFilters[filter.id] = searchParams.get(filter.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\tconst queryOptions = {}\n\t\tif (Array.isArray(options)) {\n\t\t\toptions.forEach((option) => {\n\t\t\t\tconst key = option.value\n\t\t\t\tconst allOptions = option.categories.reduce((acc, category) => {\n\t\t\t\t\treturn acc.concat(category.options)\n\t\t\t\t}, [])\n\n\t\t\t\tconst hasParam = searchParams.has(key)\n\t\t\t\tconst customColorPrefix = 'custom-color-'\n\t\t\t\tlet isValidOption = false\n\n\t\t\t\tif (hasParam && searchParams.get(key).includes(customColorPrefix)) {\n\t\t\t\t\tisValidOption =\n\t\t\t\t\t\tsearchParams.get(key).split(customColorPrefix)[1].length === 6\n\t\t\t\t} else {\n\t\t\t\t\tisValidOption = allOptions.some((o) =>\n\t\t\t\t\t\to?.value ? o.value === searchParams.get(key) : false\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tif (hasParam && isValidOption) {\n\t\t\t\t\tqueryOptions[key] = searchParams.get(key)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\treturn { queryFilters, queryOptions }\n\t}\n}\n","import template from './ProductInformation.template'\nimport { insert } from 'utilities/renderer'\nimport ProductInfo from './components/ProductInfo/ProductInfo'\nimport ProductOptions from './components/ProductOptions/ProductOptions'\nimport ProductMediaGallery from './components/ProductMediaGallery/ProductMediaGallery'\nimport ProductDetails from './components/ProductDetails/ProductDetails'\nimport ProductRelatedContent from './components/ProductRelatedContent/ProductRelatedContent'\nimport ProductInformationModel from './models/ProductInformationModel/ProductInformationModel'\nimport ProductInformationRouter from './services/ProductInformationRouter/ProductInformationRouter'\nimport Services from 'services'\nimport Analytics from 'services/Analytics/Analytics'\n\nexport default class ProductInformation {\n\tstatic SELECTORS = {\n\t\tPRODUCT_INFO: '[data-cmp-hook=\"product-info\"]',\n\t\tPRODUCT_OPTIONS: '[data-cmp-hook=\"product-options\"]',\n\t\tPRODUCT_MEDIA_GALLERY: '[data-cmp-hook=\"product-media-gallery\"]',\n\t\tPRODUCT_DETAILS: '[data-cmp-hook=\"product-details\"]',\n\t\tPRODUCT_RELATED_CONTENT: '[data-cmp-hook=\"product-related-content\"]',\n\t\tPRODUCT_CONFIG_SLOT_1: '[data-cmp-hook=\"product-configuration-slot-1\"]',\n\t\tPRODUCT_CONFIG_SLOT_2: '[data-cmp-hook=\"product-configuration-slot-2\"]',\n\t\tPRODUCT_CONFIG_SLOT_3: '[data-cmp-hook=\"product-configuration-slot-3\"]',\n\t\tPRODUCT_CONFIG_SLOT_4: '[data-cmp-hook=\"product-configuration-slot-4\"]'\n\t}\n\n\tconstructor(element, { id = '' } = {}) {\n\t\tthis.element = element\n\t\tthis.id = id\n\t\tthis.initialData = this.getInitialData()\n\t\tthis.services = Services.getInstance()\n\t\tthis.mediaQuery = this.services.BreakpointListener.queryMatch\n\t\tthis.analyticsService = Analytics.getInstance()\n\t\tthis.init()\n\t}\n\n\t/**\n\t * Initialize the product information component.\n\t */\n\tinit() {\n\t\tthis.template = template({\n\t\t\tid: this.id\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.cacheDom()\n\t\tthis.createProductInformationRouter()\n\t\tthis.createProductInformationModel()\n\t\tthis.createProductInfo()\n\t\tthis.createProductOptions()\n\t\tthis.createProductMediaGallery()\n\t\tthis.creatProductDetails()\n\t\tthis.createProductRelatedContent()\n\t\tthis.attachEvents()\n\t\tthis.setContentOrder()\n\t\tthis.render()\n\t}\n\n\t/**\n\t * Cache the DOM elements for the product information component.\n\t */\n\tcacheDom() {\n\t\tthis.productInfoEl = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_INFO\n\t\t)\n\n\t\tthis.productOptionsEl = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_OPTIONS\n\t\t)\n\n\t\tthis.productMediaGalleryEl = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_MEDIA_GALLERY\n\t\t)\n\n\t\tthis.productDetailsEl = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_DETAILS\n\t\t)\n\n\t\tthis.productRelatedContentEl = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_RELATED_CONTENT\n\t\t)\n\n\t\tthis.productConfigSlot1El = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_CONFIG_SLOT_1\n\t\t)\n\n\t\tthis.productConfigSlot2El = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_CONFIG_SLOT_2\n\t\t)\n\n\t\tthis.productConfigSlot3El = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_CONFIG_SLOT_3\n\t\t)\n\n\t\tthis.productConfigSlot4El = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_CONFIG_SLOT_4\n\t\t)\n\t}\n\n\t/**\n\t * Attach the events to the product information component.\n\t */\n\tattachEvents() {\n\t\tthis.productInformationModel.addEventListener(this.onModelUpdate)\n\t\tthis.services.BreakpointListener.addListener(this.onBreakpointChange)\n\t}\n\n\t/**\n\t * Detach the events from the product information component.\n\t */\n\tdetachEvents() {\n\t\tthis.productInformationModel.removeEventListener(this.onModelUpdate)\n\t\tthis.services.BreakpointListener.renoveListener(this.onBreakpointChange)\n\t}\n\n\t/**\n\t * Destroy the product information component.\n\t */\n\tdestroy() {\n\t\tthis.detachEvents()\n\t}\n\n\t/**\n\t * Get the initial data for the product information component from the window object.\n\t * @returns\n\t */\n\tgetInitialData() {\n\t\tif (!window.masonite?.pip) {\n\t\t\tconsole.error(\n\t\t\t\t'No initial data was found for the ProductInformation component. Please add the data to the window.masonite.pip object.'\n\t\t\t)\n\t\t\treturn {}\n\t\t}\n\n\t\treturn typeof window.masonite.pip === 'string'\n\t\t\t? JSON.parse(window.masonite.pip)\n\t\t\t: window.masonite.pip\n\t}\n\n\t/**\n\t * Create the product information router.\n\t */\n\tcreateProductInformationRouter() {\n\t\tthis.productInformationRouter = new ProductInformationRouter()\n\t}\n\n\t/**\n\t * Create the product information model.\n\t */\n\tcreateProductInformationModel() {\n\t\tconst { queryFilters, queryOptions } =\n\t\t\tthis.productInformationRouter.getOptions({\n\t\t\t\tfilters: this.initialData?.filters,\n\t\t\t\toptions: this.initialData?.options\n\t\t\t})\n\t\tthis.productInformationModel = new ProductInformationModel({\n\t\t\tinitialState: this.initialData,\n\t\t\tqueryFilters,\n\t\t\tqueryOptions\n\t\t})\n\t}\n\n\t/**\n\t * Create the product information component.\n\t */\n\tcreateProductInfo() {\n\t\tconst { context } = this.productInformationModel.getState()\n\n\t\tthis.productInfo = new ProductInfo(this.productInfoEl, {\n\t\t\tcollection: context.collection,\n\t\t\tglassAvailable: context.glassAvailable,\n\t\t\tbenefits: context.benefits,\n\t\t\tcta: context.wtbCta,\n\t\t\tconstructionEyebrow: context.constructionEyebrow,\n\t\t\tfeaturedInEyebrow: context.featuredInEyebrow,\n\t\t\tcomingSoonEyebrow: context.comingSoonEyebrow\n\t\t})\n\t}\n\n\t/**\n\t * Create the product options component.\n\t */\n\tcreateProductOptions() {\n\t\tthis.productOptions = new ProductOptions(this.productOptionsEl, {\n\t\t\tproductModel: this.productInformationModel\n\t\t})\n\t}\n\n\t/**\n\t * Create the product media gallery component.\n\t */\n\tcreateProductMediaGallery() {\n\t\tthis.productMediaGallery = new ProductMediaGallery(\n\t\t\tthis.productMediaGalleryEl,\n\t\t\t{\n\t\t\t\tproductModel: this.productInformationModel\n\t\t\t}\n\t\t)\n\t}\n\n\t/**\n\t * Create the product details component.\n\t */\n\tcreatProductDetails() {\n\t\tconst { context } = this.productInformationModel.getState()\n\n\t\tthis.productDetails = new ProductDetails(this.productDetailsEl, {\n\t\t\tdetails: context.details\n\t\t})\n\t}\n\n\t/**\n\t * Create the product related content component.\n\t */\n\tcreateProductRelatedContent() {\n\t\tconst { context } = this.productInformationModel.getState()\n\n\t\tthis.productRelatedContent = new ProductRelatedContent(\n\t\t\tthis.productRelatedContentEl,\n\t\t\t{\n\t\t\t\tcontent: context.relatedArticles\n\t\t\t}\n\t\t)\n\t}\n\n\t/**\n\t * Set the content order of the product information component based on the current breakpoint\n\t * to maintain the proper tab order as the layout reorders.\n\t */\n\tsetContentOrder() {\n\t\tif (this.mediaQuery.MEDIUM_LARGE) {\n\t\t\tthis.productConfigSlot1El.appendChild(this.productMediaGalleryEl)\n\t\t\tthis.productConfigSlot3El.appendChild(this.productInfoEl)\n\t\t\tthis.productConfigSlot4El.appendChild(this.productOptionsEl)\n\t\t} else {\n\t\t\tthis.productConfigSlot1El.appendChild(this.productMediaGalleryEl)\n\t\t\tthis.productConfigSlot4El.appendChild(this.productInfoEl)\n\t\t\tthis.productConfigSlot3El.appendChild(this.productOptionsEl)\n\t\t}\n\t}\n\n\t/**\n\t * Update the product information model when the options are updated.\n\t * @param {*} state\n\t * @param {*} event\n\t */\n\tonModelUpdate = (state, event) => {\n\t\tconst { context: { filters = {}, options = [] } = {} } = state\n\n\t\tif (\n\t\t\t(event.type === 'UPDATE_OPTIONS' && event.data.autoApply) ||\n\t\t\tevent.type === 'APPLY_OPTIONS'\n\t\t) {\n\t\t\tthis.productInformationRouter.setOptions({ filters, options })\n\t\t\tthis.trackOptions()\n\t\t}\n\t}\n\n\t/**\n\t * Update the media query state and set the content order if the breakpoint has changed.\n\t * @param {*} breakpoint\n\t */\n\tonBreakpointChange = (breakpoint) => {\n\t\tconst hasChanged =\n\t\t\tbreakpoint.SMALL !== this.mediaQuery.SMALL ||\n\t\t\tbreakpoint.MEDIUM !== this.mediaQuery.MEDIUM ||\n\t\t\tbreakpoint.MEDIUM_LARGE !== this.mediaQuery.MEDIUM_LARGE\n\n\t\tthis.mediaQuery = breakpoint\n\n\t\tif (hasChanged) {\n\t\t\tthis.setContentOrder()\n\t\t}\n\t}\n\n\t/**\n\t * Track the selected options in the analytics service.\n\t * The format of the parameters are as follows:\n\t * - product_info_selection: option name - option value | option name - option value | ...\n\t */\n\ttrackOptions = () => {\n\t\tconst selectedOptions = this.productInformationModel.getSelectedOptions()\n\n\t\tconst payload = Object.entries(selectedOptions)\n\t\t\t.map(\n\t\t\t\t([key, value]) =>\n\t\t\t\t\t`${key.toLowerCase()} - ${value?.label?.toLowerCase()}`\n\t\t\t)\n\t\t\t.join(' | ')\n\n\t\tthis.analyticsService.trackInteraction('product_info', {\n\t\t\tproduct_info_selection: payload\n\t\t})\n\t}\n\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import html from 'utilities/html'\n\nconst template = ({ id = '' } = {}) =>\n\thtml`\n \n
    \n \n
    \n
    \n \n \n \n \n \n \n \n \n \n \n \n \n \n `\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport template from './Notification.template'\n\n/**\n * ProductSave component responsible for rendering a Save button\n * @param {HTMLElement} element - the element to render the component in\n * @param {Object} props - the options for the component\n * @param {String} props.text - the text to display in the notification\n * @param {Object} props.cta - the cta to display in the notification\n * @param {String} props.cta.text - the text to display in the cta\n * @param {String} props.cta.url - the url to navigate to when the cta is clicked\n * @param {Object} props.close - the close button to display in the notification\n * @param {String} props.close.text - the text to display in the close button\n * @param {Function} props.close.onClick - the function to call when the close button is clicked\n * @param {Boolean} props.showCta - whether or not to show the cta\n * @param {String} props.id - An id for the notification\n */\nexport default class Notification {\n\tstatic SELECTORS = {\n\t\tNOTIFICATION_BUTTON: '[data-cmp-hook=\"notification-button\"]',\n\t\tNOTIFICATION_CONTAINER: '[data-cmp-is=\"notification-container\"]'\n\t}\n\n\tstatic TIMERS = {\n\t\tNOTIFICATION: 10000\n\t}\n\n\tconstructor(element, { text, cta = {}, close, showCta, id } = {}) {\n\t\tthis.element = element\n\t\tthis.text = text\n\t\tthis.cta = cta\n\t\tthis.close = close\n\t\tthis.showCta = showCta\n\t\tthis.id = id\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tthis.template = template({\n\t\t\ttext: this.text,\n\t\t\tcta: this.cta,\n\t\t\tclose: this.close,\n\t\t\tshowCta: this.showCta,\n\t\t\tid: this.id\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.cacheDom()\n\t\tthis.attachEvents()\n\t\tthis.initializeNotificationTimeout()\n\t\tthis.render()\n\t}\n\n\t/**\n\t * Cache the DOM elements for the ProductSave component.\n\t */\n\tcacheDom() {\n\t\tthis.closeButton = this.template.querySelector(\n\t\t\tNotification.SELECTORS.NOTIFICATION_BUTTON\n\t\t)\n\t}\n\n\t/**\n\t * Attach events to the Notification component.\n\t */\n\tattachEvents() {\n\t\tthis.closeButton.addEventListener('click', this.handleClose)\n\t}\n\n\t/**\n\t * Remove events from the Notification component.\n\t */\n\tdetachEvents() {\n\t\tthis.closeButton.removeEventListener('click', this.handleClose)\n\t}\n\n\t/**\n\t * Destroy the Notification component.\n\t */\n\tdestroy() {\n\t\tthis.detachEvents()\n\t\tif (this.notificationTimeout) clearTimeout(this.notificationTimeout)\n\t}\n\n\t/**\n\t * Initialize the notification timeout.\n\t */\n\tinitializeNotificationTimeout() {\n\t\tif (this.notificationTimeout) clearTimeout(this.notificationTimeout)\n\t\tthis.notificationTimeout = setTimeout(() => {\n\t\t\tthis.handleClose()\n\t\t}, Notification.TIMERS.NOTIFICATION)\n\t}\n\n\t/**\n\t * Handle the close event.\n\t */\n\thandleClose = () => {\n\t\tif (this.notificationTimeout) clearTimeout(this.notificationTimeout)\n\n\t\tthis.template?.parentElement?.remove()\n\t}\n\n\t/**\n\t * Render the ProductTools component\n\t */\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import html from 'utilities/html'\nimport textTemplate, {\n\tTYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\nimport { Default as Link } from 'foundation/Link/Link.stories'\n\n/**\n * Display a popup notification\n * @param {Object} props\n * @param {string} props.text - The notification text\n * @param {Object} props.cta - The CTA properties\n * @param {string} props.cta.url - The CTA URL\n * @param {string} props.cta.text - The CTA text\n * @param {string} props.close - The close text\n * @param {boolean} props.showCta - Whether to show the CTA\n * @param {string} props.sku - The id of the notification\n * @returns {String} - The notification template\n */\nconst template = ({ text, cta = {}, close, showCta, id }) => html`\n\t\n\t\t
    \n\t\t\t
    \n\t\t\t\t\n\t\t\t\t\t${textTemplate({\n\t\t\t\t\t\ttext: text || '',\n\t\t\t\t\t\ttextElement: 'p',\n\t\t\t\t\t\ttextType: TEXT_TYPES.BODY_MD\n\t\t\t\t\t})}\n\t\t\t\t
    \n\t\t\t\t${showCta\n\t\t\t\t\t? Link({\n\t\t\t\t\t\t\t...Link.args,\n\t\t\t\t\t\t\taccessibilityLabel: 'Go to Favorites',\n\t\t\t\t\t\t\thref: cta?.url || '#',\n\t\t\t\t\t\t\tlabel: cta?.text || 'Go to Favorites',\n\t\t\t\t\t\t\tlinkStyle: 'mod-notification__cta link-style-primary',\n\t\t\t\t\t\t\tlinkSize: 'link-small',\n\t\t\t\t\t\t\tshowAsButtonLink: true,\n\t\t\t\t\t\t\tshowAsListLink: false,\n\t\t\t\t\t\t\tshowAsTextLink: false\n\t\t\t\t\t })\n\t\t\t\t\t: ''}\n\t\t\t
    \n\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t${close}\n\t\t\t\n\t\t\n\t\n`\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport { sortObjectKeys } from 'utilities/utilities'\nimport template from './ProductSave.template'\nimport Services from 'services'\nimport Notification from 'modules/ProductTools/components/Notification/Notification'\nimport Analytics from 'services/Analytics/Analytics'\n\n/**\n * ProductSave component responsible for rendering a Save button\n * @param {HTMLElement} element - the element to render the component in\n * @param {Object} props - the options for the component\n * @param {Boolean} props.isButton - whether the component should render as a button\n * @param {String} props.showCta - whether the component should show the CTA in the notification\n * @param {Object} props.product\n * @param {String} props.product.sku - Product sku\n * @param {String} props.product.collection - Product collection name\n * @param {Object} props.product.media - Product media\n * @param {String} props.product.media.src - Product media url\n * @param {String} props.product.media.alt - Product media alt\n * @param {String} props.product.url - Product url\n * @param {Object} props.product.customOptions - Product options\n * @param {Object} props.content - Product tools content\n * @param {Object} props.content.save - Product save content\n * @param {Object} props.content.saved - Product saved content\n * @param {Object} props.content.saveSuccess - Product saved success content\n * @param {Object} props.content.saveRemove - Product save remove content\n * @param {Object} props.content.saveError - Product save error content\n * @param {Object} props.content.share - Product share content\n * @param {Object} props.content.pinterest - Product pinterest content\n * @param {Object} props.content.copy - Product copy content\n * @param {Object} props.content.copySuccess - Product copy success content\n */\nexport default class ProductSave {\n\tstatic SELECTORS = {\n\t\tSAVE_BUTTON: '[data-cmp-hook=\"save-button\"]',\n\t\tSAVE_ICON: '[data-cmp-hook=\"save-icon\"]',\n\t\tSTATUS: '[data-product-favorite-saved]',\n\t\tNOTIFICATION_CONTAINER: '[data-cmp-is=\"notification-container\"]'\n\t}\n\n\tstatic CLASSES = {\n\t\tBLANK_SAVED: 'mod-product-save__blank-style--saved',\n\t\tBUTTON_SAVED: 'mod-product-save__button-style--saved',\n\t\tACTIVE: 'mod-product-save__notification--active',\n\t\tNOTIFICATION_CONTAINER: 'mod-notification__container',\n\t\tNOTIFICATION_ITEM: 'mod-notification__item'\n\t}\n\n\tstatic MESSAGES = {\n\t\tSAVED: 'was added to your Favorites',\n\t\tREMOVED: 'was removed from your Favorites',\n\t\tERROR: 'We were unable to process your request, please try again later'\n\t}\n\n\tstatic EVENTS = {\n\t\tSAVE: 'saveFavorite',\n\t\tREMOVE: 'removeFavorite',\n\t\tDISMISS_NOTIFICATION: 'dismissNotificationFavorite'\n\t}\n\n\tstatic DATA_ATTRIBUTES = {\n\t\tNOTIFICATION: {\n\t\t\tATTRIBUTE: 'data-cmp-is',\n\t\t\tVALUE: 'notification-container'\n\t\t}\n\t}\n\n\tconstructor(element, { isButton, product, content, showCta } = {}) {\n\t\tthis.element = element\n\t\tthis.isFavorite = false\n\t\tthis.product = product\n\t\tthis.content = content\n\t\tthis.isButton = isButton\n\t\tthis.showCta = showCta\n\t\tthis.services = Services.getInstance()\n\t\tthis.analyticsService = Analytics.getInstance()\n\n\t\tthis.EventEmitterService = this.services.EventEmitterService\n\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tthis.template = template({\n\t\t\tlabel: this.isFavorite\n\t\t\t\t? this.content.saved?.label\n\t\t\t\t: this.content.save?.label,\n\t\t\tlabelAccessibility: this.isFavorite\n\t\t\t\t? this.content.saved?.labelAccessibility\n\t\t\t\t: this.content.save?.labelAccessibility,\n\t\t\tisFavorite: this.isFavorite,\n\t\t\tisButton: this.isButton\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.cacheDom()\n\t\tthis.attachEvents()\n\t\tthis.initializeSavedState()\n\t\tthis.createNotificationContainer()\n\t\tthis.render()\n\t}\n\n\t/**\n\t * Cache the DOM elements for the ProductSave component.\n\t */\n\tcacheDom() {\n\t\tthis.saveButton = this.template.querySelector(\n\t\t\tProductSave.SELECTORS.SAVE_BUTTON\n\t\t)\n\n\t\tthis.saveIcon = this.template.querySelector(\n\t\t\tProductSave.SELECTORS.SAVE_ICON\n\t\t)\n\n\t\tthis.saveLabel = this.template.querySelector(\n\t\t\tProductSave.SELECTORS.SAVE_BUTTON\n\t\t).lastElementChild\n\t}\n\n\t/**\n\t * Attach event listeners to the ProductSave component\n\t */\n\tattachEvents() {\n\t\tthis.saveButton.addEventListener('click', this.handleClick)\n\t}\n\n\t/**\n\t * Detach the events from the ProductSave component\n\t */\n\tdetachEvents() {\n\t\tthis.saveButton.removeEventListener('click', this.handleClick)\n\t}\n\n\t/**\n\t * Destroy the ProductSave component.\n\t */\n\tdestroy() {\n\t\tthis.detachEvents()\n\t\tif (this.notification) this.notification.destroy()\n\t}\n\n\t/**\n\t * Initialize the component state\n\t */\n\tinitializeSavedState() {\n\t\t// Get current favorites from local storage\n\t\tconst doorFavorites = localStorage.getItem('doorFavorites')\n\t\t\t? JSON.parse(localStorage.getItem('doorFavorites'))\n\t\t\t: []\n\n\t\t// Check if the current product is saved to favorites\n\t\tconst productExists = doorFavorites.some(\n\t\t\t(product) =>\n\t\t\t\tproduct.sku === this.product.sku &&\n\t\t\t\tJSON.stringify(sortObjectKeys(product.customOptions || {})) ===\n\t\t\t\t\tJSON.stringify(sortObjectKeys(this.product.customOptions || {}))\n\t\t)\n\n\t\t// Update the state of the component\n\t\tthis.isFavorite = productExists\n\t\tthis.applyState(productExists)\n\t}\n\n\t/**\n\t * Handle the click event on the ProductSave component\n\t * @param {boolean} saved - If the current product is saved to favorites\n\t */\n\tapplyState(saved) {\n\t\tif (saved) {\n\t\t\tthis.saveIcon.src = '/dist/assets/icons/save-active.svg'\n\t\t\tthis.saveButton.dataset.ProductSaveSaved = 'true'\n\t\t\tthis.saveButton.setAttribute(\n\t\t\t\t'aria-label',\n\t\t\t\tthis.content.saved?.labelAccessibility\n\t\t\t)\n\t\t\tthis.saveButton.classList.add(\n\t\t\t\tthis.isButton\n\t\t\t\t\t? ProductSave.CLASSES.BUTTON_SAVED\n\t\t\t\t\t: ProductSave.CLASSES.BLANK_SAVED\n\t\t\t)\n\t\t\tthis.saveLabel.innerText = this.content.saved?.label\n\t\t} else {\n\t\t\tthis.saveIcon.src = '/dist/assets/icons/save.svg'\n\t\t\tthis.saveButton.dataset.ProductSaveSaved = 'false'\n\t\t\tthis.saveButton.setAttribute(\n\t\t\t\t'aria-label',\n\t\t\t\tthis.content.save?.labelAccessibility\n\t\t\t)\n\t\t\tthis.saveButton.classList.remove(\n\t\t\t\tthis.isButton\n\t\t\t\t\t? ProductSave.CLASSES.BUTTON_SAVED\n\t\t\t\t\t: ProductSave.CLASSES.BLANK_SAVED\n\t\t\t)\n\t\t\tthis.saveLabel.innerText = this.content.save?.label\n\t\t}\n\t}\n\n\t/**\n\t * Create notification container\n\t */\n\tcreateNotificationContainer() {\n\t\tthis.notificationContainer = document.querySelector(\n\t\t\tProductSave.SELECTORS.NOTIFICATION_CONTAINER\n\t\t)\n\n\t\tif (!this.notificationContainer) {\n\t\t\tconst notificationContainer = document.createElement('div')\n\t\t\tnotificationContainer.setAttribute(\n\t\t\t\tProductSave.DATA_ATTRIBUTES.NOTIFICATION.ATTRIBUTE,\n\t\t\t\tProductSave.DATA_ATTRIBUTES.NOTIFICATION.VALUE\n\t\t\t)\n\t\t\tnotificationContainer.classList.add(\n\t\t\t\tProductSave.CLASSES.NOTIFICATION_CONTAINER\n\t\t\t)\n\t\t\tdocument.body.appendChild(notificationContainer)\n\n\t\t\tthis.notificationContainer = document.querySelector(\n\t\t\t\tProductSave.SELECTORS.NOTIFICATION_CONTAINER\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Create notification\n\t * @param {string} text - The notification text\n\t * @param {boolean} error - If the notification is an error\n\t */\n\tcreateNotification(text, error = false) {\n\t\t// Create a new notification\n\t\tthis.notificationEl = document.createElement('div')\n\t\tthis.notificationEl.classList.add(ProductSave.CLASSES.NOTIFICATION_ITEM)\n\t\tthis.notification = new Notification(this.notificationEl, {\n\t\t\ttext: error\n\t\t\t\t? text\n\t\t\t\t: `${this.product.collection || 'This door'} ${text}`,\n\t\t\tcta: this.content.saveSuccess?.cta,\n\t\t\tclose: this.content.saveSuccess?.close,\n\t\t\tshowCta: this.showCta,\n\t\t\tid: this.product.sku\n\t\t})\n\n\t\t// Search for a previous notification that matches the current product\n\t\tconst previousNotification = document.querySelector(\n\t\t\t`[data-notification-id=\"${this.product.sku}\"]`\n\t\t)\n\n\t\t// If a previous notification for this product exists, replace it\n\t\tif (previousNotification) {\n\t\t\tpreviousNotification.replaceWith(this.notificationEl)\n\t\t} else {\n\t\t\t// Otherwise, append the new notification to the container\n\t\t\tthis.notificationContainer.appendChild(this.notificationEl)\n\t\t}\n\t}\n\n\t/**\n\t * Save the current product to favorites\n\t */\n\thandleSave() {\n\t\tconst favoriteObject = this.product\n\n\t\tconst doorFavorites = localStorage.getItem('doorFavorites')\n\t\t\t? JSON.parse(localStorage.getItem('doorFavorites'))\n\t\t\t: []\n\n\t\tconst productExists = doorFavorites.some(\n\t\t\t(product) =>\n\t\t\t\tproduct.sku === favoriteObject.sku &&\n\t\t\t\tJSON.stringify(sortObjectKeys(product.customOptions || {})) ===\n\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\tsortObjectKeys(favoriteObject.customOptions || {})\n\t\t\t\t\t)\n\t\t)\n\n\t\tif (!productExists) {\n\t\t\tdoorFavorites.push(favoriteObject)\n\t\t\tlocalStorage.setItem('doorFavorites', JSON.stringify(doorFavorites))\n\t\t\tthis.EventEmitterService.emit(ProductSave.EVENTS.SAVE, {\n\t\t\t\tproduct: this.product\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Remove the current product from favorites\n\t */\n\thandleRemove() {\n\t\tconst doorFavorites = localStorage.getItem('doorFavorites')\n\t\t\t? JSON.parse(localStorage.getItem('doorFavorites'))\n\t\t\t: []\n\n\t\tconst productExists = doorFavorites.some(\n\t\t\t(product) =>\n\t\t\t\tproduct.sku === this.product.sku &&\n\t\t\t\tJSON.stringify(sortObjectKeys(product.customOptions || {})) ===\n\t\t\t\t\tJSON.stringify(sortObjectKeys(this.product.customOptions || {}))\n\t\t)\n\n\t\tif (productExists) {\n\t\t\tconst filteredProducts = doorFavorites.filter(\n\t\t\t\t(product) =>\n\t\t\t\t\tproduct.sku !== this.product.sku ||\n\t\t\t\t\tJSON.stringify(sortObjectKeys(product.customOptions || {})) !==\n\t\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t\tsortObjectKeys(this.product.customOptions || {})\n\t\t\t\t\t\t)\n\t\t\t)\n\t\t\tlocalStorage.setItem('doorFavorites', JSON.stringify(filteredProducts))\n\t\t\tthis.EventEmitterService.emit(ProductSave.EVENTS.REMOVE, {\n\t\t\t\tproduct: this.product\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Handle clicking on the Save button\n\t * @param {event} event The click event\n\t */\n\thandleClick = (event) => {\n\t\tevent.preventDefault()\n\n\t\ttry {\n\t\t\tif (!this.isFavorite) {\n\t\t\t\tthis.handleSave()\n\t\t\t\tthis.isFavorite = true\n\t\t\t\tthis.applyState(true)\n\t\t\t\tthis.createNotification(\n\t\t\t\t\tthis.content.saveSuccess?.message || ProductSave.MESSAGES.SAVED\n\t\t\t\t)\n\t\t\t\tthis.trackSave(true)\n\t\t\t} else {\n\t\t\t\tthis.handleRemove()\n\t\t\t\tthis.isFavorite = false\n\t\t\t\tthis.applyState(false)\n\t\t\t\tthis.createNotification(\n\t\t\t\t\tthis.content.saveRemove?.message || ProductSave.MESSAGES.REMOVED\n\t\t\t\t)\n\t\t\t\tthis.trackSave(false)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.createNotification(\n\t\t\t\tthis.content.saveError?.message || ProductSave.MESSAGES.ERROR,\n\t\t\t\ttrue\n\t\t\t)\n\t\t\tconsole.error(error)\n\t\t}\n\t}\n\n\t/**\n\t * Track the save action\n\t * @param {Boolean} isSave - Indicator for if the product is being added or removed\n\t */\n\ttrackSave = (isSave) => {\n\t\tthis.analyticsService.trackInteraction('product_favorite', {\n\t\t\tproduct_name: this.product.collection,\n\t\t\tproduct_favorite_type: isSave ? 'add' : 'remove'\n\t\t})\n\t}\n\n\t/**\n\t * Render the component to the dom\n\t */\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import html from 'utilities/html'\nimport textTemplate, {\n\tTYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\n\n/**\n * ProductSave Template\n * @param {object} props\n * @param {string} props.label - The label for the button\n * @param {string} props.labelAccessibility - The accessibility label for the button\n * @param {boolean} props.isFavorite - Whether the product is a favorite\n * @param {boolean} props.isButton - Whether the component should be a button\n * @returns\n */\nconst template = ({ label, labelAccessibility, isFavorite, isButton }) =>\n\thtml`\n\t\t
    \n\t\t\t\n\t\t\t\t\n\t\t\t\t${isButton\n\t\t\t\t\t? textTemplate({\n\t\t\t\t\t\t\taddClassName: 'mod-product-save__label',\n\t\t\t\t\t\t\ttext: label || 'Save',\n\t\t\t\t\t\t\ttextElement: 'span',\n\t\t\t\t\t\t\ttextType: TEXT_TYPES.BODY_SM,\n\t\t\t\t\t\t\tlinesToDisplay: 1\n\t\t\t\t\t })\n\t\t\t\t\t: ''}\n\t\t\t\n\t\t
    \n\t`\n\nexport default template\n","import Tabs from './Tabs'\n\nexport default Tabs\n","import Services from 'services'\nimport playIcon, { POSITIONS } from 'modules/PlayIcon/PlayIcon.template'\nimport { fromTemplate } from 'utilities/renderer'\nimport Analytics from 'services/Analytics/Analytics'\nimport { debounce } from 'utilities/utilities'\n\n/**\n * Video Player component\n */\nexport default class VideoPlayer {\n\tstatic SELECTORS = {\n\t\tVIDEO: '[data-video-player=\"video-player\"]',\n\t\tPLAY_BUTTON: '[data-video-payer=\"play-button\"]'\n\t}\n\n\tstatic ATTRIBUTES = {\n\t\tPLAY_BUTTON_STATUS: 'data-is-paused',\n\t\tPLAY_BUTTON_LABEL: 'data-play-label',\n\t\tPAUSE_BUTTON_LABEL: 'data-pause-label',\n\t\tPLAY_BUTTON_POSITION: 'data-play-button-position',\n\t\tHIDE_PLAY_BUTTON_AFTER_PLAY: 'data-hide-button-after-play'\n\t}\n\n\tstatic EVENTS = {\n\t\tPLAY: 'videoPlay',\n\t\tPAUSE: 'videoPause',\n\t\tSTOP: 'videoStop',\n\t\tPLAY_VIDEO: 'playVideo', // Remote instruction to play video\n\t\tPAUSE_VIDEO: 'pauseVideo' // Remote instruction to pause video\n\t}\n\n\tstatic CLASSES = {\n\t\tHIDDEN: 'mod-player__play-button--hidden'\n\t}\n\n\tconstructor(element) {\n\t\tthis.element = element\n\t\tthis.services = Services.getInstance()\n\t\tthis.analyticsService = Analytics.getInstance() // ref to analytics service\n\t\tthis.videoProgressMarkers = new Map()\n\t\tthis.EventEmitterService = this.services.EventEmitterService\n\t\tthis.trackInteractionDebounce = debounce(this.trackInteraction, 200)\n\t\tthis.hasStarted = false\n\n\t\tthis.cacheDom()\n\t\tthis.initPlayButton()\n\t\tthis.attachEvents()\n\t}\n\n\t/**\n\t * Cache DOM elements\n\t */\n\tcacheDom() {\n\t\tthis.videoEl = this.element.querySelector(VideoPlayer.SELECTORS.VIDEO)\n\t\tthis.videoProgressMarkers.set(this.videoEl, [25, 50, 75, 100])\n\n\t\tthis.playButtonEl = this.element.querySelector(\n\t\t\tVideoPlayer.SELECTORS.PLAY_BUTTON\n\t\t)\n\n\t\tthis.hasControls = this.videoEl?.hasAttribute('controls')\n\n\t\tthis.videoElId = this.videoEl?.id || null\n\t}\n\n\t/**\n\t * Add event listeners\n\t */\n\tattachEvents() {\n\t\tthis.playButton?.addEventListener('click', this.togglePlay)\n\n\t\tthis.videoEl.addEventListener('ended', this.handleVideoEnd)\n\t\tthis.videoEl.addEventListener('play', this.trackInteractionDebounce)\n\t\tthis.videoEl.addEventListener('seeking', this.trackInteractionDebounce)\n\t\tthis.videoEl.addEventListener('timeupdate', this.trackInteractionDebounce)\n\t\tthis.videoEl.addEventListener('pause', this.trackInteractionDebounce)\n\t\tthis.videoEl.addEventListener('ended', this.trackInteraction)\n\n\t\tthis.EventEmitterService.on(\n\t\t\tVideoPlayer.EVENTS.PLAY_VIDEO,\n\t\t\tthis.remotePlay\n\t\t)\n\t\tthis.EventEmitterService.on(\n\t\t\tVideoPlayer.EVENTS.PAUSE_VIDEO,\n\t\t\tthis.remotePause\n\t\t)\n\t}\n\n\t/**\n\t * Remove event listeners\n\t */\n\tremoveEvents() {\n\t\tthis.playButton?.removeEventListener('click', this.togglePlay)\n\n\t\tthis.videoEl.removeEventListener('ended', this.handleVideoEnd)\n\n\t\tthis.videoEl.removeEventListener('play', this.trackInteractionDebounce)\n\t\tthis.videoEl.removeEventListener(\n\t\t\t'timeupdate',\n\t\t\tthis.trackInteractionDebounce\n\t\t)\n\t\tthis.videoEl.removeEventListener('pause', this.trackInteractionDebounce)\n\t\tthis.videoEl.removeEventListener('ended', this.trackInteraction)\n\n\t\tthis.EventEmitterService.off(\n\t\t\tVideoPlayer.EVENTS.PLAY_VIDEO,\n\t\t\tthis.remotePlay\n\t\t)\n\t\tthis.EventEmitterService.off(\n\t\t\tVideoPlayer.EVENTS.PAUSE_VIDEO,\n\t\t\tthis.remotePause\n\t\t)\n\t}\n\n\t/**\n\t * Destroy the modal instance and remove event listeners\n\t */\n\tdestroy() {\n\t\tthis.removeEvents()\n\t}\n\n\t/**\n\t * Track interaction\n\t */\n\ttrackInteraction = (event) => {\n\t\tconst { target } = event\n\t\tconst videoType = target.dataset?.type\n\n\t\tif (\n\t\t\t(videoType !== 'poster' && videoType !== 'modal') ||\n\t\t\tthis.filterAnalyticsEvent\n\t\t)\n\t\t\treturn\n\n\t\tswitch (event.type) {\n\t\t\tcase 'play':\n\t\t\t\tif (this.hasStarted) return\n\n\t\t\t\tthis.hasStarted = true\n\t\t\t\tthis.analyticsService.trackInteraction('video', {\n\t\t\t\t\tvideo_title: target.dataset?.title || undefined,\n\t\t\t\t\tvideo_status: 'start',\n\t\t\t\t\tvideo_view: 1,\n\t\t\t\t\tvideo_url: target.currentSrc,\n\t\t\t\t\tvideo_provider: 'widen'\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\tcase 'timeupdate': {\n\t\t\t\tconst progress = Math.floor(\n\t\t\t\t\t(target.currentTime / target.duration) * 100\n\t\t\t\t)\n\t\t\t\tlet progressMarkers = this.videoProgressMarkers.get(target)\n\n\t\t\t\tfor (let i = 0; i < progressMarkers.length; i++) {\n\t\t\t\t\tif (progress >= progressMarkers[i]) {\n\t\t\t\t\t\tthis.analyticsService.trackInteraction('video', {\n\t\t\t\t\t\t\tvideo_title: target.dataset?.title || undefined,\n\t\t\t\t\t\t\tvideo_status: 'progress',\n\t\t\t\t\t\t\tvideo_percent: progressMarkers[i],\n\t\t\t\t\t\t\tvideo_url: target.currentSrc,\n\t\t\t\t\t\t\tvideo_provider: 'widen'\n\t\t\t\t\t\t})\n\t\t\t\t\t\tprogressMarkers = progressMarkers.slice(i + 1)\n\t\t\t\t\t\tthis.videoProgressMarkers.set(target, progressMarkers)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'pause': {\n\t\t\t\t/**\n\t\t\t\t * This is a workaround to stop the video player firing the pause event\n\t\t\t\t * along with the ended event when a file finishes playing.\n\t\t\t\t */\n\t\t\t\tconst eventThreshold = Math.floor(target.duration) - 2 // Stop registering events 2 seconds before end of video\n\t\t\t\tif (target.currentTime >= eventThreshold) return\n\n\t\t\t\tthis.analyticsService.trackInteraction('video', {\n\t\t\t\t\tvideo_title: target.dataset?.title || undefined,\n\t\t\t\t\tvideo_status: 'pause',\n\t\t\t\t\tvideo_url: target.currentSrc,\n\t\t\t\t\tvideo_provider: 'widen'\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'ended':\n\t\t\t\tthis.hasStarted = false\n\n\t\t\t\tthis.analyticsService.trackInteraction('video', {\n\t\t\t\t\tvideo_title: target.dataset?.title || undefined,\n\t\t\t\t\tvideo_status: 'complete',\n\t\t\t\t\tvideo_percent: 100,\n\t\t\t\t\tvideo_url: target.currentSrc,\n\t\t\t\t\tvideo_provider: 'widen'\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\t/**\n\t * Initialize and render the play button if there is an element to render it to\n\t */\n\tinitPlayButton() {\n\t\tconst hasPlayButton = !!this.playButton\n\n\t\tif (this.playButtonEl) {\n\t\t\tconst playButtonPosition =\n\t\t\t\tthis.playButtonEl.getAttribute(\n\t\t\t\t\tVideoPlayer.ATTRIBUTES.PLAY_BUTTON_POSITION\n\t\t\t\t) || POSITIONS.BOTTOM_RIGHT\n\n\t\t\tif (!hasPlayButton) {\n\t\t\t\tthis.playButton = fromTemplate(\n\t\t\t\t\tplayIcon({\n\t\t\t\t\t\tisButton: true,\n\t\t\t\t\t\tisInline: true,\n\t\t\t\t\t\tposition: playButtonPosition\n\t\t\t\t\t})\n\t\t\t\t)\n\n\t\t\t\tthis.playButtonEl.appendChild(this.playButton)\n\t\t\t}\n\n\t\t\tthis.playButton.setAttribute(\n\t\t\t\tVideoPlayer.ATTRIBUTES.PLAY_BUTTON_STATUS,\n\t\t\t\t!this.videoEl.autoplay\n\t\t\t)\n\n\t\t\tthis.playButton.setAttribute(\n\t\t\t\t'aria-label',\n\t\t\t\tthis.element.getAttribute(\n\t\t\t\t\tthis.videoEl.autoplay\n\t\t\t\t\t\t? VideoPlayer.ATTRIBUTES.PAUSE_BUTTON_LABEL\n\t\t\t\t\t\t: VideoPlayer.ATTRIBUTES.PLAY_BUTTON_LABEL\n\t\t\t\t)\n\t\t\t)\n\n\t\t\tif (this.hasControls) {\n\t\t\t\t// hide the controls when the custom play button is enabled\n\t\t\t\tthis.videoEl.removeAttribute('controls')\n\t\t\t}\n\n\t\t\tthis.playButtonEl.classList.remove(VideoPlayer.CLASSES.HIDDEN)\n\t\t}\n\t}\n\n\t/**\n\t * Toggle Video\n\t */\n\ttogglePlay = () => {\n\t\tif (this.videoEl.paused) {\n\t\t\tthis.play()\n\t\t} else {\n\t\t\tthis.pause()\n\t\t}\n\t}\n\n\t/**\n\t * Play Video and update button\n\t * @param {object} event - Event object\n\t * @param {boolean} event.forcePause - Force the video to play without checking if it is already playing\n\t */\n\tplay = ({ forcePlay = false, triggerAnalyticsEvent = false } = {}) => {\n\t\tif (this.videoEl?.paused || forcePlay) {\n\t\t\tthis.videoEl.play()\n\t\t\tthis.EventEmitterService.emit(VideoPlayer.EVENTS.PLAY, {\n\t\t\t\tvideoId: this.videoElId\n\t\t\t})\n\n\t\t\tif (triggerAnalyticsEvent) {\n\t\t\t\tthis.videoEl.dispatchEvent(new Event('play'))\n\t\t\t}\n\n\t\t\tif (this.playButton) {\n\t\t\t\tthis.playButton.setAttribute(\n\t\t\t\t\tVideoPlayer.ATTRIBUTES.PLAY_BUTTON_STATUS,\n\t\t\t\t\tfalse\n\t\t\t\t)\n\t\t\t\tthis.playButton.setAttribute(\n\t\t\t\t\t'aria-label',\n\t\t\t\t\tthis.element.getAttribute(\n\t\t\t\t\t\tVideoPlayer.ATTRIBUTES.PAUSE_BUTTON_LABEL\n\t\t\t\t\t)\n\t\t\t\t)\n\n\t\t\t\tif (\n\t\t\t\t\tthis.playButtonEl.getAttribute(\n\t\t\t\t\t\tVideoPlayer.ATTRIBUTES.HIDE_PLAY_BUTTON_AFTER_PLAY\n\t\t\t\t\t) === 'true'\n\t\t\t\t) {\n\t\t\t\t\tthis.playButtonEl.classList.add(VideoPlayer.CLASSES.HIDDEN)\n\t\t\t\t}\n\n\t\t\t\tif (this.hasControls && !this.videoEl.getAttribute('controls')) {\n\t\t\t\t\t// reenable the controls when the custom play button is enabled and controls has been set\n\t\t\t\t\tthis.videoEl.setAttribute('controls', '')\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Stop Video\n\t */\n\tstop = ({ triggerAnalyticsEvent = false }) => {\n\t\tthis.hasStarted = false\n\t\tthis.videoEl.pause()\n\t\tthis.EventEmitterService.emit(VideoPlayer.EVENTS.STOP, {\n\t\t\tvideoId: this.videoElId\n\t\t})\n\n\t\tif (triggerAnalyticsEvent) {\n\t\t\tthis.videoEl.dispatchEvent(new Event('pause'))\n\t\t\t// reset the video to the beginning after a pause event\n\t\t\t// setting a timeout give the debounce function time to clear so that\n\t\t\t// timeupdate event is not fired\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.videoEl.currentTime = 0\n\t\t\t}, 500)\n\t\t} else {\n\t\t\tthis.videoEl.currentTime = 0\n\t\t}\n\t}\n\n\t/**\n\t * Pause Video and update play button\n\t * @param {object} event - Event object\n\t * @param {boolean} event.forcePause - Force the video to pause without checking if it is already paused\n\t */\n\tpause = ({ forcePause = false } = {}) => {\n\t\tif (!this.videoEl?.paused || forcePause) {\n\t\t\tthis.videoEl.pause()\n\t\t\tthis.EventEmitterService.emit(VideoPlayer.EVENTS.PAUSE, {\n\t\t\t\tvideoId: this.videoElId\n\t\t\t})\n\n\t\t\tif (this.playButton) {\n\t\t\t\tthis.playButton.setAttribute(\n\t\t\t\t\tVideoPlayer.ATTRIBUTES.PLAY_BUTTON_STATUS,\n\t\t\t\t\ttrue\n\t\t\t\t)\n\n\t\t\t\tthis.playButton.setAttribute(\n\t\t\t\t\t'aria-label',\n\t\t\t\t\tthis.element.getAttribute(\n\t\t\t\t\t\tVideoPlayer.ATTRIBUTES.PLAY_BUTTON_LABEL\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Process a Remote play event\n\t * @param {object} event - Event object\n\t * @param {string} event.videoId - Video ID\n\t */\n\tremotePlay = (event) => {\n\t\tconst { videoId } = event\n\n\t\tif (videoId === this.videoElId) {\n\t\t\tthis.play({ forcePlay: true })\n\t\t}\n\t}\n\n\t/**\n\t * Process a Remote pause event\n\t * @param {object} event - Event object\n\t * @param {string} event.videoId - Video ID\n\t */\n\tremotePause = (event) => {\n\t\tconst { videoId } = event\n\n\t\tif (videoId === this.videoElId) {\n\t\t\tthis.pause({ forcePause: true })\n\t\t}\n\t}\n\n\t/**\n\t * When the video ends, emit a STOP event, reset the poster image and show play button\n\t */\n\thandleVideoEnd = () => {\n\t\tthis.EventEmitterService.emit(VideoPlayer.EVENTS.STOP, {\n\t\t\tvideoId: this.videoElId\n\t\t})\n\t\tthis.initPlayButton()\n\t\tthis.videoEl.load()\n\t}\n}\n","import classNames from 'utilities/classnames'\nimport { POSITIONS as PLAY_BUTTON_POSITIONS } from 'modules/PlayIcon/PlayIcon.template'\n\nexport { PLAY_BUTTON_POSITIONS }\n\n/**\n * Render Video Player component template\n * @param {Object} args\n * @param {Array} args.dataAttributes Additional data attributes\n * @param {Object} args.a11y\n * @param {String} args.a11y.playLabel Play button label\n * @param {String} args.a11y.pauseLabel Pause button label\n * @param {String} addClassName Additional class name\n * @param {Boolean} autoplay enable autoplay\n * @param {String} buttonClassName Button class name\n * @param {Boolean} hideControls hide controls\n * @param {Boolean} hidePlayButtonAfterPlay hide play button after video is played the first time\n * @param {String} id Component ID\n * @param {Boolean} muted mute video\n * @param {String} playButtonPosition play button position\n * @param {Boolean} playsInline play video inline\n * @param {String} posterSrc Video poster image\n * @param {Boolean} showPlayButton show play/pause button\n * @param {String} videoSrc Video source\n */\nconst VideoPlayerTemplate = ({\n\ta11y: { playLabel = 'Play', pauseLabel = 'Pause' } = {},\n\taddClassName = '',\n\tautoplay = false,\n\tbuttonClassName = '',\n\thideControls = false,\n\thidePlayButtonAfterPlay = false,\n\tid = '',\n\tmuted = false,\n\tplayButtonPosition = PLAY_BUTTON_POSITIONS.BOTTOM_RIGHT,\n\tplaysInline = false,\n\tposterSrc = '',\n\tshowPlayButton = false,\n\tvideoSrc,\n\tdataAttributes,\n\tvideoCaptions\n}) => /* HTML */ `\n\t\n\t\t${showPlayButton\n\t\t\t? `
    `\n\t\t\t: ''}\n\t\t\n\t\t\t${videoCaptions && videoCaptions.src\n\t\t\t\t? `\n \n `\n\t\t\t\t: ''}\n\t\t\tYour browser does not support the video tag.\n\t\t\n\t\n`\n\nexport default VideoPlayerTemplate\n"],"names":["_ref","addClassName","altText","defaultAspectRatio","defaultSrc","loading","mobileAspectRatio","mobileSrc","classNames","ColorPicker","static","WHEEL","INPUT_HEX","INPUT_RGB","constructor","element","height","onChange","noop","initialColor","theme","arguments","length","undefined","this","services","Services","getInstance","resizeService","ResizeService","init","template","html","inputTemplate","accessibilityLabel","dataAttributes","id","label","name","getNode","cacheDom","createWheel","attachEvents","render","setPickerWidth","wheelEl","querySelector","SELECTORS","inputHex","inputsRgb","querySelectorAll","addEventListener","onHexChange","forEach","input","onRgbChange","wheel","on","onWheelChange","addCallback","detachEvents","removeEventListener","off","removeCallback","destroy","iro","display","width","boxHeight","color","layout","component","ui","Box","Slider","options","sliderType","sliderSize","setHexInput","hex","value","setRgbInputs","rgb","dataset","offsetWidth","resize","hexString","event","set","currentTarget","e","colorType","r","g","b","toString","insert","POSITIONS","BOTTOM_LEFT","BOTTOM_RIGHT","CENTER","TOP_LEFT","TOP_RIGHT","SIZES","LARGE","SMALL","a11y","buttonLabel","playLabel","pauseLabel","isButton","isInline","position","size","isBlackAndWhite","tag","join","Icon","icon","ProductInfo","collection","glassAvailable","benefits","cta","constructionEyebrow","featuredInEyebrow","comingSoonEyebrow","titleTemplate","text","headingElement","headingType","TITLE_TYPES","H4","ally","textTemplate","textElement","textType","TEXT_TYPES","BODY_XSM","Array","isArray","map","benefit","linkTemplate","href","url","target","linkStyle","linkButtonStyle","linkTextStyle","linkSize","showAsButtonLink","startIcon","analytics","cta_text","cta_title","_ref2","alignment","fullWidth","moduleSpacing","tabs","displaySelect","find","tab","isActive","title","index","displayTabs","disabled","Tab","displayContent","content","getCustomColor","option","customColorPrefix","isCustomColor","includes","split","activeOptionImageTemplate","selectedOption","displayDarkImage","imageDark","imageTemplate","image","categoryTemplate","category","optionDetailsTemplate","tooltip","rangeLabel","rangeMax","rangeMin","isToggleButton","isColor","type","customColor","CTA_LG","iconTemplate","BODY_SM","CALLOUT","rangeValue","CAPTION","from","_","i","rangeTemplate","range","viewMoreButton","_ref6","isLargeBreakpoint","optionsWrapperId","_ref9","groupValue","groupType","maxOptions","hasOptions","tile","tileText","helperLabel","labelAccessibility","_ref5","categoryValue","optionId","isDisabled","isSelected","customColorTemplate","tileOptionTemplate","_ref4","tileTextOptionTemplate","_ref3","textOptionTemplate","categoryOptionTemplate","note","_ref8","noteTemplate","_ref7","viewMoreTemplate","defaultOpen","children","closeButtonAriaLabel","closeButtonClass","fullScreen","hasHeader","modalClass","transition","headerTitle","modalContent","description","optionTools","isMediumLarge","BODY_MEDIUM","buttonTemplate","buttonSize","buttonStyle","cancel","select","desktopButtons","mobileButtons","ProductOptionCustomColor","BUTTON_CANCEL","BUTTON_SELECT","COLOR_PICKER_BUTTON","COLOR_PICKER","MODAL","onSelect","onCancel","EventEmitterService","mediaQuery","BreakpointListener","queryMatch","pendingColor","modalTemplate","cancelAccessibility","MEDIUM_LARGE","colorPickerButtonEl","colorPickerEl","modalEl","buttonSelect","buttonCancel","Modal","EVENTS","CLOSE_MODAL","onModalClose","onSelectHandler","onCancelHandler","addListener","onBreakpointChange","removeListener","setColor","openColorPicker","modal","requestAnimationFrame","open","colorPicker","modalId","close","breakpoint","hasChanged","ProductOptionCategory","INPUT","OPTIONS","OPTION","OPTION_CUSTOM_COLOR_INPUT","OPTION_CUSTOM_COLOR_LABEL","CUSTOM_COLOR","VIEW_MORE","VIEW_MORE_LABEL","OPTION_HIDE","VIEW_MORE_EXPANDED","MAX_OPTIONS","isExpanded","createCustomColor","checkViewMore","optionsEl","optionEls","optionCustomColorInput","optionCustomColorLabel","customColorEl","viewMoreButtonEls","viewMoreLabelEls","viewMoreButtonEl","toggleViewMore","onCustomColorInputSelect","colorPrefix","customColorOption","indexOf","productOptionCustomColor","helperText","onCustomColorSelect","key","stopImmediatePropagation","replace","checked","dispatchEvent","Event","selectedOptionIdx","findIndex","expandViewMore","collapseViewMore","optionEl","classList","remove","CLASSES","setAttribute","removeAttribute","add","seeLessAccessibility","viewMoreLabelEl","innerHTML","seeLess","seeAllAccessibility","seeAll","ProductOptionGroup","TABS","DRAWER","TOGGLE","TOGGLE_CONTENT","DETAILS","SUBMIT_BUTTON","CANCEL_BUTTON","MORE_DETAILS","TOOLTIP_TOGGLE_BUTTON","TOOLTIP_DRAWER_INFO","ACTIVE_GROUP","DISABLED_GROUP","THEME_LIGHT","THEME_DARK","onProductSelect","onProductSubmit","onProductCancel","categories","tooltipsToggleButtons","isDrawerOpen","eventEmitterService","analyticsService","Analytics","hasSingleOption","reduce","acc","concat","tabsTemplate","disableTabsScrollIntoView","categoryTabsTemplate","moreDetails","detailsId","showAsTextLink","moreDetailsTemplate","getSelectedOption","createCategories","createToggleButton","createDrawerTooltips","createTabs","setTheme","setDisabledDrawer","tabsEl","optionInputs","optionDrawer","optionToggleButton","optionToggleButtonContent","submitButton","cancelButton","onProductSelectHandler","onToggleFocus","onToggleKeydown","toggleDrawer","onSubmit","onMoreDetails","closeDrawer","group","optionValue","preventDefault","emit","Tabs","SWITCH_TAB","tabsId","tabId","setTimeout","tabNav","document","getElementById","scrollIntoView","behavior","toggleButton","optionInfoTemplate","toggleButtonTemplate","createTooltipToggleButtons","categoryEl","el","createElement","appendChild","tooltipToggleButtonsEls","tooltipEl","tooltipContent","createTooltip","push","tooltipsDrawers","tooltipDrawerEls","tippy","allowHTML","animateFill","interactive","placement","trigger","flipOnUpdate","onTrigger","instance","onUntrigger","getSelectedCategoryIndex","getAllOptions","THEMES","LIGHT","DARK","setActiveTab","activeCatIdx","activeTabId","Object","keys","tabIds","switchTab","setSelectedOptions","optionsApplied","prevSelectedOption","hasDisabledChanged","allOptions","hasOptionChanged","customColorIdx","val","setOptionDetails","optionDetails","updatedOptionDetails","optionDetail","replaceWith","cloneNode","inline","block","eyCode","openDrawer","actionOnClickOutside","limitKeyboardAccessibility","trackDrawer","focus","clearListener","clearKeyHandler","action","trackInteraction","state","toLowerCase","ProductOptionFilters","filters","onFilterSelect","filterOptions","filter","checkboxItemTemplate","onFilterSelectHandler","filterId","ProductOptions","PRODUCT_OPTION_FILTERS","PRODUCT_OPTION_WRAPPER","PRODUCT_OPTION_MESSAGE","PRODUCT_OPTION_MESSAGE_ICON","PRODUCT_OPTION_MESSAGE_TEXT","FILTER_OPTION","MESSAGE_ACTIVE","productModel","productOptions","createProductOptions","createOptionFilters","productOptionFilterItemsEl","productOptionWrapperEl","productOptionMessageTextEl","productOptionMessageEl","onModelUpdate","context","getState","productFilterOptions","pendingOptions","setProductOptionMessage","hasModifiedSelectedOption","optionMessages","message","modifiedOption","setFilter","autoApply","getCurrentBreakpoint","setOption","applyOptions","cancelOptions","data","optionGroup","scripts","ProductShare","shareTooltip","shareCopy","sharePinterest","successMessage","product","share","pinterest","copy","copySuccess","loadPinterestScript","copyHandler","isPinterestLoaded","window","PinUtils","onPinterestClick","navigator","clipboard","writeText","then","hasAttribute","showSuccessMessage","trackShare","showShareCopy","urlPath","onComplete","headElm","script","src","defer","onload","onerror","loadDependency","onPinterestLoaded","isLoaded","pinOne","media","product_name","product_share_type","ProductTools","PRODUCT_SAVE","PRODUCT_SHARE","createProductSave","createProductShare","productSaveEl","productShareEl","productSave","ProductSave","showCta","productShare","ProductMediaThumbnails","THUMBAIL_BUTTON","THUMBNAIL_ACTIVE","mediaGallery","mediaItem","isSlab","playIconTemplate","PLAY_BUTTON_POSITIONS","PLAY_BUTTON_SIZES","poster","alt","thumbnailButtons","button","setActiveThumbnail","contains","ProductMediaImage","ProductMediaVideo","VIDEO_PLAYER","videoPlayer","videoPlayerTemplate","hidePlayButtonAfterPlay","playButtonPosition","playsInline","posterSrc","showPlayButton","videoSrc","videoPlayerEl","VideoPlayer","visualizer","arModalMessage","ProductMediaVisualizer","HIDE","VISUALIZER_BUTTON","initialData","getInitialData","hasDependency","focusableElements","createPlayer","setupButtonClone","isMobileDevice","userAgent","opera","test","checkForButton","arButton","newButton","setupModal","parentNode","insertBefore","style","addEventListeners","viewDoorButton","click","onVisualizerButtonClick","masonite","pip","JSON","parse","console","error","body","onModalOpen","attachVisualizerButtonEvents","visualizerButton","showARModal","OPEN_MODAL","detachVisualizerButtonEvents","Promise","resolve","reject","library","Error","isInterior","threekitPlayer","authToken","customId","initialConfiguration","getConfiguration","cache","maxAge","cacheMaxAge","scope","cacheScope","showConfigurator","showAR","showShare","classnames","mobile","popup","ar","fullscreen","help","showLoadingThumbnail","showLoadingProgress","publishStage","async","player","when","configurator","getConfigurator","stageConfigurator","getStageConfigurator","getSnapshot","convertHexToRgbScale","hexValue","parseInt","substring","sku","disabledOptions","getOptions","optionParams","getOptionParams","configuration","Door","isDisabledOption","some","Color","PaintColorPicker","log","setConfiguration","setScene","sceneId","Backplate","savedScene","snapshotAsync","mimeType","setVisualizerSnapshot","hideVisualizer","getFocusableElements","showVisualizer","ProductMediaGallery","THUMBNAILS","MEDIA","MEDIA_VISUALIZER","MEDIA_WRAPPER","TOOLS","SLOT_1","SLOT_2","createProductTools","createThumbnails","createMediaPlayer","setContentOrder","thumbnailsEl","mediaEl","mediaVisualizerEl","productToolsEl","productMediaWrapperEl","productMediaSlot1El","productMediaSlot2El","productMediaThumbnails","onThumbnailSelect","isVisualizerEnabled","empty","mediaVisualizer","isVisualizer","createMediaVisualizer","createMediaVideo","createMediaImage","mediaImage","mediaVideo","backplateScene","customOptions","tools","visualizerSnapshot","productTools","location","MEDIUM","trackThumbnailClick","image_title","_state","_event","contentMap","doorFeatures","features","additionalFeaturesLabel","additionalFeatures","BODY_LG","TEXT_THEMES","feature","displayFeatures","BODY_MD_INLINE","BODY_MD","displayAdditionalFeatures","productSpecifications","specs","measurements","measurementText","measurementLink","measurementLinkText","widthLabel","heightLabel","widths","heights","available","EYEBROW","technicalDocuments","documents","showAsDownloadLink","file_extension","file_name","click_url","displayDocumentsLinks","ProductDetails","TABS_CMP","DOOR_FEATURES","PRODUCT_SPECIFICATIONS","MEASUREMENTS","TECHNICAL_DOCUMENTS","TOOLTIP","details","productDetails","entries","contentFunc","generateProductDetails","createTooltips","doorFeaturesEl","productSpecificationsEl","measurementsEl","technicalDocumentsEl","productDetailsCategories","tabsCmpEl","ProductRelatedContent","ProductInformationModel","initialState","queryFilters","queryOptions","listeners","parseInitialData","machine","createMachine","initial","states","idle","UPDATE_FILTERS","actions","UPDATE_OPTIONS","APPLY_OPTIONS","CANCEL_OPTIONS","SET_VISUALIZER_SNAPSHOT","updateFilters","assign","updatedFilters","updateOptions","updatedOptions","meta","snapshot","machineService","interpret","start","subscribe","onUpdate","listener","l","filterOption","idx","isCustomColorOption","isCustomColorQuery","parsedOptions","parseOptions","controlledOptions","selectedOptionValues","values","parseSelectedOptions","controls","control","hasDisabledSelectedOption","updatedOptionGroup","hasOwn","mustHaveOne","hasMustHave","mustHave","isDefaultSelected","j","send","o","c","params","selectedOptions","getSelectedOptions","ProductInformationRouter","History","setOptions","origin","pathname","searchParams","URLSearchParams","search","has","delete","replaceState","get","hasParam","isValidOption","ProductInformation","PRODUCT_INFO","PRODUCT_OPTIONS","PRODUCT_MEDIA_GALLERY","PRODUCT_DETAILS","PRODUCT_RELATED_CONTENT","PRODUCT_CONFIG_SLOT_1","PRODUCT_CONFIG_SLOT_2","PRODUCT_CONFIG_SLOT_3","PRODUCT_CONFIG_SLOT_4","createProductInformationRouter","createProductInformationModel","createProductInfo","createProductMediaGallery","creatProductDetails","createProductRelatedContent","productInfoEl","productOptionsEl","productMediaGalleryEl","productDetailsEl","productRelatedContentEl","productConfigSlot1El","productConfigSlot2El","productConfigSlot3El","productConfigSlot4El","productInformationModel","renoveListener","productInformationRouter","productInfo","wtbCta","productMediaGallery","productRelatedContent","relatedArticles","trackOptions","payload","product_info_selection","Notification","NOTIFICATION_BUTTON","NOTIFICATION_CONTAINER","NOTIFICATION","Link","args","showAsListLink","initializeNotificationTimeout","closeButton","handleClose","notificationTimeout","clearTimeout","TIMERS","parentElement","SAVE_BUTTON","SAVE_ICON","STATUS","BLANK_SAVED","BUTTON_SAVED","ACTIVE","NOTIFICATION_ITEM","SAVED","REMOVED","ERROR","SAVE","REMOVE","DISMISS_NOTIFICATION","ATTRIBUTE","VALUE","isFavorite","linesToDisplay","saved","save","initializeSavedState","createNotificationContainer","saveButton","saveIcon","saveLabel","lastElementChild","handleClick","notification","productExists","localStorage","getItem","stringify","sortObjectKeys","applyState","ProductSaveSaved","innerText","notificationContainer","DATA_ATTRIBUTES","createNotification","notificationEl","saveSuccess","previousNotification","handleSave","favoriteObject","doorFavorites","setItem","handleRemove","filteredProducts","saveRemove","MESSAGES","trackSave","saveError","isSave","product_favorite_type","VIDEO","PLAY_BUTTON","PLAY_BUTTON_STATUS","PLAY_BUTTON_LABEL","PAUSE_BUTTON_LABEL","PLAY_BUTTON_POSITION","HIDE_PLAY_BUTTON_AFTER_PLAY","PLAY","PAUSE","STOP","PLAY_VIDEO","PAUSE_VIDEO","HIDDEN","videoProgressMarkers","Map","trackInteractionDebounce","debounce","hasStarted","initPlayButton","videoEl","playButtonEl","hasControls","videoElId","playButton","togglePlay","handleVideoEnd","remotePlay","remotePause","removeEvents","videoType","filterAnalyticsEvent","video_title","video_status","video_view","video_url","currentSrc","video_provider","progress","Math","floor","currentTime","duration","progressMarkers","video_percent","slice","eventThreshold","hasPlayButton","getAttribute","ATTRIBUTES","fromTemplate","playIcon","autoplay","paused","play","pause","_this","forcePlay","triggerAnalyticsEvent","videoId","stop","_this2","forcePause","load","buttonClassName","hideControls","muted","videoCaptions","srclang"],"sourceRoot":""}