UNPKG

@stormid/cookie-banner

Version:

GDPR compliant cookie banner

1 lines 40.9 kB
{"version":3,"file":"index.modern.mjs","sources":["../src/lib/constants.js","../src/lib/utils.js","../src/lib/defaults.js","../src/lib/reducers.js","../src/lib/consent.js","../src/lib/ui.js","../src/lib/factory.js","../src/index.js","../src/lib/store.js"],"sourcesContent":["/* istanbul ignore file */\nexport const ACCEPTED_TRIGGERS = ['button', 'a'];\n\nexport const FOCUSABLE_ELEMENTS = ['a[href]', 'area[href]', 'input:not([disabled]):not([type=hidden])', 'select:not([disabled])', 'textarea:not([disabled])', 'button:not([disabled])', 'iframe', 'object', 'embed', '[contenteditable]', '[tabindex]:not([tabindex=\"-1\"])'];\n\nexport const EVENTS = {\n SHOW: 'banner.show',\n HIDE: 'banner.hide',\n CONSENT: 'banner.consent'\n};","import { FOCUSABLE_ELEMENTS } from './constants';\n\n//Modernizr cookie test\nexport const cookiesEnabled = () => {\n try {\n document.cookie = 'cookietest=1';\n const ret = document.cookie.indexOf('cookietest=') !== -1;\n document.cookie = 'cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT';\n return ret;\n } catch (error) {\n return false;\n }\n};\n\nexport const writeCookie = state => {\n document.cookie = [\n `${state.settings.name}=${btoa(JSON.stringify({ consent: state.consent }))};`,\n `expires=${(new Date(new Date().getTime() + (state.settings.expiry*24*60*60*1000))).toGMTString()};`,\n state.settings.path ? `path=${state.settings.path};` : '',\n state.settings.domain ? `domain=${state.settings.domain};` : '',\n state.settings.samesite ? `SameSite=${state.settings.samesite};` : '',\n state.settings.secure ? `secure` : ''\n ].join('');\n};\n\nexport const readCookie = settings => {\n const cookies = document.cookie.split('; ');\n for (let n = 0; n <= cookies.length; n++) {\n if (!cookies[n]) return false;\n const [ name, value ] = cookies[n].split('=');\n if (name === settings.name) return window.atob(value);\n }\n return false;\n};\n\nconst updateCookie = (state, cookie) => document.cookie = [\n `${cookie.name}=${cookie.value};`,\n `expires=${cookie.expiry};`,\n `path=${state.settings.path};`,\n state.settings.domain ? `domain=${state.settings.domain};` : '',\n state.settings.samesite ? `SameSite=${state.settings.samesite};` : '',\n state.settings.secure ? `secure` : ''\n].join('');\n\nexport const deleteCookies = state => {\n document.cookie\n .split('; ')\n .map(part => ({\n name: part.split('=')[0],\n value: part.split('=')[1],\n expiry: 'Thu, 01 Jan 1970 00:00:01 GMT'\n }))\n .map(cookie => updateCookie(state, cookie));\n};\n\nexport const extractFromCookie = settings => {\n try {\n const cookie = readCookie(settings);\n if (!cookie) return [false, {}];\n const { consent } = JSON.parse(cookie);\n const hasCookie = consent !== undefined;\n if (!categoriesMatch(Object.keys(consent), Object.keys(settings.types))) return [false, {}];\n return [hasCookie, consent || {}];\n } catch (e){\n return [false, {}];\n }\n};\n\nconst categoriesMatch = (found, categories) => {\n if (found.length !== categories.length) return false;\n for (const category of categories) {\n if (found.indexOf(category) === -1) return false;\n }\n return true;\n};\n\nexport const isCheckable = field => (/radio|checkbox/i).test(field.type);\n\nconst hasValue = input => (input.value !== undefined && input.value !== null && input.value.length > 0);\n\nexport const groupValueReducer = (acc, input) => {\n if (!isCheckable(input) && hasValue(input)) acc = input.value;\n if (isCheckable(input) && input.checked) {\n if (Array.isArray(acc)) acc.push(input.value);\n else acc = [input.value];\n }\n return acc;\n};\n\nconst firstTLDs = 'ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|be|bf|bg|bh|bi|bj|bm|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|cl|cm|cn|co|cr|cu|cv|cw|cx|cz|de|dj|dk|dm|do|dz|ec|ee|eg|es|et|eu|fi|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|im|in|io|iq|ir|is|it|je|jo|jp|kg|ki|km|kn|kp|kr|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|na|nc|ne|nf|ng|nl|no|nr|nu|nz|om|pa|pe|pf|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|yt'.split('|');\nconst secondTLDs = 'netlify|azurewebsites|com|edu|gov|net|mil|org|nom|sch|caa|res|off|gob|int|tur|ip6|uri|urn|asn|act|nsw|qld|tas|vic|pro|biz|adm|adv|agr|arq|art|ato|bio|bmd|cim|cng|cnt|ecn|eco|emp|eng|esp|etc|eti|far|fnd|fot|fst|g12|ggf|imb|ind|inf|jor|jus|leg|lel|mat|med|mus|not|ntr|odo|ppg|psc|psi|qsl|rec|slg|srv|teo|tmp|trd|vet|zlg|web|ltd|sld|pol|fin|k12|lib|pri|aip|fie|eun|sci|prd|cci|pvt|mod|idv|rel|sex|gen|nic|abr|bas|cal|cam|emr|fvg|laz|lig|lom|mar|mol|pmn|pug|sar|sic|taa|tos|umb|vao|vda|ven|mie|北海道|和歌山|神奈川|鹿児島|ass|rep|tra|per|ngo|soc|grp|plc|its|air|and|bus|can|ddr|jfk|mad|nrw|nyc|ski|spy|tcm|ulm|usa|war|fhs|vgs|dep|eid|fet|fla|flå|gol|hof|hol|sel|vik|cri|iwi|ing|abo|fam|gok|gon|gop|gos|aid|atm|gsm|sos|elk|waw|est|aca|bar|cpa|jur|law|sec|plo|www|bir|cbg|jar|khv|msk|nov|nsk|ptz|rnd|spb|stv|tom|tsk|udm|vrn|cmw|kms|nkz|snz|pub|fhv|red|ens|nat|rns|rnu|bbs|tel|bel|kep|nhs|dni|fed|isa|nsn|gub|e12|tec|орг|обр|упр|alt|nis|jpn|mex|ath|iki|nid|gda|inc'.split('|');\n\nexport const removeSubdomain = s => {\n s = s.replace(/^www\\./, '');\n let parts = s.split('.');\n \n while (parts.length > 3) {\n parts.shift();\n }\n\n if (parts.length === 3 && ((secondTLDs.indexOf(parts[1]) === -1) && firstTLDs.indexOf(parts[2]) === -1)) {\n parts.shift();\n }\n\n return parts.join('.');\n};\n\nexport const getFocusableChildren = node => [].slice.call(node.querySelectorAll(FOCUSABLE_ELEMENTS.join(','))).filter(el => el.offsetWidth > 0 || el.offsetHeight > 0);\n\nexport const broadcast = (type, store) => () => {\n const event = new CustomEvent(type, {\n bubbles: true,\n detail: {\n getState: store.getState\n }\n });\n window.document.dispatchEvent(event);\n};\n\nexport const renderIframe = () => {\n [].slice.call(document.querySelectorAll('[data-iframe-src]')).forEach(node => {\n const iframe = document.createElement('iframe');\n iframe.src = node.getAttribute('data-iframe-src');\n if (node.hasAttribute('data-iframe-height')) iframe.style.height = node.getAttribute('data-iframe-height');\n iframe.setAttribute('title', node.getAttribute('data-iframe-title') || 'iFrame embed');\n if (node.hasAttribute('data-iframe-width')) iframe.style.width = node.getAttribute('data-iframe-width' || '100%');\n iframe.setAttribute('tabindex', '0');\n iframe.setAttribute('frameborder', '0');\n iframe.setAttribute('webkitallowfullscreen', 'webkitallowfullscreen');\n iframe.setAttribute('mozallowfullscreen', 'mozallowfullscreen');\n iframe.setAttribute('allowfullscreen', 'allowfullscreen');\n node.parentNode.appendChild(iframe);\n node.parentNode.removeChild(node);\n });\n};\n\nexport const gtmSnippet = id => {\n !function(e, t, c, n, w, o) {\n e[n] = e[n] || [], e[n].push({\n \"gtm.start\": (new Date).getTime(),\n event: \"gtm.js\"\n });\n var r = t.getElementsByTagName(c)[0], \n s = t.createElement(c);\n s.async = !0, s.src = 'https://www.googletagmanager.com/gtm.js?id=' + w, r.parentNode.insertBefore(s, r)\n }(window, document, \"script\", \"dataLayer\", id);\n};\n\n/* eslint-disable prefer-rest-params */\nfunction gtag() {\n window.dataLayer = window.dataLayer || [];\n //The Google libraries that use the dataLayer do not work if arguments are spread\n //or data is passed in as an array\n window.dataLayer.push(arguments);\n}\n\nexport const setGoogleConsent = (store, pushType = 'update') => () => {\n const { settings, consent } = store.getState();\n const { euConsentTypes } = settings;\n if (!euConsentTypes) return;\n \n const euConsent = Object.keys(euConsentTypes).reduce((acc, type) => {\n if (Object.keys(consent).length > 0 && consent[euConsentTypes[type]] === undefined) {\n console.warn(`Cannot find consent type '${euConsentTypes[type]}' in preferences cookie, check your euConsentTypes configuration matches your cookie types`);\n }\n acc[type] = (consent[euConsentTypes[type]] && pushType === 'update') ? 'granted' : 'denied';\n return acc;\n }, {});\n if (pushType !== 'update') euConsent['wait_for_update'] = 500;\n\n gtag('consent', pushType, euConsent);\n};","/* istanbul ignore file */\nimport { removeSubdomain } from './utils';\n\nexport default {\n name: '.CookiePreferences',\n path: '/',\n domain: window.location.hostname === 'localhost' ? '' : `.${removeSubdomain(window.location.hostname)}`,\n secure: true,\n samesite: 'strict',\n expiry: 365,\n types: {},\n necessary: [],\n policyURL: '/cookie-policy/#preferences',\n classNames: {\n banner: 'privacy-banner',\n acceptBtn: 'privacy-banner__accept',\n rejectBtn: 'privacy-banner__reject',\n submitBtn: 'privacy-banner__submit',\n optionsBtn: 'privacy-banner__options',\n field: 'privacy-banner__field',\n form: 'privacy-banner__form',\n fieldset: 'privacy-banner__fieldset',\n legend: 'privacy-banner__legend',\n formContainer: 'privacy-banner__form-container',\n formMessage: 'privacy-banner__form-msg',\n formAnnouncement: 'privacy-banner__form-announcement',\n title: 'privacy-banner__form-title',\n description: 'privacy-banner__form-description',\n bannerToggle: 'on--privacy-banner-toggle',\n bannerToggleTrigger: 'js-toggle-btn'\n },\n hideBannerOnFormPage: true,\n trapTab: false,\n savedMessage: 'Your settings have been saved.',\n bannerTemplate(model){\n return `<div role=\"region\" aria-live=\"polite\" aria-label=\"Your privacy\" class=\"${model.classNames.banner}\">\n <div class=\"privacy-content\">\n <div class=\"wrap\">\n <!--googleoff: all-->\n <div class=\"privacy-banner__title\">Cookies</div>\n <p>We use cookies to improve your experience on our site and show you personalised advertising.</p>\n <p>Find out more from our <a class=\"privacy-banner__link\" rel=\"noopener noreferrer nofollow\" href=\"/privacy-policy\">privacy policy</a> and <a class=\"privacy-banner__link\" rel=\"noopener noreferrer nofollow\" href=\"${model.policyURL}\">cookie policy</a>.</p>\n <button type=\"button\" class=\"btn btn--primary ${model.classNames.acceptBtn}\">Accept all</button>\n <button type=\"button\" class=\"btn btn--primary ${model.classNames.rejectBtn}\">Reject all</button>\n <a class=\"privacy-banner__link ${model.classNames.optionsBtn}\" rel=\"noopener noreferrer nofollow\" href=\"${model.policyURL}\">Your options</a>\n <!--googleon: all-->\n </div>\n </div>\n </div>`;\n },\n messageTemplate(model){\n return `<div class=\"${model.settings.classNames.formMessage}\" aria-hidden=\"true\">${model.settings.savedMessage}</div>`;\n },\n formTemplate(model){\n return `<form id=\"preferences\" class=\"${model.settings.classNames.form}\" novalidate>\n ${Object.keys(model.settings.types).map(type => `<fieldset class=\"${model.settings.classNames.fieldset}\">\n <legend class=\"${model.settings.classNames.legend}\">\n <span class=\"${model.settings.classNames.title}\">${model.settings.types[type].title}</span>\n <span class=\"${model.settings.classNames.description}\">${model.settings.types[type].description}</span>\n </legend>\n <div class=\"form-row\">\n <div class=\"relative\">\n <label class=\"privacy-banner__label\">\n <input\n class=\"${model.settings.classNames.field}\"\n type=\"radio\"\n name=\"privacy-${type.split(' ')[0].replace(' ', '-')}\"\n value=\"1\"\n ${model.consent[type] === 1 ? `checked` : ''}>\n <span class=\"privacy-banner__label-text\">I am OK with this</span>\n <span class=\"privacy-banner__label-description\">${model.settings.types[type].labels.yes}</span>\n </label> \n </div>\n </div>\n <div class=\"form-row\">\n <div class=\"relative\">\n <label class=\"privacy-banner__label\">\n <input\n class=\"${model.settings.classNames.field}\"\n type=\"radio\"\n name=\"privacy-${type.split(' ')[0].replace(' ', '-')}\"\n value=\"0\"\n ${model.consent[type] === 0 ? `checked` : ''}>\n <span class=\"privacy-banner__label-text\">No thank you</span>\n <span class=\"privacy-banner__label-description\">${model.settings.types[type].labels.no}</span>\n </label> \n </div>\n </div>\n </fieldset>`).join('')}\n <button class=\"${model.settings.classNames.submitBtn}\"${Object.keys(model.consent).length !== Object.keys(model.settings.types).length ? ` disabled` : ''}>Save my settings</button>\n </form>`;\n }\n};","export const updateBannerOpen = (state, data) => Object.assign({}, state, {\n bannerOpen: data\n});\n\nexport const updateBanner = (state, data) => Object.assign({}, state, {\n banner: data.banner,\n bannerOpen: data.bannerOpen\n});\n\nexport const updateConsent = (state, data) => Object.assign({}, state, {\n consent: Object.assign({}, state.consent, data)\n});\n\nexport const updateExecuted = (state, data) => Object.assign({}, state, {\n settings: Object.assign({}, state.settings, {\n types: Object.assign({}, state.settings.types, data)\n })\n});","import { updateExecuted } from './reducers';\n\nexport const applyEffects = state => {\n Object.keys(state.consent).forEach(key => {\n if (!state.settings.types[key]) return;\n if (state.settings.types[key].executed === true) return;\n if (state.consent[key] && Boolean(state.consent[key]) && state.settings.types[key].fns) {\n state.settings.types[key].fns.forEach(fn => fn(state));\n }\n });\n};\n\nexport const apply = store => state => {\n applyEffects(state);\n store.update(\n updateExecuted(\n state,\n Object.keys(state.settings.types).reduce((acc, type) => {\n acc[type] = {\n ...state.settings.types[type],\n executed: state.settings.types[type].executed || (state.consent[type] && Boolean(state.consent[type]))\n };\n return acc;\n }, {})\n )\n );\n};\n\nexport const necessary = state => {\n state.settings.necessary.forEach(fn => fn(state));\n};","import { writeCookie, groupValueReducer, deleteCookies, getFocusableChildren, broadcast, setGoogleConsent } from './utils';\nimport { ACCEPTED_TRIGGERS, EVENTS } from './constants';\nimport { apply } from './consent';\nimport { updateConsent, updateBannerOpen, updateBanner } from './reducers';\n\nexport const initBanner = store => () => {\n const state = store.getState();\n if (state.bannerOpen || (state.settings.hideBannerOnFormPage && document.querySelector(`.${state.settings.classNames.formContainer}`))) return;\n document.body.firstElementChild.insertAdjacentHTML('beforebegin', state.settings.bannerTemplate(state.settings));\n \n store.update(\n updateBanner(state, {\n banner: document.querySelector(`.${state.settings.classNames.banner}`),\n bannerOpen: true\n }),\n [ broadcast(EVENTS.SHOW, store) ]\n );\n\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push({ event: 'stormcb_display' });\n};\n\nexport const showBanner = store => callback => {\n initBanner(store)();\n if (!store.getState().bannerOpen) return;\n initForm(store)();\n const focusableChildren = getFocusableChildren(document.body.firstElementChild);\n if (focusableChildren.length > 0) focusableChildren[0].focus();\n if (callback && callback.call) callback(store.getState());\n};\n\nexport const initBannerListeners = store => () => {\n const state = store.getState();\n const banner = state.banner;\n if (!banner) return;\n\n const composeSelector = classSelector => ACCEPTED_TRIGGERS.map(sel => `${sel}.${classSelector}`).join(', ');\n\n const composeConsentObjects = (event, consentVal) => {\n const consentObject = Object.keys(state.settings.types).reduce((acc, type) => {\n acc[type] = consentVal;\n return acc;\n },{});\n const analyticsObject = Object.entries(consentObject).reduce((acc, [key, value]) => {\n acc['stormcb_'+key] = value;\n return acc;\n }, { event: `stormcb_${event}_all` });\n return {\n consentObject,\n analyticsObject\n };\n };\n\n const acceptBtns = [].slice.call(document.querySelectorAll(composeSelector(state.settings.classNames.acceptBtn)));\n const rejectBtns = [].slice.call(document.querySelectorAll(composeSelector(state.settings.classNames.rejectBtn)));\n\n if (state.settings.trapTab) document.addEventListener('keydown', state.keyListener);\n\n acceptBtns.forEach(acceptBtn => {\n acceptBtn.addEventListener('click', e => {\n const { consentObject, analyticsObject } = composeConsentObjects('accept', 1);\n const state = store.getState();\n store.update(\n updateConsent(state, consentObject),\n [\n deleteCookies,\n writeCookie,\n apply(store),\n removeBanner(store),\n initForm(store),\n () => {\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push(analyticsObject);\n },\n broadcast(EVENTS.CONSENT, store),\n setGoogleConsent(store),\n ]\n );\n });\n });\n\n rejectBtns.forEach(rejectBtn => {\n rejectBtn.addEventListener('click', e => {\n const { consentObject, analyticsObject } = composeConsentObjects('reject', 0);\n const state = store.getState();\n store.update(\n updateConsent(state, consentObject),\n [\n writeCookie,\n removeBanner(store),\n initForm(store),\n () => {\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push(analyticsObject);\n },\n broadcast(EVENTS.CONSENT, store),\n setGoogleConsent(store),\n ]\n );\n });\n });\n};\n\nconst trapTab = state => event => {\n const focusableChildren = getFocusableChildren(state.banner);\n const focusedIndex = focusableChildren.indexOf(document.activeElement);\n\n if (event.shiftKey && focusedIndex === 0) {\n event.preventDefault();\n focusableChildren[focusableChildren.length - 1].focus();\n } else if (!event.shiftKey && focusedIndex === focusableChildren.length - 1) {\n event.preventDefault();\n focusableChildren[0].focus();\n }\n};\n\nexport const keyListener = store => event => {\n if (store.getState().banner && event.keyCode === 9) trapTab(store.getState())(event);\n};\n\nconst removeBanner = store => () => {\n const state = store.getState();\n const banner = state.banner;\n if (banner && banner.parentNode) {\n banner.parentNode.removeChild(banner);\n store.update(updateBannerOpen(state, false), [ broadcast(EVENTS.HIDE, store) ]);\n }\n if (state.settings.trapTab) document.removeEventListener('keydown', state.keyListener);\n};\n\nconst suggestedConsent = state => Object.keys(state.consent).length > 0\n ? state\n : Object.assign({}, state, {\n consent: Object.keys(state.settings.types).reduce((acc, type) => {\n if (state.settings.types[type].suggested) acc[type] = 1;\n return acc;\n }, {})\n });\n\nexport const initForm = store => () => {\n const state = store.getState();\n const formContainer = document.querySelector(`.${state.settings.classNames.formContainer}`);\n if (!formContainer) return;\n\n formContainer.innerHTML = state.settings.formTemplate(suggestedConsent(state));\n\n const form = document.querySelector(`.${state.settings.classNames.form}`);\n const button = document.querySelector(`.${state.settings.classNames.submitBtn}`);\n const groups = [].slice.call(document.querySelectorAll(`.${state.settings.classNames.field}`)).reduce((groups, field) => {\n const groupName = field.getAttribute('name').replace('privacy-', '');\n if (groups[groupName]) groups[groupName].push(field);\n else groups[groupName] = [field];\n return groups;\n }, {});\n const formAnnouncement = document.querySelector(`.${state.settings.classNames.formAnnouncement}`)\n || document.body.appendChild(Object.assign(document.createElement('div'), { className: state.settings.classNames.formAnnouncement, role: 'alert' }));\n\n\n const extractConsentObjects = () => {\n const consentObject = Object.keys(groups).reduce((acc, key) => {\n const value = groups[key].reduce(groupValueReducer, '');\n if (value) acc[key] = parseInt(value, 10);\n return acc;\n }, {});\n\n const analyticsObject = Object.entries(consentObject).reduce((acc, [key, value]) => {\n acc['stormcb_'+key] = value;\n return acc;\n }, { event: `stormcb_save` });\n\n return {\n consentObject,\n analyticsObject\n };\n };\n\n const enableButton = e => {\n if (Object.keys(extractConsentObjects().consentObject).length !== Object.keys(groups).length) return;\n button.removeAttribute('disabled');\n form.removeEventListener('change', enableButton);\n };\n button.hasAttribute('disabled') && form.addEventListener('change', enableButton);\n \n form.addEventListener('submit', event => {\n event.preventDefault();\n const { consentObject, analyticsObject } = extractConsentObjects();\n const state = store.getState();\n store.update(\n updateConsent(state, consentObject),\n [\n deleteCookies,\n writeCookie,\n apply(store),\n removeBanner(store),\n () => {\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push(analyticsObject);\n },\n broadcast(EVENTS.CONSENT, store),\n renderMessage(button),\n renderAnnouncement(formAnnouncement),\n setGoogleConsent(store),\n ]\n );\n });\n\n if (window.location.hash.substring(1) === form.id) {\n window.scrollTo(0, form.getBoundingClientRect().top + window.scrollY);\n }\n};\n\nexport const renderMessage = button => state => {\n button.insertAdjacentHTML('afterend', state.settings.messageTemplate(state));\n button.setAttribute('disabled', 'disabled');\n /* istanbul ignore next */\n window.setTimeout(() => {\n button.parentNode.removeChild(button.nextElementSibling);\n button.removeAttribute('disabled');\n }, 3000);\n};\n\nexport const renderAnnouncement = container => state => {\n container.textContent = state.settings.savedMessage;\n /* istanbul ignore next */\n window.setTimeout(() => {\n container.textContent = '';\n }, 3000);\n};","import { cookiesEnabled, extractFromCookie, renderIframe, gtmSnippet, setGoogleConsent } from './utils';\nimport { showBanner, initBanner, initForm, initBannerListeners, keyListener } from './ui';\nimport { necessary, apply } from './consent';\nimport { createStore } from './store';\n\nexport default settings => {\n /* istanbul ignore next */\n if (!cookiesEnabled()) return;\n const store = createStore();\n \n const [ hasCookie, consent ] = extractFromCookie(settings);\n \n store.update(\n {\n settings,\n bannerOpen: false,\n keyListener: keyListener(store),\n consent,\n utils: { renderIframe, gtmSnippet }\n },\n [\n necessary,\n setGoogleConsent(store, 'default'),\n apply(store),\n ...(hasCookie ? [] : [ initBanner(store) ]),\n initForm(store),\n initBannerListeners(store),\n ...(hasCookie ? [ setGoogleConsent(store) ] : [])\n ]\n );\n\n return {\n getState: store.getState,\n showBanner(cb) {\n showBanner(store)(cb);\n initBannerListeners(store)();\n },\n renderForm: initForm(store)\n };\n};","import defaults from './lib/defaults';\nimport factory from './lib/factory';\n\nexport default opts => factory(Object.assign({}, defaults, opts));","export const createStore = () => {\n let state = {};\n \n const getState = () => state;\n\n const update = (nextState, effects) => {\n state = nextState ?? state;\n if (!effects) return;\n effects.forEach(effect => effect(state));\n };\n \n return { update, getState };\n};"],"names":["ACCEPTED_TRIGGERS","FOCUSABLE_ELEMENTS","EVENTS","writeCookie","state","document","cookie","settings","name","btoa","JSON","stringify","consent","Date","getTime","expiry","toGMTString","path","domain","samesite","secure","join","deleteCookies","split","map","part","value","updateCookie","isCheckable","field","test","type","groupValueReducer","acc","input","length","hasValue","checked","Array","isArray","push","firstTLDs","secondTLDs","getFocusableChildren","node","slice","call","querySelectorAll","filter","el","offsetWidth","offsetHeight","broadcast","store","event","CustomEvent","bubbles","detail","getState","window","dispatchEvent","renderIframe","forEach","iframe","createElement","src","getAttribute","hasAttribute","style","height","setAttribute","width","parentNode","appendChild","removeChild","gtmSnippet","id","e","t","c","n","w","r","getElementsByTagName","s","async","insertBefore","setGoogleConsent","pushType","euConsentTypes","euConsent","Object","keys","reduce","undefined","console","warn","dataLayer","arguments","gtag","defaults","location","hostname","parts","replace","shift","indexOf","removeSubdomain","types","necessary","policyURL","classNames","banner","acceptBtn","rejectBtn","submitBtn","optionsBtn","form","fieldset","legend","formContainer","formMessage","formAnnouncement","title","description","bannerToggle","bannerToggleTrigger","hideBannerOnFormPage","trapTab","savedMessage","bannerTemplate","model","messageTemplate","formTemplate","labels","yes","no","updateConsent","data","assign","apply","key","executed","Boolean","fns","fn","applyEffects","update","updateExecuted","_extends","initBanner","bannerOpen","querySelector","body","firstElementChild","insertAdjacentHTML","updateBanner","initBannerListeners","composeSelector","classSelector","sel","composeConsentObjects","consentVal","consentObject","analyticsObject","entries","acceptBtns","rejectBtns","addEventListener","keyListener","removeBanner","initForm","keyCode","focusableChildren","focusedIndex","activeElement","shiftKey","preventDefault","focus","updateBannerOpen","removeEventListener","innerHTML","suggested","suggestedConsent","button","groups","groupName","className","role","extractConsentObjects","parseInt","enableButton","removeAttribute","renderMessage","renderAnnouncement","hash","substring","scrollTo","getBoundingClientRect","top","scrollY","setTimeout","nextElementSibling","container","textContent","index","opts","cookiesEnabled","ret","error","createStore","nextState","effects","effect","hasCookie","cookies","atob","readCookie","parse","categoriesMatch","found","categories","category","extractFromCookie","utils","showBanner","cb","callback","renderForm","factory"],"mappings":"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"}