{"version":3,"file":"ContentCards-Chunk-6f20e56b853525c6a9ce.js","mappings":"8WAwBA,MA0DA,EA1DeA,IAauB,IAbtB,SACdC,EAAQ,UACRC,EAAS,WACTC,EAAU,SACVC,GAAW,EAAK,SAChBC,EAAQ,KACRC,EAAI,aACJC,EAAY,UACZC,GAAY,EAAK,6BACjBC,EAA+B,iBAAgB,YAC/CC,EAAW,SACXC,GAAW,KACRC,GAC4BZ,EAC/B,MAAMa,EAAgBC,IACpB,CACE,mGACGV,IAAaI,IAAcG,EAE9B,CAAC,GAAGF,uNACFC,EACI,GACA,qGACAN,GAAYI,IAAcG,EAEhC,kCAAmCP,EAEnC,wFACGA,IAAaI,GAAaG,GAE/B,sDACAT,GAGF,OAAOI,GAAMS,MAAQT,GAAMU,MAAQf,KAAcG,EAC/Ca,MAAAC,cAAA,KACEhB,UAAWW,EACXM,KAAMb,EAAKS,IACXK,OAAQd,EAAKc,OACb,yBAAwBf,EACxBgB,QAASd,EACT,cAAaJ,GAEZF,GAAYK,EAAKU,MAGpBC,MAAAC,cAAA,SAAAI,EAAA,GACMV,EAAW,CACfV,UAAWW,EACXT,SAAUA,EACV,yBAAwBC,EACxB,cAAaF,IAEZF,EAEJ,C,oTC3DH,MA8DA,EA9DcD,IAWkB,IAXjB,SACbC,EAAQ,QACRsB,EAAO,WACPpB,EAAU,QACVqB,EAAO,MACPC,EAAK,aACLC,EAAY,SACZC,EAAQ,SACRC,GAAW,EAAI,gBACfC,GAAkB,EAAI,MACtBC,EAAQ,IACiB9B,EACzB,MAAM+B,EAAeN,GAAOO,OACtBC,EAAeR,GAAOS,OACtBC,EAAgBV,GAAOW,QACvBC,EAAqBZ,GAAOa,aAC5BC,GAAaC,EAAAA,EAAAA,MACZC,EAAUC,IAAeC,EAAAA,EAAAA,WAAkB,GAElD,IAAKR,GAAepB,IAAK,OAAO,KAEhC,MAAM6B,EAAa,CACjB,CAACC,EAAAA,EAAeC,OAAQf,EACxB,CAACc,EAAAA,EAAeE,QAASd,EACzB,CAACY,EAAAA,EAAeG,OAAQb,EACxB,CAACU,EAAAA,EAAeI,QAASZ,GAG3B,OACEpB,MAAAC,cAAA,WAAShB,UAAWY,IAAWS,IAC7BN,MAAAC,cAAA,UACEgC,KAAK,aACLpB,MAAOA,EACPqB,OAAQ,GAAGpB,GAAchB,aAAakB,GAAclB,aAAaoB,GAAepB,cAAcsB,GAAoBtB,cAEpHE,MAAAC,cAAA,MAAAI,EAAA,CACE8B,IAAKzB,EACL0B,IAAK5B,GAAO6B,SAASC,OAAS9B,GAAO6B,QAAU,cAC/CpD,UAAWY,IACTY,EACA,uCAEF,yBAAwBF,EACxBgC,UAAU,QACVC,QAAS7B,EAAW,OAAS,QAC7B8B,OAAQA,IAAMhB,GAAY,GAC1BZ,MAAOA,EACP6B,IACElB,GAAYZ,EACRe,EAAWL,IAAaxB,IACxBgB,GAAchB,IAEpB6C,OAAQhB,EAAWL,IAAaqB,OAChCC,MAAOjB,EAAWL,IAAasB,MAC/BV,OAAQ,GAAGpB,GAAc+B,qBAAqB7B,GAAc6B,qBAAqB3B,GAAe2B,sBAAsBzB,GAAoByB,qBACrI3D,GAAc,CAAE,cAAeA,KAErCsC,GAAYxC,EACL,C,yVC9Dd,MAgGA,EAhGoBD,IASP,IATQ,MACnByB,EAAK,MACLsC,EAAK,KACLzD,EAAI,KACJ0D,EAAI,UACJC,EAAS,WACT9D,EAAa,qBAAoB,cACjC+D,EAAa,cACbC,GACMnE,EACN,MAAMoE,GAAWC,EAAAA,EAAAA,GAAc,MACzBC,GAAmBD,EAAAA,EAAAA,GAAc,OAEhCE,EAAeC,IAAoB7B,EAAAA,EAAAA,UAAS,IAG7C8B,EACAL,EAAiB,GACjBE,EAAyB,GACtB,IAGFI,GAAWC,aAAcC,KAAuBC,EAAAA,EAAAA,MAChDC,EAAgBC,IAAqBpC,EAAAA,EAAAA,WAAS,GAC/CqC,EAAaf,EAAY,EAAIQ,EAAiB,EAAIA,EAClDQ,EAAmBL,EAAoBI,EACvCE,EAAa5E,GAAMS,KAAOT,GAAMU,KAQtC,OANAmE,EAAAA,EAAAA,YAAU,KACR,MAAMC,EAAgBpB,EAAKqB,QAAQ,UAAW,IAAIA,QAAQ,OAAQ,KAClEb,GAAiBc,EAAAA,EAAAA,GAAaF,EAAe,IAAK,OAAO,GAExD,IAGDnE,MAAAC,cAAA,OAAKhB,UAAU,uCACbe,MAAAC,cAAA,OAAKhB,UAAU,eACbe,MAAAC,cAACqE,EAAAA,EAAK,CACJ9D,MAAOA,EACPC,aAAa,sDACbvB,WAAY,GAAGA,aAGnBc,MAAAC,cAAA,OAAKhB,UAAU,kDACbe,MAAAC,cAAA,KACEhB,WAAc+D,EAAY,KAAO,MAAtB,mBACX,cAAa,GAAG9D,WAEf4D,GAGH9C,MAAAC,cAAA,OAAKhB,UAAU,6BACbe,MAAAC,cAACsE,EAAAA,EAAOC,IAAGnE,EAAA,CACT8B,IAAKsB,EACLxE,UAAU,+CACLgF,EACD,CAAC,EACD,CACEQ,QAAS,CAAE9B,OAAQ,GACnB+B,QAASb,EAAiB,WAAa,YACvCc,SAAU,CACRC,SAAU,CAAEjC,OAAQ,QACpBkC,UAAW,CACTlC,OAAQqB,EAAmBD,EAAa,UAG7C,CACLe,wBAAyB,CACvBC,OAAQhC,GAAMT,OAAS,KAAO2B,EAAaX,EAAgBP,GAE7D,cAAa,GAAG7D,YAGjB8E,IAAqBC,GACpBjE,MAAAC,cAAA,UACEhB,UAAU,wCACVmB,QAASA,KACP0D,GAAmBD,EAAe,EAEpC,cAAa,GAAG3E,oBAEhBc,MAAAC,cAAA,cAAS4D,EAAiBX,EAAgBD,KAK/CgB,GACCjE,MAAAC,cAAA,WACED,MAAAC,cAAC+E,EAAAA,EAAM,CAAC3F,KAAMA,EAAMH,WAAY,GAAGA,YAIrC,E,wNClGV,MAmDA,EAnDqBH,IAAoD,IAAnD,MAAEkG,EAAK,cAAEhC,EAAa,cAAEC,GAAsBnE,EAClE,MAAMmG,GAAaC,EAAAA,EAAAA,UAAQ,KACzB,IAAIC,EAAgB,GAEpB,MAAMC,EAAc,CAClB,EAAG,CAAC,GACJ,EAAG,CAAC,GACJ,EAAG,CAAC,EAAG,GACP,EAAG,CAAC,EAAG,IACPJ,EAAM3C,QAER,IAAK+C,EAAa,MAAO,GAEzB,MAAM/E,EAAU,CAAC,gBAAiB,aAAc,cAMhD,OALA+E,EAAYC,SAASC,IACnB,MAAMC,EAAa,IAAIC,MAAMF,GAAKG,KAAKpF,EAAQiF,EAAM,IACrDH,EAAM,IAAIA,KAAQI,EAAW,IAGxBJ,CAAG,GACT,CAACH,IAEJ,OACEjF,MAAAC,cAAA,WACEhB,UAAU,8EACV,cAAY,uBAEZe,MAAAC,cAAA,OAAKhB,UAAU,qCACbe,MAAAC,cAAA,OAAKhB,UAAU,mBAAmB,cAAY,2BAC5Ce,MAAAC,cAAA,OACEhB,UAAU,4FACV,cAAY,wBAEXgG,EAAMU,KAAI,CAACC,EAAMC,IAChB7F,MAAAC,cAAA,OAAKhB,UAAWiG,EAAWW,GAAQC,IAAKF,EAAK9C,OAC3C9C,MAAAC,cAAC8F,EAAW1F,EAAA,GACNuF,EAAI,CACR1G,WAAY,sBAAsB2G,IAClC7C,UAAiC,eAAtBkC,EAAWW,GACtB5C,cAAeA,EACfC,cAAeA,WAOnB,C,uCCzDHtB,EAAc,SAAdA,GAAc,OAAdA,EAAc,WAAdA,EAAc,YAAdA,EAAc,WAAdA,EAAc,YAAdA,CAAc,EAAdA,GAAc,IAOzB,S,mCCNA,MAaA,EAbqByC,CAACtB,EAAciD,EAAmBC,KACrD,MAAM3C,EAAgBP,EAAKqB,QACzB,IAAI8B,OAAO,OAAOF,gBAClB,MAKF,MAFwD,MAAtD1C,EAAc6C,UAAU7C,EAAchB,OAAS,GAG7C,GAAGgB,EAAc8C,MAAM,GAAI,KAAKH,IAChC,GAAG3C,IAAgB2C,GAAQ,C,6DCRjC,MAAMI,EAAuBA,KAC3B,MAAMC,EAAwB,IAAxBA,EAAsC,KAAtCA,EAAuD,KACvD1D,EAAQ2D,OAAOC,WAErB,OAAI5D,EAAQ0D,EACH1E,EAAAA,EAAeC,MAEpBe,GAAS0D,GAAsB1D,EAAQ0D,EAClC1E,EAAAA,EAAeE,OAEpBc,GAAS0D,GAAuB1D,EAAQ0D,EACnC1E,EAAAA,EAAeG,MAEjBH,EAAAA,EAAeI,MAAM,EAuB9B,EApBsBT,KACpB,MAAOkF,EAAQC,IAAahF,EAAAA,EAAAA,YAEtBiF,GAAgBC,EAAAA,EAAAA,cACpB,IAAMF,EAAUL,MAChB,IAYF,OATAnC,EAAAA,EAAAA,YAAU,KACRqC,OAAOM,iBAAiB,SAAUF,GAClCD,EAAUL,KAEH,KACLE,OAAOO,oBAAoB,SAAUH,EAAc,IAEpD,CAACA,IAEGF,CAAM,C,kDClCf,MAwBA,EAxBuBM,IAKrB,MAAOC,EAAeC,IAAoBvF,EAAAA,EAAAA,YAEpCwF,GAAUN,EAAAA,EAAAA,cAAY,KAC1B,MAAMO,EAAiBZ,OAAOC,WAAaO,EAC3CE,EAAiBE,EAAe,GAC/B,CAACJ,IAWJ,OATA7C,EAAAA,EAAAA,YAAU,KACRqC,OAAOM,iBAAiB,SAAUK,GAClCA,IAEO,KACLX,OAAOO,oBAAoB,SAAUI,EAAQ,IAE9C,CAACA,IAEGF,CAAa,C,kDCrBtB,MA4CA,EA5C0BpD,KACxB,MAAMwD,GAAcC,EAAAA,EAAAA,WACbC,EAAkBC,IAAuB7F,EAAAA,EAAAA,UAAS,CACvDkB,MAAO,EACPD,OAAQ,EACR6E,YAAa,EACbC,aAAc,EACdC,YAAa,EACbhE,aAAc,IAGViE,GAAef,EAAAA,EAAAA,cAAagB,IAChC,IAAKnC,MAAMoC,QAAQD,GAAU,OAE7B,MAAME,EAAQF,EAAQ,GAEtBL,EAAoB,CAClB3E,MAAOkF,GAAOC,YAAYnF,OAAS,EACnCD,OAAQmF,GAAOC,YAAYpF,QAAU,EACrC6E,YAAaM,GAAO3H,OAAOqH,aAAe,EAC1CC,aAAcK,GAAO3H,OAAOsH,cAAgB,EAC5CC,YAAaI,GAAO3H,OAAOuH,aAAe,EAC1ChE,aAAcoE,GAAO3H,OAAOuD,cAAgB,GAC5C,GACD,IAiBH,MAAO,EAfKkD,EAAAA,EAAAA,cACToB,IACKZ,EAAYa,UAAYD,IAC1BZ,EAAYa,QAAQC,aACpBd,EAAYa,aAAUE,IAGnBf,EAAYa,SAAWD,IAC1BZ,EAAYa,QAAU,IAAIG,eAAeT,GACzCP,EAAYa,QAAQI,QAAQL,GAC9B,GAEF,CAACL,IAGUL,EAAiB,C","sources":["webpack://nikon-client/./components/atoms/Button/Button.tsx","webpack://nikon-client/./components/atoms/Image/Image.tsx","webpack://nikon-client/./components/molecules/ContentCard/ContentCard.tsx","webpack://nikon-client/./components/organisms/ContentCards/ContentCards.tsx","webpack://nikon-client/./models/enums/BreakpointEnum.ts","webpack://nikon-client/./utility/helpers/truncateText.ts","webpack://nikon-client/./utility/hooks/useBreakpoint.ts","webpack://nikon-client/./utility/hooks/useMediaQuery.ts","webpack://nikon-client/./utility/hooks/useResizeObserver.ts"],"sourcesContent":["import { ILink } from '@models/ILink';\nimport classNames from 'classnames';\nimport {\n  ButtonHTMLAttributes,\n  DetailedHTMLProps,\n  PropsWithChildren,\n} from 'react';\n\ninterface Props {\n  readonly className?: string;\n  readonly dataTestId?: string;\n  readonly disabled?: boolean;\n  readonly editHint?: string;\n  readonly link?: ILink;\n  readonly linkCallback?: () => void;\n  readonly secondary?: boolean;\n  readonly secondaryBackgroundClassName?: string;\n  readonly isLightMode?: boolean;\n  readonly inverted?: boolean;\n}\n\ntype ButtonProps = Props &\n  DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>;\n\nconst Button = ({\n  children,\n  className,\n  dataTestId,\n  disabled = false,\n  editHint,\n  link,\n  linkCallback,\n  secondary = false,\n  secondaryBackgroundClassName = 'bg-transparent',\n  isLightMode,\n  inverted = false,\n  ...buttonProps\n}: PropsWithChildren<ButtonProps>) => {\n  const buttonClasses = classNames(\n    {\n      'bg-yellow py-1 px-4 text-black-100 hover:bg-yellow-100 focus:bg-yellow-500 active:bg-yellow-500':\n        !disabled && !secondary && !inverted,\n      //\n      [`${secondaryBackgroundClassName} border border-yellow py-[3px] px-[15px] text-black-100 hover:border-yellow-100 hover:bg-yellow-100 hover:text-black-100 focus:border-yellow-500 focus:bg-yellow-500 active:border-yellow-500 active:bg-yellow-500 ${\n        isLightMode\n          ? ''\n          : 'dark:text-white dark:hover:text-black-100 dark:focus:text-black-100 dark:active:text-black-100'\n      }`]: !disabled && secondary && !inverted,\n      //\n      'bg-grey text-grey-500 py-1 px-4': disabled,\n      //\n      'bg-black text-white py-1 px-4 active:bg-grey-600 hover:bg-grey-600 focus:bg-grey-600':\n        !disabled && !secondary && inverted,\n    },\n    'cta rounded-full inline-block min-h-min select-none',\n    className\n  );\n\n  return link?.url && (link?.name || children) && !disabled ? (\n    <a\n      className={buttonClasses}\n      href={link.url}\n      target={link.target}\n      data-epi-property-name={editHint}\n      onClick={linkCallback}\n      data-testid={dataTestId}\n    >\n      {children || link.name}\n    </a>\n  ) : (\n    <button\n      {...buttonProps}\n      className={buttonClasses}\n      disabled={disabled}\n      data-epi-property-name={editHint}\n      data-testid={dataTestId}\n    >\n      {children}\n    </button>\n  );\n};\n\nexport default Button;\n","import BreakpointEnum from '@models/enums/BreakpointEnum';\nimport { IImage } from '@models/IImage';\nimport useBreakpoint from '@utils/hooks/useBreakpoint';\nimport classNames from 'classnames';\nimport { PropsWithChildren, RefObject, useState } from 'react';\n\ninterface Props {\n  readonly classes?: string;\n  readonly dataTestId?: string;\n  readonly epiEdit?: string;\n  readonly image?: IImage;\n  readonly imageClasses?: string;\n  readonly imageRef?:\n    | RefObject<HTMLImageElement>\n    | ((node: HTMLElement | null) => void);\n  readonly lazyLoad?: boolean;\n  readonly progressiveLoad?: boolean;\n  readonly sizes?: string;\n}\n\nconst Image = ({\n  children,\n  classes,\n  dataTestId,\n  epiEdit,\n  image,\n  imageClasses,\n  imageRef,\n  lazyLoad = true,\n  progressiveLoad = true,\n  sizes = '',\n}: PropsWithChildren<Props>) => {\n  const mobileSource = image?.mobile;\n  const tabletSource = image?.tablet;\n  const desktopSource = image?.desktop;\n  const largeDesktopSource = image?.largeDesktop;\n  const breakpoint = useBreakpoint() as BreakpointEnum;\n  const [isLoaded, setIsLoaded] = useState<boolean>(false);\n\n  if (!desktopSource?.url) return null;\n\n  const currentSrc = {\n    [BreakpointEnum.Small]: mobileSource,\n    [BreakpointEnum.Medium]: tabletSource,\n    [BreakpointEnum.Large]: desktopSource,\n    [BreakpointEnum.XLarge]: largeDesktopSource,\n  };\n\n  return (\n    <picture className={classNames(classes)}>\n      <source\n        type=\"image/webp\"\n        sizes={sizes}\n        srcSet={`${mobileSource?.url} 376w, ${tabletSource?.url} 768w, ${desktopSource?.url} 1024w, ${largeDesktopSource?.url} 1440w`}\n      />\n      <img\n        ref={imageRef}\n        alt={image?.altText?.length ? image?.altText : 'nikon-image'}\n        className={classNames(\n          imageClasses,\n          'transition duration-500 ease-in-out'\n        )}\n        data-epi-property-name={epiEdit}\n        draggable=\"false\"\n        loading={lazyLoad ? 'lazy' : 'eager'}\n        onLoad={() => setIsLoaded(true)}\n        sizes={sizes}\n        src={\n          isLoaded && progressiveLoad\n            ? currentSrc[breakpoint]?.url\n            : mobileSource?.url\n        }\n        height={currentSrc[breakpoint]?.height}\n        width={currentSrc[breakpoint]?.width}\n        srcSet={`${mobileSource?.originalUrl} 376w, ${tabletSource?.originalUrl} 768w, ${desktopSource?.originalUrl} 1024w, ${largeDesktopSource?.originalUrl} 1440w`}\n        {...(dataTestId && { 'data-testid': dataTestId })}\n      />\n      {isLoaded && children}\n    </picture>\n  );\n};\n\nexport default Image;\n","import Button from '@atoms/Button/Button';\nimport Image from '@atoms/Image/Image';\nimport { IContentCard } from '@models/IContentCard';\nimport truncateText from '@utils/helpers/truncateText';\nimport useMediaQuery from '@utils/hooks/useMediaQuery';\nimport useResizeObserver from '@utils/hooks/useResizeObserver';\nimport { motion } from 'framer-motion';\nimport { useEffect, useState } from 'react';\n\ninterface Props extends IContentCard {\n  readonly largeCard?: boolean;\n  readonly dataTestId?: string;\n  readonly showMoreLabel: string;\n  readonly showLessLabel: string;\n}\n\nconst ContentCard = ({\n  image,\n  title,\n  link,\n  text,\n  largeCard,\n  dataTestId = 'CT-74-Content-Card',\n  showMoreLabel,\n  showLessLabel,\n}: Props) => {\n  const isMobile = useMediaQuery(1024);\n  const isBelowXXLScreen = useMediaQuery(1920);\n\n  const [truncatedText, setTruncatedText] = useState('');\n\n  // Replicated the line heights for body-two class, in order to properly compute the cutoff height\n  const textLineHeight = (() => {\n    if (isMobile) return 22;\n    if (isBelowXXLScreen) return 26;\n    return 28;\n  })();\n\n  const [textRef, { scrollHeight: textContentHeight }] = useResizeObserver();\n  const [isTextExpanded, setIsTextExpanded] = useState(false);\n  const textCutOff = largeCard ? 4 * textLineHeight : 5 * textLineHeight;\n  const isTextExpandable = textContentHeight > textCutOff;\n  const hasCTALink = link?.url && link?.name;\n\n  useEffect(() => {\n    const formattedText = text.replace(/<\\/?p>/g, '').replace(/\\n+/g, ' ');\n    setTruncatedText(truncateText(formattedText, 300, '...'));\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []);\n\n  return (\n    <div className=\"flex h-full flex-col gap-4 lg:gap-5\">\n      <div className=\"w-full pb-4\">\n        <Image\n          image={image}\n          imageClasses=\"w-full h-full object-cover left-0 -z-1 aspect-video\"\n          dataTestId={`${dataTestId}-Image`}\n        />\n      </div>\n      <div className=\"flex w-full flex-col gap-4 md:w-[90%] lg:gap-5\">\n        <p\n          className={`${largeCard ? 'h3' : 'h4'} dark:text-white`}\n          data-testid={`${dataTestId}-Title`}\n        >\n          {title}\n        </p>\n\n        <div className=\"flex items-start flex-col\">\n          <motion.div\n            ref={textRef}\n            className=\"overflow-hidden body-two dark:text-grey-500\"\n            {...(hasCTALink\n              ? {}\n              : {\n                  initial: { height: 0 },\n                  animate: isTextExpanded ? 'expanded' : 'collapsed',\n                  variants: {\n                    expanded: { height: 'auto' },\n                    collapsed: {\n                      height: isTextExpandable ? textCutOff : 'auto',\n                    },\n                  },\n                })}\n            dangerouslySetInnerHTML={{\n              __html: text?.length > 300 && hasCTALink ? truncatedText : text,\n            }}\n            data-testid={`${dataTestId}-Text`}\n          />\n\n          {isTextExpandable && !hasCTALink && (\n            <button\n              className=\"shrink-0 underline dark:text-grey-500\"\n              onClick={() => {\n                setIsTextExpanded(!isTextExpanded);\n              }}\n              data-testid={`${dataTestId}-Show-More/Less`}\n            >\n              <strong>{isTextExpanded ? showLessLabel : showMoreLabel}</strong>\n            </button>\n          )}\n        </div>\n\n        {hasCTALink && (\n          <div>\n            <Button link={link} dataTestId={`${dataTestId}-Cta`} />\n          </div>\n        )}\n      </div>\n    </div>\n  );\n};\n\nexport default ContentCard;\n","import { IContentCard } from '@models/IContentCard';\nimport ContentCard from '@molecules/ContentCard/ContentCard';\nimport { useMemo } from 'react';\n\ninterface Props {\n  readonly cards: IContentCard[];\n  readonly showMoreLabel: string;\n  readonly showLessLabel: string;\n}\n\nconst ContentCards = ({ cards, showMoreLabel, showLessLabel }: Props) => {\n  const classArray = useMemo(() => {\n    let res: string[] = [];\n\n    const layoutArray = {\n      2: [2],\n      3: [3],\n      4: [2, 2],\n      5: [2, 3],\n    }[cards.length];\n\n    if (!layoutArray) return [];\n\n    const classes = ['col-span-full', 'col-span-6', 'col-span-4'];\n    layoutArray.forEach((row) => {\n      const rowClasses = new Array(row).fill(classes[row - 1]);\n      res = [...res, ...rowClasses];\n    });\n\n    return res;\n  }, [cards]);\n\n  return (\n    <section\n      className=\"component-padding bg-white text-black-100 dark:bg-black-100 dark:text-white\"\n      data-testid=\"CT-74-Content-Cards\"\n    >\n      <div className=\"container xl:grid xl:grid-cols-12\">\n        <div className=\"xl:col-span-full\" data-testid=\"listingCardBlockPrimary\">\n          <div\n            className=\"flex flex-col gap-x-0 gap-y-[5.625rem] dark:text-white md:gap-x-4 lg:grid lg:grid-cols-12\"\n            data-testid=\"content-card-listing\"\n          >\n            {cards.map((card, index) => (\n              <div className={classArray[index]} key={card.title}>\n                <ContentCard\n                  {...card}\n                  dataTestId={`CT-74-Content-Card-${index}`}\n                  largeCard={classArray[index] === 'col-span-6'}\n                  showMoreLabel={showMoreLabel}\n                  showLessLabel={showLessLabel}\n                />\n              </div>\n            ))}\n          </div>\n        </div>\n      </div>\n    </section>\n  );\n};\n\nexport default ContentCards;\n","const enum BreakpointEnum {\n  Small = 'sm',\n  Medium = 'md',\n  Large = 'lg',\n  XLarge = 'xl',\n}\n\nexport default BreakpointEnum;\n","// Truncates text to the specific limit but keeps the last matched word intact even if it exceeds the limit\nconst truncateText = (text: string, charLimit: number, suffix: string) => {\n  const truncatedText = text.replace(\n    new RegExp(`^(.{${charLimit}}[^\\\\s]*).*`),\n    '$1'\n  );\n  const isLastCharFullStop =\n    truncatedText.substring(truncatedText.length - 1) === '.';\n\n  return isLastCharFullStop\n    ? `${truncatedText.slice(0, -1)}${suffix}`\n    : `${truncatedText}${suffix}`;\n};\n\nexport default truncateText;\n","import BreakpointEnum from '@models/enums/BreakpointEnum';\nimport { useCallback, useEffect, useState } from 'react';\n\nconst getCurrentBreakpoint = () => {\n  const breakpoints = { tablet: 768, desktop: 1024, lgDesktop: 1440 };\n  const width = window.innerWidth;\n\n  if (width < breakpoints.tablet) {\n    return BreakpointEnum.Small;\n  }\n  if (width >= breakpoints.tablet && width < breakpoints.desktop) {\n    return BreakpointEnum.Medium;\n  }\n  if (width >= breakpoints.desktop && width < breakpoints.lgDesktop) {\n    return BreakpointEnum.Large;\n  }\n  return BreakpointEnum.XLarge;\n};\n\nconst useBreakpoint = () => {\n  const [screen, setScreen] = useState<BreakpointEnum>();\n\n  const resizeHandler = useCallback(\n    () => setScreen(getCurrentBreakpoint()),\n    []\n  );\n\n  useEffect(() => {\n    window.addEventListener('resize', resizeHandler);\n    setScreen(getCurrentBreakpoint());\n\n    return () => {\n      window.removeEventListener('resize', resizeHandler);\n    };\n  }, [resizeHandler]);\n\n  return screen;\n};\n\nexport default useBreakpoint;\n","import { useCallback, useEffect, useState } from 'react';\n\nconst useMediaQuery = (minWidth: number) => {\n  // Set the default value to undefined in order to properly distinguish the falsey values\n  // where undefined is the value before computing whether the screen size is smaller than the minWidth\n  // i.e. a state where we don't really know whether we're below the threshold or not\n  // and false is the value where the computation returns false\n  const [isSmallerThan, setIsSmallerThan] = useState<boolean>();\n\n  const handler = useCallback(() => {\n    const isDesiredWidth = window.innerWidth < minWidth;\n    setIsSmallerThan(isDesiredWidth);\n  }, [minWidth]);\n\n  useEffect(() => {\n    window.addEventListener('resize', handler);\n    handler();\n\n    return () => {\n      window.removeEventListener('resize', handler);\n    };\n  }, [handler]);\n\n  return isSmallerThan;\n};\n\nexport default useMediaQuery;\n","import { useCallback, useRef, useState } from 'react';\n\nconst useResizeObserver = () => {\n  const observerRef = useRef<ResizeObserver>();\n  const [resizeParameters, setResizeParameters] = useState({\n    width: 0,\n    height: 0,\n    clientWidth: 0,\n    clientHeight: 0,\n    scrollWidth: 0,\n    scrollHeight: 0,\n  });\n\n  const handleResize = useCallback((entries: ResizeObserverEntry[]) => {\n    if (!Array.isArray(entries)) return;\n\n    const entry = entries[0];\n\n    setResizeParameters({\n      width: entry?.contentRect.width ?? 0,\n      height: entry?.contentRect.height ?? 0,\n      clientWidth: entry?.target.clientWidth ?? 0,\n      clientHeight: entry?.target.clientHeight ?? 0,\n      scrollWidth: entry?.target.scrollWidth ?? 0,\n      scrollHeight: entry?.target.scrollHeight ?? 0,\n    });\n  }, []);\n\n  const ref = useCallback(\n    (node: HTMLElement | null) => {\n      if (observerRef.current && !node) {\n        observerRef.current.disconnect();\n        observerRef.current = undefined;\n      }\n\n      if (!observerRef.current && node) {\n        observerRef.current = new ResizeObserver(handleResize);\n        observerRef.current.observe(node);\n      }\n    },\n    [handleResize]\n  );\n\n  return [ref, resizeParameters] as const;\n};\n\nexport default useResizeObserver;\n"],"names":["_ref","children","className","dataTestId","disabled","editHint","link","linkCallback","secondary","secondaryBackgroundClassName","isLightMode","inverted","buttonProps","buttonClasses","classNames","url","name","React","createElement","href","target","onClick","_extends","classes","epiEdit","image","imageClasses","imageRef","lazyLoad","progressiveLoad","sizes","mobileSource","mobile","tabletSource","tablet","desktopSource","desktop","largeDesktopSource","largeDesktop","breakpoint","useBreakpoint","isLoaded","setIsLoaded","useState","currentSrc","BreakpointEnum","Small","Medium","Large","XLarge","type","srcSet","ref","alt","altText","length","draggable","loading","onLoad","src","height","width","originalUrl","title","text","largeCard","showMoreLabel","showLessLabel","isMobile","useMediaQuery","isBelowXXLScreen","truncatedText","setTruncatedText","textLineHeight","textRef","scrollHeight","textContentHeight","useResizeObserver","isTextExpanded","setIsTextExpanded","textCutOff","isTextExpandable","hasCTALink","useEffect","formattedText","replace","truncateText","Image","motion","div","initial","animate","variants","expanded","collapsed","dangerouslySetInnerHTML","__html","Button","cards","classArray","useMemo","res","layoutArray","forEach","row","rowClasses","Array","fill","map","card","index","key","ContentCard","charLimit","suffix","RegExp","substring","slice","getCurrentBreakpoint","breakpoints","window","innerWidth","screen","setScreen","resizeHandler","useCallback","addEventListener","removeEventListener","minWidth","isSmallerThan","setIsSmallerThan","handler","isDesiredWidth","observerRef","useRef","resizeParameters","setResizeParameters","clientWidth","clientHeight","scrollWidth","handleResize","entries","isArray","entry","contentRect","node","current","disconnect","undefined","ResizeObserver","observe"],"sourceRoot":""}