{"version":3,"file":"oneblock-client-CA9sEJAO.js","sources":["../../../../Coloplast.UI/src/oneblock/assets/js/timeout.mjs","../../../../Coloplast.UI/src/oneblock/assets/js/carousel.mjs","../../../../Coloplast.UI/src/oneblock/assets/js/common.mjs","../../../../Coloplast.UI/src/oneblock/assets/dependencies/player.es.js","../../../../Coloplast.UI/src/oneblock/assets/js/oneblock-client.mjs"],"sourcesContent":["var __spreadArrays = (this && this.__spreadArrays) || function () {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\nvar MetadataRecord = /** @class */ (function () {\r\n function MetadataRecord(callback, key, ms, params) {\r\n this.callback = callback;\r\n this.key = key;\r\n this.ms = ms;\r\n this.params = params;\r\n this.paused = false;\r\n this.startTime = new Date().getTime();\r\n this.timeSpentWaiting = 0;\r\n }\r\n return MetadataRecord;\r\n}());\r\n export default function Timeout() {\r\n }\r\n /**\r\n * clear timeout and optionally erase all knowledge of its existence\r\n * @param key\r\n * @param erase\r\n */\r\n Timeout.clear = function (key, erase) {\r\n if (erase === void 0) { erase = true; }\r\n clearTimeout(Timeout.keyId[key]);\r\n delete Timeout.keyId[key];\r\n if (erase) {\r\n delete Timeout.metadata[key];\r\n delete Timeout.originalMs[key];\r\n }\r\n };\r\n Timeout.set = function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n var key;\r\n var ms;\r\n var params;\r\n var callback;\r\n if (args.length === 0) {\r\n throw Error('Timeout.set() requires at least one argument');\r\n }\r\n if (typeof args[1] === 'function') {\r\n key = args[0], callback = args[1], ms = args[2], params = args.slice(3);\r\n }\r\n else {\r\n callback = args[0], ms = args[1], params = args.slice(2);\r\n key = callback.toString();\r\n }\r\n if (!callback) {\r\n throw Error('Timeout.set() requires a callback parameter');\r\n }\r\n Timeout.clear(key);\r\n var invoke = function () {\r\n Timeout.metadata[key].executedTime = new Date().getTime();\r\n callback.apply(void 0, params);\r\n };\r\n Timeout.keyId[key] = setTimeout(invoke, ms || 0);\r\n Timeout.originalMs[key] = Timeout.originalMs[key] || ms;\r\n Timeout.metadata[key] = new MetadataRecord(callback, key, ms, params);\r\n return function () { return Timeout.executed(key); };\r\n };\r\n Timeout.create = function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n if (args.length === 0) {\r\n throw Error('Timeout.create() requires at least one argument');\r\n }\r\n var key;\r\n if (typeof args[1] === 'function') {\r\n key = args[0];\r\n }\r\n else {\r\n var callback = args[0];\r\n key = callback.toString();\r\n }\r\n return Timeout.exists(key) ? false : Timeout.set.apply(Timeout, args);\r\n };\r\n /**\r\n * timeout has been created\r\n * @param key\r\n */\r\n Timeout.exists = function (key) {\r\n return key in Timeout.keyId || (Timeout.metadata)[key] !== undefined;\r\n };\r\n /**\r\n * test if a timeout has run\r\n * @param key\r\n */\r\n Timeout.executed = function (key) {\r\n return Timeout.exists(key) && !!Timeout.metadata[key].executedTime;\r\n };\r\n /**\r\n * when timeout was last executed\r\n * @param key\r\n */\r\n Timeout.lastExecuted = function (key) {\r\n return !Timeout.executed(key)\r\n ? null\r\n : new Date(Timeout.metadata[key].executedTime);\r\n };\r\n /**\r\n * timeout does exist, but has not yet run\r\n * @param key\r\n */\r\n Timeout.pending = function (key) {\r\n return Timeout.exists(key) && !Timeout.executed(key);\r\n };\r\n /**\r\n * timeout does exist, but will not execute because it is paused\r\n * @param key\r\n */\r\n Timeout.paused = function (key) {\r\n return Timeout.exists(key)\r\n && !Timeout.executed(key)\r\n && Timeout.metadata[key].paused;\r\n };\r\n /**\r\n * remaining time until timeout will occur\r\n * @param key\r\n */\r\n Timeout.remaining = function (key) {\r\n if (!Timeout.metadata[key])\r\n return 0;\r\n var metaDataRecord = Timeout.metadata[key];\r\n return Timeout.paused(key)\r\n ? metaDataRecord.ms - metaDataRecord.timeSpentWaiting\r\n : Math.max(0, metaDataRecord.startTime + metaDataRecord.ms - new Date().getTime());\r\n };\r\n /**\r\n * restart timeout with original time\r\n * @param key\r\n */\r\n Timeout.restart = function (key) {\r\n if (!Timeout.metadata[key] || Timeout.executed(key))\r\n return false;\r\n var metaDataRecord = Timeout.metadata[key];\r\n Timeout.clear(key, false);\r\n if (metaDataRecord.paused) {\r\n metaDataRecord.paused = false;\r\n }\r\n return Timeout.set.apply(Timeout, __spreadArrays([key, metaDataRecord.callback, Timeout.originalMs[key]], metaDataRecord.params));\r\n };\r\n /**\r\n * pause our execution countdown until we're ready for it to resume\r\n * @param key\r\n */\r\n Timeout.pause = function (key) {\r\n if (!Timeout.metadata[key] || Timeout.paused(key) || Timeout.executed(key))\r\n return false;\r\n Timeout.clear(key, false);\r\n var metaDataRecord = Timeout.metadata[key];\r\n metaDataRecord.paused = true;\r\n metaDataRecord.timeSpentWaiting = new Date().getTime() - metaDataRecord.startTime;\r\n return metaDataRecord.timeSpentWaiting;\r\n };\r\n /**\r\n * resume paused Timeout with the remaining time\r\n * @param key\r\n */\r\n Timeout.resume = function (key) {\r\n if (!Timeout.metadata[key] || Timeout.executed(key))\r\n return false;\r\n var metaDataRecord = Timeout.metadata[key];\r\n if (!metaDataRecord.paused)\r\n return false;\r\n var originalMs = Timeout.originalMs[key];\r\n var remainingTime = metaDataRecord.ms - metaDataRecord.timeSpentWaiting;\r\n var result = Timeout.set.apply(Timeout, __spreadArrays([key, metaDataRecord.callback, remainingTime], metaDataRecord.params));\r\n Timeout.originalMs[key] = originalMs;\r\n return result;\r\n };\r\n /**\r\n * instantiate timeout to handle as object\r\n * @param callback\r\n * @param ms\r\n * @param params\r\n */\r\n Timeout.instantiate = function (callback, ms) {\r\n if (ms === void 0) { ms = 0; }\r\n var params = [];\r\n for (var _i = 2; _i < arguments.length; _i++) {\r\n params[_i - 2] = arguments[_i];\r\n }\r\n if (!callback) {\r\n throw Error('Timeout.instantiate() requires a function parameter');\r\n }\r\n var key = (\"\" + Math.random() + callback).replace(/\\s/g, '');\r\n Timeout.set.apply(Timeout, __spreadArrays([key, callback, ms], params));\r\n return {\r\n clear: function (erase) {\r\n if (erase === void 0) { erase = true; }\r\n return Timeout.clear(key, erase);\r\n },\r\n executed: function () { return Timeout.executed(key); },\r\n exists: function () { return Timeout.exists(key); },\r\n lastExecuted: function () { return Timeout.lastExecuted(key); },\r\n pause: function () { return Timeout.pause(key); },\r\n paused: function () { return Timeout.paused(key); },\r\n pending: function () { return Timeout.pending(key); },\r\n remaining: function () { return Timeout.remaining(key); },\r\n restart: function () { return Timeout.restart(key); },\r\n resume: function () { return Timeout.resume(key); },\r\n set: function (newCallback, newMs) {\r\n if (newMs === void 0) { newMs = 0; }\r\n var newParams = [];\r\n for (var _i = 2; _i < arguments.length; _i++) {\r\n newParams[_i - 2] = arguments[_i];\r\n }\r\n return Timeout.set.apply(Timeout, __spreadArrays([key, newCallback, newMs], newParams));\r\n },\r\n };\r\n };\r\n Timeout.keyId = {};\r\n Timeout.originalMs = {};\r\n Timeout.metadata = {};","/* eslint no-empty: [\"error\", { \"allowEmptyCatch\": true }] */\r\n/**\r\n * Carousel module.\r\n * @module carousel.mjs\r\n * @version 0.9.49\r\n * @summary 14-10-2019\r\n * @author Mads Stoumann\r\n * @description Carousel-control\r\n */\r\n\r\n/* import tracking tools */\r\nimport { trackInteractionEvent, getVisitorID, getCulture, getPageType } from './oneblock-tracking.mjs';\r\nimport Timeout from './timeout.mjs';\r\n\r\nexport class Carousel {\r\n\tconstructor(wrapper, settings) {\r\n\t\tthis.settings = Object.assign(\r\n\t\t\t{\r\n\t\t\t\tanimateTimeout: 33,\r\n\t\t\t\tnavNext: 'M12.062 15.867c-.191.191-.502.191-.693 0l-.277-.278c-.192-.191-.192-.501 0-.693l4.062-4.063H2.99c-.27 0-.49-.22-.49-.49v-.392c0-.27.22-.49.49-.49l12.165-.001-4.063-4.064c-.192-.191-.192-.502 0-.693l.277-.278c.191-.191.502-.191.693 0l5.234 5.234.015.015.051.06-.066-.075c.029.029.054.06.077.091.08.112.127.249.127.397 0 .172-.063.33-.168.45l-5.27 5.27z',\r\n\t\t\t\tnavNextSize: 22,\r\n\t\t\t\tautoplay: false,\r\n\t\t\t\tautoplayDelay: 3000,\r\n\t\t\t\tautoplayCSSProp: '--carousel-delay',\r\n\t\t\t\tbreakpoints: [600, 1000, 1400, 1920, 3840],\r\n\t\t\t\tenablePopup: false,\r\n\t\t\t\teventSlideSet: '',\r\n\t\t\t\teventSlideChange: '',\r\n\t\t\t\trenderIndicators: true,\r\n\t\t\t\trenderNav: true,\r\n\t\t\t\trenderNavInline: true,\r\n\t\t\t\trenderThumbnails: false,\r\n\t\t\t\trenderThumbnailsNav: true,\r\n\t\t\t\tpageItems: [2, 3, 4, 6, 8],\r\n\t\t\t\tslideDir: '',\r\n\t\t\t\tslides: [],\r\n\t\t\t\tthumbnails: [],\r\n\t\t\t\ttouchDistance: 100,\r\n\t\t\t\tvideoThumbFallback: '/images/06.jpeg',\r\n\t\t\t\tcontrolsVerticalPosition: 16,\r\n\t\t\t\tcontrolsHorizontalPosition: 16,\r\n\t\t\t\tcontrolsSwitchBreakpoint: 1200,\r\n\r\n\t\t\t\tclsActive: 'c-carousel__item--active',\r\n\t\t\t\tclsAirplay: 'c-carousel__nav-airplay',\r\n\t\t\t\tclsAnimate: 'c-carousel--animate',\r\n\t\t\t\tclsCarousel: 'c-carousel__list',\r\n\t\t\t\tclsInner: 'c-carousel__inner',\r\n\t\t\t\tclsItem: 'c-carousel__item',\r\n\t\t\t\tclsItemContent: 'c-carousel__item-content',\r\n\t\t\t\tclsItemHeading: 'c-carousel__item-heading',\r\n\t\t\t\tclsItemImage: 'c-carousel__item-image',\r\n\t\t\t\tclsItemLink: 'c-carousel__item-link',\r\n\t\t\t\tclsItemText: 'c-carousel__item-text',\r\n\t\t\t\tclsItemVideo: 'c-carousel__item-video',\r\n\t\t\t\tclsIndicator: 'c-carousel__indicator',\r\n\t\t\t\tclsIndicatorFirst: 'c-carousel__indicator-item--first',\r\n\t\t\t\tclsIndicatorItem: 'c-carousel__indicator-item',\r\n\t\t\t\tclsIndicatorButton: 'c-carousel__indicator-btn',\r\n\t\t\t\tclsIndicatorButtonActive: 'c-carousel__indicator-btn--active',\r\n\t\t\t\tclsIndicatorWrapper: 'c-carousel__indicator-wrapper',\r\n\t\t\t\tclsLive: 'c-carousel__live',\r\n\t\t\t\tclsLoading: 'c-carousel--loading',\r\n\t\t\t\tclsNav: 'c-carousel__nav',\r\n\t\t\t\tclsNavNext: 'c-carousel__nav-next',\r\n\t\t\t\tclsNavPause: 'c-carousel__nav-pause',\r\n\t\t\t\tclsNavPlay: 'c-carousel__nav-play',\r\n\t\t\t\tclsNavPopup: 'c-carousel__nav-popup',\r\n\t\t\t\tclsNavPopupClose: 'c-carousel__nav-popup--close',\r\n\t\t\t\tclsNavPrev: 'c-carousel__nav-prev',\r\n\t\t\t\tclsPopup: 'c-carousel--popup',\r\n\t\t\t\tclsReverse: 'c-carousel--reverse',\r\n\t\t\t\tclsSingleSlide: 'c-carousel--single',\r\n\t\t\t\tclsThumbnailImage: 'c-carousel__thumb-image',\r\n\t\t\t\tclsThumbnailInner: 'c-carousel__thumb-inner',\r\n\t\t\t\tclsThumbnailItem: 'c-carousel__thumb-item',\r\n\t\t\t\tclsThumbnailNav: 'c-carousel__thumb-nav',\r\n\t\t\t\tclsThumbnailNext: 'c-carousel__thumb-next',\r\n\t\t\t\tclsThumbnailOuter: 'c-carousel__thumb-outer',\r\n\t\t\t\tclsThumbnailPrev: 'c-carousel__thumb-prev',\r\n\t\t\t\tclsThumbnailActive: 'c-carousel__thumb-item--active',\r\n\t\t\t\tclsThumbnailWrapper: 'c-carousel__thumb-wrapper',\r\n\r\n\t\t\t\tlabelNext: 'Next',\r\n\t\t\t\tlabelPlay: 'Play/Pause',\r\n\t\t\t\tlabelPopup: 'Open full-screen',\r\n\t\t\t\tlabelPrev: 'Previous',\r\n\r\n\t\t\t\tshowTimeBar: true,\r\n\t\t\t\ttimebarClass: 'c-carousel__timebar',\r\n\t\t\t\tclsAnimation: 'c-carousel__item--animation',\r\n\t\t\t\tclsButton: 'c-ob__link-text',\r\n\t\t\t\tclsLink: 'c-ob__link',\r\n\t\t\t\tclsDelay: '-O-ly17',\r\n\t\t\t\tclsContent: 'c-ob',\r\n\t\t\t\tisFirefox: navigator.userAgent.toLowerCase().indexOf('firefox') > -1,\r\n\t\t\t\tasParentLinked: false\r\n\t\t\t},\r\n\t\t\tthis.stringToType(settings)\r\n\t\t);\r\n\t\tthis.init(wrapper);\r\n\t}\r\n\r\n\t/**\r\n\t * @function addAirplaySupport\r\n\t * @description Adds support for Apple airplay for videos\r\n\t */\r\n\taddAirplaySupport() {\r\n\t\tif (window.WebKitPlaybackTargetAvailabilityEvent) {\r\n\t\t\tconst videos = this.wrapper.querySelectorAll('video');\r\n\t\t\tvideos.forEach(video => {\r\n\t\t\t\tconst button = document.createElement('button');\r\n\t\t\t\tbutton.classList.add(this.settings.clsAirplay);\r\n\t\t\t\tvideo.parentNode.insertBefore(button, video.nextSibling);\r\n\t\t\t\tvideo.addEventListener(\r\n\t\t\t\t\t'webkitplaybacktargetavailabilitychanged',\r\n\t\t\t\t\tfunction(event) {\r\n\t\t\t\t\t\tswitch (event.availability) {\r\n\t\t\t\t\t\t\tcase 'available':\r\n\t\t\t\t\t\t\t\tbutton.hidden = false;\r\n\t\t\t\t\t\t\t\tbutton.disabled = false;\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\tcase 'not-available':\r\n\t\t\t\t\t\t\t\tbutton.hidden = true;\r\n\t\t\t\t\t\t\t\tbutton.disabled = true;\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\tdefault:\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t);\r\n\t\t\t\tif (window.WebKitPlaybackTargetAvailabilityEvent) {\r\n\t\t\t\t\tbutton.addEventListener('click', function() {\r\n\t\t\t\t\t\tvideo.webkitShowPlaybackTargetPicker();\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @function autoPlay\r\n\t * @param {Boolean} run\r\n\t * @description Starts/stops autoplay of slides\r\n\t */\r\n\tautoPlay(run) {\r\n\t\tthis.isPlaying = run;\r\n\t\tif (this.play) {\r\n\t\t\tthis.play.setAttribute('aria-pressed', run);\r\n\t\t\tthis.play.classList.toggle(this.settings.clsNavPause, run);\r\n\t\t}\r\n\t\tif (run) {\r\n\t\t\tthis.interval = new Intrvl(() => {\r\n\t\t\t\tthis.navSlide(true);\r\n\t\t\t}, this.settings.autoplayDelay)\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @function createNavigation\r\n\t * @description Create navigation-elements: indication, next, play, prev\r\n\t */\r\n\tcreateNavigation() {\r\n\t\t/* Create navigation: next, prev, play/pause */\r\n\t\tif (this.settings.renderNav && this.slides.length > 1) {\r\n\t\t\tconst previous = this.h('button', { class: this.settings.clsNavPrev, 'aria-label': this.settings.labelPrev, rel: 'next' });\r\n\t\t\tprevious.insertAdjacentHTML('afterbegin', this.navArrow(true));\r\n\t\t\tprevious.addEventListener('click', () => {\r\n\t\t\t\tif (this.settings.autoplay) {\r\n\t\t\t\t\tthis.interval.clear();\r\n\t\t\t\t}\r\n\t\t\t\treturn this.navSlide(false)});\r\n\r\n\t\t\tconst next = this.h('button', {\tclass: this.settings.clsNavNext, 'aria-label': this.settings.labelNext, rel: 'prev' });\r\n\t\t\tnext.insertAdjacentHTML('afterbegin', this.navArrow(false));\r\n\t\t\tnext.addEventListener('click', () => {\r\n\t\t\t\tif (this.settings.autoplay) {\r\n\t\t\t\t\tthis.interval.clear();\r\n\t\t\t\t}\r\n\t\t\t\treturn this.navSlide(true)\r\n\t\t\t});\r\n\r\n\t\t\tif (this.settings.renderNavInline) {\r\n\t\t\t\tthis.inner.appendChild(previous);\r\n\t\t\t\tthis.inner.appendChild(next);\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tthis.navigation.appendChild(previous);\r\n\t\t\t\tthis.navigation.appendChild(next);\r\n\t\t\t\tthis.wrapper.appendChild(this.navigation);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/* Create indicators */\r\n\t\tif (this.settings.renderIndicators && this.slides.length > 1) {\r\n\t\t\tthis.indicators = this.h('nav', { class: this.settings.clsIndicator, itemscope: 'itemscope', itemtype: 'http://schema.org/SiteNavigationElement'});\r\n\t\t\tthis.indicators.innerHTML = this.slides.map((item, index) =>\r\n\t\t\t{return `
\r\n\t\t\t\t\r\n\t\t\t
`}).join('');\r\n\r\n\t\t\tthis.indicators.addEventListener('click', event => {\r\n\t\t\t\tconst slide = event.target.dataset.slide;\r\n\t\t\t\tif (slide) {\r\n\t\t\t\t\tconst index = parseInt(slide, 0);\r\n\t\t\t\t\tthis.gotoSlide(index, index > this.activeSlide);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\tthis.indicatorsWrapper = this.h('div', {\r\n\t\t\t\tclass: this.settings.clsIndicatorWrapper\r\n\t\t\t});\r\n\t\t\tthis.indicatorsWrapper.appendChild(this.indicators);\r\n\t\t\tthis.wrapper.appendChild(this.indicatorsWrapper);\r\n\t\t}\r\n\r\n\t\t/* Add play/pasue button if autoPlay is enabled */\r\n\t\tif (this.settings.autoplay) {\r\n\t\t\tthis.play = this.h('button', { class: this.settings.clsNavPlay, 'aria-label': this.settings.labelPlay });\r\n\t\t\tthis.play.addEventListener('click', () => {return this.autoPlay(!this.isPlaying)});\r\n\t\t\tthis.inner.appendChild(this.play);\r\n\t\t}\r\n\r\n\t\t/* Add support for popup, if enabled */\r\n\t\tif (this.settings.enablePopup) {\r\n\t\t\tthis.popup = this.h('button', { class: this.settings.clsNavPopup, 'aria-label': this.settings.labelPopup });\r\n\t\t\tthis.popup.addEventListener('click', () => { this.wrapper.classList.toggle(this.settings.clsPopup); this.popup.classList.toggle(this.settings.clsNavPopupClose); });\r\n\t\t\tthis.inner.appendChild(this.popup);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @function createSlides\r\n\t * @param {Array} json\r\n\t * @description Create slides from simple (images only) or advanced json (see readme.md)\r\n\t */\r\n\tcreateSlides(json) {\r\n\t\treturn json.map((slide, index) => {return `\r\n\t\t
  • \r\n\t\t\t
    \r\n\t\t\t${slide.type && slide.type === 'video' ? `\r\n\t\t\t\t${slide.videoType === '1' ?\r\n\t\t\t\t`` :\r\n\t\t\t\t``\r\n\t\t\t\t}`:\r\n\t\t\t\t`\"${slide.title}\"`\r\n\t\t\t}\r\n\t\t\t${this.settings.clsItemHeading ? `${slide.title}` : ''}\r\n\t\t\t${this.settings.clsItemText ? `
    ${slide.description}
    ` : ''}\r\n\t\t\t
    \r\n\t\t
  • `}).join('');\r\n\t}\r\n\r\n\t/**\r\n\t * @function createSlideWrappers\r\n\t * @param {Array} arr\r\n\t * @description Create wrappers for slide-items in custom formats\r\n\t */\r\n\tcreateSlideWrappers(arr) {\r\n\t\treturn arr.map((slide) => {return `
  • ${slide.outerHTML}
  • `}).join('')\r\n\t}\r\n\r\n\t/**\r\n\t * @function createThumbnails\r\n\t * @description Create thumbnails and thumbnail-navigation\r\n\t */\r\n\tcreateThumbnails() {\r\n\t\tthis.thumbnailNext = this.h('button', { class: this.settings.clsThumbnailNext, 'aria-label': this.settings.labelNext });\r\n\t\tthis.thumbnailNext.insertAdjacentHTML('afterbegin', this.navArrow(false));\r\n\t\tthis.thumbnailNext.addEventListener('click', () => { this.gotoPage(true);\t});\r\n\r\n\t\tthis.thumbnailPrev = this.h('button', { class: this.settings.clsThumbnailPrev, 'aria-label': this.settings.labelPrev });\r\n\t\tthis.thumbnailPrev.insertAdjacentHTML('afterbegin', this.navArrow(true));\r\n\t\tthis.thumbnailPrev.addEventListener('click', () => { this.gotoPage(false); });\r\n\r\n\t\tthis.thumbnailInner = this.h('div', { class: this.settings.clsThumbnailInner });\r\n\r\n\t\tthis.thumbnailInner.innerHTML = this.thumbnails.map((image, index) => {return `\r\n\t\t
    \r\n\t\t\t\"${image.alt}\"\r\n\t\t
    `}).join('');\r\n\r\n\t\tconst thumbnailOuter = this.h('div', { class: this.settings.clsThumbnailOuter\t});\r\n\t\tconst thumbnailWrapper = this.h('nav', { class: this.settings.clsThumbnailWrapper\t});\r\n\r\n\t\tthumbnailOuter.appendChild(this.thumbnailInner);\r\n\t\tif (this.settings.renderThumbnailsNav && this.slides.length > 1) {\r\n\t\t\tthumbnailWrapper.appendChild(this.thumbnailPrev);\r\n\t\t}\r\n\t\tthumbnailWrapper.appendChild(thumbnailOuter);\r\n\t\tif (this.settings.renderThumbnailsNav && this.slides.length > 1) {\r\n\t\t\tthumbnailWrapper.appendChild(this.thumbnailNext);\r\n\t\t}\r\n\t\tthis.wrapper.appendChild(thumbnailWrapper);\r\n\r\n\t\tthis.thumbnails = this.thumbnailInner.querySelectorAll(`.${this.settings.clsThumbnailItem}`);\r\n\r\n\t\t/* Add eventListeners */\r\n\t\tthis.thumbnailInner.addEventListener('click', event => {\r\n\t\t\tconst slide = event.target.dataset.slide;\r\n\t\t\tif (slide) {\r\n\t\t\t\tthis.gotoSlide(slide - 0);\r\n\t\t\t\t// track\r\n\t\t\t\tlet trackingValue = '';\r\n\t\t\t\tconst carousel = event.target.closest('.c-carousel');\r\n\t\t\t\tif (carousel) {\r\n\t\t\t\t\ttrackingValue = carousel.dataset.trackingValue;\r\n\t\t\t\t}\r\n\t\t\t\ttrackInteractionEvent(getPageType(), `thumbnail interaction ${trackingValue} ${getCulture()} ${location.pathname}`, getVisitorID());\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * @function getIndex\r\n\t * @param {Number} slide\r\n\t * @param {Number} length Total number of slides\r\n\t * @param {Boolean} dirUp Direction: up (true) or down (false)\r\n\t * @description Return index of next/prev slide\r\n\t * @returns Number\r\n\t */\r\n\tgetIndex(slide, length, dirUp) {\r\n\t\tlet index = slide;\r\n\r\n\t\tif (dirUp) {\r\n\t\t\tindex++;\r\n\t\t} else {\r\n\t\t\tindex--;\r\n\t\t}\r\n\r\n\t\tif (index < 0) {\r\n\t\t\tindex = length;\r\n\t\t}\r\n\t\tif (index > length) {\r\n\t\t\tindex = 0;\r\n\t\t}\r\n\t\treturn index;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * @function getVideoThumbnail\r\n\t * @description Gets / creates video-thumbnail\r\n\t * @param {Node} elm\r\n\t */\r\n\tgetVideoThumbnail(elm, fallBack) {\r\n\t\tconst vimeoJSON = async (src) => {\r\n\t\t\ttry {\r\n\t\t\t\tconst data = await (await fetch(`//vimeo.com/api/oembed.json?url=${encodeURIComponent(src)}`)).json();\r\n\t\t\t\treturn { src: data.thumbnail_url };\r\n\t\t\t}\r\n\t\t\tcatch(err) {\r\n\t\t\t\treturn fallBack;\r\n\t\t\t}\r\n\t\t}\r\n\t\tconst extractFrame = (video) => {\r\n\t\t\tconst canvas = document.createElement('canvas');\r\n\t\t\treturn new Promise(resolve => {\r\n\t\t\t\tvideo.onseeked = () => {\r\n\t\t\t\t\tconst ctx = canvas.getContext('2d');\r\n\t\t\t\t\tctx.drawImage(video, 0, 0, canvas.width, canvas.height);\r\n\t\t\t\t\tresolve(canvas.toDataURL());\r\n\t\t\t\t};\r\n\t\t\t\tvideo.currentTime = 0.1;\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\treturn new Promise(async resolve => {\r\n\t\t\tif (elm.src.includes('mp4')) {\r\n\t\t\t\tconst video = document.createElement('video');\r\n\t\t\t\tvideo.onloadedmetadata = () => {\r\n\t\t\t\t\textractFrame(video).then(response => {\r\n\t\t\t\t\t\tresolve(response ? { src: response } : fallBack);\r\n\t\t\t\t\t});\r\n\t\t\t\t};\r\n\t\t\t\tvideo.src = elm.src;\r\n\t\t\t}\r\n\t\t\telse if (elm.src.includes('vimeo')) {\r\n\t\t\t\tconst json = await vimeoJSON(elm.src);\r\n\t\t\t\tresolve(json);\r\n\t\t\t}\r\n\t\t\telse if (elm.src.includes('youtube')) {\r\n\t\t\t\tconst videoID = elm.src.match(/youtube\\.com.*(\\?v=|\\/embed\\/)(.{11})/).pop();\r\n\t\t\t\tresolve(videoID ? { src:`//img.youtube.com/vi/${videoID}/0.jpg`} : fallBack);\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * @function gotoPage\r\n\t * @param {Boolean} [dirUp]\r\n\t * @description Scroll to a specific \"page\" within timeline or thumbnails\r\n\t */\r\n\tgotoPage(dirUp) {\r\n\t\tif (typeof dirUp !== 'undefined') {\r\n\t\t\tconst page = this.page + (dirUp ? 1 : -1);\r\n\t\t\tthis.page = page > this.totalPages ? 1 : page < 1 ? this.totalPages : page;\r\n\t\t}\r\n\t\tthis.thumbnailInner.style.transform = `translateZ(0) translateX(${-100 * (this.page - 1)}%)`;\r\n\t}\r\n\r\n\t/**\r\n\t * @function gotoSlide\r\n\t * @param {Number} slideIndex\r\n\t * @param {Boolean} [dirUp]\r\n\t * @param {Boolean} [animate]\r\n\t * @description Go to specific slide\r\n\t */\r\n\tgotoSlide(slideIndex = -1, dirUp, animate = true) {\r\n\t\tif (!this.slides[slideIndex]) { return; }\r\n\r\n\t\t/* Determine slide-direction */\r\n\t\tconst slideDir = this.settings.slideDir !== '' ? this.settings.slideDir : dirUp;\r\n\t\tthis.carousel.classList.toggle(\r\n\t\t\tthis.settings.clsReverse, !slideDir\r\n\t\t);\r\n\t\tthis.previousSlide = this.activeSlide;\r\n\r\n\t\tif (slideIndex > -1) {\r\n\t\t\tthis.activeSlide = slideIndex - 0;\r\n\t\t}\r\n\r\n\t\tthis.setReference();\r\n\t\tthis.reorderSlides();\r\n\r\n\t\t/* Animate: Remove class, add it again after 50ms */\r\n\t\tif (animate && !this.settings.asParentLinked) {\r\n\t\t\tthis.carousel.classList.remove(this.settings.clsAnimate);\r\n\t\t\tTimeout.set(() => {\r\n\t\t\t\tthis.carousel.classList.add(this.settings.clsAnimate);\r\n\t\t\t}, this.settings.animateTimeout);\r\n\t\t}\r\n\r\n\t\tif (this.settings.renderIndicators) {\r\n\t\t\tthis.setActiveIndicator();\r\n\t\t}\r\n\r\n\t\tthis.setLiveRegion();\r\n\r\n\t\tthis.page = Math.ceil((slideIndex + 1) / this.itemsPerPage);\r\n\r\n\t\tif (this.settings.renderThumbnails) {\r\n\t\t\tthis.setActiveThumbnail();\r\n\t\t\tthis.gotoPage();\r\n\t\t}\r\n\r\n\t\tif (this.settings.eventSlideChange) {\r\n\t\t\tthis.wrapper.dispatchEvent(new CustomEvent(this.settings.eventSlideChange, { detail: { index: slideIndex, dir: dirUp } }));\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @function h\r\n\t * @param {String} type\r\n\t * @param {Array | Object} attributes\r\n\t * @param {Array} [children]\r\n\t * @description DOM-factory\r\n\t */\r\n\th(type, attributes, children = []) {\r\n\t\tconst element = document.createElement(type);\r\n\t\tfor (let key in attributes) {\r\n\t\t\telement.setAttribute(key, attributes[key]);\r\n\t\t}\r\n\t\tif (children.length) {\r\n\t\t\tchildren.forEach(child => {\r\n\t\t\t\tif (typeof child === 'string') {\r\n\t\t\t\t\telement.appendChild(document.createTextNode(child));\r\n\t\t\t\t} else {\r\n\t\t\t\t\telement.appendChild(child);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t\treturn element;\r\n\t}\r\n\r\n\t/**\r\n\t * @function handleKeys\r\n\t * @param {Event} event\r\n\t * @description Handle keyboard-navigation\r\n\t */\r\n\thandleKeys(event) {\r\n\t\tswitch (event.key) {\r\n\t\t\t/* Space: Pause autoplay */\r\n\t\t\tcase ' ':\r\n\t\t\t\tif (document.activeElement === this.wrapper) {\r\n\t\t\t\t\tthis.isPlaying = !this.isPlaying;\r\n\t\t\t\t\tthis.play.focus();\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\r\n\t\t\t/* Left: Previous slide */\r\n\t\t\tcase 'ArrowLeft':\r\n\t\t\tcase 'Left':\r\n\t\t\t\tthis.navSlide(false);\r\n\t\t\t\tbreak;\r\n\r\n\t\t\t/* Right: Next slide */\r\n\t\t\tcase 'ArrowRight':\r\n\t\t\tcase 'Right':\r\n\t\t\t\tthis.navSlide(true);\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @function handleTouch\r\n\t * @description Handles touch-move events\r\n\t * @param {Event} event\r\n\t * @param {Number} distance Distance to swipe before callback-function is invoked\r\n\t */\r\n\thandleTouch(event, distance) {\r\n\t\tconst currentPosition = event.changedTouches[0].pageX;\r\n\t\tif (currentPosition < this.touchPosition - distance) {\r\n\t\t\tthis.touchPosition = currentPosition;\r\n\t\t\tthis.navSlide(true);\r\n\t\t} else if (currentPosition > this.touchPosition + distance) {\r\n\t\t\tthis.touchPosition = currentPosition;\r\n\t\t\tthis.navSlide(false);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @function init\r\n\t * @description Set initial elements, create slides\r\n\t */\r\n\tinit(wrapper) {\r\n\t\tlet json, slides,\r\n\t\tthisObj = this;\r\n\r\n\t\t/* Set defaults */\r\n\t\tthis.activeSlide = 0;\r\n\t\tthis.interval = '';\r\n\t\tthis.isPlaying = this.settings.autoplay;\r\n\t\tthis.itemsPerPage = 4;\r\n\t\tthis.page = 1;\r\n\t\tthis.previousSlide = 0;\r\n\t\tthis.total = 1;\r\n\t\tthis.totalPages = 1;\r\n\t\tthis.touchPosition = 0;\r\n\r\n\t\t/* Set outer wrapper, add eventListeners */\r\n\t\tthis.wrapper = wrapper;\r\n\t\tthis.wrapper.addEventListener('keydown', event => {return this.handleKeys(event)});\r\n\t\tthis.wrapper.addEventListener('touchmove', event => {return this.handleTouch(event, this.settings.touchDistance)}, { passive: true });\r\n\t\tthis.wrapper.addEventListener('touchstart', event => { this.touchPosition = event.changedTouches[0].pageX; }, { passive: true });\r\n\r\n\t\t/* Get headings, if exists, otherwise set to empty array */\r\n\t\tthis.headings = wrapper.querySelectorAll(`.${this.settings.clsItemHeading}`) || [];\r\n\t\t\r\n\t\t/* Set navigation element */\r\n\t\tif (!this.settings.renderNavInline) {\r\n\t\t\tthis.navigation = this.h('nav', { class: this.settings.clsNav, itemscope: 'itemscope', itemtype: 'http://schema.org/SiteNavigationElement'});\r\n\t\t}\r\n\r\n\t\t/* Set inner wrapper, create if not exists */\r\n\t\tthis.inner = this.wrapper.querySelector(`.${this.settings.clsInner}`);\r\n\t\tif (!this.inner) {\r\n\t\t\t/* Markup not in correct structure, create slides from direct childNodes or this.settings.slides-array */\r\n\t\t\tif (this.settings.slides.length) {\r\n\t\t\t\tjson = typeof this.settings.slides === 'string' ? JSON.parse(this.settings.slides) : this.settings.slides;\r\n\t\t\t}\r\n\t\t\tslides = json ? this.createSlides(json) : this.createSlideWrappers(Array.from(this.wrapper.children));\r\n\t\t\tthis.wrapper.innerHTML = '';\r\n\t\t\tthis.inner = this.h('div', { class: this.settings.clsInner });\r\n\t\t\tthis.wrapper.appendChild(this.inner);\r\n\t\t}\r\n\r\n\t\t/* Set carousel (list-wrapper), create if not exists */\r\n\t\tthis.carousel = this.wrapper.querySelector(`.${this.settings.clsCarousel}`);\r\n\t\tif (!this.carousel) {\r\n\t\t\tthis.carousel = this.h('ul', {\r\n\t\t\t\tclass: this.settings.clsCarousel,\r\n\t\t\t\titemscope: 'itemscope',\r\n\t\t\t\titemtype: 'http://schema.org/ItemList'\r\n\t\t\t});\r\n\t\t\tthis.inner.appendChild(this.carousel);\r\n\t\t}\r\n\t\tif (slides) { this.carousel.innerHTML = slides; }\r\n\t\tthis.carousel.classList.add(this.settings.clsAnimate);\r\n\r\n\t\t/* Create live-region for A11y-feedback */\r\n\t\tthis.live = this.h('span', {\r\n\t\t\tclass: this.settings.clsLive,\r\n\t\t\t'aria-atomic': true,\r\n\t\t\t'aria-live': true\r\n\t\t});\r\n\t\tif (this.navigation) {\r\n\t\t\tthis.navigation.appendChild(this.live);\r\n\t\t} else {\r\n\t\t\tthis.inner.appendChild(this.live);\r\n\t\t}\r\n\r\n\t\tthis.setSlides();\r\n\r\n\t\t/* If only a single slide exists */\r\n\t\tif (this.slides.length === 1) {\r\n\t\t\tthis.carousel.classList.add(this.settings.clsSingleSlide);\r\n\t\t}\r\n\r\n\t\tthis.createNavigation();\r\n\r\n\t\t/* Create thumbnails, fetch video-frames as thumbnails */\r\n\t\tif (this.settings.renderThumbnails) {\r\n\t\t\tlet promises = [];\r\n\r\n\t\t\tif (this.settings.thumbnails.length) {\r\n\t\t\t\tpromises = this.settings.thumbnails;\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tthis.slides.map(element => {\r\n\t\t\t\t\t\tconst thumb = element.querySelector('iframe, img, video');\r\n\t\t\t\t\t\treturn thumb.tagName.toLowerCase() === 'img' ? promises.push(thumb) : promises.push(this.getVideoThumbnail(thumb, { src: this.settings.videoThumbFallback }));\r\n\t\t\t\t\t}\r\n\t\t\t\t);\r\n\t\t\t}\r\n\r\n\t\t\tPromise.all(promises).then(results => {\r\n\t\t\t\tthis.thumbnails = results;\r\n\t\t\t\t/* Create match-media-listeners for breakpoint-changes */\r\n\t\t\t\tif (this.thumbnails.length) {\r\n\t\t\t\t\tthis.breakpoints = this.settings.breakpoints.map((breakpoint, index) => {\r\n\t\t\t\t\t\t\tconst min = index > 0 ? this.settings.breakpoints[index - 1] : 0;\r\n\t\t\t\t\t\t\treturn window.matchMedia(`(min-width: ${min}px) and (max-width: ${breakpoint - 1}px)`);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t);\r\n\t\t\t\t\tthis.breakpoints.forEach(breakpoint =>\r\n\t\t\t\t\t\t{return breakpoint.addListener(this.updateItemsPerPage.bind(this))}\r\n\t\t\t\t\t);\r\n\r\n\t\t\t\t\tthis.createThumbnails();\r\n\t\t\t\t\tthis.updateItemsPerPage();\r\n\t\t\t\t\tthis.gotoSlide(this.activeSlide, true, false);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t\telse {\r\n\t\t\tthis.gotoSlide(this.activeSlide, true, false);\r\n\t\t}\r\n\r\n\t\t/* Handle external slideSet-event */\r\n\t\tif (this.settings.eventSlideSet) {\r\n\t\t\tthis.wrapper.addEventListener(this.settings.eventSlideSet, (event) => {return this.gotoSlide(event.detail.index, event.detail.dir)});\r\n\t\t}\r\n\r\n\t\t/* Update CSS Custom Property with Animation Timing */\r\n\t\tdocument.documentElement.style.setProperty(this.settings.autoplayCSSProp, `${this.settings.autoplayDelay}ms`);\r\n\r\n\t\t/* Enable Apple AirPlay for