{"version":3,"file":"default/js/postcodeCheck.js","mappings":"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","sources":["webpack://vodafoneziggo/webpack/runtime/chunk loaded","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/VZSpinner.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/form/form.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/modal.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/idType.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/form/masks/caps.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/form/masks/postcode.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/form/masks/iban.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/form/masks/date.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/form/mask.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/preventCharacters.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/readonly.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/index.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/documentNumber.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/mask.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/password.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/regex.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/decorators/valid.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/form/VZInputField.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/postcode_check/postcodeCheckHelpers.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/postcode_check/AddressCheck.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/components/postcode_check/VZPostcodeCheck.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/util/cookies.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/util/constants.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/util/urlUtils.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/util/util.js","webpack://vodafoneziggo/./cartridges/app_vodafone_ziggo/cartridge/client/default/js/util/validation.js","webpack://vodafoneziggo/webpack/bootstrap","webpack://vodafoneziggo/webpack/runtime/amd options","webpack://vodafoneziggo/webpack/runtime/compat get default export","webpack://vodafoneziggo/webpack/runtime/define property getters","webpack://vodafoneziggo/webpack/runtime/global","webpack://vodafoneziggo/webpack/runtime/hasOwnProperty shorthand","webpack://vodafoneziggo/webpack/runtime/runtimeId","webpack://vodafoneziggo/webpack/runtime/jsonp chunk loading","webpack://vodafoneziggo/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","'use strict';\n\nimport Lottie from 'lottie-web/build/player/lottie_light.min';\nconst redSpinnerData = require('./spinners/spinner_animation_min.json');\n\n/**\n * @class VZSpinner\n * @param {HTMLElement} [parent] - Parent element for the spinner to be added in.\n * @description\n * Creates a VZ-Spinner component\n *\n * @example\n * \n *
\n *
\n *
\n *
\n */\nclass VZSpinner extends HTMLElement {\n constructor(parentEl) {\n super();\n\n this.showing = false;\n this.stop = this.stop.bind(this);\n this.veil = null;\n\n const parentElement = parentEl || document.body;\n const location = parentElement.tagName === 'IMG' ? parentElement.parentElement : parentElement;\n location.appendChild(this);\n\n this.lottie = Lottie.loadAnimation({\n container: this.veil.querySelector('.spinner'),\n renderer: 'svg',\n loop: true,\n autoplay: false,\n animationData: redSpinnerData\n });\n }\n\n /**\n * @public\n * @param {string} [msg] - A message to be shown below the spinner.\n * @returns {Promise} promise\n */\n start(msg) {\n return new Promise((resolve) => {\n if (this.showing) resolve();\n const parentPosition = window.getComputedStyle(this.parentElement).getPropertyValue('position');\n\n if (parentPosition === 'static') {\n if (this.parentElement.tagName !== 'BODY') {\n this.parentElement.style.position = 'relative';\n }\n this.parentElement.classList.add('veiled');\n }\n\n if (msg) {\n this.veil.insertAdjacentHTML('beforeend', `
${msg}
`);\n }\n\n this.showing = true;\n setTimeout(() => {\n if (this.showing) {\n this.lottie?.play();\n this.veil.classList.add('show');\n }\n resolve();\n }, 500);\n });\n }\n\n /**\n * @public\n * @returns {Promise} promise\n */\n stop() {\n return new Promise((resolve) => {\n if (!this.showing) resolve();\n if (this.parentElement.classList.contains('veiled')) {\n this.parentElement.style.position = '';\n this.parentElement.classList.remove('veiled');\n }\n\n const content = this.veil.querySelector('.content');\n if (content) content.remove();\n this.veil.classList.remove('show');\n this.showing = false;\n this.lottie?.stop();\n resolve();\n });\n }\n\n connectedCallback() {\n this.innerHTML = `\n
\n
\n
\n
\n `;\n\n this.veil = this.querySelector('.veil');\n this.veil.addEventListener('click', (evt) => evt.stopPropagation());\n }\n}\n\nwindow.VZSpinner = window.customElements.get('vz-spinner') || VZSpinner;\nexport default window.VZSpinner;\n\nif (!window.customElements.get('vz-spinner')) {\n window.customElements.define('vz-spinner', VZSpinner);\n}\n","'use strict';\n\n/**\n * @public prepareFormValues\n * @param {HTMLElement} app - The app component\n *\n * @description\n * Sets the value of an input field as a property. By doing this, a previous\n * selection can be preselected when navigating back in the product configurator.\n */\nexport function prepareFormValues(app) {\n const valueTypes = ['text', 'hidden', 'range', 'email', 'number', 'tel', 'password'];\n [...app.querySelectorAll('input')].forEach((field) => {\n if (valueTypes.indexOf(field.type) !== -1) {\n field.setAttribute('value', field.value);\n } else if (field.type === 'radio' || field.type === 'checkbox') {\n if (field.checked) {\n field.setAttribute('checked', true);\n } else {\n field.removeAttribute('checked');\n }\n }\n });\n}\n\n/**\n * @public getFieldValidationMessage\n * @param {HTMLInputElement | HTMLSelectElement} field - Invalid field element\n * @returns {string | false} - Error message for invalid field\n */\nexport function getFieldValidationMessage(field) {\n // Valid\n if (field.validity.valid) return false;\n\n // Required\n if (field.required && field.value.length === 0) return field.getAttribute('data-missing-error');\n\n // Checked\n if (!field.checked && (field.matches('[type=\"checkbox\"]') || field.matches('[type=\"radio\"]'))) return field.getAttribute('data-missing-error');\n\n // Regex\n if (field.pattern && !new RegExp(field.pattern).test(field.value)) return field.getAttribute('data-pattern-error');\n\n // Dates\n if (field.dataset.mask === 'date' && field.dataset.invalid === 'true') return field.getAttribute('data-invalid-error');\n if (field.dataset.mask === 'date' && field.dataset.invalidMin === 'true') return field.getAttribute('data-mindate-error');\n if (field.dataset.mask === 'date' && field.dataset.invalidMax === 'true') return field.getAttribute('data-maxdate-error');\n if (field.dataset.mask === 'addition' && field.dataset.multipleAdditions === 'true') return field.getAttribute('data-missing-error');\n\n // No valid error messages\n return false;\n}\n","import { CONST } from 'Util/util';\nimport { validateForm, validateField } from 'app_vodafone_ziggo/util/validation';\nimport Modal from 'bootstrap/js/src/modal';\nimport VZSpinner from 'Components/VZSpinner';\nimport { appendCsrfToUrl } from 'app_vodafone_ziggo/util/urlUtils';\n\nwindow.bs = window.bs || {};\nwindow.bs.Modal = Modal;\n\nconst spinner = document.querySelector('vz-spinner') || new VZSpinner();\n\nconst selectors = {\n errorModal: 'error-modal',\n activeModal: '.modal.show',\n modalStepContainer: '.js-modal-step-container',\n modalStep: '.js-modal-step',\n modalStepInputs: '.form-control, .custom-control'\n};\n\n/**\n * @function showErrorModal\n * @param {string|null} title - The title of the modal\n * @param {string|null} body - The error message within the modal\n * @param {string|null} cta - The cta text within the modal\n */\nfunction showErrorModal(title, body, cta) {\n const errorModalHtml = `\n
\n
\n
\n
\n

${title}

\n \n
\n\n
\n
\n
${body}
\n
\n
\n\n \n
\n \n
\n
\n
\n
`;\n\n const existingModal = document.getElementById(selectors.errorModal);\n\n if (existingModal) {\n window.bs.Modal.getInstance(existingModal).show();\n } else {\n document.body.insertAdjacentHTML('beforeend', errorModalHtml);\n const modal = new window.bs.Modal(document.getElementById(selectors.errorModal));\n modal.show();\n window.addEventListener(CONST.events.popstate, () => {\n modal.hide();\n });\n }\n}\n\n/**\n * @public resetModalState\n * @param {HTMLElement} modal - A DOM modal element\n *\n * In case of a modal that has multiple steps\n * Loop over the steps to remove the active class\n * and add the active class to the first step\n */\nfunction resetModalState(modal) {\n [...modal.querySelectorAll(selectors.modalStep)].forEach((step, index) => {\n if (index === 0) {\n step.classList.add(CONST.classes.active);\n } else {\n step.classList.remove(CONST.classes.active);\n }\n });\n}\n\n/**\n * @public createModalByUrl\n * @param {string} targetId - The id of the target modal\n * @param {string} targetEndpoint - The url to call which should return the modal html\n * @returns {Promise} - Promise\n *\n * @description\n * Will create/show a modal based on a URL to a pipeline.\n * That pipeline should return a template with the modal HTML for more creative freedom\n */\nfunction createModalByUrl(targetId, targetEndpoint) {\n const modalId = `modal-${targetId}`;\n const existingModal = document.getElementById(modalId);\n\n if (existingModal) {\n return new Promise((resolve) => {\n resetModalState(existingModal);\n window.bs.Modal.getInstance(existingModal).show();\n resolve(existingModal);\n });\n }\n\n spinner.start();\n return fetch(targetEndpoint)\n .then((res) => {\n if (res.status === 500) throw new Error('Fetch failed');\n return res.text();\n })\n .then((response) => {\n document.body.insertAdjacentHTML('beforeend', response);\n\n const modalElement = document.getElementById(modalId);\n const modal = new window.bs.Modal(modalElement);\n\n new ModalClass(modal); // eslint-disable-line\n modal.show();\n document.dispatchEvent(new CustomEvent('custom_modal:shown'));\n return modalElement;\n })\n .catch((response) => {\n console.error('error', response);\n return response;\n })\n .finally(spinner.stop);\n}\n\n/**\n * @class ModalClass\n */\nclass ModalClass {\n constructor(modalInstance) {\n this.modal = modalInstance._element; // eslint-disable-line no-underscore-dangle\n this.modalActiveStep = this.modal.querySelector(`${selectors.modalStep}.${CONST.classes.active}`);\n this.modalFields = [...this.modal.querySelectorAll(selectors.modalStepInputs)];\n\n this.validateModalField = this.validateModalField.bind(this);\n this.submitStepForm = this.submitStepForm.bind(this);\n this.appendModalStep = this.appendModalStep.bind(this);\n\n this.modalFields.forEach((field) => {\n field.addEventListener(CONST.events.blur, (event) => {\n this.lastFocussedField = event.target;\n });\n\n field.addEventListener(CONST.events.keyUp, this.validateModalField);\n field.addEventListener(CONST.events.change, this.validateModalField);\n });\n\n this.modalActiveStep.addEventListener(CONST.events.submit, this.submitStepForm);\n\n const customEvent = new CustomEvent('modalLoaded', {\n detail: {\n modal: this.modal\n }\n });\n document.dispatchEvent(customEvent);\n }\n\n /**\n * @method validateModalField\n * @param {event} event - The submit event\n */\n validateModalField(event) {\n // If we're using tab, make sure to validate the previous field instead of the new field\n if (this.lastFocussedField && event.key && event.key.toLowerCase() === 'tab') {\n validateField(this.lastFocussedField);\n this.lastFocussedField = event.target;\n } else {\n const currField = event.target;\n this.lastFocussedField = currField;\n validateField(currField);\n }\n }\n\n /**\n * @method submitStepForm\n * @param {event} event - The submit event\n */\n submitStepForm(event) {\n event.preventDefault();\n const form = event.target;\n\n const validForm = validateForm(form);\n if (!validForm) {\n return;\n }\n\n const endpoint = form.getAttribute('action');\n const formData = new FormData(form);\n const csrfName = form && form.getAttribute(CONST.attributes.csrfName);\n const csrfToken = form && form.getAttribute(CONST.attributes.csrfToken);\n formData.append(csrfName, csrfToken);\n\n /* eslint-disable no-underscore-dangle */\n if (window._dd && window._dd.user && window._dd.user.ids && window._dd.user.ids.ga_id) {\n formData.append('gaId', window._dd.user.ids.ga_id);\n }\n /* eslint-enable no-underscore-dangle */\n\n spinner.start();\n\n fetch(endpoint, {\n method: 'POST',\n body: formData\n })\n .then((res) => res.text())\n .then(this.appendModalStep)\n .catch((error) => {\n console.error('submitStepForm error', error);\n })\n .finally(spinner.stop);\n }\n\n /**\n * @method scrollToTop\n */\n static scrollToTop() {\n const activeModal = document.querySelector(selectors.activeModal);\n const supportsNativeSmoothScroll = 'scrollBehavior' in document.documentElement.style;\n if (supportsNativeSmoothScroll) {\n activeModal.scrollTo({\n top: 0,\n left: 0,\n behavior: 'smooth'\n });\n } else {\n activeModal.scrollTop = 0;\n }\n }\n\n /**\n * @method appendModalStep\n * @param {string} response - The response containing the next step\n */\n appendModalStep(response) {\n const modalStepContainer = document.querySelector(`${selectors.activeModal} ${selectors.modalStepContainer}`);\n const currentStep = modalStepContainer.querySelector(`${selectors.modalStep}.${CONST.classes.active}`);\n\n currentStep.classList.remove(CONST.classes.active);\n modalStepContainer.insertAdjacentHTML('beforeend', response);\n\n const newStep = modalStepContainer.querySelector(`${selectors.modalStep}:last-child`);\n newStep.classList.add(CONST.classes.active);\n\n this.constructor.scrollToTop();\n\n const customEvent = new CustomEvent('modalStep', {\n detail: {\n currentStep: currentStep,\n newStep: newStep\n }\n });\n document.dispatchEvent(customEvent);\n }\n}\n\n/**\n * @function refreshToken\n * @description Calls an endpoint to execute authorization when the Business Scan contact me modals are opened - BO-1488.\n */\nfunction refreshToken() {\n const container = document.querySelector('[data-refresh-token-url]');\n const { refreshTokenUrl } = container.dataset;\n if (!refreshTokenUrl) return;\n\n const endpoint = appendCsrfToUrl(refreshTokenUrl);\n\n fetch(endpoint);\n}\n\nexport { showErrorModal, createModalByUrl, refreshToken };\n","'use strict';\n\n// Can't import cartridges/app_vodafone_ziggo/cartridge/scripts/forms/validator.js\nconst ID_TYPES_CODES = {\n idCard: '1',\n passport: '2',\n driversLicense: '3',\n permit1: '4',\n permit2: '5',\n permit3: '6',\n permit4: '7',\n permit5: '8',\n permitEU: '9',\n other: '10'\n};\n\nconst ID_VALIDATION_RULES = {};\nID_VALIDATION_RULES[ID_TYPES_CODES.passport] = /^[A-NP-Z]{2}[\\dA-NP-Z]{6}\\d{1}$/gi;\nID_VALIDATION_RULES[ID_TYPES_CODES.idCard] = ID_VALIDATION_RULES[ID_TYPES_CODES.passport];\nID_VALIDATION_RULES[ID_TYPES_CODES.driversLicense] = /^\\d{10}$/gi;\nID_VALIDATION_RULES[ID_TYPES_CODES.permit1] = /^(?!(X00|V))[\\dA-Z]{8,9}$/gi;\nID_VALIDATION_RULES[ID_TYPES_CODES.permit2] = ID_VALIDATION_RULES[ID_TYPES_CODES.permit1];\nID_VALIDATION_RULES[ID_TYPES_CODES.permit2] = ID_VALIDATION_RULES[ID_TYPES_CODES.permit1];\nID_VALIDATION_RULES[ID_TYPES_CODES.permit3] = ID_VALIDATION_RULES[ID_TYPES_CODES.permit1];\nID_VALIDATION_RULES[ID_TYPES_CODES.permit4] = ID_VALIDATION_RULES[ID_TYPES_CODES.permit1];\nID_VALIDATION_RULES[ID_TYPES_CODES.permit5] = ID_VALIDATION_RULES[ID_TYPES_CODES.permit1];\nID_VALIDATION_RULES[ID_TYPES_CODES.permitEU] = ID_VALIDATION_RULES[ID_TYPES_CODES.permit1];\n\n// this regexp is always invalid\nID_VALIDATION_RULES[ID_TYPES_CODES.other] = /(?=a)b/;\n\n/**\n * @constant {string} ID_TYPE - Selector for identification type\n */\nconst ID_TYPE = 'dwfrm_checkoutDetails_identification_idtype';\n\n/**\n * @private setValidationPattern\n * @param {Event} evt - Change or load event\n */\nfunction setValidationPattern(evt) {\n const element = evt.target.id === ID_TYPE ? evt.target : document.getElementById(ID_TYPE);\n if (element.value) {\n element.closest('form').dispatchEvent(\n new CustomEvent('identificationTypeChanged', {\n detail: {\n type: element.value,\n regex: ID_VALIDATION_RULES[element.value]\n }\n })\n );\n }\n}\n\n/**\n * @public idType\n * @param {HTMLSelectElement} element - Identification type selector\n */\nexport default function idType(element) {\n if (element.id !== ID_TYPE) return;\n\n element.addEventListener('change', setValidationPattern);\n window.addEventListener('load', setValidationPattern);\n}\n","'use strict';\n\n/**\n * @constant {string} CAPS_MASK_ATTRIBUTE - Attribute value for caps mask\n */\nexport const CAPS_MASK_ATTRIBUTE = 'caps';\n\n/**\n * @class CapsMask\n * @param {HTMLInputElement} element - An input field\n */\nexport class CapsMask {\n constructor(element) {\n element.addEventListener('input', this.onInput.bind(element));\n element.addEventListener('change', this.onInput.bind(element));\n }\n\n onInput() {\n const position = this.selectionStart;\n this.value = this.value.toUpperCase();\n this.setSelectionRange(position, position);\n }\n}\n","'use strict';\n\nimport { CapsMask } from './caps';\n\n/**\n * @constant {string} POSTCODE_MASK_ATTRIBUTE - Attribute value for postcode mask\n */\nconst POSTCODE_MASK_ATTRIBUTE = 'postcode';\n\n/**\n * @constant {integer} BACKSPACE_KEYCODE\n */\nconst BACKSPACE_KEYCODE = 8;\n\n/**\n * @constant {integer} DELETE_KEYCODE\n */\nconst DELETE_KEYCODE = 46;\n\n/**\n * @constant {Array} UNDO_KEYS\n */\nconst UNDO_KEYS = [BACKSPACE_KEYCODE, DELETE_KEYCODE, 'backspace', 'delete'];\n\n/**\n * @class PostCodeMask\n * @param {HTMLInputElement} element - The input field to put the postcode mask on.\n */\nclass PostCodeMask extends CapsMask {\n constructor(element) {\n super(element);\n this.element = element;\n this.onKeyUp = this.onKeyUp.bind(this);\n\n element.addEventListener('keyup', this.onKeyUp);\n }\n\n /**\n * @private onKeyUp\n * @param {KeyboardEvent} evt - On key up event\n */\n onKeyUp(evt) {\n const key = evt.key && typeof evt.key !== 'number' ? evt.key.toLocaleLowerCase() : evt.key || null;\n if (key && UNDO_KEYS.some((k) => k === key)) {\n if (this.element.value.length === 5) {\n this.element.value = this.element.value.substring(0, 4);\n }\n return;\n }\n\n // Mask the input value for postcodes using a regular expression.\n this.element.value = this.element.value.replace(/(^\\d{4})(\\w{0,2}$)/, '$1 $2');\n }\n}\n\nexport { PostCodeMask, POSTCODE_MASK_ATTRIBUTE };\n","'use strict';\n\nimport { CapsMask } from './caps';\n\n/**\n * @constant {string} POSTCODE_MASK_ATTRIBUTE - Attribute value for postcode mask\n */\nconst IBAN_MASK_ATTRIBUTE = 'iban';\n\n/**\n * @constant {integer} BACKSPACE_KEYCODE\n */\nconst BACKSPACE_KEYCODE = 8;\n\n/**\n * @constant {integer} DELETE_KEYCODE\n */\nconst DELETE_KEYCODE = 46;\n\n/**\n * @constant {Array} UNDO_KEYS\n */\nconst UNDO_KEYS = [BACKSPACE_KEYCODE, DELETE_KEYCODE, 'backspace', 'delete'];\n\nclass IBANMask extends CapsMask {\n constructor(element) {\n super(element);\n this.element = element;\n this.onKeyUp = this.onKeyUp.bind(this);\n\n element.addEventListener('keyup', this.onKeyUp);\n }\n\n /**\n * @private onKeyUp\n * @param {KeyboardEvent} evt - On key up event\n */\n onKeyUp(evt) {\n const key = evt.key && typeof evt.key !== 'number' ? evt.key.toLocaleLowerCase() : evt.key || null;\n if (key && UNDO_KEYS.some((k) => k === key)) {\n if (this.element.value.length % 4 === 1) {\n this.element.value = this.element.value.substring(0, this.element.value.length);\n }\n return;\n }\n\n // Mask the input value for iban using a regular expression.\n this.element.value = this.element.value\n .replace(/\\s/g, '')\n .replace(/^([a-zA-Z]{2}\\d{2})(\\w{0,4})(\\d{0,4})(\\d{0,4})(\\d{0,2})/, '$1 $2 $3 $4 $5')\n .replace(/\\s\\s+/g, ' ');\n }\n}\n\nexport { IBANMask, IBAN_MASK_ATTRIBUTE };\n","'use strict';\n\n/**\n * @constant {string} DATE_MASK_ATTRIBUTE - Attribute value for date mask\n */\nconst DATE_MASK_ATTRIBUTE = 'date';\n\nclass DateMask {\n constructor(element) {\n this.field = element;\n this.cursorIndex = 0;\n this.maskText = element.getAttribute('data-mask-text');\n this.pressedCharacters = [];\n\n this.onInput = this.onInput.bind(this);\n this.onPaste = this.onPaste.bind(this);\n this.replaceRemovedDigitWithLetter = this.replaceRemovedDigitWithLetter.bind(this);\n this.onArrowRight = this.onArrowRight.bind(this);\n this.onArrowLeft = this.onArrowLeft.bind(this);\n this.onCharacterRemoval = this.onCharacterRemoval.bind(this);\n this.checkIfDashIsSelected = this.checkIfDashIsSelected.bind(this);\n this.replaceAsYouType = this.replaceAsYouType.bind(this);\n\n element.addEventListener('keydown', this.onKeyDown.bind(this));\n element.addEventListener('keyup', this.onInput);\n element.addEventListener('paste', this.onPaste);\n }\n\n /**\n * @private runRegexOnValue\n * @param {string} value - The value\n * @returns {array} - The final manipulated value as an array with each character\n *\n * @description\n * Mask the input value for date using regular expressions and enforcing dashes at specific locations\n */\n static runRegexOnValue(value) {\n return value\n .toUpperCase() // In case lowercase d/m/j letters are entered\n .replace(/^(\\d{1}-)-/, '0$1-') // If we already have the mask and one digit plus a dash has been entered, prepend a 0\n .replace(/-(\\d{1}-)-/, '-0$1-') // For the 2nd group, do the same and prepend a 0\n\n .replace(/-+-/g, '-') // Convert multiple dashes to a single dash\n .replace(/[^\\dDMJ-]/g, '') // Remove any character that is not [numeric, letters D/M/J, a dash]\n .replace(/^-(\\d{1})/, '$1') // If the string starts with a dash, remove the dash\n .replace(/-/g, '') // After all manipulations and cleaning up, remove all dashes (which could also have been added in the 3rd group) and..\n .split(''); // split up our current string so we can enforce dashes on specific locations only\n }\n\n /**\n * @private totalLengthUntilLastDigit\n * @param {string} newVal - The value\n * @returns {number} - The total length\n *\n * @description\n * Calculate what the total length of newVal would be once the dashes are added through `splice`, only until the last entered digit\n * We need this to do calculations for cursorOffset\n */\n static totalLengthUntilLastDigit(newVal) {\n const untilLastDigit = newVal.join('').replace(/[\\D]*$/, '');\n let totalLength = untilLastDigit.length;\n if (totalLength > 4) {\n totalLength += 1;\n }\n if (totalLength > 2) {\n totalLength += 1;\n }\n\n return totalLength;\n }\n\n /**\n * @private replaceRemovedDigitWithLetter\n * @param {string} newVal - The value\n * @returns {array} - The updated newVal\n *\n * @description\n * Will replace the removed digit with a corresponding letter from the maskText\n */\n replaceRemovedDigitWithLetter(newVal) {\n // Calculate the offset which is necessary to determine where the replacing character should be placed\n // The offset is based on the cursorIndex and the amount of dashes that are present\n let cursorOffset = 0;\n const cursorIndex = this.cursorIndex;\n\n if (cursorIndex === 3 || cursorIndex === 4) {\n cursorOffset -= 1;\n } else if (cursorIndex > 4) {\n cursorOffset -= 2;\n }\n\n // Decide which character should take it's place and add it to the array\n const removedCharacter = this.maskText.substring(cursorIndex, cursorIndex + 1);\n\n if (removedCharacter !== '-') {\n newVal.splice(cursorIndex + cursorOffset, 0, removedCharacter);\n }\n\n return newVal;\n }\n\n /**\n * @private addDashes\n * @param {string} newVal - The value\n * @returns {array} - The updated newVal\n *\n * @description\n * Will add dashes at specific spots\n */\n static addDashes(newVal) {\n // If we have 4 or more digits, add a dash\n if (newVal.length >= 4) {\n newVal.splice(4, 0, '-');\n }\n\n // If we have 2 or more digits, add a dash\n if (newVal.length >= 2) {\n newVal.splice(2, 0, '-');\n }\n\n return newVal;\n }\n\n /**\n * @private onArrowRight\n * @param {string} newVal - The value\n *\n * @description\n * Will move the cursor to the right based on some checks\n */\n onArrowRight(newVal) {\n if (this.checkIfDashIsSelected(newVal)) this.cursorIndex += 1;\n this.field.setSelectionRange(this.cursorIndex, this.cursorIndex);\n }\n\n /**\n * @private onArrowLeft\n * @param {string} newVal - The value\n *\n * @description\n * Will move the cursor to the left based on some checks\n */\n onArrowLeft(newVal) {\n if (this.checkIfDashIsSelected(newVal, 'left')) this.cursorIndex -= 1;\n this.field.setSelectionRange(this.cursorIndex, this.cursorIndex);\n }\n\n /**\n * @private onCharacterRemoval\n * @param {string} newVal - The value\n *\n * @description\n * Will move the cursor to the left based on some checks\n */\n onCharacterRemoval(newVal) {\n // If the character on the left is a dash, move an extra spot to the left\n if (this.checkIfDashIsSelected(newVal, 'left')) this.cursorIndex -= 1;\n\n // If we end up before the beginning, reset the index\n if (this.cursorIndex < 0) this.cursorIndex = 0;\n\n this.field.setSelectionRange(this.cursorIndex, this.cursorIndex);\n }\n\n /**\n * @private checkIfDashIsSelected\n * @param {string} value - The string to check\n * @param {string} direction - Either 'left' or 'right'\n * @param {number} offset - An optional offset\n * @returns {boolean} - True of false\n */\n checkIfDashIsSelected(value, direction, offset = 0) {\n const cursorIndex = this.cursorIndex + offset;\n\n if (direction === 'left') {\n return value.substring(cursorIndex - 1, cursorIndex) === '-';\n }\n\n return value.substring(cursorIndex, cursorIndex + 1) === '-';\n }\n\n /**\n * @private replaceAt\n * @param {string} value - The original value\n * @param {number} index - The position of the old character to replace\n * @param {string} replacement - The replacement character\n * @returns {string} - An updated value\n */\n static replaceAt(value, index, replacement) {\n return value.substring(0, index) + replacement + value.substring(index + 1);\n }\n\n /**\n * @private replaceAsYouType\n * @param {string} key - The pressed key as a string\n * @returns {string} - A possibly updated value\n * @description\n * Will replace the next character as you type. This is necessary since we have a max-length on the field.\n */\n replaceAsYouType(key) {\n let value = this.field.value;\n const isDigit = !window.isNaN(key);\n const allowedDash = key === '-' && this.checkIfDashIsSelected(value, 'right', 1);\n\n // If we're not at the end\n // and there's no selection at the moment\n // and the inputted character is either a digit or a dash\n if (this.cursorIndex < value.length && !this.hasSelection && (isDigit || allowedDash)) {\n // If we're before a dash, replace the character after the dash\n if (this.checkIfDashIsSelected(value)) {\n this.cursorIndex++;\n }\n\n value = this.constructor.replaceAt(value, this.cursorIndex, key);\n this.cursorIndex++;\n }\n\n return value;\n }\n\n /**\n * @private onKeyDown\n * @param {KeyboardEvent} evt - On key down event\n */\n onKeyDown(evt) {\n // If the user is holding the key down, and it's not the backspace/delete button, preventDefault\n if (evt.repeat && evt.key !== 'Backspace' && evt.key !== 'Delete') {\n evt.preventDefault();\n return;\n }\n\n this.hasSelection = evt.target.selectionEnd > evt.target.selectionStart;\n const isDigit = !window.isNaN(evt.key);\n\n if (isDigit || evt.key === '-') {\n evt.preventDefault();\n this.pressedCharacters.push(evt.key);\n this.onInput(evt);\n }\n }\n\n /**\n * @private onInput\n * @param {KeyboardEvent} evt - On key up event\n */\n onInput(evt) {\n if (\n evt.type === 'keyup' &&\n (evt.key === 'Escape' ||\n evt.key === 'Enter' ||\n evt.key === 'Tab' ||\n evt.key === 'Control' ||\n evt.key === 'Shift' ||\n evt.key === 'Alt' ||\n evt.key === 'Meta' ||\n evt.key === 'ArrowUp' ||\n evt.key === 'ArrowDown')\n ) {\n return;\n }\n\n const field = this.field;\n const val = field.value;\n let charRemoved = evt.type === 'keyup' && (evt.key === 'Backspace' || evt.key === 'Delete');\n this.cursorIndex = field.selectionStart;\n\n // Getting the pressed character from the array is to cater for the edge case where the user held down for example '1' and then pressed '2'.\n // This should force '1' to be shown first and then '2', instead of the other way around if we would just get evt.key.\n // This is a \"complex\" workaround for a simple problem which would much easier be fixed by using `onKeyDown` instead of `onKeyUp`, but it's\n // too late to refactor half of this file now...\n const firstPressedCharacter = this.pressedCharacters[0];\n\n // If the entire value/date has been selected\n if (evt.target.selectionStart === 0 && evt.target.selectionEnd === 10) {\n if (firstPressedCharacter) {\n // If a character has been entered, reset the value to the pressed character\n field.value = firstPressedCharacter;\n this.cursorIndex++;\n } else {\n // Stop executing the rest of this method so the user can \"select all\" and then hit backspace/delete\n return;\n }\n }\n\n // Init the mask if there is no value yet (seeing as we preventDefault in `onKeyDown`)\n // Also adjust the `empty` class accordingly\n if (val.length === 0 && firstPressedCharacter) {\n field.value = firstPressedCharacter;\n field.classList.remove('empty');\n } else if (val.length === 0) {\n field.classList.add('empty');\n }\n\n // Replace characters as you type\n let newVal = this.replaceAsYouType(firstPressedCharacter, val);\n field.value = newVal;\n\n this.pressedCharacters.shift();\n\n // Mask the input value for date using regular expressions and enforcing dashes at specific locations\n newVal = this.constructor.runRegexOnValue(newVal);\n\n // Calculate what the total length of newVal would be once the dashes are added through `splice`, only until the last entered digit\n // We need this to do calculations for cursorOffset\n const totalLength = this.constructor.totalLengthUntilLastDigit(newVal);\n\n // Will replace the removed digit with a corresponding letter from the maskText\n if (charRemoved) {\n newVal = this.replaceRemovedDigitWithLetter(newVal);\n }\n\n // If we removed any digit \"in the middle\",\n // Reset `charRemoved` to false, in order to keep the cursor in the current position\n if (charRemoved && this.cursorIndex < totalLength) {\n charRemoved = false;\n }\n\n // Add dashes at specific spots\n newVal = this.constructor.addDashes(newVal);\n\n // Set final value with a format of xx-xx-xxxx\n // If the value is incomplete, finish the rest with the mask\n if (totalLength > 0) {\n newVal = newVal.join('').substring(0, 10);\n newVal += this.maskText.substring(newVal.length, 10);\n this.field.value = newVal;\n } else {\n this.field.value = '';\n return;\n }\n\n // If arrow left was pressed\n if (evt.key === 'ArrowLeft') {\n this.onArrowLeft(newVal);\n return;\n }\n\n // If arrow right was pressed\n if (evt.key === 'ArrowRight') {\n this.onArrowRight(newVal);\n return;\n }\n\n // If a character was removed\n if (charRemoved) {\n this.onCharacterRemoval(newVal);\n return;\n }\n\n // When a character has been entered, increment the cursorIndex\n if (this.checkIfDashIsSelected(newVal)) {\n this.cursorIndex += 1;\n }\n\n // Set the new selection based on calculations done in above methods\n this.field.setSelectionRange(this.cursorIndex, this.cursorIndex);\n }\n\n /**\n * @private onPaste\n * @param {KeyboardEvent} evt - On key up event\n */\n onPaste(evt) {\n this.onInput(evt);\n\n setTimeout(() => {\n const val = this.field.value;\n this.field.setSelectionRange(val.length, val.length);\n }, 100); // small delay is necessary because the dashes are added after paste\n }\n}\n\nexport { DateMask, DATE_MASK_ATTRIBUTE };\n","'use strict';\n\nimport { POSTCODE_MASK_ATTRIBUTE, PostCodeMask } from './masks/postcode';\nimport { IBAN_MASK_ATTRIBUTE, IBANMask } from './masks/iban';\nimport { DATE_MASK_ATTRIBUTE, DateMask } from './masks/date';\nimport { CAPS_MASK_ATTRIBUTE, CapsMask } from './masks/caps';\n\n/**\n * @class Mask\n * @param {HTMLInputElement} element - The input field to put a mask on\n */\nclass Mask {\n constructor(element) {\n this.element = element;\n this.maskType = this.element.getAttribute('data-mask');\n\n // PostCode mask\n if (this.maskType === POSTCODE_MASK_ATTRIBUTE) {\n this.mask = new PostCodeMask(this.element);\n }\n if (this.maskType === IBAN_MASK_ATTRIBUTE) {\n this.mask = new IBANMask(this.element);\n }\n if (this.maskType === DATE_MASK_ATTRIBUTE) {\n this.mask = new DateMask(this.element);\n }\n if (this.maskType === CAPS_MASK_ATTRIBUTE) {\n this.mask = new CapsMask(this.element);\n }\n }\n}\n\nexport default Mask;\n","'use strict';\n\n/**\n * @private preventCharacters\n * @param {Event} event - Keydown or paste event\n */\nfunction preventCharacters(event) {\n const { target } = event;\n const bannedCharacters = target.getAttribute('data-prevent');\n\n if (event.key && bannedCharacters.includes(event.key)) {\n event.preventDefault();\n } else if (event.clipboardData) {\n event.preventDefault();\n\n const clipboardData = event.clipboardData.getData('text/plain');\n const dataWithoutBannedCharacters = clipboardData\n .split('')\n .filter((character) => !bannedCharacters.includes(character))\n .join('');\n const currValue = target.value;\n\n if (typeof target.selectionStart === 'number') {\n const start = target.selectionStart;\n const end = target.selectionEnd;\n const newVal = [];\n\n if (start === 0 && end === 0) {\n newVal.push(dataWithoutBannedCharacters);\n newVal.push(currValue);\n } else {\n newVal.push(currValue.substr(0, start));\n newVal.push(dataWithoutBannedCharacters);\n newVal.push(currValue.substr(end, currValue.length - 1));\n }\n\n target.value = newVal.join('');\n } else {\n // Some input types don't support `selectionStart`. In this edge case, just append it to the end\n target.value = currValue + dataWithoutBannedCharacters;\n }\n }\n}\n\n/**\n * @public preventCharactersOnInput\n * @param {HTMLInputElement} element - The input element\n */\nexport default function preventCharactersOnInput(element) {\n if (!element.getAttribute('data-prevent')) return;\n\n element.addEventListener('keydown', preventCharacters);\n element.addEventListener('paste', preventCharacters);\n}\n","'use strict';\n\nconst events = ['keydown', 'paste', 'focus', 'mousedown'];\n\n/**\n * Prevent entry in the field\n * @param {Event} evt - An event\n */\nfunction preventEntry(evt) {\n // ignore tab\n if (evt.keyCode !== 9) evt.preventDefault();\n}\n\n/**\n * Enable the read-only feature\n * @param {HTMLElement} element - The element to make read-only\n * @returns {bool} enabled\n */\nfunction enable(element) {\n events.forEach((event) => {\n element.addEventListener(event, preventEntry);\n });\n return true;\n}\n\n/**\n * Disable the read-only feature\n * @param {HTMLElement} element - The element to make read-only\n * @returns {bool} enabled\n */\nfunction disable(element) {\n events.forEach((event) => {\n element.removeEventListener(event, preventEntry);\n });\n return false;\n}\n\n/**\n * @public idType\n * @param {HTMLSelectElement} element - Identification type selector\n */\nexport default function idType(element) {\n if (!element.hasAttribute('read-only')) return;\n Object.defineProperty(element, 'read-only', {\n enumerable: false,\n configurable: false,\n set: (bool) => {\n if (bool) {\n this.value = enable(element);\n return;\n }\n this.value = disable(element);\n }\n });\n element['read-only'] = element.getAttribute('read-only');\n}\n","'use strict';\n\nimport documentNumber from './documentNumber';\nimport idType from './idType';\nimport mask from './mask';\nimport password from './password';\nimport preventCharacters from './preventCharacters';\nimport readonly from './readonly';\nimport regex from './regex';\nimport valid from './valid';\n\nexport default {\n documentNumber,\n idType,\n mask,\n password,\n preventCharacters,\n readonly,\n regex,\n valid\n};\n","'use strict';\n\n/**\n * @constant {string} DOCUMENT_NUMBER - Input field for document number\n */\nconst DOCUMENT_NUMBER = 'dwfrm_checkoutDetails_identification_documentNumber';\n\n/**\n * @public documentNumber\n * @param {HTMLInputElement} element - Document Number input field\n */\nexport default function documentNumber(element) {\n if (element.name !== DOCUMENT_NUMBER) return;\n\n element.closest('form').addEventListener('identificationTypeChanged', (evt) => {\n // First reset regex state due to /g entries\n // https://stackoverflow.com/questions/2630418/javascript-regex-returning-true-then-false-then-true-etc/2630538#2630538\n element.pattern = evt.detail.regex.toString().replace('/^', '^').replace('$/gi', '$');\n element.regex.lastIndex = 0;\n element.regex = new RegExp(element.pattern);\n if (element.value.length > 0) {\n element.dispatchEvent(new CustomEvent('input'));\n element.dispatchEvent(new CustomEvent('blur'));\n }\n });\n\n const originalErrorMsg = element.dataset.patternError;\n element.addEventListener('input', () => {\n // Reset to original error message\n element.dataset.patternError = originalErrorMsg;\n if (element.dataset.selectedId && element.dataset.selectedId.includes('verblijfsdocument')) {\n if (element.value.toLowerCase().startsWith('x00')) element.dataset.patternError = element.dataset.patternX00Error;\n if (element.value.toLowerCase().startsWith('v')) element.dataset.patternError = element.dataset.patternVError;\n }\n });\n}\n","'use strict';\n\nimport Mask from 'Components/form/mask';\n\n/**\n * @public regex\n * @param {HTMLInputElement} element - The element to put the mask on\n */\nexport default function mask(element) {\n Object.defineProperty(element, 'mask', {\n enumerable: false,\n configurable: false,\n value: new Mask(element)\n });\n}\n","'use strict';\n\n/**\n * @constant {string} PASSWORD_VIEW_TOGGLE - Selector for toggling the view state of a password field.\n */\nconst PASSWORD_VIEW_TOGGLE = '.js-password-toggle';\n\n/**\n * @public showPassword\n * @param {HTMLInputElement} element - The element used to set the password toggle.\n */\nexport default function showPassword(element) {\n const feedbackElement = element.parentElement.querySelector(PASSWORD_VIEW_TOGGLE);\n if (!feedbackElement) return;\n\n feedbackElement.addEventListener('click', () => {\n element.showPassword = element.type === 'password';\n });\n Object.defineProperty(element, 'showPassword', {\n enumerable: false,\n configurable: false,\n set: (value) => {\n if (value) {\n element.type = 'text';\n } else {\n element.type = 'password';\n }\n }\n });\n}\n","'use strict';\n\n/**\n * @public regex\n * @param {HTMLInputElement} element - The element used to set the regex.\n */\nexport default function regex(element) {\n Object.defineProperty(element, 'regex', {\n enumerable: false,\n configurable: true,\n writable: true,\n value: element.required ? new RegExp(element.pattern) : new RegExp() // Pattern or empty when not mandatory\n });\n}\n","'use strict';\n\n/**\n * @public validate\n * @param {HTMLInputElement} element - The element used to validate.\n */\nexport default function validate(element) {\n Object.defineProperty(element, 'valid', {\n enumerable: true,\n configurable: false,\n set: (value) => {\n if (value) {\n element.classList.add('valid');\n element.classList.remove('invalid');\n } else {\n element.classList.add('invalid');\n element.classList.remove('valid');\n }\n }\n });\n}\n","'use strict';\n\nimport decorators from 'Decorators/index';\nimport { validate } from 'app_vodafone_ziggo/util/validation';\n\n/**\n * @class InputField\n * @param {HTMLInputElement} element - The element to create an instance on\n */\nclass VZInputField extends HTMLInputElement {\n constructor() {\n super();\n this.validatePattern = this.validatePattern.bind(this);\n this.setFieldStatus = this.setFieldStatus.bind(this);\n this.onPaste = this.onPaste.bind(this);\n\n this.addEventListener('input', this.validatePattern);\n this.addEventListener('input', this.setFieldStatus);\n this.addEventListener('changeDate', this.setFieldStatus);\n this.addEventListener('changeDate', validate);\n this.addEventListener('paste', this.onPaste);\n this.validate = validate;\n\n decorators.readonly(this);\n decorators.regex(this);\n decorators.valid(this);\n decorators.documentNumber(this);\n\n if (this.hasAttribute('data-mask')) {\n decorators.mask(this);\n }\n\n if (this.hasAttribute('data-prevent')) {\n decorators.preventCharacters(this);\n }\n\n if (this.type === 'password') {\n decorators.password(this);\n }\n\n // Set initial state\n this.setFieldStatus();\n\n if (this.type === 'radio' || this.type === 'checkbox') {\n this.addEventListener('change', validate);\n } else {\n this.addEventListener('blur', validate);\n }\n\n this.closest('form').addEventListener('submit', this.disableExcludedFields);\n }\n\n onPaste(evt) {\n // Execute these methods at the end of the callstack, otherwise `field.value` will be the value before the paste.\n setTimeout(() => {\n this.setFieldStatus();\n validate(evt);\n }, 1);\n }\n\n disableExcludedFields() {\n if (this.hasAttribute('data-exclude')) {\n this.setAttribute('disabled', 'disabled');\n }\n }\n\n /**\n * @private setFieldStatus\n * @description\n * Sets an empty class when the element is empty for styling purposes.\n */\n setFieldStatus() {\n const hasValue = this.value.length > 0;\n const placeholderIsShown = this.constructor.placeholderActive(this);\n if (hasValue) {\n this.classList.remove('empty');\n } else if (placeholderIsShown) {\n // input[type=\"number\"] accepts dash and dots but returns no value for that.\n this.classList.add('empty');\n }\n }\n\n /**\n * @private validatePattern\n * @description\n * Checks whether the value is valid based on pattern\n */\n validatePattern() {\n this.valid = this.regex.test(this.value);\n }\n\n /**\n * @function placeholderActive\n *\n * @param {HTMLInputElement} element - Input element\n * @return {boolean} whether the placeholder is shown or not\n */\n static placeholderActive(element) {\n const selector = `${element.nodeName.toLowerCase()}[name=\"${element.name}\"]:placeholder-shown`;\n return !!document.querySelector(selector);\n }\n}\n\nexport default window.customElements.get('vz-input') || VZInputField;\nif (!window.customElements.get('vz-input')) {\n window.customElements.define('vz-input', VZInputField, { extends: 'input' });\n}\n","'use-strict';\n\nimport { showErrorModal } from 'Root/modal';\n\nexport default class PostcodeCheckHelpers {\n /**\n * @function stripLeadingZero\n * @param {Event} event - InputEvent\n * @description Strips the leading zero and disallows zero as a value.\n */\n static stripLeadingZero(event) {\n const { target: field, data } = event;\n\n if (data === '0') {\n const value = parseInt(field.value, 10);\n field.value = value > 0 ? value : '';\n }\n }\n\n /**\n * @function preventDashDotComma\n * @param {KeyboardEvent} event - keydown\n * @description Prevents a user from filling in a dash, dot or a comma.\n */\n static preventDashDotComma(event) {\n const { key } = event;\n if (['-', ',', '.'].includes(key)) {\n event.preventDefault();\n }\n }\n\n /**\n * @function respectMaxLength\n * @param {Event} event - Input event\n * @description input[type=\"number\"] doesn't respect max-length attribute.\n * This method slices of the last character when exceeding the max length.\n */\n static respectMaxLength(event) {\n const { target } = event;\n if (target.value.length > target.maxLength) {\n target.value = target.value.slice(0, target.maxLength);\n }\n }\n\n /**\n * @function removePAID\n * @description Will remove the PAID when the user has made a change to the address while in edit mode. This references the VZPostcodeCheck form.\n */\n static removePAID() {\n if (this.hiddenInputWithPaid) this.hiddenInputWithPaid.remove();\n }\n\n /**\n * @function hideForm\n * @description Hides the location search form. This references the VZPostcodeCheck form.\n */\n static hideForm() {\n this.classList.add('d-none');\n }\n\n /**\n * @function showForm\n * @description Shows the location search form. This references the VZPostcodeCheck form.\n */\n static showForm() {\n this.classList.remove('d-none');\n }\n\n /**\n * @function handleErrors\n * @description handles network errors with a generic modal. This references the VZPostcodeCheck form.\n * @param {Error} error - The error thrown by fn fetchAddressAndAvailability is the response is not OK.\n */\n static handleErrors(error) {\n if (error) console.warn(error);\n const { title, body, cta } = JSON.parse(this.dataset?.generalError);\n showErrorModal(title, body, cta);\n }\n\n /**\n * @async\n * @function fetchAddressAndAvailability\n * @description Fetches either the address check or the availability endpoint based on waht's passed in.\n * @param {string} endpoint - A string representing the endpoint to fetch.\n * @param {HTMLFormElement} form - The availability check (VZPostcodeCheck) form.\n * @returns {Object} A Json object returned from the endpoint.\n */\n static async fetchAddressAndAvailability(endpoint, form) {\n const formData = new FormData(form);\n formData.append(window.csrf.tokenName, window.csrf.token);\n\n // This is not available in response.isml, so sending it to the BE to make it available there.\n formData.append('configuratorType', form.configuratorType);\n\n const fetchOptions = { method: 'POST', body: formData };\n const response = await fetch(endpoint, fetchOptions);\n\n if (!response.ok) {\n throw new Error(`There was an error fetching the endpoint - ${endpoint} - status: ${response.status}`);\n }\n\n const responseJson = await response.json();\n return responseJson;\n }\n\n /**\n * @function removeExistingFeedbackMessage\n * @description Removes the existing feedback messages if they exist.\n * @param {HTMLFormElement} form - The availability check (VZPostcodeCheck) form.\n * @param {string} classNames - A comma separated string of class selectors.\n */\n static removeExistingFeedbackMessage(form, classNames) {\n const existingMessages = [...form.querySelectorAll(classNames)];\n if (existingMessages) existingMessages.forEach((message) => message.remove());\n }\n\n /**\n * @function showFeedbackMessage\n * @description Shows the message by creating an element with the message and injects it into the VZPostcodeCheck form.\n * This references the VZPostcodeCheck form.\n * @param {string} message - The message to show in the form.\n * @param {boolean} isError - Determines whether the message passed in is an error message or not.\n */\n static showFeedbackMessage(message, isError = true) {\n const templateString = `
\n

${message}

\n
`;\n const domParser = new DOMParser();\n const messageElement = domParser.parseFromString(templateString, 'text/html').querySelector('.js-availability-address-check-message');\n\n PostcodeCheckHelpers.removeExistingFeedbackMessage(this, '.js-availability-address-check-message');\n this.appendChild(messageElement);\n }\n\n /**\n * @function handleUnableToOrder\n * @description Updates availability check response heading with the address from the address check when a given location has no availability.\n * @returns {void} Early exit if the element is not found.\n */\n static handleUnableToOrder() {\n const responseHeadingElement = this.parentElement.querySelector('.js-availability-response-address');\n responseHeadingElement.setAttribute('unabletoorder', true);\n if (!responseHeadingElement) return;\n\n responseHeadingElement.textContent = this.addressCheckAddress;\n }\n\n /**\n * @function pushErrorsToDataLayer\n * @description When there is an error during the availability check, this will push an event notifying tag manager of the error.\n * @param {Object} addressParts - An object containing address details including the PAID.\n * @param {boolean} locationAlreadyInBasket - Whether the location is in the basket or not.\n */\n static pushErrorsToDataLayer(addressParts, locationAlreadyInBasket) {\n // Not a real error, so locationAlreadyInBasket errors won't be pushed.\n if (locationAlreadyInBasket) return;\n\n window.dataLayer = window.dataLayer || [];\n const { postalCode, houseNumber, extension, paid } = addressParts;\n\n // FYI - using addressCheckAddressParts from AddressCheck instead of address in the response of the availability check because that address is sometimes undefined.\n const erroneousAddressCombination = `${postalCode}-${houseNumber}${extension ? `-${extension}` : ''}`;\n const elementToPush = {\n event: 'availabilityCheckError', // eslint-disable-line quote-props\n payload: {\n // eslint-disable-line quote-props\n erroneousAddressCombination: erroneousAddressCombination.replace(/\\s/g, ''),\n paid: paid || 'No PAID available for this address combination.'\n }\n };\n\n window.dataLayer.push(elementToPush);\n }\n}\n","'use-strict';\n\nimport 'core-js/features/array/at';\n\nimport PCHelpers from './postcodeCheckHelpers';\nimport VZSpinner from 'Components/VZSpinner';\nimport { toggleButtonState } from 'Root/util/util';\n\nexport default class AddressCheck {\n constructor(availabilityForm, additionSelectElement) {\n this.availabilityForm = availabilityForm;\n this.additionSelectElement = additionSelectElement;\n this.addressCheckEndpoint = this.availabilityForm.dataset?.addressCheckUrl;\n this.spinner = document.querySelector('vz-spinner') || new VZSpinner();\n this.postalCode = null;\n this.houseNumber = null;\n this.addition = null;\n\n // Hook up a change event to the addition select field so we can grab the PAID to do the availability check using that\n this.additionSelectElement.addEventListener('blur', this.handleAdditionOnBlur.bind(this));\n [...this.availabilityForm.querySelectorAll('input')].forEach((input) => input.addEventListener('blur', this.handleAddressCheckOnBlur.bind(this)));\n this.executeAddressCheckOnLoad();\n }\n\n /**\n * @function sortAddressExtensions\n * @description Sorts the addresses based on the extension. Manipulates the existing array.\n * @param {Array} addressInfoArray - The array of address information returned from the addressCheck endpoint.\n */\n static sortAddressExtensions(addressInfoArray) {\n addressInfoArray.sort((a, b) => (a.extension.toLowerCase() < b.extension.toLowerCase() ? -1 : 0));\n\n // Get the index of the no extension array item.\n const indexOfNoExtension = addressInfoArray.indexOf(addressInfoArray.find((address) => !address.extensionRequired));\n if (indexOfNoExtension >= 0) {\n // Move the no extension item to the beginning of the array, and delete it in the original location, only if it exists.\n addressInfoArray.splice(0, 0, addressInfoArray.splice(indexOfNoExtension, 1)[0]);\n }\n }\n\n /**\n * @function removeAdditionOptions\n * @description Empties the additionSelectElement except for the default option. Makes the default selected.\n * @param {HTMLOptionsCollection} options - The additionSelectElement options.\n */\n removeAdditionOptions(options) {\n const optionsArray = [...options];\n const defaultOption = optionsArray.find((option) => option.hasAttribute('default'));\n\n optionsArray.filter((option) => !option.hasAttribute('default')).forEach((option) => option.remove()); // Remove options.\n this.additionSelectElement.selectedIndex = optionsArray.indexOf(defaultOption); // Set the default value as selected.\n this.additionSelectElement.classList.remove('valid'); // Reset the validity state.\n }\n\n /**\n * @function generateAdditionElementOptions\n * @description Generates the option elements to populate the additionSelectElement based on the address info passed in.\n * @param {Array} addressInfo - The array of address information returned from the addressCheck endpoint.\n * @param {boolean} hasMultipleExtensions - A boolean determining whether the address entered by the user has more extensions than 'No extension'\n */\n generateAdditionElementOptions(addressInfo, hasMultipleExtensions) {\n // skips if there is already additions selected\n if (this.addition) {\n return;\n }\n this.removeAdditionOptions(this.additionSelectElement.options); // Prevent duplicate options from being generated.\n AddressCheck.sortAddressExtensions(addressInfo); // Sort alphabetically based on extensions.\n\n // Generate option elements based on address info returned from fetch.\n this.additionSelectElement.innerHTML = addressInfo.reduce((result, address, index) => {\n const { paid, extension, extensionRequired, formattedAddress, addressParts } = address;\n const stringifiedAddressParts = JSON.stringify(addressParts).replace(/'/g, '''); // JSON.stringify does not escape single quotes so it needs to be done manually\n\n return `${result}\n \n `;\n }, this.additionSelectElement.innerHTML);\n }\n\n /**\n * @function handleAdditionOnBlur\n * @description Grabs the PAID to be used for the availability check. Sets the address to be used when the availability service returns\n * 'unableToOrder = true'. Validates the additionSelectElement and enables the CTA.\n * @param {Event} event - The blur event fired from the additionSelectElement.\n */\n handleAdditionOnBlur(event) {\n const { target: additionSelectElement } = event;\n const selectedExtensionOption = [...additionSelectElement.options].find((option) => option.selected);\n const { paid: addressCheckPAID, formattedAddress: addressCheckAddress, addressParts } = selectedExtensionOption.dataset;\n this.addition = selectedExtensionOption.value; // set addition to stop the regeneration of additions dropdown\n const paidHiddenInput = this.availabilityForm.hiddenInputWithPAID;\n paidHiddenInput.value = addressCheckPAID; // Set the PAID to the hidden input so the availability check is performed with the PAID\n\n // Update the address on change so its up to date for use in fn handleUnableToOrder. This is used to show the address in the availability check response.\n this.availabilityForm.addressCheckAddress = addressCheckAddress;\n\n // Provide the availability check element with the parts of the address so it can be used when pushing errors to the dataLayer. See fn pushAvailabilityCheckErrorsToDataLayer().\n // This is also used to show addresses in the sidebar for One Net where there is no availability.\n this.availabilityForm.addressCheckAddressParts = JSON.parse(decodeURI(addressParts));\n\n // If the user has selected a value, mark the field as valid and enable the CTA to perform the availability check.\n if (additionSelectElement.checkValidity()) {\n additionSelectElement.classList.add('valid');\n\n // Enable the CTA once a selection has been made.\n toggleButtonState(this.availabilityForm.submitButton, true);\n }\n\n additionSelectElement.setAttribute('value', event.target.value);\n }\n\n /**\n * @function handleAddressCheckOnBlur\n * @description Executes the address check on blur of the postcode and/or house number field, given that both have a valid value.\n * @param {Event} event - The blur event.\n */\n handleAddressCheckOnBlur() {\n const { postcodeInputElement, houseNumberInputElement } = this.availabilityForm;\n // checks if there was anything changed since previous time\n if (this.postalCode !== postcodeInputElement.value || this.houseNumber !== houseNumberInputElement.value) {\n this.addition = null; // resets additions after a change in postal or houseNumber\n this.postalCode = postcodeInputElement.value;\n this.houseNumber = houseNumberInputElement.value;\n const isMinimumRequirementMet = [postcodeInputElement, houseNumberInputElement].every((element) => element.value && element.checkValidity());\n if (isMinimumRequirementMet) {\n this.executeAddressCheck().catch((error) => PCHelpers.showFeedbackMessage.bind(this.availabilityForm)(error)); // Handle rejection from promise returned in fn executeAddressCheck.\n }\n }\n }\n\n /**\n * @function handleAddressNotFound\n * @description Handles the scenario where no address is found.\n */\n handleAddressNotFound() {\n this.removeAdditionOptions(this.additionSelectElement.options); // Reset the additionSelectElement when an address is not found.\n toggleButtonState(this.availabilityForm.submitButton, false);\n PCHelpers.removeExistingFeedbackMessage(this.availabilityForm, '.js-availability-address-check-message');\n }\n\n /**\n * @function handleMultipleAdditions\n * @description When the address check responds with multiple additions for a postcode and house number,\n * this will generate options and append them to the additionSelectElement.\n * @param {Object} addressCheckResponseData - The JSON response returned from the address check.\n */\n handleMultipleAdditions(addressCheckResponseData) {\n const { addressInfo, hasMultipleExtensions } = addressCheckResponseData;\n const { additionHelpText } = this.availabilityForm.dataset;\n\n if (!this.addition) {\n this.additionSelectElement.classList.remove('valid'); // Reset the validity state of the addition element\n }\n this.generateAdditionElementOptions(addressInfo, hasMultipleExtensions); // Populate the additions field.\n this.additionSelectElement.removeAttribute('read-only'); // In case the field was previously disabled, enable it again.\n PCHelpers.removeExistingFeedbackMessage(this.availabilityForm, '.js-availability-address-check-message');\n PCHelpers.showFeedbackMessage.bind(this.availabilityForm)(additionHelpText, false); // Show a help message when there are multiple extensions\n if (!this.addition) {\n toggleButtonState(this.availabilityForm.submitButton, false); // Disable the CTA until a selection has been made\n }\n }\n\n /**\n * @function handleSuccessfulAddressCheck\n * @description Handles the successful addressCheck scenario.\n * @param {Object} addressCheckResponseData - The JSON response returned from the address check.\n */\n handleSuccessfulAddressCheck(addressCheckResponseData) {\n const { formattedAddress = null, hasMultipleExtensions, addressInfo } = addressCheckResponseData;\n\n // Update the address on change so its up to date for use in fn handleUnableToOrder\n this.availabilityForm.addressCheckAddress = formattedAddress;\n this.generateAdditionElementOptions(addressInfo, hasMultipleExtensions); // Populate the additions field.\n\n // Disable the field when there are no extensions apart from 'No Extension'.\n if (!hasMultipleExtensions && !addressInfo.extensionRequired) {\n this.additionSelectElement.setAttribute('read-only', 'true');\n this.additionSelectElement.dispatchEvent(new Event('blur'));\n }\n\n PCHelpers.removeExistingFeedbackMessage(this.availabilityForm, '.js-availability-address-check-message, .error-msg');\n }\n\n /**\n * @function executeAddressCheck\n * @description Executes the address check.\n * @returns {Promise} A promise determining whether the address check was succesful or not. Rejected when address is not found,\n * resolved in other scenarios so the availability check can be performed.\n */\n executeAddressCheck() {\n this.spinner.start();\n\n /**\n * BO-1570 - To make sure that the availability check is only executed for found addresses, a promise needs to be returned and\n * rejected when the address is not found so that the availability check is not performed.\n */\n return new Promise((resolve, reject) => {\n PCHelpers.fetchAddressAndAvailability(this.addressCheckEndpoint, this.availabilityForm)\n .then((addressCheckResponseData) => {\n const multipleExtensionsFound = addressCheckResponseData?.multipleExtensionsFound;\n\n if (!addressCheckResponseData?.success && multipleExtensionsFound) {\n this.handleMultipleAdditions(addressCheckResponseData);\n resolve();\n } else if (!addressCheckResponseData?.success) {\n this.handleAddressNotFound();\n reject(addressCheckResponseData?.serverErrors[0]);\n } else {\n this.handleSuccessfulAddressCheck(addressCheckResponseData);\n resolve();\n }\n })\n .catch(PCHelpers.handleErrors.bind(this))\n .finally(this.spinner.stop);\n });\n }\n\n /**\n * @function executeAddressCheckOnLoad\n * @description Executes the address check on load if values are present. This is mainly so the extension list is populated already,\n * and that the CTA is enabled/disabled based on the status of the address check.\n */\n executeAddressCheckOnLoad() {\n const { postcodeInputElement, houseNumberInputElement } = this.availabilityForm;\n\n if (postcodeInputElement.checkValidity() && houseNumberInputElement.checkValidity()) {\n this.executeAddressCheck().catch((error) => PCHelpers.showFeedbackMessage.bind(this.availabilityForm)(error)); // Handle rejection from promise returned in fn executeAddressCheck.\n }\n }\n}\n","'use strict';\n\nimport 'core-js/features/array/at';\n\nimport 'Components/form/VZInputField';\nimport { appendParamToURL, getParamFromURL } from 'Util/urlUtils';\nimport { toggleButtonState, trackPdpEccomerceEvent } from 'Root/util/util';\nimport VZSpinner from 'Components/VZSpinner';\nimport PCHelpers from './postcodeCheckHelpers';\nimport AddressCheck from './AddressCheck';\nimport { setCookie, getCookie } from 'Util/cookies';\nimport { isIOS, scrollTo } from 'Util/util';\n\nconst spinner = document.querySelector('vz-spinner') || new VZSpinner();\n\n/**\n * @class PostCodeCheck\n * @description the availability check component used in the BIF configurator and for a Page Designer component.\n * It performs an address check and an availability check for the given address.\n */\nexport default class VZPostCodeCheck extends HTMLFormElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.form = document.getElementById('product-form');\n this.sidebar = document.querySelector('.js-configurator-summary');\n this.pdpSubmitButtons = [...document.querySelectorAll('.js-pdp-submit-button button')];\n this.editMode = document.querySelector('.js-edit-mode');\n this.hiddenInputWithPAID = this.querySelector('[name=\"paid\"]');\n this.postcodeInputElement = this.querySelector('.js-postcode-check-postcode');\n this.houseNumberInputElement = this.querySelector('.js-postcode-check-house-number');\n this.additionSelectElement = this.querySelector('.js-postcode-check-addition');\n this.submitButton = this.querySelector('button[type=\"submit\"]');\n this.isPageDesignerComponent = !!document.querySelector('.js-pd-postcode-check');\n this.parentSelector = this.isPageDesignerComponent ? document.querySelector('.js-pd-postcode-check') : this.form;\n this.configuratorType = this.dataset.configuratorType;\n this.isOneNet = this.dataset.configuratorType === 'one-net';\n this.isBusinessInternet = this.dataset.configuratorType === 'internet';\n this.isSharedOneNetConfiguration = window.location.href.includes('sharedonenet');\n\n this.removeLocation = this.removeLocation.bind(this);\n this.updateChatInfo = this.updateChatInfo.bind(this);\n\n // Initialise the address check.\n this.addressCheck = new AddressCheck(this, this.additionSelectElement);\n\n this.addEventListener('submit', this.handleAvailabilityFormSubmit.bind(this));\n this.toggleButtonState();\n\n if (this.editMode || window.location.href.includes('paid=')) {\n this.autoSubmitForm();\n }\n\n [...this.querySelectorAll('input')].forEach((field) => {\n if (field.type === 'number') {\n field.addEventListener('input', PCHelpers.respectMaxLength);\n field.addEventListener('input', PCHelpers.stripLeadingZero);\n field.addEventListener('keydown', PCHelpers.preventDashDotComma);\n }\n\n // The order of eventListeners is important, toggle the button state after the above events are done\n field.addEventListener('input focus', this.toggleButtonState.bind(this));\n\n if (this.editMode || window.location.href.includes('paid=')) {\n field.addEventListener('input', PCHelpers.removePAID.bind(this));\n }\n });\n\n // Add an event listener to select fields change event\n [...this.querySelectorAll('select')].forEach((select) => {\n select.addEventListener('change', this.toggleButtonState.bind(this));\n });\n\n // Add an event listener to enable product configuration after one net seat is selected.\n document.addEventListener('oneNet:seatSelection', this.enableProductConfiguration.bind(this));\n }\n\n /**\n * @function toggleButtonState\n * @description Validates the form and toggles the location submit button state.\n */\n toggleButtonState() {\n if (this.checkValidity() || (this.postcodeInputElement.checkValidity() && this.houseNumberInputElement.checkValidity())) {\n this.additionSelectElement.removeAttribute('read-only');\n toggleButtonState(this.submitButton, true);\n } else {\n this.additionSelectElement.setAttribute('read-only', 'true');\n toggleButtonState(this.submitButton, false);\n }\n }\n\n /**\n * @function enableProductConfiguration\n * @description Remove transparent layer from the form and add pointer events.\n * This does/should not execute for the PD postcode check component.\n * @param {Event} event - The oneNet:seatSelection event fired from VZQuantitySelector fn. onChange().\n */\n enableProductConfiguration(event = null) {\n const oneNetTierCard = [...document.querySelectorAll('.js-one-net-variation-card')].map((card) => card.closest('.pdp-card-section'));\n const isOneNetSeatSelectionEventFired = event && event.type === 'oneNet:seatSelection';\n this.isOneNetSeatSelected = isOneNetSeatSelectionEventFired && event?.detail?.isOneNetSeatSelected;\n this.areOneNetSeatsBelowThreshold = isOneNetSeatSelectionEventFired && event?.detail?.areOneNetSeatsBelowThreshold;\n this.shouldDisableOneNetConfiguration = !this.isOneNetSeatSelected || this.areOneNetSeatsBelowThreshold; // Minimum requirement to enable the whole configurator.\n\n // Enable the sidebar on availability check success or if one net and a seat has been selected.\n const elements = [\n this.form,\n ...this.pdpSubmitButtons,\n ...(this.isOneNet ? oneNetTierCard : []),\n ...(this.isBusinessInternet || this.isOneNetSeatSelected || this.editMode || this.isSharedOneNetConfiguration ? [this.sidebar] : [])\n ];\n const elementsToEnable = elements.filter(Boolean); // Filter out falsy values.\n const oneNetCriteria = this.isOneNet && this.success && !this.isPageDesignerComponent;\n const businessInternetCriteria = this.isBusinessInternet && this.success && !this.unableToOrder && !this.isPageDesignerComponent;\n\n if (businessInternetCriteria || oneNetCriteria) {\n elementsToEnable.forEach((element) => {\n if (element) {\n element.classList.remove('opacity-50', 'pe-none');\n element.removeAttribute('disabled');\n }\n });\n }\n\n // For one net, on availability check success, we only enable the tier card, rest must be disabled and enabled only after selecting a seat, see fn disableProductConfiguration. Do not disable for edit mode, since seats are already selected\n if (oneNetCriteria && this.shouldDisableOneNetConfiguration && !this.editMode && !this.isSharedOneNetConfiguration)\n this.disableProductConfiguration.bind(this)({ isEditLocation: false });\n }\n\n /**\n * @function disableProductConfiguration\n * @description Fade out the form and remove pointer events. This does/should not execute for the PD postcode check component.\n * @param {boolean} isEditLocation - Default is true for when this function is being called by an event listener.\n */\n disableProductConfiguration({ isEditLocation = true }) {\n if (this.isPageDesignerComponent) return;\n const nonTierOneNetCards = [...document.querySelectorAll('.js-pdp-card-section:not(.js-one-net-variation-card)')];\n\n // Remove all olds cards\n if (this.isOneNet) {\n nonTierOneNetCards.forEach((card) => card.parentElement?.removeChild(card));\n }\n\n // If we are in edit mode, then we disable the entire form regardless of configurator type, the configurator specific elements will be re-evaluated in fn enableProductConfiguration.\n const elements = [...this.pdpSubmitButtons, ...(this.isOneNet && !isEditLocation ? nonTierOneNetCards : [this.form, this.sidebar])];\n\n // If one-net, disable sidebar if seats are below threshold after selection.\n if (this.shouldDisableOneNetConfiguration) elements.push(this.sidebar);\n\n elements.forEach((element) => {\n if (element) {\n element.classList.add('opacity-50', 'pe-none');\n element.setAttribute('disabled', '');\n }\n });\n\n // Reset contract duration\n const defaultDuration = document.querySelector('.js-contract-duration-card input[name=\"contractDuration\"][value=\"36\"]:not(:checked)');\n defaultDuration?.dispatchEvent(new CustomEvent('change'));\n }\n\n /**\n * @function removeLocation\n * @description Removes the previous location result.\n */\n removeLocation() {\n [this.parentElement.querySelector('.js-postcode-response'), document.querySelector('.js-current-address')].forEach((element) =>\n element?.parentElement.removeChild(element)\n );\n }\n\n /**\n * @function showEditLocation\n * @description Shows a button which allows a customer to edit the configuration.\n */\n showEditLocation() {\n const editButton = this.parentElement.querySelector('.js-postcode-edit');\n if (editButton) {\n editButton.addEventListener('click', this.removeLocation);\n editButton.addEventListener('click', PCHelpers.showForm.bind(this));\n editButton.addEventListener('click', this.disableProductConfiguration.bind(this));\n }\n spinner.stop();\n }\n\n /**\n * @function setAddress\n * @description Sets the address in the sidebar.\n * @returns {void} Early exit if this is the PD component version of VZPostcodeCheck.\n */\n setAddress() {\n if (this.isPageDesignerComponent) return;\n\n const extension = this.address.extension || this.address.houseNumberExtension || '';\n const template = `
\n
${this.address.street} ${this.address.houseNumber} ${extension},
\n
${this.address.postalCode} ${this.address.city}
\n \n \n \n
`;\n document.querySelector('#configuration-details .js-configurator-summary-group-list').insertAdjacentHTML('afterbegin', template);\n\n this.updateChatInfo();\n }\n\n /**\n * @function updateChatInfo\n * @description Will update the hidden input field (if available) containing information for the chat agent\n */\n updateChatInfo() {\n const dataField = document.getElementById('activeConfiguratorGroup');\n if (!dataField) return;\n\n dataField.dispatchEvent(\n new CustomEvent('locationChange', {\n detail: this.address || this.addressCheckAddressParts\n })\n );\n }\n\n /**\n * @function updateResult\n * @param {JSON} availabilityCheckResponseData - Response object containing the HTML response string.\n * @description Removes the previous location and inserts the new one.\n */\n updateResult(availabilityCheckResponseData) {\n const {\n success: isResponseSuccessful,\n serverErrors,\n paid,\n speed,\n html: responseHtml,\n address,\n unableToOrder = null,\n locationAlreadyInBasket = null,\n locationHasExistingSubscription = null\n } = availabilityCheckResponseData;\n this.success = isResponseSuccessful;\n this.unableToOrder = unableToOrder;\n this.removeLocation();\n\n // All the error scenarios, on which we push an event to the data layer. NOTE: not sent when locationAlreadyInBasket.\n if ((address?.active || !isResponseSuccessful || unableToOrder) && this.addressCheckAddressParts && !this.isOneNet) {\n PCHelpers.pushErrorsToDataLayer(this.addressCheckAddressParts, locationAlreadyInBasket);\n }\n\n // BO-1743: If the location is outside the serviceable area, we show a modal for BI.\n if (this.isBusinessInternet && unableToOrder && !locationHasExistingSubscription) {\n const locationUnavailableModal = document.getElementById('location-unavailable-modal');\n locationUnavailableModal.render();\n }\n\n if ((!isResponseSuccessful || locationAlreadyInBasket) && serverErrors.length) {\n PCHelpers.showFeedbackMessage.bind(this)(serverErrors[0]);\n return;\n }\n\n this.PAID = paid;\n this.availableSpeed = speed;\n this.insertAdjacentHTML('afterEnd', responseHtml); // Inject the success or error html.\n\n // Dispatch the availability:update event so the page designer components reassign the event listeners.\n document.dispatchEvent(new CustomEvent('availability:update'));\n\n // Prevent default scrolling on IOS, so document is scrolled to top once results are populated.\n if (isIOS()) {\n const outputWrapper = document.querySelector('.js-postcode-response');\n scrollTo(outputWrapper.getBoundingClientRect());\n }\n\n if (unableToOrder && this.addressCheckAddress) {\n PCHelpers.handleUnableToOrder.bind(this)();\n }\n if (!unableToOrder) {\n const responseHeadingElement = this.parentElement.querySelector('.js-availability-response-address');\n responseHeadingElement.removeAttribute('unabletoorder');\n }\n\n if ((typeof address !== 'string' && address) || this.isOneNet) {\n // In scenarios where unableToOrder is true, the address is a string of undefined, in that case, we use addressCheckAddressParts.\n this.address = typeof address === 'string' && (address.includes('undefined') || address.length === 0) ? this.addressCheckAddressParts : address;\n this.setAddress.call(this);\n }\n\n // Store the saved address in a cookie so it can be restored when the form has been cleared - BO-1660.\n const addressData = {\n postcode: this.postcodeInputElement.value,\n houseNumber: this.houseNumberInputElement.value,\n paid: paid\n };\n\n if (this.additionSelectElement.selectedIndex) {\n addressData.addition = this.additionSelectElement.getAttribute('value');\n }\n\n // Availability form address cookie \"ADDRESS-{postcode}{housenumber}{addition}\"\n const availabilityFormAddressCookieName = `ADDRESS-${addressData.postcode.replace(' ', '')}${addressData.houseNumber}${addressData.addition || ''}`;\n const availabilityFormAddressCookie = `availabilityFormAddressData-${availabilityFormAddressCookieName}`;\n\n setCookie(availabilityFormAddressCookie, JSON.stringify(addressData), window.location.hostname, 0.5);\n\n document.dispatchEvent(new CustomEvent('postcodeChanged'));\n\n this.setBiState(responseHtml);\n PCHelpers.hideForm.bind(this)();\n }\n\n /**\n * @function executeAvailabilityCheck\n * @description Performs the availability check when the form is submitted and the address check is successful.\n * Updates the DOM with location data.\n */\n executeAvailabilityCheck() {\n spinner.start();\n\n PCHelpers.fetchAddressAndAvailability(this.action, this)\n .then(this.updateResult.bind(this))\n .then(this.enableProductConfiguration.bind(this))\n .then(this.updateURLs.bind(this))\n .then(this.disableUnavailableSpeeds.bind(this))\n .catch(PCHelpers.handleErrors.bind(this))\n .finally(this.showEditLocation.bind(this));\n }\n\n /**\n * @function handleAvailabilityFormSubmit\n * @param {FormEvent} event - Form submit event.\n * @description Handles the address check when the availability form is submitted. Then, if successful, it kicks of the availability check.\n */\n handleAvailabilityFormSubmit(event) {\n event.preventDefault();\n if (!this.checkValidity()) return;\n\n trackPdpEccomerceEvent(this.configuratorType, {\n name: 'Postcode check',\n number: 2\n });\n\n // BO-1570 - Address check has to be performed before availability check so that the availability check does not fire if the address is not found.\n this.addressCheck\n .executeAddressCheck()\n .then(this.executeAvailabilityCheck.bind(this))\n .catch((error) => PCHelpers.showFeedbackMessage.bind(this)(error)) // Handle rejection from promise returned in fn executeAddressCheck.\n .finally(spinner.stop);\n }\n\n /**\n * @function updateURLs\n * @description Updates all URLs to have the PAID. This does/should not execute for the PD postcode check component.\n */\n updateURLs() {\n if (!(this.success && this.PAID)) return;\n\n [...this.parentSelector.querySelectorAll('[data-url]')].forEach((element) => {\n const url = element.getAttribute('data-url');\n const newURL = appendParamToURL(url, 'paid', this.PAID);\n element.setAttribute('data-url', newURL);\n });\n }\n\n /**\n * @function disableUnavailableSpeeds\n * @description Disables speeds which are not available in a given region.\n */\n disableUnavailableSpeeds() {\n if (!(this.success && this.availableSpeed)) return;\n\n const speedNumber = parseInt(this.availableSpeed, 10);\n [...this.parentSelector.querySelectorAll('[name=\"tier\"]')].forEach((element) => {\n const elementValueNumber = parseInt(element.value, 10);\n if (elementValueNumber > speedNumber || (speedNumber === 1000 && elementValueNumber === 700)) {\n element.setAttribute('disabled', 'disabled');\n element.nextElementSibling.classList.add('opacity-50', 'pe-none');\n\n if (element.hasAttribute('checked')) {\n element.removeAttribute('checked');\n this.selectHighestPossibleTier();\n }\n } else {\n element.removeAttribute('disabled');\n element.nextElementSibling.classList.remove('opacity-50', 'pe-none');\n }\n });\n }\n\n /**\n * @function selectHighestPossibleTier\n * @description Sorts all the tiers on speed, filters out unavailable tiers and then makes the highest available tier active.\n * This does/should not execute for the PD postcode check component.\n */\n selectHighestPossibleTier() {\n if (this.isPageDesignerComponent) return;\n\n // Available tiers\n const tiers = [...this.form.querySelectorAll('[name=\"tier\"]:not(:disabled)')];\n\n // Highest tier first\n const sortedTiers = tiers.sort((a, b) => parseInt(b.value, 10) - parseInt(a.value, 10));\n\n // First available tier\n const highestPossibleSpeed = sortedTiers.find(\n (tier) => parseInt(tier.value, 10) === parseInt(this.availableSpeed, 10) || parseInt(tier.value, 10) <= parseInt(this.availableSpeed, 10)\n );\n\n // A change event needs to be triggered to initiate a new variation fetch\n const event = new Event('change', {\n bubbles: true,\n cancelable: true\n });\n highestPossibleSpeed.dispatchEvent(event);\n }\n\n /**\n * @function autoSubmitForm\n * @description Will auto submit the form on page load if the user is in edit mode and PAID is available.\n */\n autoSubmitForm() {\n this.PAID = this.hiddenInputWithPAID && this.hiddenInputWithPAID.value !== 'null' ? this.hiddenInputWithPAID.value : getParamFromURL(window.location.href, 'paid');\n\n // Availability form address cookie \"ADDRESS-{postcode}{housenumber}{addition}\"\n const availabilityFormAddressCookieName = this.PAID;\n const { postcode, houseNumber, addition, paid } = JSON.parse(getCookie(`availabilityFormAddressData-${availabilityFormAddressCookieName}`));\n\n // Restore the form field values so that this.checkValidity() passes, and the fields are filled if the user chooses to edit the address - BO-1660.\n if (postcode && houseNumber) {\n this.postcodeInputElement.value = postcode;\n this.houseNumberInputElement.value = houseNumber;\n\n if (addition) {\n this.additionSelectElement.value = addition;\n this.additionSelectElement.setAttribute('value', addition);\n }\n\n // Call setFieldStatus so the fields are formatted correctly.\n [this.postcodeInputElement, this.houseNumberInputElement].forEach((input) => input.setFieldStatus());\n }\n\n if (this.PAID && this.checkValidity()) {\n this.hiddenInputWithPAID.value = paid;\n const customEvent = new CustomEvent('submit');\n this.dispatchEvent(customEvent);\n }\n }\n\n setBiState(responseHtml) {\n const template = document.createElement('template');\n template.innerHTML = responseHtml;\n const isOrderable = template.content.querySelector('[data-bi-orderable]')?.getAttribute('data-bi-orderable');\n this.parentElement.closest('[data-configurator-type]')?.setAttribute('data-bi-orderable', isOrderable);\n }\n}\n\nif (!window.customElements.get('vz-postcode-check')) {\n window.customElements.define('vz-postcode-check', VZPostCodeCheck, { extends: 'form' });\n}\n","/**\n * @public setCookie\n * @param {string} cookieName - The cookie name\n * @param {string} cookieValue - The cookie value\n * @param {string} domain - The domain\n * @param {string} expirationDays - The expiration in days\n */\nfunction setCookie(cookieName, cookieValue, domain, expirationDays = 30) {\n const date = new Date();\n date.setTime(date.getTime() + expirationDays * 24 * 60 * 60 * 1000);\n const expires = `expires=${date.toUTCString()}`;\n const domainAndPath = `${domain ? `domain=${domain};` : ''}path=/; secure; sameSite=None`;\n const cookieString = `${cookieName}=${cookieValue};${expires};${domainAndPath}`;\n\n document.cookie = cookieString;\n}\n\n/**\n * @public getCookie\n * @param {string} cookieName - The cookie name\n * @return {string|null} The value of the cookie || null\n */\nfunction getCookie(cookieName) {\n const value = `; ${document.cookie}`;\n const parts = value.split(`; ${cookieName}=`);\n if (parts.length === 2) return parts.pop().split(';').shift();\n return null;\n}\n\nexport { setCookie, getCookie };\n","'use strict';\n\nconst computedStyles = getComputedStyle(document.documentElement);\n\n/**\n * @constant {Object} events - All common events\n * @property {string} blur - Blur event\n * @property {string} change - Change event\n * @property {string} click - Click event\n * @property {string} keyUp - Keyup event\n * @property {string} load - Load event\n * @property {string} mousedown - Mouse down event\n * @property {string} mouseleave - Mouse leave event\n * @property {string} mouseover - Mouse over event\n * @property {string} popstate - Popstate event\n * @property {string} resize - Resize event\n * @property {string} scroll - Scroll event\n * @property {string} submit - Submit event\n * @property {string} update - Custom update event\n */\nconst events = {\n blur: 'blur',\n change: 'change',\n click: 'click',\n input: 'input',\n keyUp: 'keyup',\n load: 'load',\n mousedown: 'mousedown',\n mouseleave: 'mouseleave',\n mouseover: 'mouseover',\n paste: 'paste',\n popstate: 'popstate',\n resize: 'resize',\n responseError: 'responseError',\n scroll: 'scroll',\n submit: 'submit',\n transitionEnd: 'transitionend',\n update: 'update',\n invalid: 'invalid'\n};\n\n/**\n * @constant {Object} selectors - Common selectors\n * @property {string} body - body\n * @property {Object} form - form related selectors\n * @property {string} checkbox - checkbox\n * @property {string} form - form\n * @property {string} input - input\n * @property {string} inputFieldClear - .js-input-clear\n * @property {string} inputFieldFeedback - .js-invalid-feedback\n * @property {string} label - label\n * @property {string} radio - radio\n * @property {string} select - select\n * @property {string} submit - [type=\"submit\"]\n * @property {string} textarea - textarea\n * @property {string} html - html\n * @property {string} htmlBody - html, body\n * @property {string} img - img\n * @property {string} input - input\n */\nconst selectors = {\n body: 'body',\n form: {\n checkbox: 'input[type=\"checkbox\"]',\n file: 'input[type=\"file\"]',\n form: 'form',\n input: 'input',\n inputFieldClear: '.js-input-clear',\n inputFieldFeedback: '.js-invalid-feedback',\n label: 'label',\n radio: 'input[type=\"radio\"]',\n select: 'select',\n submit: '[type=\"submit\"]',\n textarea: 'textarea'\n },\n html: 'html',\n htmlBody: 'html, body',\n img: 'img',\n input: 'input',\n interactiveElements: 'input, button, select, textarea, a[href]'\n};\n\n/**\n * @constant {Object} classes - Common classes\n * @property {string} active - active\n * @property {Object} buttons - buttons\n * @property {string} next - next\n * @property {string} previous - previous\n * @property {string} warning - warning\n * @property {string} dBlock - d-block\n * @property {string} dFlex - d-flex\n * @property {string} dInlineBlock - d-inline-block\n * @property {string} dNone - d-none\n * @property {string} disabled - disabled\n * @property {string} empty - empty\n * @property {string} inactive - inactive\n * @property {string} invalid - invalid\n * @property {string} hidden - hidden\n * @property {string} last - last\n * @property {string} show - show\n * @property {string} valid - valid\n */\nconst classes = {\n active: 'active',\n buttons: {\n next: 'js-button-next',\n previous: 'js-button-previous',\n warning: 'js-button-warning'\n },\n dBlock: 'd-block',\n dFlex: 'd-flex',\n dInlineBlock: 'd-inline-block',\n dNone: 'd-none',\n disabled: 'disabled',\n empty: 'empty',\n inactive: 'inactive',\n invalid: 'invalid',\n hidden: 'hidden',\n last: 'last',\n show: 'show',\n valid: 'valid'\n};\n\n/**\n * @constant {Object} attributes - Common attributes\n * @property {string} action - action\n * @property {string} class - class\n * @property {string} csrfToken - data-csrf-token\n * @property {string} csrfName - data-csrf-name\n * @property {string} disabled - disabled\n * @property {string} exclude - data-exclude\n * @property {string} href - href\n * @property {string} id - id\n * @property {string} pattern - pattern\n * @property {string} url - url\n * @property {string} readonly - readonly\n * @property {string} target - data-bs-target\n * @property {string} value - value\n * @property {Object} validation - Validation related attributes\n * @property {string} patternMismatch - data-pattern-mismatch\n * @property {string} valueMissing - data-missing-error\n */\nconst attributes = {\n action: 'action',\n class: 'class',\n checked: 'checked',\n csrfToken: 'data-csrf-token',\n csrfName: 'data-csrf-name',\n disabled: 'disabled',\n exclude: 'data-exclude',\n href: 'href',\n id: 'id',\n pattern: 'pattern',\n placeholder: 'placeholder',\n required: 'required',\n readonly: 'readonly',\n selected: 'selected',\n target: 'data-bs-target',\n url: 'url',\n value: 'value',\n validation: {\n patternMismatch: 'data-pattern-mismatch',\n valueMissing: 'data-missing-error',\n tooShort: 'data-too-short'\n }\n};\n\n/**\n * @constant {Object} breakpoints - Common reusable breakpoints\n * @property {string} xxs - 0\n * @property {string} xs - 368\n * @property {string} sm - 576\n * @property {string} md - 768\n * @property {string} lg - 992\n * @property {string} xl - 1200\n * @property {string} xxl - 1400\n */\n\nconst breakpoints = {\n xxs: parseInt(computedStyles.getPropertyValue('--breakpoint-xxs'), 10),\n xs: parseInt(computedStyles.getPropertyValue('--breakpoint-xs'), 10),\n sm: parseInt(computedStyles.getPropertyValue('--breakpoint-sm'), 10),\n md: parseInt(computedStyles.getPropertyValue('--breakpoint-md'), 10),\n lg: parseInt(computedStyles.getPropertyValue('--breakpoint-lg'), 10),\n xl: parseInt(computedStyles.getPropertyValue('--breakpoint-xl'), 10),\n xxl: parseInt(computedStyles.getPropertyValue('--breakpoint-xxl'), 10)\n};\n\n/**\n * @constant {Object} localStorage - constants for local storage items\n * @property {string} preferredLayoutId - preferredLayoutId\n */\nconst localStorage = {\n preferredLayoutId: 'preferredLayoutId'\n};\n\n/**\n * @constant {Object} bscanSteps - constants for Business Scan Steps\n * @property {string} ADVICE - The advice Step\n * @property {string} INTRO - The intro Step\n * @property {string} GROUPED_QUESTIONS - The grouped questions Step\n * @property {string} THANKYOU - The thank you Step\n */\nconst bscanSteps = {\n INTRO: 'intro',\n STATEMENTS_DONE: 'bs-statements-done',\n GROUPED_QUESTIONS: 'js-bscan-question-group',\n ADVICE: 'bs-advice',\n THANKYOU: 'bs-thank-you'\n};\n\n/**\n * @constant {Object} vzLayoutToggle - Attributes used for VZLayoutToggle\n * @property {string} class - data-layout-class\n * @property {string} container - data-layout-container\n * @property {string} enabledBreakpoint - data-layout-enabled-breakpoint\n * @property {string} id - data-layout-id\n * @property {string} idDefault - data-layout-id-default\n * @property {string} localStorageKey - data-layout-key\n */\nconst vzLayoutToggle = {\n class: 'data-layout-class',\n container: 'data-layout-container',\n enabledBreakpoint: 'data-layout-enabled-breakpoint',\n id: 'data-layout-id',\n idDefault: 'data-layout-id-default',\n localStorageKey: 'data-layout-key'\n};\n\nexport default {\n bscanSteps,\n attributes,\n breakpoints,\n classes,\n events,\n selectors,\n localStorage,\n vzLayoutToggle\n};\n","'use stict';\n\nimport 'core-js/features/array/at';\n\n/**\n * @private splitUpUrl\n * @param {string} url - The url to split up\n * @returns {Object} values\n *\n * @description\n * Will return an object with different parts of the url\n */\nexport function splitUpUrl(url) {\n if (!url.includes('?')) return {};\n\n let hash;\n let paramUrl = url.split('?').at(1);\n\n // if there is a hash at the end, store the hash\n if (paramUrl.includes('#')) {\n hash = paramUrl.split('#').at(1);\n paramUrl = paramUrl.split('#').at(0);\n }\n\n return {\n domain: url.split('?').at(0),\n params: paramUrl.split('&'),\n hash: hash\n };\n}\n\n/**\n * @public removeParamFromURL\n * @param {string} url - The url from which the parameter will be removed\n * @param {string} name - The name of the parameter that will be removed from url\n * @returns {string} url\n *\n * @description\n * remove the parameter and its value from the given url and returns the\n * changed url\n */\nexport function removeParamFromURL(url, name) {\n if (!url.includes('?') || !url.includes(`${name}=`)) return url;\n\n const urlValues = splitUpUrl(url);\n const newParams = urlValues.params.filter((param) => param.split('=').at(0) !== name);\n\n return `${urlValues.domain}?${newParams.join('&')}${urlValues.hash ? `#${urlValues.hash}` : ''}`;\n}\n\n/**\n * @public getParamFromURL\n * @param {string} url - The url from which the parameter will be retrieved\n * @param {string} name - The name of the parameter that will be retrieved from url\n * @returns {string} The value of the parameter\n *\n * @description\n * remove the parameter and its value from the given url and returns the\n * changed url\n */\nexport function getParamFromURL(url, name) {\n if (!url.includes('?') || !url.includes(`${name}=`)) return url;\n\n const urlValues = splitUpUrl(url);\n const nameMatch = urlValues.params.find((item) => item.includes(`${name}=`));\n\n return nameMatch && nameMatch.split('=').at(1);\n}\n\n/**\n * @public appendParamToURL\n * @param {string} url - The url to which the parameter will be added\n * @param {string} name - The name of the parameter\n * @param {string} value the value of the parameter\n * @returns {string} url\n *\n * @description\n * appends the parameter with the given name and value to the given url\n * and returns the changed url\n */\nexport function appendParamToURL(url, name, value) {\n let newURL = url;\n // remove if the param already exists\n if (url.includes(`${name}=`)) {\n newURL = removeParamFromURL(url, name);\n }\n const separator = newURL.includes('?') ? '&' : '?';\n return `${newURL}${separator}${name}=${encodeURIComponent(value)}`;\n}\n\n/**\n * @public appendCsrfToUrl\n * @description Takes a URL and adds a CSRF token to it\n * @param {string} url - The URL to append the CSRF token on\n * @returns {string} The URL with the CSRF token appended\n */\nexport function appendCsrfToUrl(url) {\n const separator = url.includes('?') ? '&' : '?';\n return `${url}${separator}${window.csrf.tokenName}=${window.csrf.token}`;\n}\n\n/**\n * @public removeHash\n * @description Will remove the hash from the url\n */\nexport function removeHash() {\n window.history.replaceState({}, document.title, window.location.pathname + window.location.search);\n}\n\nexport const getUrlFromAttributes = (url, component, excludedAttributes) => {\n const newUrl = new URL(url);\n const urlParams = newUrl.searchParams;\n\n // Get all attributeNames except for the irrelevant ones.\n const attributeNames = component.getAttributeNames().filter((attributeName) => !excludedAttributes.includes(attributeName));\n\n // Filter the attributeNames which will be replaced by the new URL.\n attributeNames\n .filter((param) => !urlParams.has(param.replaceAll('-', '')))\n .forEach((attr) => {\n const attrValue = component.getAttribute(attr);\n if (attrValue) {\n const attrName = attr.replaceAll('-', '');\n // Append all other attributes to the new URL\n urlParams.append(attrName, attrValue);\n }\n });\n\n return `${newUrl.origin}${newUrl.pathname}?${urlParams}`;\n};\n\n/**\n * This function checks if the provided element is a part of BM Hardware card. In case of true it appends\n * the 'editIndex' parameter to the URL with the index of the current BM Hardware card, in order to keep the\n * card open after Product-Variation ajax.\n *\n * @public appendBmHardwareCardIndex\n * @param {HTMLElement} element - The HTML element triggering the ajax.\n * @param {string} url - The URL to which the parameter will be appended.\n * @returns {string} The modified URL with the appended parameter.\n */\nexport function appendBmHardwareCardIndex(element, url) {\n let newURL = url;\n if (!element.closest('.js-hardware-device-card')?.classList.contains('is-collapsed') && element.closest('.js-hardware-phones')) {\n newURL = appendParamToURL(url, 'editIndex', element.closest('.js-hardware-phones').dataset.index);\n }\n return newURL;\n}\n","'use strict';\n\nimport CONST from './constants';\n\n/**\n * addEvent - Will add an event listener to an element inside a parent\n *\n * @param {string} parent - The parent element\n * @param {string} passedEvent - The event\n * @param {string} selector - The targeted element\n * @param {function} handler - The handler\n */\nfunction addEvent(parent, passedEvent, selector, handler) {\n parent.addEventListener(\n passedEvent,\n function fnAddEvent(event) {\n // If the clicked element matches the selector, or is a child of the selector\n if (event.target.matches(`${selector} , ${selector} *`)) {\n handler.apply(event.target.closest(selector), arguments);\n }\n },\n false\n );\n}\n\n/**\n * @public documentReady\n * @param {Function} fn - function to be called after document is done loading.\n */\nfunction documentReady(fn) {\n if (document.readyState !== 'loading') {\n fn();\n } else {\n document.addEventListener('DOMContentLoaded', fn);\n }\n}\n\n/**\n * @public exists\n * @param {*} selection - The element or nodelist to verify for existence\n * @returns {boolean} - Boolean value stating the existance of the selection\n * @description\n * Verifies existance of a certain element by checking for type, null and length\n * Usage: use with either querySelector() or querySelectorAll()\n * querySelector will not have a 'length', e.g. this would return true if other conditions are true\n * querySelectorAll will have a 'length', e.g. this would return true if all conditions are true\n */\nfunction exists(selection) {\n return typeof selection !== 'undefined' && selection !== null && ('length' in selection ? selection.length > 0 : true);\n}\n\n/**\n * @public getPosition\n * @param {*} element - The element to get the position for\n * @returns {Object} - An object containing the left and top position of the element\n *\n * @description\n * Will get the position of an element relative to the document\n */\nfunction getPosition(element) {\n let top = element.offsetTop;\n let left = element.offsetLeft;\n\n let currentElement = element;\n while (currentElement.offsetParent && currentElement.offsetParent !== window) {\n currentElement = currentElement.offsetParent;\n top += currentElement.offsetTop;\n left += currentElement.offsetLeft;\n }\n\n return { left, top };\n}\n\n/**\n * isKeyInObject\n * @param {Object} object - The object\n * @param {string} key - The key\n * @returns {boolean} - True or false\n */\nfunction isKeyInObject(object, key) {\n return Object.prototype.hasOwnProperty.call(object, key);\n}\n\n/**\n * @private isAemMobileView\n * @returns {boolean} - Whether the user is on a \"mobile\" viewport or not based on AEM rules\n *\n * @description\n * Checks to see whether the user is on a \"mobile\" viewport or not based on AEM rules\n * Please note that www.vodafone.nl/zakelijk will show the mobile menu from viewports 1023 and smaller\n */\nfunction isAemMobileView() {\n return window.innerWidth < 1024;\n}\n\n/**\n * @memberof util\n * @param {string} breakpointKey from constants that should match css breakpoint\n * @param {boolean} [isUp] by default is true since mobile first, reverses condition\n * @return {boolean} whether window is larger than specified breakpoint\n */\nfunction isMediaBreakpoint(breakpointKey, isUp = true) {\n if (!isKeyInObject(CONST.breakpoints, breakpointKey)) {\n console.error(`fn isMediaBreakpoint: ${breakpointKey} -- does not exist in constants breakpoints object`); // eslint-disable-line\n }\n\n const outerWidth = window.innerWidth;\n const breakpointValue = parseInt(CONST.breakpoints[breakpointKey], 10);\n\n return isUp ? outerWidth > breakpointValue : outerWidth < breakpointValue - 1;\n}\n\n/**\n * @memberof util\n * @return {Object} An object containing the name and value of the current breakpoint\n */\nfunction getCurrentBreakpoint() {\n const breakpoints = CONST.breakpoints;\n const screenSize = document.documentElement.clientWidth;\n const currentBreakpoint = [...Object.keys(breakpoints)].reverse().find((key) => screenSize > breakpoints[key]);\n\n return {\n name: currentBreakpoint,\n value: breakpoints[currentBreakpoint]\n };\n}\n\n/**\n * @memberof util\n * @return {number} a unique number\n */\nfunction generateUniqueNumber() {\n return performance.now().toString().replace('.', 0);\n}\n\n/**\n * @public empty\n * @param {*} element - The element to remove child nodes from\n * @description\n * Empties a given element completely while the given element has child nodes.\n * Plain strings are also considered child nodes and are thus also removed.\n */\nfunction removeChildNodes(element) {\n while (element.hasChildNodes()) {\n element.removeChild(element.lastChild);\n }\n}\n\n/**\n * @public tryParseJSON\n * @param {string} string - The possible JON string\n * @returns {Object} - Either the JSON object or an empty object for consistent return\n * @description\n * Copied from https://stackoverflow.com/a/20392392\n */\nfunction tryParseJSON(string) {\n try {\n const o = JSON.parse(string);\n\n // Handle non-exception-throwing cases:\n // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,\n // but... JSON.parse(null) returns null, and typeof null === \"object\",\n // so we must check for that, too. Thankfully, null is falsey, so this suffices:\n if (o && typeof o === 'object') {\n return o;\n }\n } catch (e) {} // eslint-disable-line no-empty\n\n return {};\n}\n\n/**\n * @function isIOS\n * @public\n * @description returns a boolean to determine whether a device's OS is IOS or not\n * @returns {boolean} whether the device OS is IOS or not\n */\nfunction isIOS() {\n return (/iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) && !window.MSStream;\n}\n\n/**\n * @function isMobile\n * @returns {boolean} whether the device is an mobile device or not\n */\nfunction isMobile() {\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);\n}\n\n/**\n * @public scrollTo\n * @param {Object} data - The optional object containing the top & left positions to scroll to\n */\nfunction scrollTo(data) {\n const position = data || {\n top: 0,\n left: 0\n };\n\n const stickyHeader = document.querySelector('.page-header');\n const headerHeight = stickyHeader ? stickyHeader.offsetHeight : 0;\n const supportsNativeSmoothScroll = 'scrollBehavior' in document.documentElement.style;\n let positionTop = position.top;\n\n if (headerHeight > 0) {\n positionTop = position.top - headerHeight - 15; // Removing an additional 15px to put some space between the sticky site header and the element\n }\n\n if (supportsNativeSmoothScroll) {\n document.documentElement.scrollTo({\n top: positionTop,\n left: position.left,\n behavior: 'smooth'\n });\n } else {\n document.documentElement.scrollTop = positionTop;\n }\n}\n\n/**\n * @function toggleButtonState\n * @description Enables or disabled the button passed in based on the value of the second parameter.\n * @param {HTMLElement} button - A button element to be enabled or disabled.\n * @param {boolean} enable - True for enable and false for disable.\n */\nfunction toggleButtonState(button, enable) {\n if (enable) {\n button.classList.remove('disabled');\n button.removeAttribute('disabled');\n } else {\n button.classList.add('disabled');\n button.setAttribute('disabled', 'disabled');\n }\n}\n\n/**\n * @function removeAccentCharacters\n * @description Removes a accents from a string.\n * @param {string} string - The string from which we want to remove accents.\n * @returns {string} The string without accents.\n */\nfunction removeAccentCharacters(string) {\n return string.normalize('NFD').replace(/\\p{Diacritic}/gu, '');\n}\n\n/**\n * @function chunkArrayInGroups\n * @param {Array} arr - Array to be splitted\n * @param {number} size - Max size of the array chunk\n * @return {Array} - Array of grouped chunks\n * @description Splitting an array up into chunks of a given size\n */\nfunction chunkArrayInGroups(arr, size) {\n var groupedChunks = [];\n for (let i = 0; i < arr.length; i += size) {\n groupedChunks.push(arr.slice(i, i + size));\n }\n return groupedChunks;\n}\n\n/**\n * @function chunkGroupArrayInGroups\n * @param {Array} groupArr - Array to be splitted\n * @return {Array} - Array of grouped chunks\n * @description Splitting an array up into chunks of a given size\n */\nfunction chunkGroupArrayInGroups(groupArr) {\n // This one sorts and groups the alike product groups together\n // We need to send the requests to backend in a specific order, so we make it grouped\n const chunkGroups = [];\n Object.keys(groupArr).forEach((groupKey) => {\n const arr = groupArr[groupKey];\n const groupedChunks = [];\n // Sorts the product objects based on pids\n arr.sort((a, b) => {\n return a.pid >= b.pid ? 1 : -1;\n });\n for (let i = 0; i < arr.length; i += Math.round(arr.length / 3)) {\n groupedChunks.push(arr.slice(i, i + Math.round(arr.length / 3)));\n }\n // This makes sure that we have a separate business mobile group to send to backend\n groupedChunks.forEach((chunk, chunkIndex) => {\n Object.keys(chunk).forEach((key, index) => {\n const item = chunk[key];\n if (item?.pdpConfiguratorType === 'business-mobile') {\n chunk.splice(index, 1);\n if (chunk.length < 1) groupedChunks.splice(chunkIndex, 1);\n groupedChunks.push(item);\n }\n });\n });\n chunkGroups.push(groupedChunks);\n });\n return chunkGroups;\n}\n\n/**\n * @function trackPdpEccomerceEvent\n * @param {string} productType - Configurator type\n * @param {Object} step - Step to track\n * @description Builds and submits ecommerce event to track btn clicks on PDP\n */\nfunction trackPdpEccomerceEvent(productType, step) {\n const products = {\n brand: 'vodafone',\n category: `business-sme/acquisition/postpaid/${productType.replace(/\\s|business-/gi, '')}`,\n market: 'b2b'\n };\n\n const ecommerceObject = {\n event: 'checkout',\n events: {\n category: 'ecommerce',\n action: 'checkout'\n },\n ecommerce: {\n checkout: {\n action: 'checkout',\n has_vodafone: true,\n has_ziggo: true,\n products: products,\n step_name: step.name,\n step_nr: step.number\n }\n }\n };\n\n /* eslint-disable no-underscore-dangle */\n if (ecommerceObject && window._ddm) {\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push(ecommerceObject);\n window._ddm.trigger('ecommerce.checkout', {\n data: ecommerceObject.ecommerce.checkout\n });\n }\n /* eslint-enable no-underscore-dangle */\n}\n\n/**\n * @function assignStyling\n * @private\n * @param {Element} el - Element\n * @param {Object} styles - Styles\n * @description Assign a style object to an element\n */\nfunction assignStyling(el, styles) {\n Object.assign(el.style, styles);\n}\n\n/**\n * Calculate the total width of a collection of elements.\n *\n * @param {NodeListOf} elements - A collection of HTML elements.\n * @param {number} spacing - flex gap value in px.\n * @returns {number} The total width of all elements.\n */\nfunction getTotalWidth(elements, spacing = 0) {\n return Array.from(elements).reduce((totalWidth, element) => {\n const elementStyles = window.getComputedStyle(element);\n const elementWidth = element.offsetWidth + parseFloat(elementStyles.marginLeft) + parseFloat(elementStyles.marginRight);\n return totalWidth + elementWidth;\n }, spacing);\n}\n\n/**\n * Checks if a flex container is wrapped by comparing the total width of its flex items\n * with the container's width.\n *\n * @param {HTMLElement} flexContainer - The HTML element representing the flex container.\n * @param {NodeListOf} flexItems - A collection of HTML elements representing the flex items.\n * @param {number} spacing - flex gap value in px.\n * @returns {boolean} True if the flex container is wrapped, false if all items fit in a single row.\n */\nfunction isFlexContainerWrapped(flexContainer, flexItems, spacing) {\n const containerWidth = flexContainer.clientWidth;\n const itemsTotalWidth = getTotalWidth(flexItems, spacing);\n // Check if the items are wrapped by comparing their total width with the container width.\n const isWrapped = itemsTotalWidth > containerWidth;\n return isWrapped;\n}\n\n/**\n * @function loadCSS\n * @param {string} url - The URL of the CSS file to load.\n * @description Creates a link element and appends it to the document head to load a CSS file.\n */\nfunction loadCSS(url) {\n if (!url || document.querySelector(`link[href=\"${url}\"]`)) {\n return;\n }\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = url;\n document.head.appendChild(link);\n}\n\n/**\n * The function formats input to money string\n *\n * @param {number} num Source number\n * @returns {string} Formatted string € 1.111,11\n */\nfunction formatToPriceString(num) {\n const parts = Number.parseFloat(num, 10).toFixed(2).toString().split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, '.');\n if (parts[1] === '00') {\n return `€ ${parts[0]},00`;\n }\n return `€ ${parts.join(',')}`;\n}\n\n/**\n * Checks if two arrays of objects are equal by comparing their elements.\n *\n * @param {Array} arr1 - The first array to compare.\n * @param {Array} arr2 - The second array to compare.\n * @returns {boolean} True if the arrays are equal, false otherwise.\n */\nfunction arraysAreEqual(arr1, arr2) {\n if (arr1.length !== arr2.length) {\n return false;\n }\n\n return (\n !arr1.some((obj1) => !arr2.some((obj2) => JSON.stringify(obj1) === JSON.stringify(obj2))) &&\n !arr2.some((obj2) => !arr1.some((obj1) => JSON.stringify(obj1) === JSON.stringify(obj2)))\n );\n}\n\nexport {\n CONST,\n addEvent,\n documentReady,\n exists,\n generateUniqueNumber,\n getCurrentBreakpoint,\n getPosition,\n isIOS,\n isMobile,\n isKeyInObject,\n isAemMobileView,\n isMediaBreakpoint,\n removeChildNodes,\n scrollTo,\n tryParseJSON,\n toggleButtonState,\n removeAccentCharacters,\n chunkArrayInGroups,\n chunkGroupArrayInGroups,\n trackPdpEccomerceEvent,\n assignStyling,\n isFlexContainerWrapped,\n getTotalWidth,\n loadCSS,\n formatToPriceString,\n arraysAreEqual\n};\n","'use strict';\n\nimport { CONST } from 'Util/util';\nimport { getFieldValidationMessage } from 'Components/form/form';\n\nconst validationAttributes = ['valueMissing', 'patternMismatch', 'tooShort'];\n\n/**\n * toggleValidityClass\n * @param {boolean} [isValid] - valid or not - true or false\n * @param {HTMLElement} [target] - target element\n */\nfunction toggleValidityClass(isValid, target) {\n if (isValid) {\n target.classList.remove('invalid');\n target.classList.add('valid');\n } else {\n target.classList.add('invalid');\n target.classList.remove('valid');\n }\n}\n\n/**\n * removeValidationMessageElement\n * @param {HTMLElement} [target] - target element\n */\nfunction removeValidationMessageElement(target) {\n const element = target.parentElement.querySelector('.error-msg');\n if (element) element.remove();\n}\n\n/**\n * createValidationMessageElement\n * @param {string} [message] - validation message\n * @param {HTMLElement} [target] - target element\n */\nfunction createValidationMessageElement(message, target) {\n const element =\n target.parentElement.querySelector('.error-msg') ||\n (function createErrorElement() {\n const el = document.createElement('small');\n el.classList.add('error-msg', 'text-primary');\n return el;\n })();\n element.innerText = message;\n if (target.dataset.selectedId && target.dataset.selectedId.includes('verblijfsdocument')) element.classList.add('d-inline-flex');\n target.parentElement.insertAdjacentElement('beforeend', element);\n}\n\n/**\n * @public validateField\n * @param {HTMLFormElement} field - The form field\n * @return {boolean} valid - Whether the field is valid or not\n */\nfunction validateField(field) {\n let validField = true;\n\n validationAttributes.forEach((attribute) => {\n if (field.validity && field.validity[attribute]) {\n const errorMessage = field.getAttribute(CONST.attributes.validation[attribute]);\n validField = false;\n createValidationMessageElement(errorMessage, field);\n toggleValidityClass(false, field);\n }\n });\n\n if (validField) {\n removeValidationMessageElement(field);\n toggleValidityClass(true, field);\n }\n\n return validField;\n}\n\n/**\n * @public validateForm\n * @param {HTMLForm} form - The form\n * @return {boolean} valid - Whether the form is valid or not\n */\nfunction validateForm(form) {\n let validForm = true;\n const formFields = [...form.querySelectorAll(CONST.selectors.form.input), ...form.querySelectorAll(CONST.selectors.form.textarea)];\n const dropdowns = [...form.querySelectorAll('.js-custom-select-validation')];\n\n formFields.forEach((field) => {\n if (field.type === 'hidden') {\n return;\n }\n\n const validField = validateField(field);\n\n if (!validField) {\n validForm = false;\n }\n });\n\n dropdowns.forEach((dropdown) => {\n const validField = dropdown.checkValidity();\n\n if (!validField) {\n validForm = false;\n }\n });\n\n return validForm;\n}\n\n/**\n * @private validate\n * @param {Event} evt - blur or invalid event\n * @param {string} [msg] - validation message\n */\nfunction validate(evt, msg) {\n const message = msg || getFieldValidationMessage(evt.target);\n if (message) {\n createValidationMessageElement(message, evt.target);\n toggleValidityClass(false, evt.target);\n } else {\n removeValidationMessageElement(evt.target);\n toggleValidityClass(true, evt.target);\n }\n}\n\nexport { validateForm, validateField, validate, removeValidationMessageElement, toggleValidityClass };\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","__webpack_require__.amdO = {};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","__webpack_require__.j = 26;","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t26: 0,\n\t274: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some((id) => (installedChunks[id] !== 0))) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = globalThis[\"webpackChunkvodafoneziggo\"] = globalThis[\"webpackChunkvodafoneziggo\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [395,661,139], () => (__webpack_require__(7552)))\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","redSpinnerData","require","VZSpinner","HTMLElement","constructor","parentEl","super","this","showing","stop","bind","veil","parentElement","document","body","tagName","appendChild","lottie","Lottie","container","querySelector","renderer","loop","autoplay","animationData","start","msg","Promise","resolve","window","getComputedStyle","getPropertyValue","style","position","classList","add","insertAdjacentHTML","setTimeout","play","contains","remove","content","connectedCallback","innerHTML","addEventListener","evt","stopPropagation","customElements","get","define","getFieldValidationMessage","field","validity","valid","required","value","length","getAttribute","checked","matches","pattern","RegExp","test","dataset","mask","invalid","invalidMin","invalidMax","multipleAdditions","bs","Modal","selectors","errorModal","activeModal","modalStepContainer","modalStep","modalStepInputs","showErrorModal","title","cta","errorModalHtml","existingModal","getElementById","getInstance","show","modal","CONST","events","popstate","hide","ID_TYPES_CODES","ID_VALIDATION_RULES","ID_TYPE","setValidationPattern","element","target","id","closest","dispatchEvent","CustomEvent","detail","type","regex","CapsMask","onInput","selectionStart","toUpperCase","setSelectionRange","UNDO_KEYS","PostCodeMask","onKeyUp","key","toLocaleLowerCase","some","k","substring","replace","IBANMask","DateMask","cursorIndex","maskText","pressedCharacters","onPaste","replaceRemovedDigitWithLetter","onArrowRight","onArrowLeft","onCharacterRemoval","checkIfDashIsSelected","replaceAsYouType","onKeyDown","runRegexOnValue","split","totalLengthUntilLastDigit","newVal","totalLength","join","cursorOffset","removedCharacter","splice","addDashes","direction","offset","replaceAt","index","replacement","isDigit","isNaN","allowedDash","hasSelection","repeat","preventDefault","selectionEnd","push","val","charRemoved","firstPressedCharacter","shift","maskType","preventCharacters","event","bannedCharacters","includes","clipboardData","dataWithoutBannedCharacters","getData","filter","character","currValue","end","substr","preventEntry","keyCode","documentNumber","name","toString","lastIndex","originalErrorMsg","patternError","selectedId","toLowerCase","startsWith","patternX00Error","patternVError","idType","Object","defineProperty","enumerable","configurable","Mask","password","feedbackElement","showPassword","set","readonly","hasAttribute","bool","forEach","enable","removeEventListener","disable","writable","VZInputField","HTMLInputElement","validatePattern","setFieldStatus","validate","decorators","disableExcludedFields","setAttribute","hasValue","placeholderIsShown","placeholderActive","selector","nodeName","extends","PostcodeCheckHelpers","stripLeadingZero","data","parseInt","preventDashDotComma","respectMaxLength","maxLength","slice","removePAID","hiddenInputWithPaid","hideForm","showForm","handleErrors","error","console","warn","JSON","parse","generalError","fetchAddressAndAvailability","endpoint","form","formData","FormData","append","csrf","tokenName","token","configuratorType","fetchOptions","method","response","fetch","ok","Error","status","json","removeExistingFeedbackMessage","classNames","existingMessages","querySelectorAll","message","showFeedbackMessage","isError","templateString","messageElement","DOMParser","parseFromString","handleUnableToOrder","responseHeadingElement","textContent","addressCheckAddress","pushErrorsToDataLayer","addressParts","locationAlreadyInBasket","dataLayer","postalCode","houseNumber","extension","paid","elementToPush","payload","erroneousAddressCombination","AddressCheck","availabilityForm","additionSelectElement","addressCheckEndpoint","addressCheckUrl","spinner","addition","handleAdditionOnBlur","input","handleAddressCheckOnBlur","executeAddressCheckOnLoad","sortAddressExtensions","addressInfoArray","sort","a","b","indexOfNoExtension","indexOf","find","address","extensionRequired","removeAdditionOptions","options","optionsArray","defaultOption","option","selectedIndex","generateAdditionElementOptions","addressInfo","hasMultipleExtensions","reduce","result","formattedAddress","stringifiedAddressParts","stringify","encodeURI","selectedExtensionOption","selected","addressCheckPAID","hiddenInputWithPAID","addressCheckAddressParts","decodeURI","checkValidity","toggleButtonState","submitButton","postcodeInputElement","houseNumberInputElement","every","executeAddressCheck","catch","PCHelpers","handleAddressNotFound","handleMultipleAdditions","addressCheckResponseData","additionHelpText","removeAttribute","handleSuccessfulAddressCheck","Event","reject","then","multipleExtensionsFound","success","serverErrors","finally","VZPostCodeCheck","HTMLFormElement","sidebar","pdpSubmitButtons","editMode","isPageDesignerComponent","parentSelector","isOneNet","isBusinessInternet","isSharedOneNetConfiguration","location","href","removeLocation","updateChatInfo","addressCheck","handleAvailabilityFormSubmit","autoSubmitForm","select","enableProductConfiguration","oneNetTierCard","map","card","isOneNetSeatSelectionEventFired","isOneNetSeatSelected","areOneNetSeatsBelowThreshold","shouldDisableOneNetConfiguration","elementsToEnable","Boolean","oneNetCriteria","unableToOrder","disableProductConfiguration","isEditLocation","nonTierOneNetCards","removeChild","elements","defaultDuration","showEditLocation","editButton","setAddress","houseNumberExtension","template","street","city","dataField","updateResult","availabilityCheckResponseData","isResponseSuccessful","speed","html","responseHtml","locationHasExistingSubscription","active","render","PAID","availableSpeed","isIOS","outputWrapper","scrollTo","getBoundingClientRect","call","addressData","postcode","cookieName","cookieValue","domain","expirationDays","date","Date","setTime","getTime","cookieString","toUTCString","cookie","setCookie","hostname","setBiState","executeAvailabilityCheck","action","updateURLs","disableUnavailableSpeeds","trackPdpEccomerceEvent","number","url","newURL","appendParamToURL","speedNumber","elementValueNumber","nextElementSibling","selectHighestPossibleTier","highestPossibleSpeed","tier","bubbles","cancelable","getParamFromURL","availabilityFormAddressCookieName","parts","pop","getCookie","customEvent","createElement","isOrderable","computedStyles","documentElement","bscanSteps","INTRO","STATEMENTS_DONE","GROUPED_QUESTIONS","ADVICE","THANKYOU","attributes","class","csrfToken","csrfName","disabled","exclude","placeholder","validation","patternMismatch","valueMissing","tooShort","breakpoints","xxs","xs","sm","md","lg","xl","xxl","classes","buttons","next","previous","warning","dBlock","dFlex","dInlineBlock","dNone","empty","inactive","hidden","last","blur","change","click","keyUp","load","mousedown","mouseleave","mouseover","paste","resize","responseError","scroll","submit","transitionEnd","update","checkbox","file","inputFieldClear","inputFieldFeedback","label","radio","textarea","htmlBody","img","interactiveElements","localStorage","preferredLayoutId","vzLayoutToggle","enabledBreakpoint","idDefault","localStorageKey","splitUpUrl","hash","paramUrl","at","params","nameMatch","item","urlValues","newParams","param","removeParamFromURL","separator","encodeURIComponent","navigator","platform","maxTouchPoints","MSStream","top","left","stickyHeader","headerHeight","offsetHeight","supportsNativeSmoothScroll","positionTop","behavior","scrollTop","button","productType","step","ecommerceObject","category","ecommerce","checkout","has_vodafone","has_ziggo","products","brand","market","step_name","step_nr","_ddm","trigger","toggleValidityClass","isValid","removeValidationMessageElement","createValidationMessageElement","el","innerText","insertAdjacentElement","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","m","amdO","O","chunkIds","fn","priority","notFulfilled","Infinity","i","fulfilled","j","keys","r","n","getter","__esModule","d","definition","o","g","globalThis","Function","e","obj","prop","prototype","hasOwnProperty","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","chunkLoadingGlobal","__webpack_exports__"],"sourceRoot":""}