{"version":3,"file":"grid-fns.js?v=9.1.8","mappings":";qJAiEA,SAASA,IACP,MAAMC,EAAQC,SAASC,eAAe,UAChCC,EAAeF,SAASC,eAAe,oBACvCE,EAAOH,SAASI,cAAc,QAEpC,GAAIL,GAASG,GAAgBC,EAAM,CACjC,MAAME,EAAQN,EAAMO,WAAU,GAC9B,IAAIC,EAAYC,KAAKC,KAAKN,EAAKO,aAAgBX,EAAkB,cAEjE,KAAOG,EAAaS,YAClBT,EAAaU,YAAYV,EAAaS,YAGxC,IAAK,IAAIE,EAAI,EAAGA,EAAIN,EAAWM,IAC7BX,EAAaY,YAAYT,EAAMC,WAAU,IAG/C,CAUe,SAASS,EAAcC,GAChCA,IAAU,KAASC,IAKnBD,IAAU,KAASE,YArEzB,WACE,MAAMC,EAAanB,SAASoB,uBAAuB,cAI7CC,EAAcC,GACXA,IAAYA,EAAQC,UAAUC,SAJpB,yBAI4CF,EAAQC,UAAUC,SAHhE,yBAMjB,IAAK,MAAMC,KAAOC,MAAMC,KAAKR,GAAa,CACxC,MAAMS,EAAgBP,EAAWI,GAC3BI,EAAUJ,EAAIK,uBACdC,EAAUN,EAAIO,mBAEpB,GAAIJ,EAAe,CACjB,IAAIK,EAAW,qBAEXZ,EAAWQ,IAAYR,EAAWU,GACpCE,EAAW,aACFZ,EAAWQ,GAKlBI,EAJGF,EAIQ,iBAHA,aAKJV,EAAWU,KACpBE,EAAW,eAGbR,EAAIF,UAAUW,IAAID,IAGxB,CAqCIE,GACArC,KA9FJ,WACE,MAAMqB,EAAanB,SAASoB,uBAAuB,cAEnD,IAAKD,EACH,OAGF,MAAMiB,EAAWV,MAAMC,KAAKR,GAE5BiB,EAASC,SAAQ,CAACZ,EAAKZ,KACrB,GAAIY,EAAIF,UAAUC,SAAS,wBAAyB,CAClD,MAAMc,EAAUF,EAASvB,EAAI,GACvB0B,EAAQC,OAAOC,iBAAiBH,GAASI,gBAE3CH,IACDd,EAAuBkB,MAAMD,gBAAkBH,MAIxD,CAqEIK,EAQJ,CAlBAJ,OAAOK,iBAAiB,QAAQ,WAC9B/C,GACF,IAEA0C,OAAOK,iBAAiB,UAAU,WAChC/C,GACF,kFCzBA,MACagD,EAAgB,CAC3BC,IAFW,KAGXC,IAAKC,QACLC,IAAKD,WACLE,IAAKF,cACLG,IAAKH,gBACLI,IAAKJ,oBAcMK,EAAiB,CAC5BC,IAAK,OACLC,IAAK,OACLC,IAAK,OACLC,IAAK,OACLC,IAAK,QAGA,SAASC,EAAkBC,GAChC,OAAOA,EAAIC,WAAWC,QAAQ,wBAAyB,IACzD,CAGA,IAAYC,EAMAC,GANZ,SAAYD,GACV,mBACA,kBACD,CAHD,CAAYA,IAAAA,EAAS,KAMrB,SAAYC,GACV,YACA,uBACD,CAHD,CAAYA,IAAAA,EAAQ","sources":["webpack://empori-base/./src/generic/GridFunctions.ts","webpack://empori-base/./src/util/util.ts"],"sourcesContent":["// Gets a row parent with \"has-background-image\" class and attempts to set a background\r\n// color of its ::after element (a paper-like svg). The color gets taken from the previous\r\n\r\nimport { ThemeIds } from '../util/util';\r\n\r\n// row parent sibling.\r\nfunction SetSvgColor() {\r\n const rowParents = document.getElementsByClassName('row-parent');\r\n\r\n if (!rowParents) {\r\n return;\r\n }\r\n\r\n const rowArray = Array.from(rowParents);\r\n\r\n rowArray.forEach((row, i) => {\r\n if (row.classList.contains('has-background-image')) {\r\n const sibling = rowArray[i - 1];\r\n const color = window.getComputedStyle(sibling).backgroundColor;\r\n\r\n if (color) {\r\n (row as HTMLDivElement).style.backgroundColor = color;\r\n }\r\n }\r\n });\r\n}\r\n\r\n// Adds classes to row parent elements based on whether their adjacent siblings have the class 'has-background-color'.\r\n// These classes are used to add graphic pseudo-elements and to handle margins.\r\nfunction determineGraphics() {\r\n const rowParents = document.getElementsByClassName('row-parent');\r\n const hasBgColor = 'has-background-color';\r\n const hasBgImg = 'has-background-image';\r\n\r\n const hasGraphic = (element: Element | null) => {\r\n return element && (element.classList.contains(hasBgColor) || element.classList.contains(hasBgImg));\r\n };\r\n\r\n for (const row of Array.from(rowParents)) {\r\n const hasBackground = hasGraphic(row);\r\n const prevRow = row.previousElementSibling;\r\n const nextRow = row.nextElementSibling;\r\n\r\n if (hasBackground) {\r\n let cssClass = 'top-bottom-graphic';\r\n\r\n if (hasGraphic(prevRow) && hasGraphic(nextRow)) {\r\n cssClass = 'no-graphic';\r\n } else if (hasGraphic(prevRow)) {\r\n if (!nextRow) {\r\n cssClass = 'no-graphic';\r\n }\r\n else {\r\n cssClass = 'bottom-graphic';\r\n }\r\n } else if (hasGraphic(nextRow)) {\r\n cssClass = 'top-graphic';\r\n }\r\n\r\n row.classList.add(cssClass);\r\n }\r\n }\r\n}\r\n\r\n// Handles the number of background SVGs depending on the screen size.\r\nfunction updateSvgAmount() {\r\n const bgSvg = document.getElementById('bg-svg');\r\n const svgContainer = document.getElementById('bg-svg-container');\r\n const main = document.querySelector('main');\r\n\r\n if (bgSvg && svgContainer && main) {\r\n const clone = bgSvg.cloneNode(true);\r\n let svgAmount = Math.ceil(main.clientHeight / (bgSvg.clientHeight));\r\n\r\n while (svgContainer.firstChild) {\r\n svgContainer.removeChild(svgContainer.firstChild);\r\n }\r\n\r\n for (let i = 0; i < svgAmount; i++) {\r\n svgContainer.appendChild(clone.cloneNode(true));\r\n }\r\n }\r\n}\r\n\r\nwindow.addEventListener('load', function() {\r\n updateSvgAmount();\r\n});\r\n\r\nwindow.addEventListener('resize', function() {\r\n updateSvgAmount();\r\n});\r\n\r\nexport default function GridFunctions(theme: ThemeIds) {\r\n if (theme === ThemeIds.raw) {\r\n SetSvgColor();\r\n return;\r\n }\r\n\r\n if (theme === ThemeIds.exclusive) {\r\n determineGraphics();\r\n updateSvgAmount();\r\n }\r\n}\r\n","import * as React from 'react';\r\n\r\nexport type MappedArrayObject = {\r\n [key: string]: T;\r\n};\r\n\r\nexport type GroupedArrayObject = {\r\n [key: string]: T[];\r\n};\r\n\r\nexport function arrayToObject(array: T[], key: (item: T) => string): MappedArrayObject {\r\n const obj: MappedArrayObject = {};\r\n\r\n for (let item of array) {\r\n obj[key(item)] = item;\r\n }\r\n\r\n return obj;\r\n}\r\n\r\nexport function groupArray(array: T[], key: (item: T) => string): GroupedArrayObject {\r\n const obj: GroupedArrayObject = {};\r\n\r\n for (let item of array) {\r\n const itemKey = key(item);\r\n (obj[itemKey] || (obj[itemKey] = [])).push(item);\r\n }\r\n\r\n return obj;\r\n}\r\n\r\nexport function camelCase(value?: string) {\r\n if (!value || value.length <= 1) {\r\n return value ?? '';\r\n }\r\n\r\n return value.charAt(0).toLocaleLowerCase() + value.substring(1);\r\n}\r\n\r\nconst formatMustasch = /{([^{}]*)}/g;\r\n\r\n/**\r\n * Format a string template in a provided mustasch format using an object as a lookup source.\r\n *\r\n * @example\r\n * formatObject('test {key1} format', { key1: 'string' }) // \"test string format\"\r\n *\r\n * @param format Format string template.\r\n * @param object Object to use as lookup.\r\n * @param replacementFunc Optional callback function for each parsed tag.\r\n * Returned `string` will be used instead of given mapped item.\r\n * @returns Formatted string template.\r\n */\r\nexport function formatObject(format: string, object?: any, replacementFunc?: (key: string, item: any) => string) {\r\n if (object == null) {\r\n return '';\r\n }\r\n\r\n return format.replace(formatMustasch, (a: string, b: string) => {\r\n let val = object[b] ?? object[camelCase(b)];\r\n let formatVal = replacementFunc?.(b, val);\r\n return formatVal ?? val;\r\n });\r\n}\r\n\r\nconst byte = 1024;\r\nexport const FileSizeUnits = {\r\n KiB: byte,\r\n MiB: byte * byte,\r\n GiB: byte * byte * byte,\r\n TiB: byte * byte * byte * byte,\r\n PiB: byte * byte * byte * byte * byte,\r\n EiB: byte * byte * byte * byte * byte * byte\r\n};\r\n\r\n/**\r\n * Returns a new array with one item replaced at given index.\r\n * Does not mutate the original array.\r\n * @param items The original array\r\n * @param index What item to replace\r\n * @param newItem The new replacementitem\r\n */\r\nexport function replaceItem(items: T[], index: number, newItem: T) {\r\n return items.map((item, idx) => idx === index ? newItem : item);\r\n}\r\n\r\nexport const FileExtensions = {\r\n PDF: '.pdf',\r\n MP4: '.mp4',\r\n OGG: '.ogg',\r\n SVG: '.svg',\r\n GIF: '.gif'\r\n};\r\n\r\nexport function thousandSeparator(num: number) {\r\n return num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ' ');\r\n};\r\n\r\n// eslint-disable-next-line no-shadow\r\nexport enum Direction {\r\n prev,\r\n next\r\n}\r\n\r\n// eslint-disable-next-line no-shadow\r\nexport enum ThemeIds {\r\n raw = 'Raw',\r\n exclusive = 'Exclusive'\r\n}\r\n\r\nexport function parseStyleString(styleString: string) {\r\n const styleObj: React.CSSProperties = {};\r\n\r\n if (!styleString) {\r\n return styleObj;\r\n }\r\n\r\n styleString.split(';').forEach(style => {\r\n const [property, value] = style.split(':').map(str => str.trim());\r\n\r\n if (property && value) {\r\n (styleObj as any)[property] = value;\r\n }\r\n });\r\n\r\n return styleObj;\r\n}\r\n\r\nexport function useDebounce(value: T, delay = 500) {\r\n const [debouncedValue, setDebouncedValue] = React.useState();\r\n const timerRef = React.useRef(0);\r\n\r\n React.useEffect(() => {\r\n timerRef.current = setTimeout(() => setDebouncedValue(value), delay) as unknown as number;\r\n\r\n return () => {\r\n clearTimeout(timerRef.current);\r\n };\r\n }, [value, delay]);\r\n\r\n return debouncedValue;\r\n}\r\n"],"names":["updateSvgAmount","bgSvg","document","getElementById","svgContainer","main","querySelector","clone","cloneNode","svgAmount","Math","ceil","clientHeight","firstChild","removeChild","i","appendChild","GridFunctions","theme","raw","exclusive","rowParents","getElementsByClassName","hasGraphic","element","classList","contains","row","Array","from","hasBackground","prevRow","previousElementSibling","nextRow","nextElementSibling","cssClass","add","determineGraphics","rowArray","forEach","sibling","color","window","getComputedStyle","backgroundColor","style","SetSvgColor","addEventListener","FileSizeUnits","KiB","MiB","byte","GiB","TiB","PiB","EiB","FileExtensions","PDF","MP4","OGG","SVG","GIF","thousandSeparator","num","toString","replace","Direction","ThemeIds"],"sourceRoot":""}