{"version":3,"sources":["webpack:///./src/modules/FeaturedItems/FeaturedItems.tsx","webpack:///./src/modules/FeaturedItems/index.ts","webpack:///./src/utils/gtag.ts","webpack:///./src/utils/dom.ts","webpack:///./src/utils/image-utils.ts","webpack:///./src/components/FeaturedItemCard/FeaturedItemCard.tsx","webpack:///./src/components/FeaturedItemCardGrid/FeaturedItemCardGrid.tsx"],"names":["FeaturedItems","_React$Component","_classCallCheck","_callSuper","arguments","_inherits","_createClass","key","value","_this$props","this","props","items","heading","icon","hideDivider","React","className","styles","featuredItemGrid","headingWrapper","HeadingWithImg","title","size","FeaturedItemCardGrid","version","eventName","DividerComp","_defineProperty","ONLY_SERVER","global","trackEvent","_ref","event","eventData","eventLabel","window","gtmEvent","concat","site_section","dataLayer","push","truncateString","string","length","substring","Error","DIMENSION_NAMES","aspectRatios","mobile","desktop","defaultBreakpoints","hd","breakpoints","xs","sm","md","lg","generateSizes","imageBreaks","undefined","maxWidth","queries","reduce","acc","breakpoint","index","breakpointSize","imgSizes","FeaturedItemCard","text","link","image","date","cx","featuredItemCard","Link","Object","assign","noUnderline","featuredItemCardLink","Image","height","width","sizes","textWrapper","news","Paragraph","tag","Heading","level","ctaWrapper","CtaButton","featuredLink","flat","noLink","eventMeta","displayName","defaultProps","viewMore","MediaQuery","defaultMatches","query","matches","Carousel","moduleName","renderItems","slice","map","item","itemCard","last","featuredItemsGrid"],"mappings":"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","file":"static/scripts/42-b71f183f38c5f6221f31.js","sourcesContent":["import * as React from 'react'\n\nimport DividerComp from '../../components/DividerComp/DividerComp'\nimport FeaturedItemCardGrid from '../../components/FeaturedItemCardGrid/FeaturedItemCardGrid'\nimport HeadingWithImg from '../../components/HeadingWithImg/HeadingWithImg'\nimport type { FeaturedItemsCardViewModel } from '../../view-models/FeaturedItemsCardViewModel'\nimport styles from './featuredItems-style.css'\n\ntype Props = {\n items: Array\n heading?: string\n icon?: string\n hideDivider?: boolean\n}\ntype State = {}\n\nclass FeaturedItems extends React.Component {\n static displayName = 'FeaturedItems'\n static defaultProps = {}\n\n render() {\n const { items, heading, icon, hideDivider } = this.props\n\n return (\n
\n {heading && (\n
\n \n
\n )}\n \n {!hideDivider && }\n
\n )\n }\n}\n\nexport default FeaturedItems","export { default } from './FeaturedItems'\n\n/**\n * Should the component only render server side?\n * You can set this to true if the component is a pure static component.\n */\nexport const ONLY_SERVER = false","global.dataLayer = global.dataLayer || []\nexport type GtagEvent = {\n event?: string\n eventData?: string\n eventLabel?: string\n}\n\n/**\n * Track an event\n * Supply a callback, that gets triggered after the event is tracked\n */\nexport function trackEvent({ event, eventData, eventLabel }: GtagEvent) {\n if (typeof window === 'undefined') return\n const eventName = event ? `${window.site_section || 'pensam'}-${event}` : ''\n const gtmEvent = {\n event: eventName,\n 'event-data': eventData || '',\n 'event-label': eventLabel || '',\n }\n\n if (global.dataLayer && gtmEvent.event) {\n global.dataLayer.push(gtmEvent)\n } //\n // if (\n // process.env.NODE_ENV === 'development' &&\n // global.dataLayer &&\n // gtmEvent.event\n // ) {\n // console.log('dataLayer', global.dataLayer)\n // }\n}\n","export function scrollOffset(element, offset = 0, alignment = 'top') {\n const body = document.body\n const html = document.documentElement\n const elemRect = element.getBoundingClientRect()\n const clientHeight = html.clientHeight\n const documentHeight = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight,\n )\n let scrollPosition\n\n if (alignment === 'bottom') {\n scrollPosition = elemRect.bottom - clientHeight\n } else if (alignment === 'middle') {\n scrollPosition = elemRect.bottom - clientHeight / 2 - elemRect.height / 2\n } else {\n // top and default\n scrollPosition = elemRect.top\n }\n\n const maxScrollPosition = documentHeight - clientHeight\n return Math.min(scrollPosition + offset + window.pageYOffset, maxScrollPosition)\n}\n\n/**\n * Return true if child is contained in parent\n * @param parent {HTMLElement}\n * @param child {HTMLElement}\n * @returns {boolean}\n */\nexport function isDescendant(parent, child) {\n if (!child || !child.parentNode) return false\n let node = child.parentNode\n\n while (node != null) {\n if (node === parent) {\n return true\n }\n\n node = node.parentNode\n }\n\n return false\n}\nlet matchesFn\n\n/**\n * Find the closest element that matches the selector\n * @param el {HTMLElement}\n * @param selector {string}\n * @returns {HTMLElement}\n */\nexport function closest(el, selector) {\n if (!matchesFn) {\n // find vendor prefix\n ;[\n 'matches',\n 'webkitMatchesSelector',\n 'mozMatchesSelector',\n 'msMatchesSelector',\n 'oMatchesSelector',\n ].some((fn) => {\n if (typeof document.body[fn] === 'function') {\n matchesFn = fn\n return true\n }\n\n return false\n })\n }\n\n // traverse parents\n let parent\n let element = el\n\n while (element !== null) {\n parent = element.parentElement\n\n if (parent !== null && parent[matchesFn](selector)) {\n return parent\n }\n\n element = parent\n }\n\n return null\n}\n\n/**\n * Get the previous sibling DOM node to an element\n * @param node {HTMLElement}\n * @returns {HTMLElement}\n */\nexport function previousSibling(node) {\n if (!node) return null\n let element = node\n\n do {\n element = element.previousSibling\n if (!isIgnorable(element)) return element\n } while (element)\n\n return null\n}\n\n/**\n * Get the next sibling DOM node to an element\n * @param node {HTMLElement}\n * @returns {HTMLElement}\n */\nexport function nextSibling(node) {\n if (!node) return null\n let element = node\n\n do {\n element = element.nextSibling\n if (element && !isIgnorable(element)) return element\n } while (element)\n\n return null\n}\n\n/**\n * Ignore commment and text nodes.\n * @param node\n * @returns {*}\n */\nfunction isIgnorable(node) {\n if (!node) return null\n return node.nodeType === 8 || (node.nodeType === 3 && isAllWs(node))\n}\n\n/**\n * Ignore all whitespace nodes\n * @param node\n * @returns {*}\n */\nfunction isAllWs(node) {\n if (!node) return null\n // Use ECMA-262 Edition 3 String and RegExp features\n return !/[^\\t\\n\\r ]/.test(node.textContent)\n}\n\nexport function getNodePath(node) {\n if (!node) return null\n let currentNode = node\n let path\n\n while (currentNode.parentNode) {\n const tag = currentNode.tagName.toLowerCase()\n const classes = currentNode.getAttribute('class')\n const className = classes ? `.${classes.trim().split(' ').join('.')}` : ''\n\n if (path) {\n path = `${tag}${className} > ${path}`\n } else {\n path = `${tag}${className}`\n }\n\n // Move up in the tree\n currentNode = currentNode.parentNode\n }\n\n return path\n}\nexport function insertAfter(newNode, referenceNode) {\n referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling)\n}\nexport function truncateString(string, length) {\n if (string.length > length) {\n if (typeof string === 'string' && typeof length === 'number') {\n return string.substring(0, length) + '\\u2026'\n } else {\n throw new Error('Function truncateString take args @string, @number')\n }\n } else return string\n}\nexport default {\n closest,\n isDescendant,\n previousSibling,\n nextSibling,\n scrollOffset,\n getNodePath,\n insertAfter,\n truncateString,\n}","export type ImageRatio = 'original' | 'dim16_9' | 'dim3_2'\nexport const DIMENSION_NAMES = ['xs', 'sm', 'md', 'lg', 'hd']\nexport const aspectRatios = {\n mobile: 10 / 23,\n desktop: 10 / 27,\n}\n\n/** Max image width at a given breakpoint. */\nexport type ImageBreakpoints = {\n xs?: string\n sm?: string\n md?: string\n lg?: string\n hd?: string\n}\nexport const IMAGE_WIDTHS = [150, 300, 560, 660, 750, 880, 1024, 1350, 1440, 1720, 1920, 2048, 2700]\nexport type ImageSizes = {\n breakpoints?: ImageBreakpoints\n maxWidth: string | number\n}\n// If image breaks are undefined, make sure the width tops out 100 viewport width\nconst defaultBreakpoints = {\n hd: '100vw',\n}\nconst breakpoints = {\n xs: 0,\n sm: 48,\n // 48*16 = 768px\n md: 64,\n // 64*16 = 1024px\n lg: 75,\n // 75*16 = 1200px\n hd: 90, // 88*16 = 1408px\n}\n\n/**\n * Converts a string number with a known unit type, to a unitless number in px size\n **/\nexport function sizeToNumber(size: string | number): number {\n if (!size) return 0\n if (typeof size === 'number') return size\n if (size.endsWith('px')) return parseInt(size.substr(0, size.length - 2), 10)\n if (size.endsWith('em')) return parseInt(size.substr(0, size.length - 2), 10) * 16\n if (size.endsWith('vw')) return (parseInt(size.substr(0, size.length - 2), 10) * 1440) / 100\n if (size.endsWith('rem')) return parseInt(size.substr(0, size.length - 3), 10) * 16\n return parseInt(size, 10)\n}\n\n/**\n * Generate the actual ratio for the the known Image ratios\n **/\nexport function calculateRatio(width: number = 16, height: number = 9, aspect: number) {\n return Math.min(aspect, height === 0 ? 1 : height / width === 0 ? 1 : width) // switch (aspect) {\n // case 'dim3_2':\n // return 2 / 3\n // case 'dim16_9':\n // return 9 / 16\n // default:\n // return height / width\n // }\n}\n\n/**\n * Generate sizes for images, while respecting Breakpoints\n **/\nexport function generateSizes(\n imageBreaks: ImageBreakpoints = defaultBreakpoints,\n maxWidth: string | number = '1440px',\n) {\n const queries = DIMENSION_NAMES.reduce((acc, breakpoint, index) => {\n // If the breakpoint is 0, or undefined, take the next dimension\n const maxWidth = breakpoints[breakpoint] || breakpoints[DIMENSION_NAMES[index + 1]]\n const breakpointSize = imageBreaks[breakpoint]\n\n if (breakpointSize) {\n return `${acc}(max-width: ${maxWidth}em) ${breakpointSize}, `\n }\n\n return acc\n }, '')\n return queries + (typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth)\n}","import cx from 'classnames'\nimport * as React from 'react'\n\nimport type { FeaturedItemsCardViewModel } from '../../view-models/FeaturedItemsCardViewModel'\nimport CtaButton from '../CtaButton/CtaButton'\nimport Heading from '../Heading/Heading'\nimport Image from '../Image/Image'\nimport Link from '../Link/Link'\nimport Paragraph from '../Paragraph/Paragraph'\nimport styles from './featuredItemCard-style.css'\nimport { ButtonTypes } from '@/view-models/ButtonTypes'\n\nexport type FeaturedItemCardProps = FeaturedItemsCardViewModel & {\n eventName: string\n}\n\nconst imgSizes = {\n maxWidth: 420,\n}\n\nfunction FeaturedItemCard({\n title,\n text,\n link,\n image,\n className,\n version,\n date,\n eventName,\n}: FeaturedItemCardProps) {\n\n return (\n
\n \n {image ? (\n \n ) : null}\n \n {version === 'news' ? (\n \n {date}\n \n ) : null}\n {title ? (\n \n {title}\n \n ) : null}\n {text ? {text} : null}\n {link ? (\n
\n \n
\n ) : null}\n \n \n
\n )\n}\n\nFeaturedItemCard.displayName = 'FeaturedItemCard'\nFeaturedItemCard.defaultProps = {}\n\nexport default FeaturedItemCard\n","import cx from 'classnames'\nimport * as React from 'react'\n\nimport type { FeaturedItemsCardViewModel } from '../../view-models/FeaturedItemsCardViewModel'\nimport type { LinkViewModel } from '../../view-models/LinkViewModel'\nimport Carousel from '../Carousel/Carousel'\nimport FeaturedItemCard from '../FeaturedItemCard/FeaturedItemCard'\nimport MediaQuery from '../MediaQuery/MediaQuery'\nimport styles from './featuredItemCardGrid-style.css'\n\nexport type FeaturedItemCardGridProps = {\n items: Array\n version: 'pages' | 'news'\n viewMore?: LinkViewModel\n eventName: string\n}\n\nfunction FeaturedItemCardGrid({ items, version, viewMore, eventName }: FeaturedItemCardGridProps) {\n if (!items) return null\n\n return (\n \n {(matches) =>\n matches && version === 'news' ? (\n \n items\n .slice(0, items.length)\n .map((item, index) => (\n \n ))\n }\n />\n ) : (\n
\n {items.map((item, index) => (\n \n ))}\n
\n )\n }\n
\n )\n}\n\nFeaturedItemCardGrid.displayName = 'FeaturedItemCardGrid'\nFeaturedItemCardGrid.defaultProps = {}\nexport default FeaturedItemCardGrid"],"sourceRoot":""}