{"version":3,"file":"client/scripts/category.409fb25ea817066e148d.js","mappings":"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","sources":["webpack://svensksten.web/webpack/runtime/chunk loaded","webpack://svensksten.web/./ClientApp/shared/scripts/easyfy.core.ts","webpack://svensksten.web/./ClientApp/shared/scripts/easyfy.utils.ts","webpack://svensksten.web/./ClientApp/shared/scripts/easyfy.decorators.ts","webpack://svensksten.web/./ClientApp/shared/scripts/easyfy.datalayer.ts","webpack://svensksten.web/./ClientApp/shared/scripts/easyfy.events/easyfy.eventdata.ts","webpack://svensksten.web/./ClientApp/shared/scripts/easyfy.events/exporters/eventExporter.stats.ts","webpack://svensksten.web/./ClientApp/shared/scripts/easyfy.events/easyfy.event.devlogger.ts","webpack://svensksten.web/./ClientApp/shared/scripts/easyfy.events/exporters/eventExporter.ga4.ts","webpack://svensksten.web/./ClientApp/web/scripts/services/features.service.ts","webpack://svensksten.web/./ClientApp/shared/scripts/easyfy.events/exporters/eventExporter.klaviyo.ts","webpack://svensksten.web/./ClientApp/shared/scripts/easyfy.events/easyfy.eventhandler.ts","webpack://svensksten.web/./ClientApp/shared/scripts/easyfy.axios.ts","webpack://svensksten.web/./ClientApp/web/scripts/services/filter.service.ts","webpack://svensksten.web/./ClientApp/web/scripts/modules/filter.ts","webpack://svensksten.web/./ClientApp/shared/scripts/easyfy.togglecss.ts","webpack://svensksten.web/./ClientApp/web/scripts/pages/category.ts","webpack://svensksten.web/webpack/bootstrap","webpack://svensksten.web/webpack/runtime/compat get default export","webpack://svensksten.web/webpack/runtime/define property getters","webpack://svensksten.web/webpack/runtime/hasOwnProperty shorthand","webpack://svensksten.web/webpack/runtime/jsonp chunk loading","webpack://svensksten.web/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};","// exemple\n// element('.about'); //
\n// element('[data-action=\"top-nav\"]'); //
\n//export const element = (query: string) => document.querySelector(query);\nexport const element = (query: string) => document.querySelector(query);\n\nexport const elements = (query: string) => document.querySelectorAll(query);\n\nexport const elementsOf = (element: Element | HTMLElement, query: string) => element.querySelector(query);\n\n// exemple\n// elementContains(document.querySelector('head'), document.querySelector('title')); // true\n// elementContains(document.querySelector('body'), document.querySelector('body')); // false\nexport const elementContains = (parent: Element, child: Element) => parent !== child && parent.contains(child);\n\nexport const on = (action: string | Element, type: string, callback: Function, ref?: object, meta?: object) => {\n docReady(() => {\n type.split(' ').forEach(function (t) {\n (action instanceof Element ? action : element(action)).addEventListener(\n t,\n (e) => {\n try {\n callback.call(e.target, e, ref ?? null, meta ?? null);\n } catch (err) { }\n },\n { once: false, passive: true }\n );\n });\n });\n};\n\nexport const one = (action: string | Element, type: string, callback: Function) => {\n docReady(() => {\n type.split(' ').forEach(function (e) {\n (action instanceof Element ? action : element(action)).addEventListener(e, callback, { once: true });\n });\n });\n};\n\nexport const event = (action: string, type: string, callback: EventListener | EventListenerObject) => {\n docReady(() => {\n element(`[data-event=\"${action}\"]`)?.addEventListener(type, callback, false);\n });\n};\n\nexport const events = (action: string, type: string, callback: EventListener | EventListenerObject) => {\n docReady(() => {\n elements(`[data-event=\"${action}\"]`)?.forEach((item) => {\n item.addEventListener(type, callback, false);\n });\n });\n};\n\nexport const action = (action: string, type: string, callback: EventListener | EventListenerObject) => {\n docReady(() => {\n element(`[data-action=\"${action}\"]`)?.addEventListener(type, callback, false);\n });\n};\n\nexport const actions = (action: string, type: string, callback: EventListener | EventListenerObject | Function) => {\n docReady(() => {\n elements(`[data-action=\"${action}\"]`)?.forEach((el) => el?.addEventListener(type, callback, false));\n });\n};\n\nexport const bind = (action: string, type: string, callback: EventListener | EventListenerObject) => {\n docReady(() => {\n elements(action || '')?.forEach((item) => {\n type.split(' ').forEach(t => {\n item.addEventListener(t, callback, false);\n });\n });\n });\n};\n\nexport const off = (action: string | Element | HTMLElement | Array, type: string, callback: EventListener | EventListenerObject) => {\n if (action instanceof String || action instanceof Element || action instanceof HTMLElement) {\n (action instanceof Element || action instanceof HTMLElement ? action : element(action)).removeEventListener(type, callback, false);\n }\n\n if (action instanceof Array) {\n for (let x of action) {\n let item: any = x;\n (item instanceof Element || item instanceof HTMLElement ? item : element(item)).removeEventListener(type, callback, false);\n }\n }\n};\n\nexport const offAll = (action: string, type: string, callback: EventListener | EventListenerObject) => {\n elements(action).forEach((item) => {\n item.removeEventListener(type, callback, false);\n });\n};\n\nexport interface IEventChain {\n target: string;\n type: string;\n events: Array;\n}\n\nexport interface IEventChainItem {\n action?: string;\n event?: string;\n callback?: Function;\n}\n\nexport const eventChain = (arg: IEventChain) => {\n bind(arg.target, arg.type, (e) => {\n const target: any = e.target;\n let eventTarget = target?.attributes['data-action']?.value ?? target?.attributes['data-event']?.value;\n\n if (!eventTarget) eventTarget = target.parentNode?.attributes['data-action']?.value ?? target.parentNode?.attributes['data-event']?.value;\n\n if (!eventTarget) return;\n\n const item: any = arg.events.find(({ action, event }) => (action ?? event).includes(eventTarget));\n if (item?.callback) item.callback(e);\n });\n};\n\n\n// Need to wait for blazor\n\nexport const docReady = (callback?: Function, context?: Object | string | number | boolean) => {\n\n let blazorFinishedLoadingEventRegistered: boolean = true;\n\n // Method to trigger window events\n if (!window.EasyfyMethods) {\n window.EasyfyMethods = {};\n window.EasyfyMethods.triggerWindowEvent = (eventName, eventData) => {\n if (eventName) {\n let event = new CustomEvent(eventName, {\n detail: eventData\n });\n window.dispatchEvent(event);\n }\n }\n }\n\n if (window.isAdminModeEnabled) {\n blazorFinishedLoadingEventRegistered = false;\n }\n\n // The public function name defaults to window.docReady\n // but you can pass in your own object and own function name and those will be used\n // if you want to put them in a different namespace\n // funcName = funcName || \"docReady\";\n // baseObj = baseObj || window;\n let readyList = [];\n let readyFired = false;\n let readyEventHandlersInstalled = false;\n\n // call this when the document is ready\n // this function protects itself against being called more than once\n const ready = () => {\n const readyBody = () => {\n if (!readyFired) {\n // this must be set to true before we start calling callbacks\n readyFired = true;\n for (var i = 0; i < readyList.length; i++) {\n // if a callback here happens to add new ready handlers,\n // the docReady() function will see that it already fired\n // and will schedule the callback to run right after\n // this event loop finishes so all handlers will still execute\n // in order and no new ones will be added to the readyList\n // while we are processing the list\n readyList[i].fn.call(window, readyList[i].ctx);\n // allow any closures held by these functions to free\n }\n readyList = [];\n }\n }\n if (window.isAdminModeEnabled) {\n if (!blazorFinishedLoadingEventRegistered) {\n blazorFinishedLoadingEventRegistered = true;\n window.addEventListener('blazorFinishedLoading', () => { readyBody(); }, false);\n }\n }\n else {\n readyBody();\n }\n\n };\n\n const readyStateChange = () => {\n if (document.readyState === 'complete') {\n ready();\n }\n };\n\n // This is the one public interface\n // docReady(fn, context);\n // the context argument is optional - if present, it will be passed\n // as an argument to the callback\n\n if (typeof callback !== 'function') {\n throw new TypeError('callback for docReady(fn) must be a function');\n }\n // if ready has already fired, then just schedule the callback\n // to fire asynchronously, but right away\n if (readyFired) {\n setTimeout(function () {\n callback(context);\n }, 1);\n return;\n } else {\n // add the function and context to the list\n readyList.push({ fn: callback, ctx: context });\n }\n // if document already ready to go, schedule the ready function to run\n if (document.readyState === 'complete') {\n setTimeout(ready, 1);\n } else if (!readyEventHandlersInstalled) {\n // otherwise if we don't have event handlers installed, install them\n if (document.addEventListener) {\n // first choice is DOMContentLoaded event\n document.addEventListener('DOMContentLoaded', ready, false);\n // backup is window load event\n window.addEventListener('load', ready, false);\n }\n readyEventHandlersInstalled = true;\n }\n};\n\nexport interface IEvent {\n type: string;\n event?: IEventItem;\n events?: Array;\n}\n\nexport interface IEventItem {\n action?: string;\n event?: string;\n callback?: Function;\n}\n\ninterface IGlobalEventItem {\n type: string;\n action?: string;\n event?: string;\n callback?: Array;\n}\n\n// Global event\nexport let globalEventList: Array = [];\n\nexport const globalEvent = (event: IEvent) => {\n event.type.split(' ').forEach((type) => {\n if (event.event) event.events = [...(event.events ?? []), ...[event.event]];\n\n if (event.events) {\n for (let item of event.events) {\n let foundItem;\n\n if (item?.action) {\n let actionFound: IGlobalEventItem = globalFindAction(type, item?.action);\n if (actionFound) {\n foundItem = actionFound;\n }\n }\n\n if (item?.event) {\n let eventFound: IGlobalEventItem = globalFindEvent(type, item?.event);\n if (eventFound) {\n foundItem = eventFound;\n }\n }\n\n if (!item?.event && !item?.action) {\n // check global state.\n let globalFound: IGlobalEventItem = globalFind(type);\n if (globalFound) {\n foundItem = globalFound;\n }\n }\n\n foundItem ? foundItem.callback.push(item.callback) : globalEventAdd(type, item);\n }\n }\n\n document.body.removeEventListener(type, globalEventHandler);\n document.body.addEventListener(type, globalEventHandler);\n });\n};\n\nexport const debounce = (func, wait) => {\n let timeout;\n\n return function executedFunction(...args) {\n const later = () => {\n clearTimeout(timeout);\n func(...args);\n };\n\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n };\n};\n\nconst globalEventHandler = (e) => {\n const target: any = e.target;\n\n // check action\n let eventTarget = globalGetTargetAction(target);\n if (eventTarget) {\n const item: IGlobalEventItem = globalFindAction(e.type, eventTarget);\n if (item?.callback) {\n globalEventInvokeCallback(item?.callback, e);\n }\n return;\n }\n\n // check event\n eventTarget = globalGetTargetEvent(target);\n if (eventTarget) {\n const item: IGlobalEventItem = globalFindEvent(e.type, eventTarget);\n if (item?.callback) {\n globalEventInvokeCallback(item?.callback, e);\n }\n return;\n }\n\n // check event\n const item = globalMatchType(e.type);\n if (item?.callback) {\n globalEventInvokeCallback(item?.callback, e);\n return;\n }\n};\n\nconst globalEventInvokeCallback = (cbs: Array, e: any) => {\n for (let item of cbs) {\n item?.call(null, e);\n }\n};\n\nconst globalEventAdd = (type: string, item: IEventItem): void => {\n globalEventList.push({\n type: type,\n action: item?.action,\n event: item?.event,\n callback: [item?.callback],\n });\n};\n\nconst globalFind = (itemType: string): IGlobalEventItem => {\n return globalEventList.find(({ type, action, event }) => type === itemType && !action && !event);\n};\n\nconst globalFindEvent = (itemType: string, eventType: string): IGlobalEventItem => globalEventList.find(({ type, event }) => type === itemType && (event ?? '') === (eventType ?? ''));\n\nconst globalFindAction = (itemType: string, actionType: string): IGlobalEventItem => globalEventList.find(({ type, action }) => type === itemType && (action ?? '') === (actionType ?? ''));\n\nconst globalMatchType = (itemType: string): IGlobalEventItem => globalEventList.find(({ type, action, event }) => type === itemType && !action && !event);\n\nconst globalGetTargetAction = (target) => globalGetTarget(target, 'data-action');\n\nconst globalGetTargetEvent = (target) => globalGetTarget(target, 'data-event');\n\nconst globalGetTarget = (target, dataTarget: string) => {\n let eventTarget = target?.attributes[dataTarget]?.value;\n if (!eventTarget) eventTarget = target.parentNode?.attributes[dataTarget]?.value;\n return eventTarget;\n};","import { element, elements } from './easyfy.core';\n/*import mobileDetect from 'mobile-detect';*/\n\nexport interface Attribute {\n name: string;\n value: string;\n}\n\n/*export const detector = new mobileDetect(window.navigator.userAgent);*/\n\n// exemple\n// findKey(\n// {\n// barney: { age: 36, active: true },\n// fred: { age: 40, active: false },\n// pebbles: { age: 1, active: true }\n// },\n// o => o['active']\n// ); // 'barney\nexport const findKey = (obj: any, fn: any) => Object.keys(obj).find((key) => fn(obj[key], key, obj));\n\n// exemple\n// findLast([1, 2, 3, 4], n => n % 2 === 1); // 3\nexport const findLast = (arr: Array, fn: any) => arr.filter(fn).pop();\n\n// exemple\n// all([4, 2, 3], x => x > 1); // true\n// all([1, 2, 3]); // true\nexport const all = (arr: Array, fn = Boolean) => arr.every(fn);\n\n// exemple\n// allEqual([1, 2, 3, 4, 5, 6]); // false\n// allEqual([1, 1, 1, 1]); // true\nexport const allEqual = (arr: Array) => arr.every((val) => val === arr[0]);\n\n// exemple\n// arrayToHtmlList('#myListID', 'li' ,['item 1', 'item 2']);\nexport const arrayToHtmlList = (selector: string, elementType: string, arr: Array) => ((el) => ((el = document.querySelector(selector)), (el.innerHTML += arr.map((item) => `<${elementType}>${item}`).join(''))))();\n\n// exemple\n//hasClass(document.querySelector('p.special'), 'special'); // true\nexport const hasClass = (el: HTMLElement, className: string) => el?.classList?.contains(className);\n\n// exemple\n// isBrowserTabFocused(); // true\nexport const isBrowserTabFocused = () => !document.hidden;\n\n// exemple\n// isNil(null); // true\n// isNil(undefined); // true\nexport const isNil = (val: any) => val === undefined || val === null;\n\n// exemple\n// isNull(null); // true\nexport const isNull = (val: any) => val === null;\n\n// exemple\n// isNumber('1'); // false\n// isNumber(1); // true\nfunction isNumber(n: any) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n}\n\n// exemple\n// isObject([1, 2, 3, 4]); // true\n// isObject([]); // true\n// isObject(['Hello!']); // true\n// isObject({ a: 1 }); // true\n// isObject({}); // true\n// isObject(true); // false\nexport const isObject = (obj: any) => obj === Object(obj);\n\n// exemple\n// isObjectLike({}); // true\n// isObjectLike([1, 2, 3]); // true\n// isObjectLike(x => x); // false\n// isObjectLike(null); // false\nexport const isObjectLike = (val: any) => val !== null && typeof val === 'object';\n\n// exemple\n// isPlainObject({ a: 1 }); // true\n// isPlainObject(new Map()); // false\n// export const isPlainObject = (val: any) =>\n// !!val && typeof val === \"object\" && val.export && constructor === Object;\n\n// exemple\n// isString('10'); // true\nexport const isString = (val: any) => typeof val === 'string';\n\n// exemple\n// isUndefined(undefined); // true\nexport const isUndefined = (val: any) => val === undefined;\n\n// exemple\n// parse string into boolean\nexport const parseToBoolean = (val: string) => isString(val) && val?.toLowerCase() === 'true';\n\n// exemple\n// isValidJSON('{\"name\":\"Adam\",\"age\":20}'); // true\n// isValidJSON('{\"name\":\"Adam\",age:\"20\"}'); // false\n// isValidJSON(null); // true\nexport const isValidJSON = (str: string) => {\n try {\n JSON.parse(str);\n return true;\n } catch (e) {\n return false;\n }\n};\n\nexport const replaceHtml = (element: HTMLElement, html: string) => {\n if (element?.outerHTML) {\n element.outerHTML = html;\n }\n else {\n let tmpElement = document.createElement(\"div\");\n tmpElement.innerHTML = html;\n element?.parentNode?.replaceChild(tmpElement, element);\n }\n};\n\n// exemple\n// matches({ age: 25, hair: 'long', beard: true }, { hair: 'long', beard: true }); // true\n// matches({ hair: 'long', beard: true }, { age: 25, hair: 'long', beard: true }); // false\nexport const matches = (obj: any, source: any) => Object.keys(source).every((key) => obj.hasOwnProperty(key) && obj[key] === source[key]);\n\n// exemple\n// randomHexColorCode(); // \"#e34155\"\nexport const randomHexColorCode = () => {\n let n = (Math.random() * 0xfffff * 1000000).toString(16);\n return '#' + n.slice(0, 6);\n};\n\n// exemple\n// redirect('https://google.com');\nexport const redirect = (url, asLink = true) => (asLink ? (window.location.href = url) : window.location.replace(url));\n\n// exemple\n// scrollToTop();\nexport const scrollToTop = () => {\n const c = document.documentElement.scrollTop || document.body.scrollTop;\n if (c > 0) {\n window.requestAnimationFrame(scrollToTop);\n window.scrollTo(0, c - c / 8);\n }\n};\n\n// exemple\n// setStyle('p', 'font-size', '20px');\nexport const setStyle = (selector: string, ruleName: string, val: string) => (element(selector).style[ruleName] = val);\n\n// exemple\n// getStyle('p', 'font-size');\nexport const getStyle = (selector: string, ruleName: string) => element(selector).style[ruleName];\n\n// exemple\n// show(...document.querySelectorAll(\"img\")); // Shows all elements on the page\nexport const showAll = (el: Array, displayType?: string) => [...el].forEach((e) => (e.style.display = displayType || 'block'));\n\n// exemple\n// hide(document.querySelectorAll('img')); // Hides all elements on the page\nexport const hideAll = (el: Array | NodeListOf) => el.forEach((e) => (e.style.display = 'none'));\n\nexport const show = (selector: string | Element, displayType?: string) => showAll([selector instanceof Element ? selector : element(selector)], displayType);\n\nexport const hide = (selector: string | Element) => hideAll([selector instanceof Element ? selector : element(selector)]);\n\nexport const toggleShow = (selector: string, displayType?: string) => {\n const el = element(selector);\n visible(el) ? hideAll([el]) : showAll([el], displayType);\n};\n\nexport const removeCss = (el: HTMLElement | Element | Array | NodeListOf, className: string | Array) => {\n if (Array.isArray(el) || el instanceof NodeList) {\n el.forEach((element) => {\n Array.isArray(className) ? element?.classList?.remove(...className) : element?.classList?.remove(className);\n });\n } else {\n Array.isArray(className) ? (el as HTMLElement | Element)?.classList?.remove(...className) : (el as HTMLElement | Element)?.classList?.remove(className);\n return el;\n }\n};\n\nexport const addCss = (el: HTMLElement | Element, className: string | Array) => {\n if (Array.isArray(className)) {\n el?.classList?.add(...className);\n return el;\n }\n\n el?.classList?.add(className);\n return el;\n};\n\n// exemple\n// async function sleepyWork() {\n// console.log(\"I'm going to sleep for 1 second.\");\n// await sleep(1000);\n// console.log('I woke up after 1 second.');\n// }\nexport const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport const visible = (element: HTMLElement): boolean => {\n return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);\n};\n\n// exemple\n// smoothScroll('#fooBar'); // scrolls smoothly to the element with the id fooBar\n// smoothScroll('.fooBar'); // scrolls smoothly to the first element with a class of fooBar\nexport const smoothScroll = (element: any) =>\n document.querySelector(element).scrollIntoView({\n behavior: 'smooth',\n });\n\n// exemple\n// splitLines('This\\nis a\\nmultiline\\nstring.\\n'); // ['This', 'is a', 'multiline', 'string.' , '']\nexport const splitLines = (str: string) => str.split(/\\r?\\n/);\n\n// exemple\n// stripHTMLTags('

lorem ipsum

'); // 'lorem ipsum'\nexport const stripHTMLTags = (str: string) => str.replace(/<[^>]*>/g, '');\n\n// exemple\n// sum(1, 2, 3, 4); // 10\n// sum(...[1, 2, 3, 4]); // 10\nexport const sum = (...arr: any) => [...arr].reduce((acc, val) => acc + val, 0);\n\n// exemple\n// timeTaken(() => Math.pow(2, 10)); // 1024, (logged): timeTaken: 0.02099609375ms\nexport const timeTaken = (callback: any) => {\n console.time(\"timeTaken\");\n const r = callback();\n console.timeEnd(\"timeTaken\");\n return r;\n};\n\n// exemple\n// toCurrency(123456.789, \"EUR\"); // €123,456.79 | currency: Euro | currencyLangFormat: Local\n// toCurrency(123456.789, 'USD', 'en-us'); // $123,456.79 | currency: US Dollar | currencyLangFormat: English (United States)\n// toCurrency(123456.789, 'USD', 'fa'); // ۱۲۳٬۴۵۶٫۷۹ ؜$ | currency: US Dollar | currencyLangFormat: Farsi\n// toCurrency(322342436423.2435, 'JPY'); // ¥322,342,436,423 | currency: Japanese Yen | currencyLangFormat: Local\n// toCurrency(322342436423.2435, 'JPY', 'fi'); // 322 342 436 423 ¥ | currency: Japanese Yen | currencyLangFormat: Finnish\nexport const toCurrency = (n: any, curr: any, languageFormat = undefined) =>\n Intl.NumberFormat(languageFormat, {\n style: 'currency',\n currency: curr,\n }).format(n);\n\n// exemple\n// toDecimalMark(12305030388.9087); // \"12,305,030,388.909\"\n// toDecimalMark(12305030388.9087, \"en-us\"); // \"12,305,030,388.909\"\nexport const toDecimalMark = (num: any, languageFormat = undefined) => num.toLocaleString(languageFormat);\n\n// exemple\n// toggleClass('p.special', 'special'); // The paragraph will not have the 'special' class anymore\nexport const toggleClass = (selector: string | HTMLElement, className: any, force?: boolean) => {\n //if (selector instanceof String) easyfyCore.element(selector as string).classList.toggle(className);\n\n if (selector instanceof HTMLElement) selector.classList.toggle(className, force);\n};\n\nexport const debounce = any>(func: F, waitFor: number) => {\n let timeout;\n\n return (...args: Parameters): Promise> =>\n new Promise((resolve) => {\n if (timeout) {\n clearTimeout(timeout);\n }\n\n timeout = setTimeout(() => resolve(func(...args)), waitFor);\n });\n};\n\nexport const isFunction = (f: Function) => {\n return f && {}.toString.call(f) === '[object Function]';\n};\n\nexport const Id = (len: number) => {\n return '_' + Math.random().toString(36).substr(2, len);\n};\n\nexport const toggleClassBySelector = (selector: string, className: string, toggle: boolean) => {\n let els = elements(selector);\n els.forEach((item) => {\n if (toggle) {\n addCss(item, className);\n } else {\n removeCss(item, className);\n }\n });\n};\n\nexport const setAttributes = (element: HTMLElement, attributes: Array): HTMLElement | Element => {\n attributes.forEach((item) => {\n if (item?.name && item?.value) {\n element.setAttribute(item.name, item.value);\n }\n });\n return element;\n};\n\nexport const offset = (element: HTMLElement): { top: number; left: number } => {\n const rect = element.getBoundingClientRect(),\n scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,\n scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\n};\n\nexport const winHeight = () => window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;\nexport const winWidth = () => window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\nexport const isMobile = () => window.innerWidth <= 768 ? true : false;\n\nexport const isBetweenDates = (startDate: Date, endDate: Date, checkDate: Date) => {\n if (checkDate > startDate && checkDate < endDate) {\n return true;\n }\n return false;\n};\n\n//todo: support other short date string formats other then 2020-01-01\nexport const getDate = (date: string) => {\n if (date !== \"\") {\n var d = date.split(\"-\");\n if (d.length == 3) {\n return new Date(parseInt(d[0]), parseInt(d[1]) - 1, parseInt(d[2]));\n }\n }\n return new Date();\n};\nexport const getSelectedValue = (select: HTMLSelectElement) => {\n if (select) {\n const selectedOption = select.options[select.selectedIndex];\n return { text: selectedOption.text, value: selectedOption.value };\n }\n return;\n};\n\nexport const removeHash = () => {\n var scrollV, scrollH, loc = window.location;\n if (\"pushState\" in history) {\n history.pushState(\"\", document.title, loc.pathname + loc.search);\n } else {\n // Prevent scrolling by storing the page's current scroll offset\n scrollV = document.body.scrollTop;\n scrollH = document.body.scrollLeft;\n\n loc.hash = \"\";\n\n // Restore the scroll offset, should be flicker free\n document.body.scrollTop = scrollV;\n document.body.scrollLeft = scrollH;\n }\n};","import { docReady, event as eventHandler, events as eventsHandler, action as actionHandler, actions as actionsHandler, bind as bindHandler } from './easyfy.core';\nimport { Id } from './easyfy.utils';\n\nexport interface Idependencies {\n func: { new(...args: any[]): {} };\n data?: any;\n}\n\ninterface IActionEvent {\n target: string;\n type: string;\n meta?: object;\n}\n\ninterface IInjectorDependencies {\n name: string;\n func: object;\n}\n\ninterface IInjector {\n dependencies: {\n [key: string]: IInjectorDependencies;\n };\n resolveOnload: Array;\n resolve: (depends: Array, ctor: any, cb: Function) => void;\n}\n\nexport const invoke = function (ctor: T): void {\n let newClass: Object;\n\n const readyAfter = () => {\n // call class function onInit\n try {\n ctor?.prototype?.onInit?.apply(newClass);\n } catch (error) {\n console.log('Invoke onInit error', error);\n }\n };\n\n const init = (resolves?: Array) => {\n try {\n newClass = new ctor(...(resolves || []));\n } catch (err) {\n console.log('Error ', err);\n }\n\n if (ctor.prototype.hasOwnProperty('onInit')) {\n // Use the handy event callback\n docReady(readyAfter);\n }\n };\n\n const depends = ctor['depends'];\n depends\n ? injector.resolve(ctor['depends'], ctor, (resolves) => {\n delete ctor['depends'];\n init(resolves);\n })\n : init();\n};\n\n\nconst injector: IInjector = {\n dependencies: {},\n resolveOnload: [],\n resolve: function (depends: Array, ctor: any, cb?: Function): void {\n depends.forEach((item) => {\n const id = Id(10);\n injector.dependencies[id] = { name: id, func: new item.func(item.data || {}) };\n if (injector.dependencies[id].func.hasOwnProperty('loaded')) {\n injector.resolveOnload.push(id);\n }\n });\n\n if (injector.resolveOnload.length > 0) {\n injector.resolveOnload.forEach((item, index) => {\n if (injector.dependencies[item].func.hasOwnProperty('loaded')) {\n const dependencyItem = injector.dependencies[item].func;\n\n let loadedVal = dependencyItem['loaded'];\n Object.defineProperty(dependencyItem, 'loaded', {\n get: () => {\n return loadedVal;\n },\n set: function (val) {\n if (val !== loadedVal) {\n if (val) {\n if (dependencyItem) {\n injector.resolveOnload.splice(index, 1);\n delete dependencyItem['loaded'];\n\n if (injector.resolveOnload.length === 0 && cb) {\n let dependencyFunc: Array = [];\n for (const key in injector.dependencies) {\n if (injector.dependencies.hasOwnProperty(key)) {\n const item = injector.dependencies[key];\n dependencyFunc.push(item.func);\n }\n }\n cb.call(this, dependencyFunc);\n }\n }\n }\n }\n\n loadedVal = val;\n },\n enumerable: true,\n configurable: true,\n });\n }\n });\n } else {\n cb?.call(this);\n }\n },\n};\n\ntype InferValue = Desc extends { get(): any; value: any } ? never : Desc extends { value: infer T } ? Record : Desc extends { get(): infer T } ? Record : never;\n\ntype DefineProperty = Desc extends { writable: any; set(val: any): any }\n ? never\n : Desc extends { writable: any; get(): any }\n ? never\n : Desc extends { writable: false }\n ? Readonly>\n : Desc extends { writable: true }\n ? InferValue\n : Readonly>;\n\nfunction defineProperty(obj: Obj, prop: Key, val: PDesc): asserts obj is Obj & DefineProperty {\n Object.defineProperty(obj, prop, val);\n}\n\ndefineProperty(Object.prototype, 'watch', {\n enumerable: false,\n configurable: true,\n writable: false,\n value(this: any, prop, handler) {\n let oldval: any = this[prop],\n newval: any = oldval,\n getter = function () {\n return newval;\n },\n setter = function (this: any, val) {\n oldval = newval;\n return (newval = handler.call(this, prop, oldval, val));\n };\n\n if (delete this[prop]) {\n // can't watch constants\n Object.defineProperty(this, prop, {\n get: getter,\n set: setter,\n enumerable: true,\n configurable: true,\n });\n }\n },\n});\n\nexport const event = (event: IActionEvent) => {\n return (_target: any, _key: string, descriptor: PropertyDescriptor) => {\n eventHandler(event.target, event.type, actionEventHelper(descriptor, event.meta).value);\n };\n};\n\nexport const events = (event: IActionEvent) => {\n return (_target: any, _key: string, descriptor: PropertyDescriptor) => {\n eventsHandler(event.target, event.type, actionEventHelper(descriptor, event.meta).value);\n };\n};\n\nexport const action = (event: IActionEvent) => {\n return (_target: any, _key: string, descriptor: PropertyDescriptor) => {\n actionHandler(event.target, event.type, actionEventHelper(descriptor, event.meta).value);\n };\n};\n\nexport const actions = (event: IActionEvent) => {\n return (_target: any, _key: string, descriptor: PropertyDescriptor) => {\n actionsHandler(event.target, event.type, actionEventHelper(descriptor, event.meta).value);\n };\n};\n\nexport const bind = (event: IActionEvent) => {\n return (_target: any, _key: string, descriptor: PropertyDescriptor) => {\n bindHandler(event.target, event.type, actionEventHelper(descriptor, event.meta).value);\n };\n};\n\nconst actionEventHelper = (descriptor: PropertyDescriptor, meta?: object) => {\n const decorated: Function = descriptor.value;\n descriptor.value = function (event: Event) {\n if (event?.preventDefault) event?.preventDefault();\n\n return decorated.apply(this, [...Array.from(arguments), meta]);\n };\n return descriptor;\n};","\nnamespace Easyfy.Shared.Scripts {\n export interface IGtmEvent {\n event: string;\n ecommerce: object;\n }\n\n export interface IActionField {\n list: string;\n }\n\n export interface ICheckoutActionField {\n step: number;\n option: string;\n }\n export interface IGtmImpressionProduct extends ProductBase {\n position: number;\n list: string;\n }\n\n export interface IGtmClickProduct extends ProductBase {\n position: number;\n dimension6: string; // depict-recommendation\n }\n\n export interface IGtmBasketProduct extends ProductBase {\n quantity: number;\n }\n\n export interface IGtmDetailProduct extends ProductBase { };\n\n interface ProductBase {\n name: string;\n id: string;\n price: number;\n brand: string,\n category: string;\n variant: string;\n dimension3: string; // product-type\n dimension4: string; // ean\n dimension5: string; // all-categories\n dimension7: string; //prescriptive (excluded for facebook)\n }\n\n\n export interface IGtmProductImpressionEvent {\n impressions: IGtmImpressionProduct[];\n currencyCode: string;\n };\n\n export interface IGtmProductClickEvent {\n click: {\n actionField: IActionField;\n products: IGtmClickProduct[];\n currencyCode: string;\n }\n };\n\n export interface IGtmProductDetailEvent {\n detail: {\n actionField: IActionField;\n products: IGtmDetailProduct[];\n currencyCode: string;\n }\n }\n\n export interface IGtmProductRemoveEvent {\n remove: {\n actionField: IActionField;\n products: IGtmBasketProduct[];\n }\n };\n\n export interface IGtmProductAddEvent {\n add: {\n actionField: IActionField;\n products: IGtmBasketProduct[];\n currencyCode: string;\n }\n };\n\n export interface IGtmCheckoutEvent {\n checkout: {\n actionField: ICheckoutActionField;\n products: IGtmBasketProduct[];\n }\n };\n\n export const PushProductImpressionEvent = async (eventProducts: IGtmImpressionProduct[], listName: string, currencyCode: string): Promise => {\n let impressionEvent: IGtmProductImpressionEvent = {\n impressions: eventProducts,\n currencyCode: currencyCode\n };\n let gtmEvent: IGtmEvent = {\n event: \"impressions\",\n ecommerce: impressionEvent\n }\n PushToDataLayer(gtmEvent);\n };\n\n export const PushProductClickEvent = async (eventProducts: IGtmClickProduct[], listName: string, currencyCode: string): Promise => {\n let clickEvent: IGtmProductClickEvent = {\n click: {\n actionField: {\n list: ListNameCleanUp(listName)\n },\n products: eventProducts,\n currencyCode: currencyCode\n }\n };\n let gtmEvent: IGtmEvent = {\n event: \"productClick\",\n ecommerce: clickEvent\n }\n PushToDataLayer(gtmEvent);\n };\n\n export const PushProductDetailEvent = async (eventProducts: IGtmDetailProduct[], listName: string, currencyCode): Promise => {\n let detailEvent: IGtmProductDetailEvent = {\n detail: {\n actionField: {\n list: ListNameCleanUp(listName)\n },\n products: eventProducts,\n currencyCode: currencyCode\n }\n };\n let gtmEvent: IGtmEvent = {\n event: \"productDetail\",\n ecommerce: detailEvent\n }\n PushToDataLayer(gtmEvent);\n };\n\n export const PushProductAddEvent = async (eventProducts: IGtmBasketProduct[], listName: string, currencyCode: string): Promise => {\n let removeEvent: IGtmProductAddEvent = {\n add: {\n actionField: {\n list: ListNameCleanUp(listName)\n },\n products: eventProducts,\n currencyCode: currencyCode\n }\n };\n let gtmEvent: IGtmEvent = {\n event: \"addToCart\",\n ecommerce: removeEvent\n }\n PushToDataLayer(gtmEvent);\n };\n\n export const PushProductRemoveEvent = async (eventProducts: IGtmBasketProduct[], listName: string): Promise => {\n let removeEvent: IGtmProductRemoveEvent = {\n remove: {\n actionField: {\n list: ListNameCleanUp(listName)\n },\n products: eventProducts,\n }\n };\n let gtmEvent: IGtmEvent = {\n event: \"removeFromCart\",\n ecommerce: removeEvent\n }\n PushToDataLayer(gtmEvent);\n };\n\n export const PushCheckoutEvent = async (eventProducts: IGtmBasketProduct[], step: number, option: string): Promise => {\n let checkoutEvent: IGtmCheckoutEvent = {\n checkout: {\n actionField: {\n step: step,\n option: option\n },\n products: eventProducts,\n }\n };\n let gtmEvent: IGtmEvent = {\n event: \"checkout\",\n ecommerce: checkoutEvent\n }\n PushToDataLayer(gtmEvent);\n };\n\n export const HandleDataEvents = async (response: any): Promise => {\n if (response?.data?.dataLayer) {\n BuildAndPushEvents(response.data.dataLayer);\n }\n return response;\n };\n\n export const BuildAndPushEvents = async (dataEvents: any): Promise => {\n if (!dataEvents) return;\n\n dataEvents.forEach(dataEvent => {\n let gtmEvent: IGtmEvent = null;\n if (!dataEvent?.eventName) return;\n\n switch (dataEvent.eventName) {\n case 'addToCart': {\n let products: IGtmBasketProduct[] = [];\n dataEvent.products.forEach(dataProduct => {\n let product: IGtmBasketProduct = {\n brand: dataProduct.brand,\n category: dataProduct.category,\n id: dataProduct.id,\n name: dataProduct.name,\n price: dataProduct.price,\n variant: dataProduct.variant,\n quantity: dataProduct.quantity,\n dimension3: dataProduct.dimension3,\n dimension4: dataProduct.dimension4,\n dimension5: dataProduct.dimension5,\n dimension7: dataProduct.dimension7\n };\n products.push(product);\n });\n PushProductAddEvent(products, dataEvent.listName, dataEvent.currencyCode);\n break;\n }\n case 'removeFromCart': {\n let products: IGtmBasketProduct[] = [];\n dataEvent.products.forEach(dataProduct => {\n let product: IGtmBasketProduct = {\n brand: dataProduct.brand,\n category: dataProduct.category,\n id: dataProduct.id,\n name: dataProduct.name,\n price: dataProduct.price,\n variant: dataProduct.variant,\n quantity: dataProduct.quantity,\n dimension3: dataProduct.dimension3,\n dimension4: dataProduct.dimension4,\n dimension5: dataProduct.dimension5,\n dimension7: dataProduct.dimension7\n };\n products.push(product);\n });\n PushProductRemoveEvent(products, dataEvent.listName)\n break;\n }\n case 'productClick': {\n let clickProducts: IGtmClickProduct[] = [];\n dataEvent.products.forEach(dataProduct => {\n let clickProduct: IGtmClickProduct = {\n brand: dataProduct.brand,\n category: dataProduct.category,\n id: dataProduct.id,\n name: dataProduct.name,\n price: dataProduct.price,\n variant: dataProduct.variant,\n position: dataProduct.position,\n dimension3: dataProduct.dimension3,\n dimension4: dataProduct.dimension4,\n dimension5: dataProduct.dimension5,\n dimension6: \"\",\n dimension7: dataProduct.dimension7\n };\n clickProducts.push(clickProduct);\n });\n PushProductClickEvent(clickProducts, dataEvent.listName, dataEvent.currencyCode)\n break;\n }\n case 'impressions': {\n let impressionProducts: IGtmImpressionProduct[] = [];\n dataEvent.products.forEach(dataProduct => {\n let impressionProduct: IGtmImpressionProduct = {\n brand: dataProduct.brand,\n category: dataProduct.category,\n id: dataProduct.id,\n name: dataProduct.name,\n price: dataProduct.price,\n variant: dataProduct.variant,\n position: dataProduct.position,\n list: ListNameCleanUp(dataProduct.list),\n dimension3: dataProduct.dimension3,\n dimension4: dataProduct.dimension4,\n dimension5: dataProduct.dimension5,\n dimension7: dataProduct.dimension7\n };\n impressionProducts.push(impressionProduct);\n });\n PushProductImpressionEvent(impressionProducts, dataEvent.listName, dataEvent.currencyCode)\n break;\n }\n case 'checkout': {\n let products: IGtmBasketProduct[] = [];\n dataEvent.products.forEach(dataProduct => {\n let product: IGtmBasketProduct = {\n brand: dataProduct.brand,\n category: dataProduct.category,\n id: dataProduct.id,\n name: dataProduct.name,\n price: dataProduct.price,\n variant: dataProduct.variant,\n quantity: dataProduct.quantity,\n dimension3: dataProduct.dimension3,\n dimension4: dataProduct.dimension4,\n dimension5: dataProduct.dimension5,\n dimension7: dataProduct.dimension7\n };\n products.push(product);\n });\n PushCheckoutEvent(products, dataEvent.step, dataEvent.option)\n break;\n }\n case 'productDetail': {\n let detailProducts: IGtmDetailProduct[] = [];\n dataEvent.products.forEach(dataProduct => {\n let detailProduct: IGtmDetailProduct = {\n brand: dataProduct.brand,\n category: dataProduct.category,\n id: dataProduct.id,\n name: dataProduct.name,\n price: dataProduct.price,\n variant: dataProduct.variant,\n dimension3: dataProduct.dimension3,\n dimension4: dataProduct.dimension4,\n dimension5: dataProduct.dimension5,\n dimension7: dataProduct.dimension7\n };\n detailProducts.push(detailProduct);\n });\n PushProductDetailEvent(detailProducts, dataEvent.listName, dataEvent.currencyCode)\n break;\n }\n default: {\n console.warn(\"Faulty data event: propterties name?\")\n console.dir(dataEvent);\n }\n }\n });\n };\n\n async function PushToDataLayer(gtmEvent: any): Promise {\n if (!gtmEvent) return;\n window['dataLayer'] = window['dataLayer'] || [];\n window['dataLayer'].push(gtmEvent);\n\n /* - For debugging the dataLayer - */\n //console.group('%c GA DataLayer ', 'color: #bada55');\n //console.dir(window['dataLayer']);\n //console.groupEnd();\n };\n\n const ListNameCleanUp = (listname: string): string => {\n if (!listname) return null;\n let cleanedListName = listname.replace(/\\s+/g, '').replace('&', '').toLowerCase();\n\n return cleanedListName;\n };\n}\n\nexport default Easyfy.Shared.Scripts;","import { event } from \"../easyfy.core\";\nimport { LocalStorageKeys } from \"./easyfy.eventhandler\";\nimport { parseToBoolean } from '../easyfy.utils';\n\ndeclare global {\n interface Window {\n EasyfyEventLayer: any,\n EasyfyEventLayerInstance: any\n isAdminModeEnabled?: boolean;\n EasyfyMethods: any;\n }\n}\n\nexport interface IDataMapper {\n MapEventData(event: IEasyfyEvent): any;\n}\n\nexport interface IEasyfyEventExporter {\n mapper: IDataMapper;\n WithMapper(mapper: IDataMapper): void;\n RegisterEvent(event: IEasyfyEvent): Promise;\n};\n\nexport interface IEasyfyEvent {\n eventName: string;\n data: any;\n}\nexport interface IEasyfyEventService {\n name: string;\n includeAllEvents: boolean;\n events: string;\n enabled: boolean;\n}\n\nexport interface IEasyfySiteInfo {\n currencyCode: string;\n}\n\nexport interface IEasyfyPageInfo {\n PageType: string;\n ViewName: string;\n}\n\nexport interface IProductData {\n Id: any;\n DomainId: any;\n Ean: any;\n DisplayName: any;\n Brand: any;\n Categories: any[];\n Price: number;\n PriceExVat: number;\n CampaignCode: string;\n}\n\nexport interface IProductSalesUnitPrice {\n salesUnitsCode: string;\n packSize: number;\n priceExVat: number;\n priceIncVat: number;\n}\n\nexport interface IBasket {\n priceIncVat: number;\n priceExVat: number;\n priceIncVatExShipping: number;\n vat: number;\n rows: IBasketRow[];\n}\n\nexport interface IBasketRow {\n productIdentifier: string;\n qty: number;\n salesUnitCode: string;\n}\n\nexport interface IProductList {\n ListName: string;\n ProductIds: string[];\n}\n\nexport interface IBannerData {\n Id: any;\n DisplayName: any;\n PageUrl: any;\n LinkUrl: any;\n}\n\nexport interface ISearchPerformedData {\n searchString: string;\n source: string;\n productIdentifiers: any[];\n productHits: number;\n articleHits: number;\n brandHits: number;\n pageHits: number;\n totalProductResults: number;\n suggestions: any[];\n}\n\nexport interface IPageViewData {\n pageId: string;\n searchPageId: string;\n}\n\nexport interface IQuantityChangedData {\n productIdentifier: string;\n listName: string;\n salesUnitCode: string;\n oldQuantity: number;\n newQuantity: number;\n}\n\nexport interface ISessionStarted {\n Culture: string;\n Currency: string;\n IsDesktop: boolean;\n IsMobilePhone: boolean;\n IsTablet: boolean;\n RecurringUser: boolean;\n Referrer: string;\n Path: string;\n UserAgent: string;\n SessionId: string;\n ClientId: string;\n UserId: string;\n VisitorId: string;\n}\n\nexport interface IWorkerJob {\n readonly Type: string;\n Data: any;\n Runs: number;\n MaxRuns: number;\n\n RunJob(data: any): Promise;\n AnonymizeWithDbId(db_id: any): any;\n}\n\nexport interface IWorkerMessage {\n Message: string;\n Data: any;\n}\n\nexport interface ITrackableElement {\n Id: any;\n Type: any;\n Properties: Map;\n}\n\nexport interface IClientEventMetaData {\n ClientId: string;\n UserId: string;\n SessionId: string;\n IsDesktop: boolean;\n IsMobilePhone: boolean;\n IsTablet: boolean;\n IPAddress: string;\n}\n\nexport interface IStatsEventData {\n ClientMetaData: IClientEventMetaData;\n EventRequests: any[];\n}\n\nexport module EasyfyEventData {\n export function AddDataToEventLayer(data: any): void {\n if (data) {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n data.events.forEach((event: any) => {\n if (!window.EasyfyEventLayer.events) {\n window.EasyfyEventLayer.events = [];\n }\n window.EasyfyEventLayer.events.push(event);\n });\n\n window.EasyfyEventLayer.products = window.EasyfyEventLayer.products || {};\n\n for (const product in data.products) {\n if (!window.EasyfyEventLayer.products || window.EasyfyEventLayer.products[product]) continue;\n window.EasyfyEventLayer.products[product] = data.products[product];\n }\n\n window.EasyfyEventLayer.productLists = window.EasyfyEventLayer.productLists || {};\n\n for (const productList in data.productLists) {\n if (!window.EasyfyEventLayer.productLists || window.EasyfyEventLayer.productLists[productList]) continue;\n window.EasyfyEventLayer.productLists[productList] = data.productLists[productList];\n }\n\n window.EasyfyEventLayer.productPrices = window.EasyfyEventLayer.productPrices || {};\n\n for (const price in data.productPrices) {\n if (!window.EasyfyEventLayer.productPrices || window.EasyfyEventLayer.productPrices[price]) continue;\n window.EasyfyEventLayer.productPrices[price] = data.productPrices[price];\n }\n\n window.EasyfyEventLayer.basket = window.EasyfyEventLayer.basket || {};\n\n if (data.basket) {\n window.EasyfyEventLayer.basket = data.basket;\n }\n }\n }\n\n export function AddCustomDataToEventLayer(data: Map): void {\n\n if (!data) return;\n\n if (!window.EasyfyEventLayer.customData) {\n window.EasyfyEventLayer.customData = {};\n }\n data.forEach((value: object, key: string) => {\n window.EasyfyEventLayer.customData[key] = value;\n })\n }\n\n export function GlobalIgnoreEvents(): boolean {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result: boolean;\n if (window.EasyfyEventLayer.configuration?.addProductImpressionsServerSide != undefined) {\n result = (window.EasyfyEventLayer.configuration.addProductImpressionsServerSide as boolean) == false;\n }\n\n return result;\n }\n\n export function SiteInfo(): IEasyfySiteInfo {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result: IEasyfySiteInfo;\n if (window.EasyfyEventLayer.site) {\n result = window.EasyfyEventLayer.site as IEasyfySiteInfo;\n }\n\n return result;\n }\n\n export function PageInfo(): IEasyfyPageInfo {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result: IEasyfyPageInfo;\n if (window.EasyfyEventLayer.pageInfo) {\n result = window.EasyfyEventLayer.pageInfo as IEasyfyPageInfo;\n }\n\n return result;\n }\n\n export function Events(): IEasyfyEvent[] {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result: IEasyfyEvent[] = [];\n if (window.EasyfyEventLayer.events) {\n result = window.EasyfyEventLayer.events as IEasyfyEvent[];\n }\n\n return result;\n }\n\n export function ClearEvents(): void {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n if (window.EasyfyEventLayer.events) {\n window.EasyfyEventLayer.events = [];\n }\n }\n\n export function ShouldRegisterProductImpressions(): boolean {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result: boolean;\n if (window.EasyfyEventLayer.configuration?.addProductImpressionsServerSide != undefined) {\n result = (window.EasyfyEventLayer.configuration.addProductImpressionsServerSide as boolean) == false;\n }\n\n return result;\n }\n\n export function ShouldRegisterBannerImpressions(): boolean {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result: boolean;\n if (window.EasyfyEventLayer.configuration?.addBannerImpressionsServerSide != undefined) {\n result = (window.EasyfyEventLayer.configuration.addBannerImpressionsServerSide as boolean) == false;\n }\n\n return result;\n }\n\n export function GetAllServices(): IEasyfyEventService[] {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result: IEasyfyEventService[] = [];\n if (window.EasyfyEventLayer?.configuration?.services) {\n result = window.EasyfyEventLayer.configuration.services as IEasyfyEventService[];\n }\n\n return result;\n }\n\n export function GetService(serviceName: string): IEasyfyEventService {\n var service = EasyfyEventData.GetAllServices().find(serviceInstance => serviceInstance.name.toLowerCase() == serviceName.toLowerCase());\n return service;\n }\n\n export function GetServiceNames(): string[] {\n var result: string[] = [];\n EasyfyEventData.GetAllServices().forEach(service => result.push(service.name));\n return result;\n }\n\n export function ServiceIsActive(serviceName: string): boolean {\n var service = EasyfyEventData.GetAllServices().find(serviceInstance => serviceInstance.name.toLowerCase() == serviceName.toLowerCase());\n return (service && service.enabled);\n }\n\n export function ConsumesEvent(serviceName: string, eventName: string): boolean {\n var service = EasyfyEventData.GetService(serviceName);\n if (!service || !service.enabled) return false;\n if (service.includeAllEvents) {\n return true;\n }\n else {\n var serviceConsumables = service.events?.trim().replace(/\\s/g, '').split(\",\");\n return serviceConsumables.find(event => event.trim().toLowerCase() == eventName.toLowerCase()) != undefined ?? false;\n }\n }\n\n export function Product(id: string): T | undefined {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result: T = null;\n if (window.EasyfyEventLayer.products) {\n result = window.EasyfyEventLayer.products[id] as T;\n }\n return result;\n }\n\n export function ProductAt(atIndex: number): T | undefined {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result: T = null;\n try {\n if (window.EasyfyEventLayer.products) {\n result = window.EasyfyEventLayer.products[atIndex] as T;\n }\n }\n catch (error) { }\n\n return result;\n }\n\n export function Products(ids: string[]): T[] {\n var productDataSet: T[] = [];\n ids.forEach((id) => {\n productDataSet.push(EasyfyEventData.Product(id));\n });\n return productDataSet;\n }\n\n export function ProductsAt(indexes: number[]): T[] {\n var productDataSet: T[] = [];\n indexes.forEach((index) => {\n productDataSet.push(EasyfyEventData.ProductAt(index));\n });\n return productDataSet;\n }\n\n export function AllProducts(): T[] {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result: T[] = [];\n if (window.EasyfyEventLayer.products) {\n result = window.EasyfyEventLayer.products as T[];\n }\n return result;\n }\n export function AllProductLists(): IProductList[] {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result = [];\n if (window.EasyfyEventLayer.productLists) {\n result = window.EasyfyEventLayer.productLists;\n }\n return result;\n }\n\n export function ProductIndexInList(listName: string, productId: string): number | null {\n if (!listName || !productId) return null;\n var productsInList = window.EasyfyEventLayer.productLists[listName];\n if (!productsInList) return null;\n var indexOfProduct = productsInList.indexOf(productId);\n\n return indexOfProduct;\n }\n\n export function ProductSalesUnitPrice(id: string): IProductSalesUnitPrice | undefined {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result: IProductSalesUnitPrice = null;\n\n if (window.EasyfyEventLayer.productPrices) {\n result = window.EasyfyEventLayer.productPrices[id] as IProductSalesUnitPrice;\n }\n\n return result;\n }\n\n export function ProductSalesUnitPrices(ids: string[]): IProductSalesUnitPrice[] | undefined {\n var prices: IProductSalesUnitPrice[] = [];\n ids.forEach((id) => {\n prices.push(EasyfyEventData.ProductSalesUnitPrice(id));\n });\n return prices;\n }\n\n export function AllProductSalesUnitPrices(): IProductSalesUnitPrice[] {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result: IProductSalesUnitPrice[] = [];\n\n if (window.EasyfyEventLayer.productPrices) {\n result = window.EasyfyEventLayer.productPrices as IProductSalesUnitPrice[];\n }\n\n return result;\n }\n\n export function Banner(id: string): IBannerData | undefined {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result: IBannerData = null;\n if (window.EasyfyEventLayer.banners) {\n result = window.EasyfyEventLayer.banners[id] as IBannerData;\n }\n return result;\n }\n\n export function AllBanners(): IBannerData[] {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n var result: IBannerData[] = [];\n if (window.EasyfyEventLayer.banners) {\n result = window.EasyfyEventLayer.banners as IBannerData[];\n }\n return result;\n }\n\n export function HasEvents(): boolean {\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n return (window.EasyfyEventLayer && window.EasyfyEventLayer.events?.length > 0);\n };\n\n export function Basket(): IBasket {\n window.EasyfyEventLayer.basket = window.EasyfyEventLayer.basket || {};\n var result: IBasket;\n if (window.EasyfyEventLayer.basket) {\n result = window.EasyfyEventLayer.basket as IBasket;\n }\n return result;\n };\n\n export function GetCurrencyCode(): string {\n var returnValue = null;\n window.EasyfyEventLayer = window.EasyfyEventLayer || {};\n if (window.EasyfyEventLayer && window.EasyfyEventLayer.site) {\n returnValue = window.EasyfyEventLayer.site.currencyCode as string;\n }\n\n return returnValue;\n };\n\n export function GetCustomData(key: string): any {\n if (!window.EasyfyEventLayer.customData) {\n window.EasyfyEventLayer.customData = {};\n }\n return window.EasyfyEventLayer.customData[key];\n }\n\n export function GetClientEventMetaData(): IClientEventMetaData {\n var result: IClientEventMetaData = {\n SessionId: localStorage.getItem(LocalStorageKeys.SessionId),\n UserId: localStorage.getItem(LocalStorageKeys.UserId),\n ClientId: localStorage.getItem(LocalStorageKeys.ClientId),\n IsDesktop: parseToBoolean(localStorage.getItem(LocalStorageKeys.IsDekstop)),\n IsMobilePhone: parseToBoolean(localStorage.getItem(LocalStorageKeys.IsMobilePhone)),\n IsTablet: parseToBoolean(localStorage.getItem(LocalStorageKeys.IsTablet)),\n IPAddress: localStorage.getItem(LocalStorageKeys.IPAddress)\n }\n return result;\n }\n\n export function IsRecurringUser(flagAsRecurringAfterCheck: boolean): boolean {\n var cookieKey = localStorage.getItem(LocalStorageKeys.UserIdCookieKey);\n var userId = EasyfyEventData.GetCookieValue(cookieKey);\n var lastCheckedUserId = localStorage.getItem(LocalStorageKeys.LastCheckedUserId);\n var result = false\n\n if (userId == lastCheckedUserId) {\n result = true; \n }\n\n if (flagAsRecurringAfterCheck) {\n localStorage.setItem(LocalStorageKeys.LastCheckedUserId, userId);\n }\n\n return result;\n }\n\n export function GetCookieValue(cookieName) {\n let cookie = {};\n document.cookie.split(';').forEach(function (el) {\n let [key, value] = el.split('=');\n cookie[key.trim()] = value;\n })\n return cookie[cookieName];\n }\n export function SetStatsApiBlock(block: boolean) {\n if (block) {\n localStorage.setItem(LocalStorageKeys.StatsIsBlocked, \"1\");\n }\n else {\n localStorage.removeItem(LocalStorageKeys.StatsIsBlocked);\n }\n }\n export function StatsApiIsBlocked(): boolean {\n var blockedFlag = localStorage.getItem(LocalStorageKeys.StatsIsBlocked);\n\n if (blockedFlag) {\n return true;\n }\n\n return false;\n }\n}\n\n","import { IEasyfyEvent, IDataMapper, IEasyfyEventExporter, EasyfyEventData, IStatsEventData } from '@shared/easyfy.events/easyfy.eventdata';\nimport { EventNames, LocalStorageKeys } from '../easyfy.eventhandler';\n\n/* Stats Exporter class */\nexport class StatsEventExporter implements IEasyfyEventExporter {\n private _eventData: IStatsEventData;\n private _blob: Blob;\n private readonly _payloadKbThreshold: number = 50;\n private readonly _eventThreshold: number = 3;\n private _eventThresholdRemoved: boolean = false;\n\n mapper: IDataMapper;\n async WithMapper(mapper: IDataMapper): Promise {\n this.mapper = mapper;\n await this.LoadAndSetTransitionStatus();\n document.addEventListener(\"visibilitychange\", this.CheckVisibility.bind(this));\n }\n\n public RegisterEvent(event: IEasyfyEvent): Promise {\n return new Promise(async (resolve) => {\n if (this.mapper) {\n if (!EasyfyEventData.StatsApiIsBlocked()) {\n const eventData = this.mapper.MapEventData(event);\n if (eventData) {\n if (Array.isArray(eventData)) {\n eventData.forEach(async (event) => {\n await this.AccumulateEvent(event);\n });\n }\n else {\n await this.AccumulateEvent(eventData);\n }\n }\n }\n }\n resolve();\n });\n }\n\n private async LoadAndSetTransitionStatus(): Promise {\n const eventThresholdRemoved = localStorage.getItem(LocalStorageKeys.StatsEventsThresholdRemoved);\n if (eventThresholdRemoved === \"true\") {\n this._eventThresholdRemoved = true;\n return;\n }\n\n const storedDataString = localStorage.getItem(LocalStorageKeys.StatsEventsTransitionObj);\n if (storedDataString) {\n\n try {\n this._eventData = JSON.parse(storedDataString) as IStatsEventData;\n } catch (error) {\n this._eventData = {\n ClientMetaData: null,\n EventRequests: []\n };\n }\n }\n }\n\n private async RecheckAndSetTransitionStatus(): Promise {\n\n let eventsMatch = 0;\n const skipEventNames = [EventNames.BannerImpression, EventNames.ElementImpression, EventNames.ProductImpression];\n\n for (const event of this._eventData?.EventRequests) {\n if (skipEventNames.includes(event?.Event?.type?.toLowerCase()) == false) {\n eventsMatch++;\n }\n }\n\n if (eventsMatch >= this._eventThreshold) {\n localStorage.setItem(LocalStorageKeys.StatsEventsThresholdRemoved, \"true\");\n this._eventThresholdRemoved = true;\n localStorage.removeItem(LocalStorageKeys.StatsEventsTransitionObj);\n }\n else {\n localStorage.setItem(LocalStorageKeys.StatsEventsTransitionObj, JSON.stringify(this._eventData));\n }\n }\n\n private async AccumulateEvent(event: any): Promise {\n return new Promise(async (resolve) => {\n if (!this._eventData || !this._eventData?.ClientMetaData || !this._eventData?.EventRequests) {\n this._eventData = {\n ClientMetaData: EasyfyEventData.GetClientEventMetaData(),\n EventRequests: []\n }\n }\n\n this._eventData.EventRequests.push({ \"Event\": event });\n\n const str = JSON.stringify(this._eventData);\n const bytes = new TextEncoder().encode(str);\n const blob = new Blob([bytes], {\n type: \"application/json;charset=utf-8\"\n });\n\n this._blob = blob;\n\n if (this._eventThresholdRemoved) {\n const payloadSize = await this.GetObjectSizeInKB(this._eventData);\n if (payloadSize > this._payloadKbThreshold) {\n await this.SendEventsToStatsApi();\n }\n }\n else {\n await this.RecheckAndSetTransitionStatus();\n }\n\n resolve();\n });\n }\n\n private async SendEventsToStatsApi(): Promise {\n if (this._eventData?.ClientMetaData && this._eventData?.EventRequests?.length > 0 && this._blob) {\n navigator.sendBeacon(\"/api/stats/events\", this._blob);\n this._eventData = null;\n this._blob = null;\n }\n }\n\n private async CheckVisibility() {\n if (document.visibilityState === \"hidden\" && this._eventThresholdRemoved) {\n await this.SendEventsToStatsApi();\n }\n }\n\n async GetObjectSizeInKB(obj: any): Promise {\n\n const jsonString = JSON.stringify(obj);\n const bytes = new TextEncoder().encode(jsonString).length;\n const kilobytes = bytes / 1024;\n\n return kilobytes;\n }\n}","import { EasyfyEventData } from '@shared/easyfy.events/easyfy.eventdata';\n\ndeclare var process: {\n env: {\n NODE_ENV: string\n }\n}\n\nexport module EasyfyEventLogger {\n const topParagraphStyle: string = \"line-height:6px; border-radius: 5px; width: fit-content;\";\n const paragraphStyle: string = \"line-height:6px; padding:6px; border-radius: 5px; width: fit-content;\";\n\n\n export function ConsoleLog(message: string, prefix?: string, color?: string, bgColor?: string) {\n if (process.env.NODE_ENV === \"development\") {\n if (color == undefined) {\n color = '#ffffff';\n }\n\n var style = `color: ${color};`;\n\n if (bgColor) {\n style += `background: ${bgColor};`;\n }\n\n console.log(`%c ${prefix}${message}`, style);\n }\n }\n\n export function Log(this: any, obj): void {\n if (process.env.NODE_ENV === \"development\") {\n //return;\n\n try {\n var haveInjectedCss = window[\"injectedCss\"];\n if (!haveInjectedCss) {\n window[\"injectedCss\"] = true;\n var injectedCss = window.document.styleSheets[0];\n injectedCss.insertRule(`\n @keyframes messageFlash {\n 0% { background-color: rgba(255, 255, 255, 0);}\n 50% { background-color: rgba(255, 255, 255, 0.5);}\n 100% { background-color: rgba(255, 255, 255, 0);}\n }\n `, injectedCss.cssRules.length);\n\n injectedCss.insertRule(`.flash{\n animation: messageFlash 0.2s 2;\n }`, injectedCss.cssRules.length);\n\n injectedCss.insertRule(`\n @keyframes impressionBorder {\n 0% { border: 0px solid #ff7600; }\n 100% { border: 8px solid #ff7600; }\n }\n `, injectedCss.cssRules.length);\n\n injectedCss.insertRule(`.impressionSeen{\n animation: impressionBorder 0.8s 1;\n border: 8px solid #ff7600;\n }`, injectedCss.cssRules.length);\n }\n }\n catch (error) {\n console.warn(error);\n }\n\n var devEventLogButton = document.querySelector(\"#devEventLogButton\");\n if (!devEventLogButton) {\n var logButtonElem = document.createElement('div');\n logButtonElem.id = \"devEventLogButton\";\n logButtonElem.style.position = \"fixed\";\n logButtonElem.style.cursor = \"pointer\";\n logButtonElem.style.bottom = \"5px\";\n logButtonElem.style.left = \"5px\";\n logButtonElem.style.width = \"10px\";\n logButtonElem.style.height = \"10px\";\n logButtonElem.style.fontSize = \"10px\";\n logButtonElem.style.zIndex = \"2147483646\";\n\n logButtonElem.onclick = this.EnableLog;\n logButtonElem.innerHTML = \"🖥️\";\n\n document.querySelector('body').appendChild(logButtonElem);\n }\n\n var devEventOutput = document.querySelector(\"#devEventOutput\");\n if (!devEventOutput) {\n var outputDiv = document.createElement('div');\n outputDiv.id = \"devEventOutput\";\n outputDiv.style.position = \"fixed\";\n outputDiv.style.backgroundColor = \"#000000de\";\n outputDiv.style.color = \"#c4c4c4\";\n outputDiv.style.zIndex = \"2147483646\";\n outputDiv.style.width = \"100%\";\n outputDiv.style.height = \"200px\";\n outputDiv.style.bottom = \"0\";\n outputDiv.style.fontSize = \"10px\";\n outputDiv.style.fontFamily = \"Roboto, Helvetica\";\n outputDiv.style.lineHeight = \"4px\";\n outputDiv.style.display = \"grid\";\n outputDiv.style.gridTemplateColumns = \"120px 1fr\";\n outputDiv.style.gridTemplateRows = \"30px 1fr\";\n\n var topElement = document.createElement('div');\n topElement.style.position = \"sticky\";\n topElement.style.top = \"0px\";\n topElement.style.width = \"100%\";\n topElement.style.height = \"30px\";\n topElement.style.padding = \"7px 5px\";\n topElement.style.color = \"#73ff69\";\n topElement.style.display = \"flex\";\n topElement.style.gridGap = \"20px\";\n topElement.style.gridColumn = \"2\";\n topElement.style.gridRow = \"1\";\n\n topElement.innerHTML = '

EventLayer.Services: No registered

' +\n '

EventLayer.Products: 0

' +\n '

EventLayer.ProductLists: 0

' +\n '

EventLayer.ProductPrices: 0

' +\n '

EventLayer.Banners: 0

' +\n '

Product impressions: 0

';\n\n var leftElement = document.createElement('div');\n leftElement.style.width = \"120px;\"\n leftElement.style.height = \"30px\";\n leftElement.style.gridColumn = \"1\";\n leftElement.style.gridRow = \"1\";\n leftElement.style.display = \"flex\";\n\n var iconParagraph1 = document.createElement('p');\n iconParagraph1.style.cursor = \"pointer\";\n iconParagraph1.style.width = \"30px\";\n iconParagraph1.style.height = \"30px\";\n iconParagraph1.style.padding = \"0px 6px\";\n iconParagraph1.style.lineHeight = \"30px\";\n iconParagraph1.onclick = EasyfyEventLogger.DisableLog;\n iconParagraph1.innerHTML = \"🖥️\";\n\n leftElement.appendChild(iconParagraph1);\n\n var iconParagraph2 = document.createElement('p');\n iconParagraph2.style.cursor = \"pointer\";\n iconParagraph2.style.width = \"30px\";\n iconParagraph2.style.height = \"30px\";\n iconParagraph2.style.padding = \"0px 6px\";\n iconParagraph2.style.lineHeight = \"30px\";\n iconParagraph2.onclick = EasyfyEventLogger.PrintEventLayer;\n iconParagraph2.innerHTML = \"📄\";\n\n leftElement.appendChild(iconParagraph2);\n\n var iconParagraph3 = document.createElement('p');\n iconParagraph3.style.cursor = \"pointer\";\n iconParagraph3.style.width = \"30px\";\n iconParagraph3.style.height = \"30px\";\n iconParagraph3.style.padding = \"0px 8px\";\n iconParagraph3.style.lineHeight = \"30px\";\n iconParagraph3.style.transform = \"scale(1.6)\";\n\n if (ImpressionVisualizerIsOn()) {\n iconParagraph3.style.color = \"#ff7600\";\n } else {\n iconParagraph3.style.color = \"#c4c4c4\";\n }\n\n iconParagraph3.id = \"toggleImpressionBtn\"\n iconParagraph3.onclick = EasyfyEventLogger.ToggleImpressionVisualizer;\n iconParagraph3.innerHTML = \"👁\";\n\n leftElement.appendChild(iconParagraph3);\n\n\n var textElement = document.createElement('div');\n textElement.id = \"outputText\";\n textElement.style.padding = \"5px\";\n textElement.style.overflowY = \"scroll\";\n textElement.style.height = \"170px\";\n textElement.style.gridColumn = \"2\";\n textElement.style.gridRow = \"2\";\n textElement.style.borderRadius = \"5px\";\n\n outputDiv.appendChild(topElement);\n outputDiv.appendChild(leftElement);\n outputDiv.appendChild(textElement);\n document.querySelector('body').appendChild(outputDiv);\n\n this.CheckLogStatus();\n }\n\n devEventOutput = document.querySelector(\"#devEventOutput\");\n if (!devEventOutput) return;\n\n if (obj.type == \"productimpression\") {\n var textOutput = devEventOutput.querySelector('#outputText');\n textOutput.innerHTML += \"

\" + obj.message + \"

\";\n var productImpressions = Number.parseInt(devEventOutput.querySelector('#devProductImpressions').innerHTML);\n devEventOutput.querySelector('#devProductImpressions').innerHTML = (productImpressions + 1).toString();\n\n textOutput.scrollTop = textOutput.scrollHeight;\n\n if (obj.target && ImpressionVisualizerIsOn()) {\n (obj.target as HTMLElement).classList.add(\"impressionSeen\")\n }\n }\n else if (obj.type == \"servicesregistered\") {\n devEventOutput.querySelector('#devEventServices').innerHTML = obj.message;\n }\n else if (obj.type == \"updateeventlayerstatus\") {\n var lists = EasyfyEventData.AllProductLists();\n var products = EasyfyEventData.AllProducts();\n var banners = EasyfyEventData.AllBanners();\n var prices = EasyfyEventData.AllProductSalesUnitPrices();\n\n var eventLayerProductsCount = Object.keys(products).length;\n var eventLayerProductListsCount = Object.keys(lists).length;\n var eventLayerBannersCount = Object.keys(banners).length;\n var eventLayerPricesCount = Object.keys(prices).length;\n\n\n devEventOutput.querySelector('#devLayerLists').innerHTML = eventLayerProductListsCount.toString();\n devEventOutput.querySelector('#devLayerProducts').innerHTML = eventLayerProductsCount.toString();\n devEventOutput.querySelector('#devEventServices').innerHTML = EasyfyEventData.GetServiceNames().join(\", \");\n devEventOutput.querySelector('#devLayerBanners').innerHTML = eventLayerBannersCount.toString();\n devEventOutput.querySelector('#devLayerPrices').innerHTML = eventLayerPricesCount.toString();\n\n }\n else if (obj.type == \"event\") {\n var textOutput = devEventOutput.querySelector('#outputText');\n textOutput.className = \"\";\n textOutput.innerHTML += \"

\" + obj.message + \"

\";\n textOutput.scrollTop = textOutput.scrollHeight;\n setTimeout(() => {\n var textOutput = devEventOutput.querySelector('#outputText');\n textOutput.className = \"flash\";\n }, 20);\n }\n else if (obj.type == \"warning\") {\n var textOutput = devEventOutput.querySelector('#outputText');\n textOutput.innerHTML += \"

\" + obj.message + \"

\";\n textOutput.scrollTop = textOutput.scrollHeight;\n }\n else if (obj.type == \"error\") {\n var textOutput = devEventOutput.querySelector('#outputText');\n textOutput.innerHTML += \"

\" + obj.message + \"

\";\n textOutput.scrollTop = textOutput.scrollHeight;\n }\n else {\n var textOutput = devEventOutput.querySelector('#outputText');\n textOutput.innerHTML += \"

\" + obj.message + \"

\";\n textOutput.scrollTop = textOutput.scrollHeight;\n }\n }\n };\n\n export function CheckLogStatus(this: any): void {\n if (process.env.NODE_ENV === \"development\") {\n var useEventLog = localStorage.getItem(\"easyfyDevEventLog\") == \"true\";\n\n useEventLog ? this.EnableLog() : this.DisableLog();\n }\n };\n\n export function EnableLog(): void {\n if (process.env.NODE_ENV === \"development\") {\n localStorage.setItem(\"easyfyDevEventLog\", \"true\");\n var devEventOutput = document.querySelector(\"#devEventOutput\") as HTMLElement;\n if (devEventOutput) {\n devEventOutput.style.display = \"grid\";\n }\n }\n };\n\n export function DisableLog(): void {\n if (process.env.NODE_ENV === \"development\") {\n localStorage.setItem(\"easyfyDevEventLog\", \"false\");\n var devEventOutput = document.querySelector(\"#devEventOutput\") as HTMLElement;\n if (devEventOutput) {\n devEventOutput.style.display = \"none\";\n }\n }\n };\n\n export function ToggleImpressionVisualizer(): void {\n if (process.env.NODE_ENV === \"development\") {\n var date = new Date();\n date.setDate(date.getDate() + 30); \n var visualizerValue = localStorage.getItem(\"easyfyDevImpVisualizer\");\n var btn = document.querySelector(\"#toggleImpressionBtn\") as HTMLElement;\n\n if (visualizerValue == \"true\") {\n localStorage.setItem(\"easyfyDevImpVisualizer\", \"false\");\n btn.style.color = \"#c4c4c4\";\n\n document.querySelectorAll('.impressionSeen').forEach((elem) => {\n elem.classList.remove('impressionSeen');\n });\n }\n else {\n localStorage.setItem(\"easyfyDevImpVisualizer\", \"true\");\n btn.style.color = \"#ff7600\";\n document.querySelectorAll('[data-track-product][data-track-impression=\"True\"]').forEach((elem) => {\n elem.classList.add('impressionSeen');\n });\n }\n }\n };\n\n function ImpressionVisualizerIsOn(): boolean {\n var visualizerValue = localStorage.getItem(\"easyfyDevImpVisualizer\");\n if (visualizerValue == \"true\") {\n return true;\n }\n else {\n return false;\n }\n }\n\n export function PrintEventLayer(): void {\n if (process.env.NODE_ENV === \"development\") {\n\n var devEventLayerOutput = document.querySelector(\"#devEventLayerOutput\") as HTMLDivElement;\n if (!devEventLayerOutput) {\n var outputDiv = document.createElement('div');\n outputDiv.id = \"devEventLayerOutput\";\n outputDiv.style.position = \"fixed\";\n outputDiv.style.height = \"66%\";\n outputDiv.style.width = \"70%\";\n outputDiv.style.top = \"100px\";\n outputDiv.style.left = \"15%\";\n outputDiv.style.backgroundColor = \"#000000de\";\n outputDiv.style.color = \"#c4c4c4\";\n outputDiv.style.zIndex = \"2147483647\";\n outputDiv.style.borderRadius = \"5px\";\n outputDiv.style.boxShadow = \"1px 0px 14px 1px rgba(0,0,0,0.3)\";\n outputDiv.style.fontSize = \"11px\";\n outputDiv.style.overflow = \"auto\";\n\n var iconParagraph = document.createElement('p');\n iconParagraph.style.cursor = \"pointer\";\n iconParagraph.style.width = \"30px\";\n iconParagraph.style.height = \"30px\";\n iconParagraph.style.padding = \"0px 8px\";\n iconParagraph.style.lineHeight = \"30px\";\n iconParagraph.style.position = \"fixed\";\n iconParagraph.onclick = EasyfyEventLogger.HidePrintedEventLayer;\n iconParagraph.innerHTML = \"✖\";\n\n var textElement = document.createElement('div');\n textElement.id = \"devEventLayerOutputText\";\n textElement.style.padding = \"30px\";\n textElement.style.fontFamily = \"monospace\";\n textElement.style.whiteSpace = \"pre\";\n\n outputDiv.appendChild(iconParagraph);\n outputDiv.appendChild(textElement);\n\n\n document.querySelector('body').appendChild(outputDiv);\n devEventLayerOutput = document.querySelector(\"#devEventLayerOutput\") as HTMLDivElement;\n\n }\n\n devEventLayerOutput.style.display = \"block\";\n const brace = {\n brace: 0\n };\n\n var jsonstring = JSON.stringify(window.EasyfyEventLayer, null, 2);\n var outputElement = document.querySelector(\"#devEventLayerOutputText\") as HTMLDivElement;\n outputElement.innerHTML = \"

Event layer:

\" + jsonstring;\n //console.log(JSON.stringify(window.EasyfyEventLayer, null, 2));\n }\n };\n\n export function HidePrintedEventLayer(): void {\n if (process.env.NODE_ENV === \"development\") {\n var devEventLayerOutput = document.querySelector(\"#devEventLayerOutput\") as HTMLDivElement;\n if (devEventLayerOutput) {\n devEventLayerOutput.style.display = \"none\";\n }\n }\n };\n}\n\n","import { IEasyfyEvent, IDataMapper, IEasyfyEventExporter } from '@shared/easyfy.events/easyfy.eventdata';\n\n/* Ga4 Exporter class */\nexport class Ga4EventExporter implements IEasyfyEventExporter {\n mapper: IDataMapper;\n WithMapper(mapper: IDataMapper): void {\n this.mapper = mapper;\n }\n\n RegisterEvent(event: IEasyfyEvent): Promise {\n return new Promise(async (resolve) => {\n if (!this.mapper) return;\n var eventData = this.mapper.MapEventData(event);\n await this.PushToDataLayer(eventData);\n resolve();\n })\n }\n\n async PushToDataLayer(ga4Event: any): Promise {\n return new Promise(async (resolve) => {\n if (ga4Event) {\n window['dataLayer'] = window['dataLayer'] || [];\n window['dataLayer'].push({ ecommerce: null });\n window['dataLayer'].push(ga4Event);\n }\n resolve();\n })\n\n //console.group('%c GA DataLayer ', 'color: #bada55');\n //console.dir(window['dataLayer']);\n //console.groupEnd();\n }\n}","\nexport class FeatureNames {\n static EventTracking: string = \"eventtracking\";\n}\n\nexport class Features {\n static FeatureIsActive = (featureName: string): boolean => {\n var featureIsActiveForClient = document.querySelector('html').hasAttribute(featureName);\n return featureIsActiveForClient;\n }\n}\n\n\n\n","import { IEasyfyEvent, IDataMapper, IEasyfyEventExporter } from '@shared/easyfy.events/easyfy.eventdata';\n\n/* Klaviyo Exporter class */\nexport class KlaviyoEventExporter implements IEasyfyEventExporter {\n mapper: IDataMapper;\n WithMapper(mapper: IDataMapper): void {\n this.mapper = mapper;\n }\n\n RegisterEvent(event: IEasyfyEvent): Promise {\n return new Promise(async (resolve) => {\n if (this.mapper) {\n var eventData = this.mapper.MapEventData(event);\n await this.PushToKlaviyo(eventData);\n }\n resolve();\n });\n }\n\n async PushToKlaviyo(klaviyoEvent: any): Promise {\n return new Promise(async (resolve) => {\n if (klaviyoEvent) {\n window['klaviyo'] = window?.['klaviyo'] || [];\n window['klaviyo'].push([\"track\", klaviyoEvent.event, klaviyoEvent.data])\n\n //console.group('%c Klaviyo ', 'color: #bada55');\n //console.dir(window['klaviyo']);\n //console.groupEnd();\n resolve()\n }\n });\n }\n}","import { element } from '@shared/easyfy.core';\nimport { StatsEventExporter } from '@shared/easyfy.events/exporters/eventExporter.stats';\nimport { Ga4EventExporter } from '@shared/easyfy.events/exporters/eventExporter.ga4';\nimport { EasyfyEventData, IDataMapper, IEasyfyEvent, IEasyfyEventExporter, IWorkerJob, ITrackableElement, ISessionStarted, IClientEventMetaData, IWorkerMessage } from '@shared/easyfy.events/easyfy.eventdata';\nimport { EasyfyEventLogger } from '@shared/easyfy.events/easyfy.event.devlogger';\nimport { FeatureNames, Features } from '@webServices/features.service';\nimport { KlaviyoEventExporter } from './exporters/eventExporter.klaviyo';\n\nexport class ServiceNames {\n static Stats: string = \"stats\";\n static Ga4: string = \"ga4\";\n static Klaviyo: string = \"klaviyo\";\n}\nexport class EventNames {\n static PageView: string = \"pageview\";\n static ProductImpression: string = \"productimpression\";\n static ProductClick: string = \"productclick\";\n static ProductPageView: string = \"productpageview\";\n static BannerImpression = \"bannerimpression\";\n static BannerClick = \"bannerclick\";\n static ElementImpression = \"elementimpression\";\n static ElementClick = \"elementclick\";\n static AddToCart: string = \"addtocart\";\n static RemoveFromCart: string = \"removefromcart\";\n static QuantityChanged: string = \"quantitychanged\";\n static StartedCheckout: string = \"startedcheckout\";\n static CompletedCheckout: string = \"completedcheckout\";\n static SearchPerformed: string = \"searchperformed\";\n static ContinueToPayment: string = \"continuetopayment\";\n static SessionStarted: string = \"sessionstarted\";\n}\n\nexport class Message {\n static FetchClientMetaData = \"cmd_fetch_client_meta_data\";\n static BlockStatsApi = \"cmd_block_stats_api\";\n}\n\nexport class LocalStorageKeys {\n static SessionTimer = \"e_sessionTimer\";\n static SessionId = \"e_sessionId\";\n static ClientId = \"e_clientId\";\n static UserId = \"e_userId\";\n static LastCheckedUserId = \"e_lastCheckedUserId\";\n static IsTablet = \"e_tablet\";\n static IsMobilePhone = \"e_mobilephone\";\n static IsDekstop = \"e_desktop\";\n static UserIdCookieKey = \"e_userIdCookieKey\";\n static IPAddress = \"e_ipAddress\";\n static StatsIsBlocked = \"e_statsServiceBlocked\";\n static StatsEventsThresholdRemoved = \"e_StatsEventsTresholdRemoved\"\n static StatsEventsTransitionObj = \"e_statsEventsTransitionObj\"\n}\n\nnamespace Easyfy.Modules {\n\n export class EasyfyEventHandler {\n private eventExporters: Map = new Map();\n private observedElements: string[] = [];\n private intersectionObserver: IntersectionObserver;\n private bannerIntersectionObserver: IntersectionObserver;\n private mutationObserver: MutationObserver;\n public static instance: EasyfyEventHandler;\n private featureFlag: boolean;\n private initiated: boolean = false;\n\n constructor(eventMappers: Map) {\n EasyfyEventHandler.instance = this;\n EasyfyEventHandler.instance.featureFlag = Features.FeatureIsActive(FeatureNames.EventTracking);\n window.EasyfyEventLayerInstance = this;\n\n if (!EasyfyEventHandler.instance.featureFlag) return;\n\n EasyfyEventData.GetAllServices().forEach(service => {\n var eventExporter: IEasyfyEventExporter;\n switch (service.name.toLowerCase()) {\n case ServiceNames.Stats: {\n eventExporter = new StatsEventExporter();\n break;\n }\n case ServiceNames.Klaviyo: {\n eventExporter = new KlaviyoEventExporter();\n break;\n }\n case ServiceNames.Ga4: {\n eventExporter = new Ga4EventExporter();\n break;\n }\n }\n if (eventExporter) {\n eventExporter.WithMapper(eventMappers.get(service.name));\n this.eventExporters.set(service.name, eventExporter);\n }\n })\n\n EasyfyEventLogger.Log({\n type: \"updateeventlayerstatus\",\n });\n\n EasyfyEventHandler.CheckSessionStart().then(() => {\n EasyfyEventHandler.RunEvents().then(() => {\n if (EasyfyEventData.ShouldRegisterProductImpressions()) {\n EasyfyEventHandler.InitProductIntersectionObserver();\n EasyfyEventHandler.InitMutationObserver();\n }\n if (EasyfyEventData.ShouldRegisterBannerImpressions()) {\n EasyfyEventHandler.InitBannerIntersectionObserver();\n }\n EasyfyEventHandler.InitElementIntersectionObserver();\n window.addEventListener('click', EasyfyEventHandler.ClickEventChecker);\n EasyfyEventHandler.instance.initiated = true;\n });\n });\n };\n\n static async RunEvents(): Promise {\n return new Promise(async (resolve) => {\n var inlineScript = element('[data-container=\"easyfy-preload-tracking-events\"]');\n if (inlineScript) {\n inlineScript.remove();\n }\n\n if (!EasyfyEventData.HasEvents()) {\n resolve();\n return;\n }\n for await (const event of EasyfyEventData.Events()) {\n await EasyfyEventHandler.RunEvent(event);\n };\n\n EasyfyEventData.ClearEvents();\n resolve();\n });\n };\n\n static async CheckSessionStart(): Promise {\n return new Promise(async (resolve) => {\n if (EasyfyEventData.ServiceIsActive(ServiceNames.Stats) !== true) {\n resolve();\n return;\n }\n var sessionTimer = localStorage.getItem(LocalStorageKeys.SessionTimer);\n if (!sessionTimer) {\n localStorage.setItem(LocalStorageKeys.SessionTimer, new Date(Date.now()).toUTCString());\n sessionTimer = localStorage.getItem(LocalStorageKeys.SessionTimer);\n await EasyfyEventHandler.FetchClientMetaData();\n await EasyfyEventHandler.SendStartSessionEvent();\n resolve();\n }\n\n var checkTime = new Date(sessionTimer);\n var now = new Date(Date.now());\n\n var diff = (checkTime.getTime() - now.getTime()) / 1000;\n diff /= 60;\n var minutesBetween = Math.abs(Math.round(diff));\n\n if (minutesBetween >= 20) {\n var oldSessionId = localStorage.getItem(LocalStorageKeys.SessionId);\n await EasyfyEventHandler.FetchClientMetaData();\n var newSessionId = localStorage.getItem(LocalStorageKeys.SessionId);\n if (oldSessionId != newSessionId) {\n await EasyfyEventHandler.SendStartSessionEvent();\n }\n }\n\n localStorage.setItem(LocalStorageKeys.SessionTimer, new Date(Date.now()).toUTCString());\n\n resolve();\n });\n }\n\n static async FetchClientMetaData(): Promise {\n return new Promise(async (resolve) => {\n\n EasyfyEventData.SetStatsApiBlock(false);\n\n const response = await fetch(\"/api/stats/clientmetadata/\");\n\n if (!response.ok) {\n if (response.status == 428 || response.status == 404) {\n EasyfyEventData.SetStatsApiBlock(true);\n }\n\n localStorage.setItem(LocalStorageKeys.SessionId, null);\n localStorage.setItem(LocalStorageKeys.ClientId, null);\n localStorage.setItem(LocalStorageKeys.UserId, null);\n localStorage.setItem(LocalStorageKeys.IsDekstop, null);\n localStorage.setItem(LocalStorageKeys.IsMobilePhone, null);\n localStorage.setItem(LocalStorageKeys.IsTablet, null);\n localStorage.setItem(LocalStorageKeys.UserIdCookieKey, null);\n localStorage.setItem(LocalStorageKeys.IPAddress, null);\n\n resolve(false);\n return;\n }\n\n var clientMetaData = await response.json()\n\n localStorage.setItem(LocalStorageKeys.SessionId, clientMetaData.sessionId);\n localStorage.setItem(LocalStorageKeys.ClientId, clientMetaData.clientId);\n localStorage.setItem(LocalStorageKeys.UserId, clientMetaData.userId);\n localStorage.setItem(LocalStorageKeys.IsDekstop, clientMetaData.isDesktop);\n localStorage.setItem(LocalStorageKeys.IsMobilePhone, clientMetaData.isMobilePhone);\n localStorage.setItem(LocalStorageKeys.IsTablet, clientMetaData.isTablet);\n localStorage.setItem(LocalStorageKeys.UserIdCookieKey, clientMetaData.userIdCookieKey);\n localStorage.setItem(LocalStorageKeys.IPAddress, clientMetaData.ipAddress);\n\n\n var data: IClientEventMetaData = {\n ClientId: clientMetaData.clientId,\n SessionId: clientMetaData.sessionId,\n UserId: clientMetaData.userId,\n IsDesktop: clientMetaData.isDesktop,\n IsMobilePhone: clientMetaData.isMobilePhone,\n IsTablet: clientMetaData.isTablet,\n IPAddress: clientMetaData.ipAddress\n }\n resolve(true);\n });\n }\n\n static BlockStatsApi(): void {\n EasyfyEventData.SetStatsApiBlock(true);\n }\n\n static HandleWorkerMessage(message) {\n var typedMessage = message.data as IWorkerMessage\n switch (typedMessage.Message) {\n case Message.FetchClientMetaData: {\n EasyfyEventHandler.FetchClientMetaData()\n break;\n }\n case Message.BlockStatsApi: {\n EasyfyEventHandler.BlockStatsApi()\n break;\n }\n }\n }\n\n static SendStartSessionEvent(): Promise {\n return new Promise(async (resolve) => {\n var clientMetaData: IClientEventMetaData = EasyfyEventData.GetClientEventMetaData();\n var clientData: ISessionStarted = {\n Culture: \"not-set-yet\", //todo -> ? \n Currency: EasyfyEventData.SiteInfo().currencyCode,\n IsDesktop: clientMetaData.IsDesktop,\n IsMobilePhone: clientMetaData.IsMobilePhone,\n IsTablet: clientMetaData.IsTablet,\n RecurringUser: EasyfyEventData.IsRecurringUser(true),\n Referrer: document.referrer,\n Path: window.location.pathname,\n UserAgent: window.navigator.userAgent,\n ClientId: clientMetaData.ClientId,\n SessionId: clientMetaData.SessionId,\n UserId: clientMetaData.UserId,\n VisitorId: clientMetaData.UserId\n };\n\n var sessionStartedEvent: IEasyfyEvent = {\n eventName: EventNames.SessionStarted,\n data: clientData\n };\n\n await EasyfyEventHandler.RunEvent(sessionStartedEvent);\n resolve();\n });\n }\n\n static InitMutationObserver(): void {\n let options = {\n childList: true,\n subtree: true,\n attributes: false,\n characterData: false\n };\n\n let targets = document.querySelectorAll('[data-track-list], [data-container=\"search-result\"]');\n EasyfyEventHandler.instance.mutationObserver = new MutationObserver(this.ElementMutated);\n targets.forEach(target => EasyfyEventHandler.instance.mutationObserver.observe(target, options));\n }\n\n static ElementMutated(mutations: MutationRecord[]) {\n mutations.forEach(mutation => {\n EasyfyEventHandler.RebindObserveProducts();\n });\n }\n\n static BannerElementMutated(mutations: MutationRecord[]) {\n mutations.forEach(mutation => {\n EasyfyEventHandler.RebindObserveBanners();\n });\n }\n\n static InitProductIntersectionObserver(): void {\n let options = {\n root: null,\n rootMargin: '0px',\n threshold: 0.1\n };\n EasyfyEventHandler.instance.intersectionObserver = new IntersectionObserver(this.ProductCardObserved, options);\n let targets = document.querySelectorAll('[data-track-product]');\n targets.forEach(target => EasyfyEventHandler.instance.intersectionObserver.observe(target));\n }\n\n static InitBannerIntersectionObserver(): void {\n let options = {\n root: null,\n rootMargin: '0px',\n threshold: 0.1\n };\n EasyfyEventHandler.instance.bannerIntersectionObserver = new IntersectionObserver(this.BannerElementObserved, options);\n let bannerTargets = document.querySelectorAll('[data-track-banner]');\n bannerTargets.forEach(target => EasyfyEventHandler.instance.bannerIntersectionObserver.observe(target));\n }\n\n static InitElementIntersectionObserver(): void {\n let options = {\n root: null,\n rootMargin: '0px',\n threshold: 0.1\n };\n EasyfyEventHandler.instance.bannerIntersectionObserver = new IntersectionObserver(this.TrackableElementObserved, options);\n let bannerTargets = document.querySelectorAll('[data-track-element]');\n bannerTargets.forEach(target => EasyfyEventHandler.instance.bannerIntersectionObserver.observe(target));\n }\n\n static RebindObserveProducts() {\n EasyfyEventHandler.instance.intersectionObserver.disconnect();\n let targets = document.querySelectorAll('[data-track-product]');\n targets.forEach(target => EasyfyEventHandler.instance.intersectionObserver.observe(target));\n }\n\n static RebindObserveBanners() {\n EasyfyEventHandler.instance.bannerIntersectionObserver.disconnect();\n let targets = document.querySelectorAll('[data-track-banner]');\n targets.forEach(target => EasyfyEventHandler.instance.bannerIntersectionObserver.observe(target));\n }\n\n static ProductCardObserved(entries: IntersectionObserverEntry[], observer: any) {\n var eventProductIds: string[] = [];\n var eventProductSalesUnitCodes: string[] = [];\n var listIds: string[] = [];\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n EasyfyEventHandler.instance.intersectionObserver.unobserve(entry.target);\n var elementIsRegisteredForImpression = entry.target.getAttribute(\"data-track-impression\").toLowerCase() === 'true';\n if (!elementIsRegisteredForImpression) return;\n\n var productIdentifier = entry.target.getAttribute(\"data-product-event-id\");\n var defaultSalesUnitCode = entry.target.getAttribute(\"data-default-sales-unit-code\");\n\n if (productIdentifier) {\n if (!EasyfyEventHandler.instance.observedElements.includes(productIdentifier + defaultSalesUnitCode)) {\n EasyfyEventHandler.instance.observedElements.push(productIdentifier + defaultSalesUnitCode);\n EasyfyEventLogger.Log({\n type: \"productimpression\",\n message: (`Product '${productIdentifier}' with SalesCodeUnit '${defaultSalesUnitCode}' seen`),\n target: entry.target\n });\n eventProductIds.push(productIdentifier);\n eventProductSalesUnitCodes.push(defaultSalesUnitCode);\n var node = entry.target;\n while (true) {\n node = node.parentElement;\n if (node.hasAttribute(\"data-track-list\")) {\n let listId = node.getAttribute(\"data-list-name\");\n if (listId) {\n listIds.push(listId);\n break;\n }\n }\n else if (node.nodeName == 'BODY') {\n listIds.push(null);\n break;\n }\n }\n }\n }\n else {\n EasyfyEventLogger.Log({\n type: \"error\",\n message: \"Product impression failed: missing event product ID\"\n });\n }\n }\n });\n\n if (eventProductIds.length > 0) {\n let event: IEasyfyEvent = {\n eventName: EventNames.ProductImpression,\n data: {\n productIdentifiers: eventProductIds,\n salesUnitCodes: eventProductSalesUnitCodes,\n listIds: listIds\n }\n }\n EasyfyEventHandler.RunEvent(event);\n }\n }\n\n static BannerElementObserved(entries: IntersectionObserverEntry[], observer: any) {\n var bannerIds: string[] = [];\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n EasyfyEventHandler.instance.bannerIntersectionObserver.unobserve(entry.target);\n var elementIsRegisteredForImpression = entry.target.getAttribute(\"data-track-impression\").toLowerCase() === 'true';\n if (!elementIsRegisteredForImpression) return;\n var bannerIdentifier = entry.target.getAttribute(\"data-banner-event-id\");\n if (bannerIdentifier) {\n if (!EasyfyEventHandler.instance.observedElements.includes(bannerIdentifier)) {\n EasyfyEventHandler.instance.observedElements.push(bannerIdentifier);\n EasyfyEventLogger.Log({\n type: \"bannerimpression\",\n message: (\"Banner '\" + bannerIdentifier + \"' seen\")\n });\n bannerIds.push(bannerIdentifier);\n }\n }\n else {\n EasyfyEventLogger.Log({\n type: \"error\",\n message: \"Banner impression failed: missing event banner ID\"\n });\n }\n }\n });\n\n if (bannerIds.length > 0) {\n bannerIds.forEach(id => {\n let event: IEasyfyEvent = {\n eventName: EventNames.BannerImpression,\n data: { bannerIdentifier: id }\n }\n EasyfyEventHandler.RunEvent(event);\n });\n }\n }\n\n static TrackableElementObserved(entries: IntersectionObserverEntry[], observer: any) {\n var elements: ITrackableElement[] = [];\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n\n var elementIsRegisteredForImpression = entry.target.getAttribute(\"data-track-impression\").toLowerCase() === 'true';\n if (!elementIsRegisteredForImpression) return;\n\n var elementIdentifier = entry.target.getAttribute(\"data-event-id\");\n if (elementIdentifier) {\n\n var multiObserve = entry.target.getAttribute(\"data-multi-observe\").toLowerCase() === 'true';\n if (multiObserve == false) {\n EasyfyEventHandler.instance.bannerIntersectionObserver.unobserve(entry.target);\n if (!EasyfyEventHandler.instance.observedElements.includes(elementIdentifier)) {\n EasyfyEventHandler.instance.observedElements.push(elementIdentifier);\n }\n }\n\n var trackType = entry.target.getAttribute(\"data-track-type\");\n var properties = new Map();\n\n for (const attribute of entry.target.getAttributeNames()) {\n if (attribute.startsWith(\"data-event-property-\")) {\n const value = entry.target.getAttribute(attribute);\n var key = attribute.replace(\"data-event-property-\", \"\");\n properties.set(key, value);\n }\n }\n\n elements.push({\n Id: elementIdentifier,\n Type: trackType,\n Properties: properties\n });\n\n EasyfyEventLogger.Log({\n type: \"elementimpression\",\n message: (\"Element '\" + elementIdentifier + \"' seen\")\n });\n\n }\n else {\n EasyfyEventLogger.Log({\n type: \"error\",\n message: \"Element impression failed: missing event ID on element\"\n });\n }\n }\n });\n\n if (elements.length > 0) {\n elements.forEach(element => {\n let event: IEasyfyEvent = {\n eventName: EventNames.ElementImpression,\n data: element\n }\n EasyfyEventHandler.RunEvent(event);\n });\n }\n }\n\n static ClickEventChecker(event: any) {\n if (event.target.closest('A') != null) {\n var node = event.target.closest('A');\n var targetUrl = node.href;\n if (node.closest('[data-track-product]') != null) {\n EasyfyEventHandler.ClickEventProduct(event, node, targetUrl);\n return;\n }\n else if (node.closest('[data-track-banner]') != null) {\n EasyfyEventHandler.ClickEventBanner(event, node, targetUrl);\n return;\n }\n else if (node.closest('[data-track-element]') != null) {\n EasyfyEventHandler.ClickEventElement(event, node, targetUrl);\n return;\n }\n }\n else {\n var node = event.target;\n if (node.closest('[data-track-element]') != null) {\n EasyfyEventHandler.ClickEventElement(event, node);\n return;\n }\n }\n }\n\n static ClickEventProduct(event: any, node: any, targetUrl: any) {\n node = node.closest('[data-track-product]');\n var elementIsRegisteredForClick = node.getAttribute(\"data-track-click\").toLowerCase() === 'true';\n if (elementIsRegisteredForClick) {\n event.stopPropagation();\n event.preventDefault();\n\n var defaultSalesUnitCode = node.getAttribute(\"data-default-sales-unit-code\");\n var productId = node.getAttribute('data-product-event-id');\n if (productId) {\n var listName\n while (true) {\n node = node.parentElement;\n if (!node) {\n break;\n }\n if (node.hasAttribute(\"data-track-list\")) {\n listName = node.getAttribute(\"data-list-name\");\n break;\n }\n else if (node.nodeName == 'body') {\n listName = null;\n break;\n }\n }\n\n let event: IEasyfyEvent = {\n eventName: EventNames.ProductClick,\n data: {\n productIdentifier: productId,\n salesUnitCode: defaultSalesUnitCode,\n listName: listName\n }\n }\n EasyfyEventHandler.RunEvent(event);\n window.location = targetUrl;\n }\n else {\n //Don't block links\n window.location = targetUrl;\n }\n }\n }\n\n static ClickEventBanner(event: any, node: any, targetUrl: any) {\n node = node.closest('[data-track-banner]');\n var elementIsRegisteredForClick = node.getAttribute(\"data-track-click\").toLowerCase() === 'true';\n if (elementIsRegisteredForClick) {\n event.stopPropagation();\n event.preventDefault();\n\n var bannerId = node.getAttribute('data-banner-event-id');\n if (bannerId) {\n let event: IEasyfyEvent = {\n eventName: EventNames.BannerClick,\n data: {\n bannerIdentifier: bannerId,\n }\n }\n EasyfyEventHandler.RunEvent(event);\n window.location = targetUrl;\n }\n else {\n //Don't block links\n window.location = targetUrl;\n }\n }\n }\n\n static ClickEventElement(event: any, node: any, targetUrl?: any) {\n node = node.closest('[data-track-element]');\n var elementIsRegisteredForClick = node.getAttribute(\"data-track-click\")?.toLowerCase() === 'true' ?? false;\n if (elementIsRegisteredForClick) {\n\n if (targetUrl) {\n event.stopPropagation();\n event.preventDefault();\n }\n\n var elementId = node.getAttribute('data-event-id');\n\n if (elementId) {\n var trackType = node.getAttribute('data-track-type');\n var properties = new Map();\n\n for (const attribute of node.getAttributeNames()) {\n if (attribute.startsWith(\"data-event-property-\")) {\n const value = node.getAttribute(attribute);\n var key = attribute.replace(\"data-event-property-\", \"\");\n properties.set(key, value);\n }\n }\n\n var data: ITrackableElement = {\n Id: elementId,\n Type: trackType,\n Properties: properties\n }\n\n let event: IEasyfyEvent = {\n eventName: EventNames.ElementClick,\n data\n }\n\n EasyfyEventHandler.RunEvent(event);\n\n if (targetUrl) {\n window.location = targetUrl;\n }\n }\n else if (targetUrl) {\n //Don't block links\n window.location = targetUrl;\n }\n }\n }\n\n static GetCurrentInstance(): EasyfyEventHandler {\n var instance: EasyfyEventHandler;\n if (EasyfyEventHandler.instance) {\n instance = EasyfyEventHandler.instance\n }\n else if (window.EasyfyEventLayerInstance) {\n instance = window.EasyfyEventLayerInstance as EasyfyEventHandler;\n }\n\n return instance;\n }\n\n static RunEvent(event: IEasyfyEvent): Promise {\n return new Promise(async (resolve) => {\n var dispatchedToServices = [];\n var errors = new Map();\n for await (const service of EasyfyEventData.GetAllServices()) {\n if (EasyfyEventData.ConsumesEvent(service.name, event.eventName)) {\n try {\n var instance = EasyfyEventHandler.GetCurrentInstance();\n\n await instance.eventExporters.get(service.name)?.RegisterEvent(event);\n dispatchedToServices.push(service.name);\n\n }\n catch (error) {\n errors.set(service.name, event.eventName);\n console.warn(error);\n }\n }\n };\n\n if (dispatchedToServices.length > 0) {\n EasyfyEventLogger.Log({ type: \"event\", message: `Event '${event.eventName}' dispatched to: ${dispatchedToServices.join(', ')}` });\n } else {\n EasyfyEventLogger.Log({ type: \"event\", message: `Event '${event.eventName}' fired but not dispatched to any services` });\n }\n errors.forEach((value, key) => {\n EasyfyEventLogger.Log({ type: \"error\", message: `Error when trying to dispatch event '${value}' to: ${key}` });\n });\n\n resolve();\n });\n }\n\n static async RegisterResponseData(responseData: any): Promise {\n return new Promise(async (resolve) => {\n var instance = EasyfyEventHandler.GetCurrentInstance();\n if (instance?.initiated) {\n await EasyfyEventHandler.CheckSessionStart();\n if (responseData?.data?.eventLayer) {\n EasyfyEventLogger.Log({\n message: \"Event layer data added from response\",\n });\n\n EasyfyEventData.AddDataToEventLayer(responseData.data.eventLayer);\n\n EasyfyEventLogger.Log({\n type: \"updateeventlayerstatus\",\n });\n await EasyfyEventHandler.RunEvents();\n }\n }\n resolve();\n });\n }\n\n static GetCookie(cookieName) {\n let cookie = {};\n document.cookie.split(';').forEach(function (el) {\n let [key, value] = el.split('=');\n cookie[key.trim()] = value;\n })\n return cookie[cookieName];\n }\n\n }\n}\n\nexport default Easyfy.Modules;\n","import axios, { AxiosRequestConfig } from 'axios';\nimport EasyfyDataLayer from '@shared/easyfy.datalayer';\nimport Event from './easyfy.events/easyfy.eventhandler';\n\nnamespace Easyfy.Shared.Scripts {\n export interface IExtraHeaders {\n key: string;\n value: string;\n }\n\n export const get = async (url: string, config?: AxiosRequestConfig): Promise => {\n axios.defaults.headers.common[\"IsAxiosRequest\"] = true;\n axios.defaults.headers.common[\"OriginalUrl\"] = window.location.href;\n\n var response = await axios.get(url, config);\n Event.EasyfyEventHandler.RegisterResponseData(response);\n return await EasyfyDataLayer.HandleDataEvents(response);\n };\n\n export const post = async (url: string, data: any, token?: string, config?: AxiosRequestConfig) => {\n if (token) {\n axios.defaults.headers.common[\"RequestVerificationToken\"] = token;\n }\n axios.defaults.headers.common[\"IsAxiosRequest\"] = true;\n axios.defaults.headers.common[\"OriginalUrl\"] = window.location.href;\n\n var response = await axios.post(url, data, config);\n Event.EasyfyEventHandler.RegisterResponseData(response);\n return await EasyfyDataLayer.HandleDataEvents(response);\n };\n\n export const patch = async (url: string, data: any, token?: string, config?: AxiosRequestConfig) => {\n if (token) {\n axios.defaults.headers.common[\"RequestVerificationToken\"] = token;\n }\n axios.defaults.headers.common[\"IsAxiosRequest\"] = true;\n axios.defaults.headers.common[\"OriginalUrl\"] = window.location.href;\n\n var response = await axios.patch(url, data, config);\n Event.EasyfyEventHandler.RegisterResponseData(response);\n return await EasyfyDataLayer.HandleDataEvents(response)\n };\n\n export const axiosDelete = async (url: string, token?: string, config?: AxiosRequestConfig) => {\n if (token) {\n axios.defaults.headers.common[\"RequestVerificationToken\"] = token;\n }\n axios.defaults.headers.common[\"IsAxiosRequest\"] = true;\n axios.defaults.headers.common[\"OriginalUrl\"] = window.location.href;\n\n var response = await axios.delete(url, config);\n Event.EasyfyEventHandler.RegisterResponseData(response);\n return await EasyfyDataLayer.HandleDataEvents(response)\n }; \n}\n\nexport default Easyfy.Shared.Scripts;","import easyfyAxios from '@shared/easyfy.axios';\n\nnamespace Easyfy.Web.Services.Filter {\n export interface IQuery {\n checkedFilters: IFilter[];\n sorter?: ISorter;\n page: number;\n applyFilterGroupCount?: IFacetGroupCount;\n searchString: string;\n }\n\n export interface IFacetGroupCount {\n key: string;\n valueCountData: IFacetValueCount[];\n }\n\n export interface IFacetValueCount {\n value: string;\n count: Number;\n }\n\n export interface IFilter {\n key: string;\n operator: FilterOperator;\n values: string[];\n } \n\n export enum FilterOperator {\n Equal,\n NotEqual,\n GreaterThan,\n LessThan \n }\n\n export interface ISorter {\n key: string;\n sortdirection: number;\n }\n\n export const GetProducts = async (pageId: string, data: IQuery, filterFor: string, productListName): Promise => {\n productListName = encodeURIComponent(productListName);\n return await easyfyAxios.post(`/category?handler=ProductList&pageId=${pageId}&filterFor=${filterFor}&productListName=${productListName}`, data);\n };\n\n export const GetArticles = async (pageId: string, data: IQuery): Promise => {\n return await easyfyAxios.post(`/articlelist?handler=ArticleList&pageId=${pageId}`, data);\n };\n}\n\nexport default Easyfy.Web.Services.Filter;","import { invoke } from '@shared/easyfy.decorators';\nimport { globalEvent, element, elements, event } from '@shared/easyfy.core';\nimport { hide, show } from '@shared/easyfy.utils';\nimport filterService from '@webServices/filter.service';\n\nnamespace Easyfy.Modules {\n @invoke\n export class Filter {\n static Instance: Filter;\n\n static FilterQuerySelector: string;\n static PagingQuerySelector: string;\n static ItemsQuerySelector: string;\n static SortersQuerySelector: string;\n static FilterFor: FilterFor;\n static Page: number;\n static Sorter: Sorter;\n static SearchString: string;\n\n static elementsStates: IElementState[];\n\n constructor(filterFor: FilterFor, filterQuerySelector: string, pagingQuerySelector: string, itemsQuerySelector: string, sortersQuerySelector: string) {\n Filter.FilterQuerySelector = filterQuerySelector;\n Filter.PagingQuerySelector = pagingQuerySelector;\n Filter.ItemsQuerySelector = itemsQuerySelector;\n Filter.SortersQuerySelector = sortersQuerySelector;\n Filter.Page = 1;\n Filter.FilterFor = filterFor;\n }\n\n onInit() {\n globalEvent({\n type: 'click',\n event: {\n action: 'load-more-items',\n callback: Filter.loadMoreItems\n }\n });\n\n globalEvent({\n type: 'change',\n event: {\n action: 'change-filter',\n callback: Filter.changeFilter\n }\n });\n\n globalEvent({\n type: 'click',\n event: {\n action: 'clear-filters',\n callback: Filter.clearFilters\n }\n });\n\n globalEvent({\n type: 'change',\n event: {\n action: 'change-sort',\n callback: Filter.changeSort\n }\n });\n\n globalEvent({\n type: 'click',\n event: {\n action: 'change-filter-top',\n callback: Filter.changeFilterTop\n }\n });\n\n document.addEventListener(\"change-sort-option\", function (e) {\n Filter.changeSort(e);\n });\n }\n\n static loadMoreItems = (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n let button: HTMLElement = e.target as HTMLElement;\n\n if (!button.hasAttribute('data-page-id')) { \n button = button.parentElement as HTMLElement; \n }\n\n const pageId: string = button.attributes['data-page-id']?.value;\n const productListName: string = element('[data-container=\"products\"]')?.attributes[\"data-list-name\"]?.value;\n Filter.Page = button.attributes['data-page']?.value as number;\n Filter.RefreshData(pageId, productListName, false);\n\n return false;\n }\n\n static changeFilter = (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n let input: HTMLElement = e.target as HTMLElement;\n var value = input.attributes['value']?.value;\n var id = input.attributes['id']?.value;\n\n //if (e.type == \"click\") {\n // input = document.querySelector('input[id=\"' + id + '\"]')\n //}\n\n const pageId: string = input.attributes['data-page-id']?.value?.toString();\n const productListName: string = element('[data-container=\"products\"]')?.attributes[\"data-list-name\"]?.value;\n\n const filterGroup = input.closest('[data-container=\"filter-group\"]') as HTMLElement;\n var counts = Filter.GetFacetCountsForCurrentGroup(filterGroup.id);\n \n if (input.getAttribute(\"checked\") != null) {\n document.querySelector('[data-container=\"all-selected-filters\"]').querySelector('[value=\"' + value + '\"]').remove();\n } else {\n let span = document.createElement('span');\n span.classList.add('selected-filter');\n span.setAttribute('data-container', 'selected-filter');\n span.setAttribute('value', value);\n span.setAttribute('data-action', \"change-filter-top\");\n span.setAttribute('data-id', id);\n let i = document.createElement('i');\n i.classList.add('remove-filter');\n i.textContent = \"x\";\n span.textContent = value;\n span.appendChild(i);\n document.querySelector('[data-container=\"all-selected-filters\"]').appendChild(span);\n }\n\n Filter.Page = 1;\n Filter.RefreshData(pageId, productListName, true, counts);\n\n return false;\n }\n\n static GetFacetCountsForCurrentGroup = (facetGroupKey: string): filterService.IFacetGroupCount => {\n var filterGroup = element('.filter-groups #' + facetGroupKey) as HTMLElement;\n if (!filterGroup) return null;\n\n var countData: Array = [];\n\n var inputs = filterGroup.querySelectorAll('.filter-row [data-action=\"change-filter\"]')\n inputs.forEach(filterInput => {\n countData.push({\n value: filterInput.attributes[\"value\"]?.value,\n count: Number.parseInt(filterInput.attributes[\"data-result\"]?.value) ?? 0\n });\n });\n\n var facetGroupCountValues: filterService.IFacetGroupCount = {\n key: facetGroupKey,\n valueCountData: countData\n };\n\n return facetGroupCountValues;\n }\n\n static RefreshData = (pageId: string, productListName: string, replaceProducts: boolean = true, facetGroupCount: filterService.IFacetGroupCount = null) => {\n Filter.saveFilterState();\n\n const urlParams = new URLSearchParams(window.location.search);\n const searchQuery = urlParams.get('q');\n \n var QueryParams: filterService.IQuery = {\n checkedFilters: Filter.getFilterData(),\n page: Filter.Page,\n sorter: {\n key: Filter.Sorter?.key ?? null,\n sortdirection: Number.parseInt(SortDirection[Filter.Sorter?.sortDirection])\n },\n searchString: searchQuery\n };\n\n if (facetGroupCount) {\n QueryParams.applyFilterGroupCount = facetGroupCount;\n }\n\n if (QueryParams.sorter.key == null || QueryParams.sorter.sortdirection == null) {\n QueryParams.sorter = null;\n }\n console.log(QueryParams);\n Filter.getItems(pageId, productListName, QueryParams).then((response) => {\n console.log(response)\n if (response.status == 200 && response.data != null && response.data.success) {\n const filterContainer = element(Filter.FilterQuerySelector);\n const pagingContainer = element(Filter.PagingQuerySelector);\n const itemsContainer = element(Filter.ItemsQuerySelector);\n const sorterContainers = elements(Filter.SortersQuerySelector);\n\n if (replaceProducts && itemsContainer) {\n itemsContainer.innerHTML = response.data.productsPartial;\n } else {\n if (itemsContainer.children.length > 0) {\n itemsContainer.lastElementChild.insertAdjacentHTML('afterend', response.data.productsPartial);\n }\n else {\n itemsContainer.innerHTML = response.data.productsPartial;\n }\n }\n if (filterContainer) {\n filterContainer.innerHTML = response.data.filterPartial;\n }\n\n if (pagingContainer) {\n pagingContainer.innerHTML = response.data.pagingPartial;\n }\n\n if (sorterContainers) {\n sorterContainers.forEach(sorterContainer => {\n sorterContainer.innerHTML = response.data.sortPartial;\n })\n }\n\n document.dispatchEvent(new CustomEvent('filter.totalHitsUpdated', { bubbles: true, detail: { totalHits: response.data.totalHits } }))\n Filter.setFilterState();\n Filter.setUrlParams(QueryParams);\n\n const clearFilterLink = document.querySelector('[data-action=\"clear-filters\"]');\n if (clearFilterLink) {\n if (QueryParams.checkedFilters.length > 0) {\n show(clearFilterLink, \"flex\");\n } else {\n hide(clearFilterLink);\n }\n }\n\n }\n }).catch(error => {\n console.log(error);\n });\n };\n\n static getItems = async (pageId: string, productListName: string, queryParams: any): Promise => {\n switch (Filter.FilterFor) {\n case FilterFor.Category:\n case FilterFor.Brand:\n case FilterFor.Search:\n const filterForName = FilterFor[Filter.FilterFor];\n return await filterService.GetProducts(pageId, queryParams, filterForName, productListName);\n case FilterFor.Articles:\n return await filterService.GetArticles(pageId, queryParams);\n }\n };\n\n static getFilterData = (): filterService.IFilter[] => {\n const filterContainer = element(Filter.FilterQuerySelector);\n if (!filterContainer) return;\n\n let filters: filterService.IFilter[] = [];\n filterContainer.querySelectorAll('[data-container=\"filter-group\"]').forEach((filterGroupElement: HTMLElement) => {\n const key = filterGroupElement.attributes['data-key']?.value;\n let anyValueChecked = false;\n\n var filter: filterService.IFilter = {\n key: key,\n operator: filterService.FilterOperator.Equal,\n values: []\n };\n\n filterGroupElement.querySelectorAll('[data-action=\"change-filter\"]:checked').forEach((filterInputElement: HTMLInputElement) => {\n anyValueChecked = true;\n filter.values.push(filterInputElement.value);\n });\n\n if (anyValueChecked) {\n filters.push(filter);\n }\n });\n\n return filters;\n };\n\n static clearFilters = (e) => {\n e.preventDefault();\n e.stopPropagation();\n \n let eventElement: HTMLElement = e.target as HTMLElement;\n let pageId: string = eventElement.attributes['data-page-id']?.value?.toString();\n if (!pageId) {\n pageId = eventElement.parentElement.attributes['data-page-id']?.value?.toString();\n }\n\n document.querySelector('[data-container=\"all-selected-filters\"]').querySelectorAll('[data-container=\"selected-filter\"]').forEach(el => {\n el.remove();\n })\n if (!pageId)\n return false;\n const filterContainer = element(Filter.FilterQuerySelector);\n const filterCheckboxes = filterContainer.querySelectorAll('input:checked')\n const productListName: string = element('[data-container=\"products\"]')?.attributes[\"data-list-name\"]?.value;\n\n if (!filterCheckboxes || filterCheckboxes.length < 1)\n return false;\n\n filterCheckboxes?.forEach(checkbox => {\n checkbox = checkbox as HTMLInputElement;\n checkbox.checked = false;\n });\n\n\n\n Filter.Page = 1;\n Filter.RefreshData(pageId, productListName, true);\n\n if (!eventElement.hasAttribute('data-action')) {\n eventElement = eventElement.parentElement;\n }\n\n hide(eventElement);\n\n return false;\n };\n\n static changeSort = (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n const input: HTMLSelectElement = e.target as HTMLSelectElement;\n const pageId: string = input.attributes['data-page-id']?.value?.toString();\n const selectedValue = input.value;\n const sortKey = selectedValue.split('-')[0];\n const direction = selectedValue.split('-')[1];\n const productListName: string = element('[data-container=\"products\"]')?.attributes[\"data-list-name\"]?.value;\n\n Filter.Page = 1;\n Filter.Sorter = {\n key: sortKey,\n sortDirection: direction\n };\n console.log(Filter.Sorter);\n Filter.RefreshData(pageId, productListName, true);\n };\n\n static changeFilterTop = (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n let el = e.target as HTMLElement;\n if (el.attributes[\"data-id\"]?.value == undefined) {\n el = el.parentElement;\n }\n const id = el.attributes[\"data-id\"]?.value;\n\n const input = document.querySelector('input[id=\"' + id + '\"]');\n input.removeAttribute(\"checked\")\n \n const pageId: string = input.attributes['data-page-id']?.value?.toString();\n const productListName: string = element('[data-container=\"products\"]')?.attributes[\"data-list-name\"]?.value;\n el.remove();\n const filterGroup = input.closest('[data-container=\"filter-group\"]') as HTMLElement;\n var counts = Filter.GetFacetCountsForCurrentGroup(filterGroup.id);\n Filter.Page = 1;\n Filter.RefreshData(pageId, productListName, true, counts);\n\n return false;\n }\n\n static saveFilterState = () => {\n let saveElementsState = elements('[data-save-state]');\n if (saveElementsState && saveElementsState.length > 0) {\n Filter.elementsStates = [];\n var tempStates: IElementState[] = []\n saveElementsState.forEach(element => {\n element = element as HTMLElement;\n\n var elementState = Filter.resolveStateAndValue(element);\n if (elementState) {\n tempStates.push(elementState)\n }\n });\n\n //arrange states so opens occur before scrolls.\n tempStates.forEach(state => {\n if (state.stateType != StateType.Scroll)\n Filter.elementsStates.push(state);\n });\n tempStates.forEach(state => {\n if (state.stateType == StateType.Scroll)\n Filter.elementsStates.push(state);\n });\n }\n };\n\n static setFilterState = () => {\n if (!Filter.elementsStates)\n return;\n Filter.elementsStates.forEach(elementState => {\n console.log(elementState)\n var domelement = element(\"#\" + elementState.elementId) as HTMLElement;\n if (!domelement)\n return;\n switch (elementState.stateType) {\n case StateType.Open: {\n if (domelement.nodeName.toLocaleLowerCase() == 'details') {\n if (elementState.value) {\n domelement.setAttribute(\"open\", \"true\");\n }\n }\n }\n case StateType.Scroll: {\n elementState.stateType = StateType.Scroll;\n domelement.scrollTop = elementState.value;\n break;\n }\n }\n });\n };\n\n static resolveStateAndValue = (element: HTMLElement): IElementState => {\n var elementState = {} as IElementState;\n if (!element.id)\n return null;\n\n elementState.elementId = element.id;\n let stateType: StateType = StateType[element.getAttribute('data-save-state')];\n let elementType = element.nodeName.toLowerCase();\n\n switch (stateType) {\n case StateType.Open: {\n elementState.stateType = StateType.Open;\n if (elementType == 'details') {\n elementState.value = element.hasAttribute(\"open\");\n }\n break;\n }\n case StateType.Scroll: {\n elementState.stateType = StateType.Scroll;\n elementState.value = element.scrollTop;\n break;\n }\n }\n return elementState;\n };\n\n static setUrlParams = (queryParams: filterService.IQuery) => {\n var urlQuery = new URLSearchParams(window.location.search);\n\n if (queryParams.page > 1) {\n urlQuery.set(\"p\", queryParams.page.toString());\n }\n else {\n urlQuery.delete(\"p\");\n }\n\n if (queryParams.checkedFilters.length > 0) {\n var filterQuery = \"\";\n queryParams.checkedFilters.forEach(filter => {\n filterQuery += filter.key.toString() + \":\";\n filterQuery += filter.values.join(\"|\") + \";\";\n });\n\n urlQuery.set(\"f\", filterQuery);\n }\n else {\n urlQuery.delete(\"f\");\n }\n\n if (queryParams.sorter != null) {\n urlQuery.set(\"s\", queryParams.sorter.key);\n urlQuery.set(\"d\", queryParams.sorter.sortdirection.toString());\n }\n else {\n urlQuery.delete(\"s\");\n urlQuery.delete(\"d\");\n }\n if (urlQuery.toString().length > 0) {\n history.replaceState(null, null, \"?\" + urlQuery.toString());\n }\n else {\n history.replaceState(null, null, window.location.origin + window.location.pathname);\n }\n };\n }\n\n export interface IElementState {\n elementId: string;\n stateType: StateType;\n value: any;\n }\n\n export enum StateType {\n Scroll,\n Open\n }\n\n export interface Sorter {\n key: string;\n sortDirection: string;\n }\n\n export enum SortDirection {\n \"Ascending\" = 0,\n \"Descending\" = 1\n }\n\n export enum FilterFor {\n Category,\n Brand,\n Search,\n Articles\n }\n}\n\nexport default Easyfy.Modules;","import { globalEvent, elements } from '@shared/easyfy.core';\nimport { visible, hideAll, showAll, toggleClass, removeCss } from '@shared/easyfy.utils';\n\nexport default class ToggleCss {\n static Instance: ToggleCss;\n static Event: string;\n\n constructor(event: string) {\n ToggleCss.Instance = this;\n ToggleCss.Event = event;\n \n globalEvent({\n type: 'click',\n events: [\n {\n callback: e => {\n ToggleCss.Instance.hideToggle(e?.target);\n },\n },\n {\n event: ToggleCss.Event,\n callback: this.onToggleElement,\n },\n ],\n });\n }\n\n onToggleElement(e: any, hide: boolean) {\n if (e?.preventDefault) e.preventDefault();\n if (e.target) e = e.target;\n\n let target = e.attributes['data-target']?.value;\n\n if (!target) {\n e = e.parentNode as HTMLElement;\n target = e.attributes['data-target']?.value;\n }\n\n if (!target) return false;\n\n const el = document.querySelectorAll(`[data-container=\"${target}\"]`);\n const toggleClassName: string = e.attributes['data-toggleClassName']?.value;\n\n if (!hide) {\n ToggleCss.Instance.hideToggle(e);\n }\n\n el.forEach((item) => {\n\n if (toggleClassName) {\n toggleClass(item, toggleClassName);\n }\n });\n\n return false;\n }\n\n hideToggle(target: any) {\n const toggleElements: NodeListOf = elements(`[data-event=\"${ToggleCss.Event}\"]`);\n toggleElements.forEach((el) => {\n const dataTarget = el.attributes['data-target']?.value;\n\n const dataTargetElement: NodeListOf = document.querySelectorAll(`[data-container=\"${dataTarget}\"]`);\n dataTargetElement.forEach((item) => {\n if (!el.contains(target) && visible(item) && visible(el) && !item.contains(target) && el !== target) {\n this.onToggleElement(el, true);\n }\n });\n });\n }\n}","import { invoke } from \"@shared/easyfy.decorators\";\nimport filter from '@clientWebModules/filter';\nimport ToggleCss from '@shared/easyfy.togglecss';\n \nnamespace Easyfy.Web.Pages {\n @invoke\n class Category {\n static Instance: Category;\n private togglecss: ToggleCss;\n\n constructor() {\n Category.Instance = this;\n this.togglecss = new ToggleCss('togglecss');\n }\n\n onInit() {\n new filter.Filter(filter.FilterFor.Category, '[data-container=\"filter\"]', '[data-container=\"paging\"]', '[data-container=\"products\"]', '[data-container=\"sorter\"]');\n }\n }\n}\n\nexport default Easyfy.Web.Pages;","// 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](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","// 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__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// 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\t354: 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 = self[\"webpackJsonpWeb\"] = self[\"webpackJsonpWeb\"] || [];\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, [17], () => (__webpack_require__(5281)))\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","query","document","querySelector","querySelectorAll","docReady","callback","context","blazorFinishedLoadingEventRegistered","window","EasyfyMethods","triggerWindowEvent","eventName","eventData","event","CustomEvent","detail","dispatchEvent","isAdminModeEnabled","readyList","readyFired","readyEventHandlersInstalled","ready","readyBody","i","length","fn","call","ctx","addEventListener","TypeError","setTimeout","push","readyState","globalEventList","globalEvent","type","split","forEach","events","item","foundItem","action","actionFound","globalFindAction","eventFound","globalFindEvent","globalFound","globalFind","globalEventAdd","body","removeEventListener","globalEventHandler","e","target","eventTarget","globalGetTargetAction","globalEventInvokeCallback","globalGetTargetEvent","globalMatchType","cbs","itemType","find","eventType","actionType","globalGetTarget","dataTarget","attributes","value","parentNode","parseToBoolean","val","isString","toLowerCase","showAll","el","displayType","style","display","hideAll","hide","selector","Element","visible","element","offsetWidth","offsetHeight","getClientRects","invoke","ctor","newClass","readyAfter","prototype","onInit","apply","error","init","resolves","err","hasOwnProperty","injector","resolve","dependencies","resolveOnload","depends","cb","id","len","Math","random","toString","substr","name","func","data","index","dependencyItem","loadedVal","Object","defineProperty","get","set","splice","dependencyFunc","key","this","enumerable","configurable","obj","prop","writable","handler","oldval","newval","getter","setter","Easyfy","Shared","Scripts","PushToDataLayer","gtmEvent","PushProductImpressionEvent","eventProducts","listName","currencyCode","ecommerce","impressions","PushProductClickEvent","click","actionField","list","ListNameCleanUp","products","PushProductDetailEvent","PushProductAddEvent","add","PushProductRemoveEvent","remove","PushCheckoutEvent","step","option","checkout","HandleDataEvents","response","dataLayer","BuildAndPushEvents","dataEvents","dataEvent","dataProduct","product","brand","category","price","variant","quantity","dimension3","dimension4","dimension5","dimension7","clickProducts","clickProduct","position","dimension6","impressionProducts","impressionProduct","detailProducts","detailProduct","console","dir","listname","replace","EasyfyEventData","AddDataToEventLayer","EasyfyEventLayer","productLists","productList","productPrices","basket","AddCustomDataToEventLayer","customData","GlobalIgnoreEvents","result","undefined","configuration","addProductImpressionsServerSide","SiteInfo","site","PageInfo","pageInfo","Events","ClearEvents","ShouldRegisterProductImpressions","ShouldRegisterBannerImpressions","addBannerImpressionsServerSide","GetAllServices","services","GetService","serviceName","serviceInstance","GetServiceNames","service","ServiceIsActive","enabled","ConsumesEvent","includeAllEvents","trim","Product","ProductAt","atIndex","Products","ids","productDataSet","ProductsAt","indexes","AllProducts","AllProductLists","ProductIndexInList","productId","productsInList","indexOf","ProductSalesUnitPrice","ProductSalesUnitPrices","prices","AllProductSalesUnitPrices","Banner","banners","AllBanners","HasEvents","Basket","GetCurrencyCode","returnValue","GetCustomData","GetClientEventMetaData","SessionId","localStorage","getItem","LocalStorageKeys","UserId","ClientId","IsDesktop","IsDekstop","IsMobilePhone","IsTablet","IPAddress","IsRecurringUser","flagAsRecurringAfterCheck","cookieKey","UserIdCookieKey","userId","GetCookieValue","LastCheckedUserId","setItem","cookieName","cookie","SetStatsApiBlock","block","StatsIsBlocked","removeItem","StatsApiIsBlocked","StatsEventExporter","_payloadKbThreshold","_eventThreshold","_eventThresholdRemoved","WithMapper","mapper","LoadAndSetTransitionStatus","CheckVisibility","bind","RegisterEvent","Promise","MapEventData","Array","isArray","AccumulateEvent","StatsEventsThresholdRemoved","storedDataString","StatsEventsTransitionObj","_eventData","JSON","parse","ClientMetaData","EventRequests","RecheckAndSetTransitionStatus","eventsMatch","skipEventNames","EventNames","BannerImpression","ElementImpression","ProductImpression","includes","Event","stringify","str","bytes","TextEncoder","encode","blob","Blob","_blob","GetObjectSizeInKB","SendEventsToStatsApi","navigator","sendBeacon","visibilityState","jsonString","EasyfyEventLogger","Ga4EventExporter","ga4Event","ConsoleLog","message","prefix","color","bgColor","Log","CheckLogStatus","EnableLog","DisableLog","ToggleImpressionVisualizer","PrintEventLayer","HidePrintedEventLayer","FeatureNames","EventTracking","Features","FeatureIsActive","featureName","hasAttribute","KlaviyoEventExporter","PushToKlaviyo","klaviyoEvent","ServiceNames","Stats","Ga4","Klaviyo","PageView","ProductClick","ProductPageView","BannerClick","ElementClick","AddToCart","RemoveFromCart","QuantityChanged","StartedCheckout","CompletedCheckout","SearchPerformed","ContinueToPayment","SessionStarted","Message","FetchClientMetaData","BlockStatsApi","SessionTimer","Modules","EasyfyEventHandler","constructor","eventMappers","eventExporters","Map","observedElements","initiated","instance","featureFlag","EasyfyEventLayerInstance","eventExporter","CheckSessionStart","then","RunEvents","InitProductIntersectionObserver","InitMutationObserver","InitBannerIntersectionObserver","InitElementIntersectionObserver","ClickEventChecker","inlineScript","RunEvent","sessionTimer","Date","now","toUTCString","SendStartSessionEvent","checkTime","diff","getTime","abs","round","oldSessionId","fetch","ok","status","clientMetaData","json","sessionId","clientId","isDesktop","isMobilePhone","isTablet","userIdCookieKey","ipAddress","HandleWorkerMessage","clientData","Culture","Currency","RecurringUser","Referrer","referrer","Path","location","pathname","UserAgent","userAgent","VisitorId","sessionStartedEvent","options","childList","subtree","characterData","targets","mutationObserver","MutationObserver","ElementMutated","observe","mutations","mutation","RebindObserveProducts","BannerElementMutated","RebindObserveBanners","intersectionObserver","IntersectionObserver","ProductCardObserved","root","rootMargin","threshold","bannerIntersectionObserver","BannerElementObserved","TrackableElementObserved","disconnect","entries","observer","eventProductIds","eventProductSalesUnitCodes","listIds","entry","isIntersecting","unobserve","getAttribute","productIdentifier","defaultSalesUnitCode","node","parentElement","listId","nodeName","productIdentifiers","salesUnitCodes","bannerIds","bannerIdentifier","elements","elementIdentifier","trackType","properties","attribute","getAttributeNames","startsWith","Id","Type","Properties","closest","targetUrl","href","ClickEventProduct","ClickEventBanner","ClickEventElement","stopPropagation","preventDefault","salesUnitCode","bannerId","elementId","GetCurrentInstance","dispatchedToServices","errors","join","RegisterResponseData","responseData","eventLayer","GetCookie","url","config","headers","common","post","token","patch","axiosDelete","Web","Services","Filter","FilterOperator","GetProducts","pageId","filterFor","productListName","encodeURIComponent","GetArticles","StateType","SortDirection","FilterFor","filterQuerySelector","pagingQuerySelector","itemsQuerySelector","sortersQuerySelector","FilterQuerySelector","PagingQuerySelector","ItemsQuerySelector","SortersQuerySelector","Page","loadMoreItems","changeFilter","clearFilters","changeSort","changeFilterTop","button","RefreshData","input","filterGroup","counts","GetFacetCountsForCurrentGroup","span","createElement","classList","setAttribute","textContent","appendChild","facetGroupKey","countData","filterInput","count","Number","parseInt","valueCountData","replaceProducts","facetGroupCount","saveFilterState","searchQuery","URLSearchParams","search","QueryParams","checkedFilters","getFilterData","page","sorter","Sorter","sortdirection","sortDirection","searchString","applyFilterGroupCount","getItems","success","filterContainer","pagingContainer","itemsContainer","sorterContainers","innerHTML","productsPartial","children","lastElementChild","insertAdjacentHTML","filterPartial","pagingPartial","sorterContainer","sortPartial","bubbles","totalHits","setFilterState","setUrlParams","clearFilterLink","catch","queryParams","Category","Brand","Search","filterForName","Articles","filters","filterGroupElement","anyValueChecked","filter","operator","Equal","values","filterInputElement","eventElement","filterCheckboxes","checkbox","checked","selectedValue","sortKey","direction","removeAttribute","saveElementsState","elementsStates","tempStates","elementState","resolveStateAndValue","state","stateType","Scroll","domelement","Open","toLocaleLowerCase","scrollTop","elementType","urlQuery","delete","filterQuery","history","replaceState","origin","ToggleCss","Instance","hideToggle","onToggleElement","toggleClassName","className","force","HTMLElement","toggle","contains","Pages","togglecss","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","exports","module","__webpack_modules__","m","O","chunkIds","priority","notFulfilled","Infinity","fulfilled","j","keys","every","r","n","__esModule","d","a","definition","o","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","chunkLoadingGlobal","self","__webpack_exports__"],"sourceRoot":""}