{"version":3,"file":"9010.bundle.15419ca455566877efd9.js","mappings":"yJAEA,MAAMA,EAAQC,IAAA,IAAC,IAAEC,EAAG,QAAEC,GAASF,EAAA,OAC3BG,EAAAA,EAAAA,KAAA,OACIC,UAAU,6BACVH,IAAKA,EACLI,IAAI,cACJH,QAASA,EACTI,eAAe,eACjB,EAWOC,EAAqBC,IAA6B,IAA5B,IAAEP,EAAG,IAAEQ,EAAG,UAAEC,GAAWF,EAEtD,MAAMG,EAAQV,EAAIU,MAAM,KAExB,OADAA,EAAMC,QAAQ,EAAG,EAAGH,GACb,GAAPI,OAAUF,EAAMG,KAAK,MAAID,OAVN,eAAC,OAAEE,EAAS,CAAC,GAAGC,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,CAAC,EAAC,OACxCG,OAAOC,KAAKL,GAAQM,QAChB,CAACC,EAAKC,SAAgC,IAAhBR,EAAOQ,GAAuB,GAAHV,OAAMS,GAAGT,OAAIS,EAAY,IAAN,KAAST,OAAGU,EAAG,KAAAV,OAAIE,EAAOQ,IAASD,GACvG,GACH,CAM2BE,CAAe,CAAET,OAAQL,IAAY,EAwB/De,EAA2BC,IAAmD,IAAlD,OAAEC,EAAM,WAAEC,EAAU,eAAEC,GAAiB,GAAMH,EAC3E,MAAM,IAAEzB,EAAKC,QAAS4B,GAAeH,EAErC,IAvC6BI,KAAA,IAAC,IAAEC,GAAKD,EAAA,MAAK,8BAA8BE,KAAKD,EAAI,EAuC5EE,CAAkB,CAAEF,IAAK/B,IAC1B,OAAOE,EAAAA,EAAAA,KAACJ,EAAK,CAACG,QAAS4B,EAAY7B,IAAKA,IAG5C,MAGMkC,GAHoBP,GAAc,CAAC,CAAElB,UAAWiB,EAAOjB,aAGpB0B,KAAIC,IAA+B,IAA9B,MAAEC,EAAK,UAAE5B,EAAY,CAAC,GAAG2B,EACnE,MAAME,EAAa,CAAChC,EAAmB,CAAEN,MAAKQ,IAAK,OAAQC,eAiB3D,OAdImB,IAAmBnB,EAAU8B,OAAS9B,EAAU+B,UAChDF,EAAW,IAAM,MACjBA,EAAWG,KACPnC,EAAmB,CACfN,MACAQ,IAAK,OACLC,UAAW,IACJA,EACH+B,OAAQ/B,EAAU+B,QAA6B,EAAnB/B,EAAU+B,OACtCD,MAAO9B,EAAU8B,OAA2B,EAAlB9B,EAAU8B,SAEvC,QAGN,CACHF,QACAC,aACH,IAKCI,EAAgBR,EAAeS,MAAKC,IAAA,IAAC,WAAEN,EAAU,MAAED,GAAOO,EAAA,OAAKN,EAAWtB,OAAS,GAAKqB,CAAK,IAC7FH,EAAeC,KAAIU,IAAa,IACzBA,EACHP,WAAYO,EAAUP,WAAWH,KAAIW,GAAOA,EAAIC,QAAQ,QAAS,cAErE,KAEN,OACIC,EAAAA,EAAAA,MAAA,WAAAC,SAAA,CACKf,EAAeC,KAAIW,IAChB,MAAMI,EAASJ,EAAIR,WAAWzB,KAAK,MACnC,OAAOX,EAAAA,EAAAA,KAAA,UAAqBiD,KAAK,aAAad,MAAOS,EAAIT,MAAOa,OAAQA,GAApDA,EAA8D,IAErFR,aAAa,EAAbA,EAAeP,KAAIW,IAChB,MAAMI,EAASJ,EAAIR,WAAWzB,KAAK,MACnC,OAAOX,EAAAA,EAAAA,KAAA,UAAqBiD,KAAK,aAAad,MAAOS,EAAIT,MAAOa,OAAQA,GAApDA,EAA8D,KAGtFhD,EAAAA,EAAAA,KAACJ,EAAK,CAACG,QAAS4B,EAAY7B,IAAKM,EAAmB,CAAEN,MAAKQ,IAAK,MAAOC,UAAWiB,EAAOjB,gBACnF,EAIZ2C,EAAoB,CAEtBC,KAAMC,IAAAA,OAENf,MAAOe,IAAAA,OAEPd,OAAQc,IAAAA,OAERC,OAAQD,IAAAA,MAAgB,CAAC,GAAI,IAAK,MA0BlCE,SAAUF,IAAAA,MAAgB,CAAC,WAAY,UAAW,OAAQ,YAAa,QAEvEG,OAAQH,IAAAA,KAERI,OAAQJ,IAAAA,MAGZ9B,EAAyBmC,UAAY,CACjCjC,OAAQ4B,IAAAA,MAAgB,CACpBtD,IAAKsD,IAAAA,OAAiBM,WACtB3D,QAASqD,IAAAA,MAAgB,CAAC,QAAS,SACnC7C,UAAW6C,IAAAA,MAAgBF,KAC5BQ,WACHjC,WAAY2B,IAAAA,QACRA,IAAAA,MAAgB,CACZjB,MAAOiB,IAAAA,OACP7C,UAAW6C,IAAAA,MAAgBF,GAAmBQ,cAKtDhC,eAAgB0B,IAAAA,MAGpB,M,wBCrKA,SAASO,EAAaC,GAAuB,IAAjBC,EAAMhD,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,OACjC,OAAO+C,EAAKE,eAAe,UAAW,CAAEC,QAASF,GACrD,CAEA,SAASG,EAAeJ,GAAuB,IAAjBC,EAAMhD,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,OACnC,OAAO+C,EAAKE,eAAe,UAAW,CAAEG,MAAOJ,GACnD,CAEA,SAASK,EAA0BN,GAC/B,IAAIO,EAAU,IAAIC,KAAKR,GAEnBS,EAAiB,IADRF,EAAQG,oBAErB,OAAO,IAAIF,KAAKD,EAAQI,UAAYF,EACxC,CAEA,SAASG,EAAcC,GACnB,GAAIA,aAAyBL,KACzB,OAAOK,EAKoC,KAA3CA,EAAcA,EAAc3D,OAAS,KACrC2D,GAAiB,KAGrB,MAAMb,EAAO,IAAIQ,KAEjB,OADAR,EAAKc,QAAQN,KAAKO,MAAMF,IACjBb,CACX,CAmIA,SAASgB,EAAeC,EAASC,GAC7B,OAhHG,SAAmBjF,GAAgE,IAA/D,YAAEkF,EAAW,SAAEC,EAAW,IAAIZ,KAAM,cAAEU,GAAgB,GAAOjF,EACpF,MAGMoF,EAHiB,IAAIb,KAAKW,GACZ,IAAIX,KAAKY,GAGvBE,EAAWD,GAAY,EAGvBE,EAAsB,CACxBC,OAAQ,QACRC,KAAM,SACNC,EAAG,gBAGHC,EAAG,WACHC,GAAI,aACJC,EAAG,UACHC,GAAI,WACJC,EAAG,QACHC,GAAI,UACJC,EAAG,SACHC,GAAI,WACJC,EAAG,UACHC,GAAI,YACJC,EAAG,SACHC,GAAI,YAGFC,EAAmB,MACrB,MAAMC,EAAgBC,KAAKC,IAAIrB,EAAW,KAE1C,GAAImB,EAAgB,GAChB,MAAO,CAAC,IAAKA,GAGjB,MAAMG,EAAgBH,EAAgB,GAEtC,GAAIA,EAAgB,GAChB,MAAO,CAAC,IAAKG,GAEjB,GAAIA,EAAgB,GAChB,MAAO,CAAC,KAAMA,GAElB,MAAMC,EAAcD,EAAgB,GAEpC,GAAIA,EAAgB,GAChB,MAAO,CAAC,IAAKC,GAEjB,GAAIA,EAAc,GACd,MAAO,CAAC,KAAMA,GAElB,MAAMC,EAAaD,EAAc,GAEjC,GAAIA,EAAc,GACd,MAAO,CAAC,IAAKC,GAEjB,GAAIA,EAAa,GACb,MAAO,CAAC,KAAMA,GAElB,MAAMC,EAAeD,EAAa,GAGlC,GAAIA,GAAcvB,EAAW,GAAK,IAC9B,MAAO,CAAC,IAAKwB,GAIjB,GAAID,GAAcvB,EAAW,IAAM,KAC/B,MAAO,CAAC,KAAMmB,KAAKM,IAAID,EAAc,KAEzC,MAAME,EAAcH,EAAa,IAGjC,OAAIA,GAAcvB,EAAW,IAAM,KACxB,CAAC,IAAK0B,GAEV,CAAC,KAAMA,EACjB,EAjDwB,GAmDnBC,EAAqB1B,EAAoBgB,EAAiB,IAAItD,QAAQ,KAAMwD,KAAKS,KAAKX,EAAiB,KAE7G,OAAOrB,EACD+B,GACC3B,EAAWC,EAA4B,OAAIA,EAA0B,MAAGtC,QAAQ,KAAMgE,EACjG,CA4BWE,CAAW,CAAEhC,YAAaP,EAAcK,GAAUC,kBAAiBjC,QAAQ,mBAAoB,WAC1G,CAEA,SAASmE,EAAQvC,GAAgC,IAAjBZ,EAAMhD,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,OACrC,MAAMoG,EAAYzC,EAAcC,GAE1ByC,EAAM,IAAI9C,KACV+C,GAAgBD,EAAI3C,UAAY0C,EAAU1C,WAAa,IAE7D,GAAI4C,EAAe,EACf,MAAO,MAGX,MACMC,GAAwBF,EADhB,IAAI9C,KAAK8C,GACmBG,SAAS,EAAG,EAAG,EAAG,IAAM,IAElE,GAAIF,GAAgBC,EAChB,MAAO,QAGX,MAAME,EAAY,IAAIlD,KAAK8C,GAC3BI,EAAUD,SAAS,EAAG,EAAG,EAAG,GAC5BC,EAAUC,QAAQL,EAAIM,UAAY,GAGlC,GAAIL,EAAeC,GAAwBD,IADJD,EAAMI,GAAa,IAEtD,MAAO,YAGX,GAAIJ,EAAIO,gBAAkBR,EAAUQ,cAAe,CAC/C,IAAIC,EAAU,CAAEzD,MAAO,OAAQ0D,IAAK,WACpC,OAAOV,EAAUnD,eAAe,QAAS4D,EAC7C,CAEA,IAAIA,EAAU,CAAEE,KAAM,UAAW3D,MAAiB,QAAVJ,EAAmB,OAAS,UAAW8D,IAAK,WACpF,OAAOV,EAAUnD,eAAe,QAAS4D,EAC7C,CAEA,SAASG,EAAWpD,GAAqE,IAAtDqD,EAAWjH,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,CAAEgD,OAAQ,OAAQkE,aAAa,GAC5E,MAAMd,EAAYzC,EAAcC,GAEhC,IAAIiD,EAAU,CAAEzD,MAAO6D,EAAYjE,OAAQ8D,IAAK,WAKhD,OAJKG,EAAYC,cACbL,EAAQE,KAAO,WAGZX,EAAUnD,eAAe,QAAS4D,EAC7C,CAEA,SAASM,EAAcnD,EAASoD,GAAkC,IAAxBC,EAASrH,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAG,IAAIuD,KACtD,MAAM+D,EAAQ,IAAI/D,KAAK8D,GACjBZ,EAAY,IAAIlD,KAAK+D,EAAM5D,UAAY,OACvC6D,EAAc5D,EAAcK,GAC5BwD,GAAcF,EAAQC,GAAe,IACrCE,EAAUF,EAAYZ,YAAcW,EAAMX,WAAanB,KAAKC,IAAI8B,EAAcD,GAAS,MACvFI,EACFH,EAAYZ,YAAcF,EAAUE,WAAanB,KAAKC,IAAI8B,EAAcD,GAAS,OAE/EK,EAAaJ,EAAYX,gBAAkBU,EAAMV,cAEvD,IAAIgB,EAAa,GAajB,GAXIA,EADAJ,EAAa,EACA,MACNC,EACM,QACNC,EACM,YACNC,EACMJ,EAAYtE,eAAe,QAAS,CAAEG,MAAO,QAAS0D,IAAK,YAE3DS,EAAYtE,eAAe,QAAS,CAAEG,MAAO,UAAW0D,IAAK,UAAWC,KAAM,YAG3FK,GAAYI,GAAc,EAAG,CAE7BI,EAAaA,EAAa,OADNL,EAAYtE,eAAe,QAAS,CAAE4E,KAAM,UAAWC,OAAQ,UAAWC,QAAQ,GAE1G,CAEA,OAAOH,CACX,C,gOChPA,SAASI,EAAuBC,GAC5B,MAAMC,EAAU1C,KAAK2C,MAAMF,GACrBG,EAAQ5C,KAAK6C,MAAMH,EAAU,MACnC,IAAII,EAAmBJ,EAAU,KACjC,MAAMK,EAAU/C,KAAK6C,MAAMC,EAAmB,IAG9C,OAFAA,GAAsC,GAElCF,EAAQ,EACD,GAAPvI,OAAUuI,EAAK,KAAAvI,OAAI0I,EAAQC,WAAWC,SAAS,EAAG,KAAI,KAAA5I,OAAIyI,EAAiBE,WAAWC,SAAS,EAAG,MAE3F,GAAP5I,OAAU0I,EAAO,KAAA1I,OAAIyI,EAAiBE,WAAWC,SAAS,EAAG,KAErE,CAiBO,SAASC,EAAyBC,EAAgBC,GACrD,GAAsB,MAAlBD,EACA,OAAO,KAGX,IAAIE,EAAYF,EAAeG,UAAU,EAAGF,GACxCG,EAAiBF,EAAUG,YAAY,KAK3C,OAJIH,EAAU5I,OAAS0I,EAAe1I,SAClC4I,EAAYA,EAAUC,UAAU,EAAGC,GACnCF,GAAwB,KAErBA,CACX,CA4BA,SAASI,EAA0BC,GAC/B,OAAIC,MAAMD,GACCA,EAGJA,EAAIjG,eAAe,QAC9B,CAEA,SAASmG,EAAkBC,GACvB,IACIC,GADW,GAAKD,GAAmBrH,QAAQ,MAAO,IAClCsH,MAAM,gCAC1B,GAAIA,EAAO,CAEP,MAAO,CADQA,EAAM,GAAK,MAAQ,GAChB,IAAKA,EAAM,GAAI,KAAMA,EAAM,GAAI,IAAKA,EAAM,IAAIxJ,KAAK,GACzE,CACA,OAAO,IACX,C,iNCjFA,SAASyJ,EAAa1C,EAAS2C,GAC3B,YAA0B,IAAZ3C,GAA2BA,EAAQ4C,eAAeD,EACpE,CAEO,SAASE,EAAWC,GAEE,oBAAdC,gBAAgD1J,IAAnB0J,UAAUlI,MAC9CkI,UAAUlI,KAAKiI,EAEvB,CAEO,SAASE,EAAcC,EAAQC,EAAUlD,GAE5CmD,EAASF,EAAQC,EADG5J,OAAO8J,OAAO,CAAEC,kBAAkB,GAAQrD,GAElE,CAEO,SAASmD,EAASF,EAAQC,EAAUlD,GACvC,KAAKsD,EAAAA,EAAAA,KAAqB,CAEtB,QAAsB,IAAXL,IAA2BA,EAClC,OAGJ,IAAIH,EAAO,CAAES,MAAO,YAEpBT,EAAK,mBAAqBG,EAC1BH,EAAK,0BAA2C,IAAbI,GAA4BA,EAAWA,EAAW,UACrFJ,EAAK,kBAAoBJ,EAAa1C,EAAS,SAAWA,EAAQwD,WAAQnK,EAC1EyJ,EAAK,kBAAoBJ,EAAa1C,EAAS,SAAWA,EAAQyD,WAAQpK,EAC1EyJ,EAAK,gCACDJ,EAAa1C,EAAS,sBAAuBA,EAAQqD,wBAA0BhK,EASnFwJ,EAAWC,EACf,CACJ,C,wDC7CO,MACMQ,EAAoBA,IAAMI,OAAOC,eAAiBD,OAAOC,cAAcC,c,wHCCpF,MAIaC,EAAiB1L,IAAA,IAAC,QAAE2L,EAAO,SAAEC,GAAU5L,EAAA,OAChD6L,EAAAA,EAAKC,KAAK,GAADjL,OALG,gBAKQ,oBAAAA,OAAmB8K,GAAW,CAAEC,YAAW,EAEtDG,EAAyBhK,IAAA,IAAC,gBAAEiK,EAAe,UAAEC,GAAWlK,EAAA,OACjE8J,EAAAA,EAAKK,IAAI,GAADrL,OAPK,aAOO,YAAAA,OAAWmL,GAAmB,CAAEC,aAAY,EAEvDE,EAAqB3L,IAAA,IAAC,gBAAEwL,EAAe,UAAEC,EAAS,QAAEN,GAASnL,EAAA,OACtEqL,EAAAA,EAAKK,IAAI,GAADrL,OATM,0BASO,SAAAA,OAAQmL,GAAmB,CAAEC,YAAWN,WAAU,C","sources":["webpack://fieldlevel.app/./app-core/components/OptimizedVideoThumbnail/_OptimizedVideoThumbnail.jsx","webpack://fieldlevel.app/./app-core/utility/dateUtils.js","webpack://fieldlevel.app/./app-core/utility/formatter.js","webpack://fieldlevel.app/./app-core/utility/googleAnalytics.js","webpack://fieldlevel.app/./app-core/utility/masquerading.js","webpack://fieldlevel.app/./app-public/shared/api/videoApi.js"],"sourcesContent":["import PropTypes from 'prop-types';\r\n\r\nconst Image = ({ src, loading }) => (\r\n <img\r\n className=\"w-full h-full object-cover\"\r\n src={src}\r\n alt=\"Video image\"\r\n loading={loading}\r\n referrerPolicy=\"no-referrer\"\r\n />\r\n);\r\n\r\nexport const getIsMuxThumbnail = ({ url }) => /https:\\/\\/image\\.mux\\.com\\//.test(url);\r\n\r\nconst getQueryString = ({ params = {} } = {}) =>\r\n Object.keys(params).reduce(\r\n (acc, key) => (typeof params[key] !== 'undefined' ? `${acc}${!acc ? '?' : '&'}${key}=${params[key]}` : acc),\r\n ''\r\n );\r\n\r\nexport const getMuxOptimizedUrl = ({ src, ext, muxParams }) => {\r\n // getMuxOptimizedUrl() relies on mux url's being of the form 'https://image.mux.com/[id]/thumbnail.[ext]\r\n const split = src.split('.');\r\n split.splice(-1, 1, ext);\r\n return `${split.join('.')}${getQueryString({ params: muxParams })}`;\r\n};\r\n\r\n/**\r\n * This component is intended to be used to generate optimized thumbnails for retrieval from Mux videos. Its api\r\n * is UNSTABLE so it shouldn't be used freely throughout the app.\r\n *\r\n * In general, the component will take a basic thumbnail url along with params supported by Mux's api and generate\r\n * a .webp-first <picture>/srcSet implementation. It will also take care of generating 1x/2x resolution options\r\n * for the browser if you provide either a width/height as a muxParam.\r\n *\r\n * Basic usage:\r\n * <_OptimizedVideoThumbnail\r\n * imgDef={{ src: 'https://image.mux.com/[id]/thumbnail.png', muxParams: {{ width: 400 }} }}\r\n * />\r\n *\r\n * // Yields\r\n * <picture>\r\n * <source type=\"image/webp\" srcSet=\"https://image.mux.com/[id]/thumbnail.webp?width=400 1x, https://image.mux.com/[id]/thumbnail.webp?width=800 2x\" />\r\n * <source type=\"image/jpeg\" srcSet=\"https://image.mux.com/[id]/thumbnail.jpg?width=400 1x, https://image.mux.com/[id]/thumbnail.jpg?width=800 2x\" />\r\n * <img src=\"https://image.mux.com/[id]/thumbnail.jpg?width=400\" />\r\n * </picture\r\n *\r\n */\r\nconst _OptimizedVideoThumbnail = ({ imgDef, sourceDefs, includeHighRes = true }) => {\r\n const { src, loading: imgLoading } = imgDef;\r\n\r\n if (!getIsMuxThumbnail({ url: src })) {\r\n return <Image loading={imgLoading} src={src} />;\r\n }\r\n\r\n const derivedSourceDefs = sourceDefs || [{ muxParams: imgDef.muxParams }];\r\n\r\n // Build out the <source>/srcSet definitions for .webp images\r\n const webPSourceDefs = derivedSourceDefs.map(({ media, muxParams = {} }) => {\r\n const srcSetDefs = [getMuxOptimizedUrl({ src, ext: 'webp', muxParams })];\r\n\r\n // If includeHighRes is specified, create 1x/2x variants to populate the srcSet\r\n if (includeHighRes && (muxParams.width || muxParams.height)) {\r\n srcSetDefs[0] += ` 1x`;\r\n srcSetDefs.push(\r\n getMuxOptimizedUrl({\r\n src,\r\n ext: 'webp',\r\n muxParams: {\r\n ...muxParams,\r\n height: muxParams.height && muxParams.height * 2,\r\n width: muxParams.width && muxParams.width * 2\r\n }\r\n }) + ` 2x`\r\n );\r\n }\r\n return {\r\n media,\r\n srcSetDefs\r\n };\r\n });\r\n\r\n // If the webp sourceDefs either take advantage of media queries (responsive), or specify multiple resolutions,\r\n // we'll want to build jpeg sourceDefs also for browsers that support <picture>/srcSet but not webp\r\n const jpgSourceDefs = webPSourceDefs.some(({ srcSetDefs, media }) => srcSetDefs.length > 1 || media)\r\n ? webPSourceDefs.map(sourceDef => ({\r\n ...sourceDef,\r\n srcSetDefs: sourceDef.srcSetDefs.map(def => def.replace('.webp', '.jpg'))\r\n }))\r\n : null;\r\n\r\n return (\r\n <picture>\r\n {webPSourceDefs.map(def => {\r\n const srcSet = def.srcSetDefs.join(', ');\r\n return <source key={srcSet} type=\"image/webp\" media={def.media} srcSet={srcSet} />;\r\n })}\r\n {jpgSourceDefs?.map(def => {\r\n const srcSet = def.srcSetDefs.join(', ');\r\n return <source key={srcSet} type=\"image/jpeg\" media={def.media} srcSet={srcSet} />;\r\n })}\r\n {/* Fallback to jpeg by default*/}\r\n <Image loading={imgLoading} src={getMuxOptimizedUrl({ src, ext: 'jpg', muxParams: imgDef.muxParams })} />\r\n </picture>\r\n );\r\n};\r\n\r\nconst muxParamsPropType = {\r\n /* The time (in seconds) of the video timeline where the image should be pulled. Defaults to the middle of the original video. */\r\n time: PropTypes.number, //\r\n /* The width of the thumbnail (in pixels). Defaults to the width of the original video. */\r\n width: PropTypes.number,\r\n /* The height of the thumbnail (in pixels). Defaults to the height of the original video. */\r\n height: PropTypes.number,\r\n /* Rotate the image clockwise by the given number of degrees. Valid values are 90, 180, and 270. */\r\n rotate: PropTypes.oneOf([90, 180, 270]),\r\n /* How to fit a thumbnail within width + height. Valid values are preserve, stretch, crop, smartcrop, and pad (see below). */\r\n /*\r\n The fit_mode parameter can have the following values:\r\n\r\n preserve : By default, Mux will preserve the aspect ratio of the video, while fitting the image\r\n within the requested width and height. For example if the thumbnail width is 100, the\r\n height is 100, and the video's aspect ratio is 16:9, the delivered image will be\r\n 100x56 (16:9).\r\n\r\n stretch : The thumbnail will exactly fill the requested width and height, even if it distorts the\r\n image. Requires both width and height to be set. (Not very popular.)\r\n\r\n crop : The video image will be scaled up or down until it fills the requested width and height box.\r\n Pixels then outside of the box will be cropped off. The crop is always centered on the image.\r\n Requires both width and height to be set.\r\n\r\n smartcrop : An algorithm will attempt to find an area of interest in the image and center it within\r\n the crop, while fitting the requested width and height. Requires both width and\r\n height to be set.\r\n\r\n pad : Similar to preserve but Mux will \"letterbox\" or \"pillar box\" (add black padding to) the image\r\n to make it fit the requested width and height exactly. This is less efficient than preserve\r\n but allows for maintaining the aspect ratio while always getting thumbnails of the same size.\r\n Requires both width and height to be set.\r\n */\r\n fit_mode: PropTypes.oneOf(['preserve', 'stretch', 'crop', 'smartcrop', 'pad']),\r\n /* Flip the image top-bottom after performing all other transformations. */\r\n flip_v: PropTypes.bool,\r\n /* Flip the image left-right after performing all other transformations. */\r\n flip_h: PropTypes.bool\r\n};\r\n\r\n_OptimizedVideoThumbnail.propTypes = {\r\n imgDef: PropTypes.exact({\r\n src: PropTypes.string.isRequired,\r\n loading: PropTypes.oneOf(['eager', 'lazy']),\r\n muxParams: PropTypes.exact(muxParamsPropType)\r\n }).isRequired,\r\n sourceDefs: PropTypes.arrayOf(\r\n PropTypes.exact({\r\n media: PropTypes.string,\r\n muxParams: PropTypes.exact(muxParamsPropType).isRequired\r\n })\r\n ),\r\n /* If true and either muxParams.height or muxParams.width are provided, it will create \"2x\" sources by multiplying\r\n each of the muxParams.height and muxParams.width by 2 */\r\n includeHighRes: PropTypes.bool\r\n};\r\n\r\nexport default _OptimizedVideoThumbnail;\r\n","function dayOfTheWeek(date, format = 'long') {\r\n return date.toLocaleString('default', { weekday: format });\r\n}\r\n\r\nfunction monthOfTheYear(date, format = 'long') {\r\n return date.toLocaleString('default', { month: format });\r\n}\r\n\r\nfunction adjustDateToLocalizedDate(date) {\r\n let newDate = new Date(date);\r\n let offset = newDate.getTimezoneOffset();\r\n let offsetInMiilis = 60 * 1000 * offset;\r\n return new Date(newDate.getTime() + offsetInMiilis);\r\n}\r\n\r\nfunction convertToDate(utcDateString) {\r\n if (utcDateString instanceof Date) {\r\n return utcDateString;\r\n }\r\n\r\n // assumes a UTC date in format - 2017-06-07T23:12:16.98\r\n // tell Date.parse that this is a UTC date\r\n if (utcDateString[utcDateString.length - 1] != 'Z') {\r\n utcDateString += 'Z';\r\n }\r\n\r\n const date = new Date();\r\n date.setTime(Date.parse(utcDateString));\r\n return date;\r\n}\r\n\r\nfunction isNewerThan(utcDateString, monthsAgo) {\r\n if (utcDateString) {\r\n let promotionDate = convertToDate(utcDateString);\r\n let today = new Date();\r\n let monthsAgoDate = new Date().setMonth(today.getMonth() - monthsAgo);\r\n\r\n return promotionDate > monthsAgoDate;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * This function is intended to replicate the functionality of moment.from() using the standard\r\n * 'en-US' locality. There may be slight differences between month/day calculations, but we're not\r\n * overly concerned with 100% parity. This function is enabling a transition away from momentjs\r\n * entirely, and should be phased out once a holistic alternative is discovered (e.g Temporal)\r\n */\r\nexport function momentFrom({ compareDate, baseDate = new Date(), withoutSuffix = false }) {\r\n const compareDateObj = new Date(compareDate);\r\n const baseDateObj = new Date(baseDate);\r\n\r\n const diffInMs = compareDateObj - baseDateObj;\r\n const isFuture = diffInMs >= 0;\r\n\r\n // This table was copied from the moment.js documentation, for en-US locales only\r\n const relativeLookupTable = {\r\n future: 'in %s',\r\n past: '%s ago',\r\n s: 'a few seconds',\r\n // The ss setting is apparently only enabled if explicitly configured by the implementing codebase\r\n // ss: '%d seconds',\r\n m: 'a minute',\r\n mm: '%d minutes',\r\n h: 'an hour',\r\n hh: '%d hours',\r\n d: 'a day',\r\n dd: '%d days',\r\n w: 'a week',\r\n ww: '%d weeks',\r\n M: 'a month',\r\n MM: '%d months',\r\n y: 'a year',\r\n yy: '%d years'\r\n };\r\n\r\n const differenceLookup = (() => {\r\n const diffInSeconds = Math.abs(diffInMs / 1000);\r\n\r\n if (diffInSeconds < 45) {\r\n return ['s', diffInSeconds];\r\n }\r\n\r\n const diffInMinutes = diffInSeconds / 60;\r\n\r\n if (diffInSeconds < 90) {\r\n return ['m', diffInMinutes];\r\n }\r\n if (diffInMinutes < 45) {\r\n return ['mm', diffInMinutes];\r\n }\r\n const diffInHours = diffInMinutes / 60;\r\n\r\n if (diffInMinutes < 90) {\r\n return ['h', diffInHours];\r\n }\r\n if (diffInHours < 22) {\r\n return ['hh', diffInHours];\r\n }\r\n const diffInDays = diffInHours / 24;\r\n\r\n if (diffInHours < 36) {\r\n return ['d', diffInDays];\r\n }\r\n if (diffInDays < 26) {\r\n return ['dd', diffInDays];\r\n }\r\n const diffInMonths = diffInDays / 31;\r\n\r\n // For future dates, tests seem to confirm this cutoff is 46 days, but past dates it's 47\r\n if (diffInDays < (isFuture ? 46 : 47)) {\r\n return ['M', diffInMonths];\r\n }\r\n\r\n // For future dates, tests seem to confirm this cutoff is 322 days, but past dates it's 320\r\n if (diffInDays < (isFuture ? 322 : 320)) {\r\n return ['MM', Math.min(diffInMonths, 10)];\r\n }\r\n const diffInYears = diffInDays / 365;\r\n\r\n // For future dates, tests seem to confirm this cutoff is 549 days, but past dates it's 547\r\n if (diffInDays < (isFuture ? 549 : 547)) {\r\n return ['y', diffInYears];\r\n }\r\n return ['yy', diffInYears];\r\n })();\r\n\r\n const differentialString = relativeLookupTable[differenceLookup[0]].replace('%d', Math.ceil(differenceLookup[1]));\r\n\r\n return withoutSuffix\r\n ? differentialString\r\n : (isFuture ? relativeLookupTable['future'] : relativeLookupTable['past']).replace('%s', differentialString);\r\n}\r\n\r\nexport function getIsWithinBusinessHours({ date = new Date() } = {}) {\r\n const currentPacificHourString = new Date(date).toLocaleString('en-US', {\r\n timeZone: 'America/Los_Angeles',\r\n hour: 'numeric',\r\n hour12: false\r\n });\r\n const currentPacificHour = parseInt(currentPacificHourString);\r\n\r\n return currentPacificHour >= 9 && currentPacificHour < 17;\r\n}\r\n\r\n/**\r\n * This function is intended to replicate the functionality of moment.format(moment.HTML5_FMT.DATETIME_LOCAL)\r\n */\r\nexport function formatDateTimeLocal({ date = new Date() } = {}) {\r\n const dateObj = new Date(date);\r\n\r\n const paddedMonth = (dateObj.getMonth() + 1).toString().padStart(2, '0');\r\n const paddedDate = dateObj.getDate().toString().padStart(2, '0');\r\n const paddedHours = dateObj.getHours().toString().padStart(2, '0');\r\n const paddedMinutes = dateObj.getMinutes().toString().padStart(2, '0');\r\n\r\n return `${dateObj.getFullYear()}-${paddedMonth}-${paddedDate}T${paddedHours}:${paddedMinutes}`;\r\n}\r\n\r\nfunction fromNowVerbose(utcDate, withoutSuffix) {\r\n return momentFrom({ compareDate: convertToDate(utcDate), withoutSuffix }).replace('in a few seconds', 'just now');\r\n}\r\n\r\nfunction fromNow(utcDateString, format = 'long') {\r\n const inputDate = convertToDate(utcDateString);\r\n\r\n const now = new Date();\r\n const secondsApart = (now.getTime() - inputDate.getTime()) / 1000;\r\n\r\n if (secondsApart < 3) {\r\n return 'Now';\r\n }\r\n\r\n const today = new Date(now);\r\n const secondsSinceMidnight = (now - today.setHours(0, 0, 0, 0)) / 1000;\r\n\r\n if (secondsApart <= secondsSinceMidnight) {\r\n return 'Today';\r\n }\r\n\r\n const yesterday = new Date(now);\r\n yesterday.setHours(0, 0, 0, 0);\r\n yesterday.setDate(now.getDate() - 1);\r\n\r\n const secondsSinceMidnightYesterday = (now - yesterday) / 1000;\r\n if (secondsApart > secondsSinceMidnight && secondsApart <= secondsSinceMidnightYesterday) {\r\n return 'Yesterday';\r\n }\r\n\r\n if (now.getFullYear() === inputDate.getFullYear()) {\r\n let options = { month: 'long', day: 'numeric' };\r\n return inputDate.toLocaleString('en-US', options);\r\n }\r\n\r\n let options = { year: 'numeric', month: format == 'long' ? 'long' : 'numeric', day: 'numeric' };\r\n return inputDate.toLocaleString('en-US', options);\r\n}\r\n\r\nfunction formatDate(utcDateString, dateOptions = { format: 'long', excludeYear: false }) {\r\n const inputDate = convertToDate(utcDateString);\r\n\r\n let options = { month: dateOptions.format, day: 'numeric' };\r\n if (!dateOptions.excludeYear) {\r\n options.year = 'numeric';\r\n }\r\n\r\n return inputDate.toLocaleString('en-US', options);\r\n}\r\n\r\nfunction simpleFromNow(utcDate, withTime, todayDate = new Date()) {\r\n const today = new Date(todayDate);\r\n const yesterday = new Date(today.getTime() - 1000 * 60 * 60 * 24);\r\n const messageDate = convertToDate(utcDate);\r\n const secondsAgo = (today - messageDate) / 1000;\r\n const isToday = messageDate.getDate() === today.getDate() && Math.abs(messageDate - today) < 1000 * 60 * 60 * 24;\r\n const isYesterday =\r\n messageDate.getDate() === yesterday.getDate() && Math.abs(messageDate - today) < 1000 * 60 * 60 * 48;\r\n\r\n const isSameYear = messageDate.getFullYear() === today.getFullYear();\r\n\r\n let dateString = '';\r\n if (secondsAgo < 3) {\r\n dateString = 'Now';\r\n } else if (isToday) {\r\n dateString = 'Today';\r\n } else if (isYesterday) {\r\n dateString = 'Yesterday';\r\n } else if (isSameYear) {\r\n dateString = messageDate.toLocaleString('en-US', { month: 'short', day: 'numeric' });\r\n } else {\r\n dateString = messageDate.toLocaleString('en-US', { month: 'numeric', day: 'numeric', year: '2-digit' });\r\n }\r\n\r\n if (withTime && secondsAgo >= 3) {\r\n const messageTime = messageDate.toLocaleString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true });\r\n dateString = dateString + ' at ' + messageTime;\r\n }\r\n\r\n return dateString;\r\n}\r\n\r\nconst daysApart = (dateString1, dateString2, includeLabel = true) => {\r\n const date1 = convertToDate(dateString1);\r\n const date2 = convertToDate(dateString2);\r\n const secondsApart = Math.abs((date2.getTime() - date1.getTime()) / 1000);\r\n const days = Math.floor(secondsApart / 86400);\r\n return includeLabel ? `${days} day${days > 1 ? 's' : ''}` : days;\r\n};\r\n\r\nconst hoursApart = (dateString1, dateString2) => {\r\n const date1 = convertToDate(dateString1);\r\n const date2 = convertToDate(dateString2);\r\n const secondsApart = Math.abs((date2.getTime() - date1.getTime()) / 1000);\r\n return Math.floor(secondsApart / (60 * 60));\r\n};\r\n\r\nfunction fromDate(dateString1, dateString2) {\r\n if (!dateString1 || !dateString2) return false;\r\n\r\n let from;\r\n const date1 = convertToDate(dateString1).getTime();\r\n const date2 = convertToDate(dateString2).getTime();\r\n\r\n // convert to positive and make seconds vs milliseconds\r\n const difference = Math.abs(date2 - date1) / 1000;\r\n\r\n const years = 60 * 60 * 24 * 365;\r\n const months = 60 * 60 * 24 * 30;\r\n const days = 60 * 60 * 24;\r\n const hours = 60 * 60;\r\n\r\n if (difference / years > 1) {\r\n from = Math.floor(difference / years);\r\n from += from > 1 ? ' years' : ' year';\r\n } else if (difference / months > 1) {\r\n from = Math.floor(difference / months);\r\n from += from > 1 ? ' months' : ' month';\r\n } else if (difference / days > 1) {\r\n from = Math.floor(difference / days);\r\n from += from > 1 ? ' days' : ' day';\r\n } else if (difference / hours > 1) {\r\n from = Math.floor(difference / hours);\r\n from += from > 1 ? ' hours' : ' hour';\r\n } else if (difference / 60 > 1) {\r\n from = Math.floor(difference / 60);\r\n from += from > 1 ? ' minutes' : ' minute';\r\n } else {\r\n from = 'seconds';\r\n }\r\n\r\n return from;\r\n}\r\n\r\nexport {\r\n adjustDateToLocalizedDate,\r\n convertToDate,\r\n fromNow,\r\n formatDate,\r\n isNewerThan,\r\n simpleFromNow,\r\n fromNowVerbose,\r\n dayOfTheWeek,\r\n monthOfTheYear,\r\n daysApart,\r\n hoursApart,\r\n fromDate\r\n};\r\n","function videoDurationFormatter(seconds) {\r\n const rounded = Math.round(seconds);\r\n const hours = Math.floor(rounded / 3600);\r\n let remainingSeconds = rounded % 3600;\r\n const minutes = Math.floor(remainingSeconds / 60);\r\n remainingSeconds = remainingSeconds % 60;\r\n\r\n if (hours > 0) {\r\n return `${hours}:${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;\r\n } else {\r\n return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;\r\n }\r\n}\r\n\r\nfunction golfHandicapFormatter(handicap) {\r\n if (isNaN(handicap)) {\r\n return '--';\r\n }\r\n\r\n return handicap < 1 ? '' + -1 * handicap : '+' + handicap;\r\n}\r\n\r\nfunction twoDecimalFormatter(num) {\r\n if (isNaN(num)) {\r\n return num;\r\n }\r\n return num.toFixed(2);\r\n}\r\n\r\nexport function truncatedStringFormatter(originalString, truncateLength) {\r\n if (originalString == null) {\r\n return null;\r\n }\r\n\r\n let truncated = originalString.substring(0, truncateLength);\r\n let lastSpaceIndex = truncated.lastIndexOf(' ');\r\n if (truncated.length < originalString.length) {\r\n truncated = truncated.substring(0, lastSpaceIndex);\r\n truncated = truncated + '…';\r\n }\r\n return truncated;\r\n}\r\n\r\nfunction gpaFormatter(gpa) {\r\n if (isNaN(gpa)) {\r\n return gpa;\r\n }\r\n\r\n return gpa.toFixed(1);\r\n}\r\n\r\nfunction orgLabelFormatter(athleticAssociation) {\r\n if (!athleticAssociation) {\r\n return 'School/Organization';\r\n } else {\r\n switch (athleticAssociation) {\r\n case 'Professional':\r\n case 'ClubHighSchool':\r\n case 'PostGrad':\r\n case 'TrainingFacility':\r\n return 'Organization';\r\n case 'HighSchool':\r\n return 'School';\r\n default:\r\n return 'College';\r\n }\r\n }\r\n}\r\n\r\nfunction numberWithCommasFormatter(num) {\r\n if (isNaN(num)) {\r\n return num;\r\n }\r\n\r\n return num.toLocaleString('en-us');\r\n}\r\n\r\nfunction formatPhoneNumber(phoneNumberString) {\r\n let cleaned = ('' + phoneNumberString).replace(/\\D/g, '');\r\n let match = cleaned.match(/^(1|)?(\\d{3})(\\d{3})(\\d{4})$/);\r\n if (match) {\r\n let intlCode = match[1] ? '+1 ' : '';\r\n return [intlCode, '(', match[2], ') ', match[3], '-', match[4]].join('');\r\n }\r\n return null;\r\n}\r\n\r\nexport {\r\n golfHandicapFormatter,\r\n twoDecimalFormatter,\r\n gpaFormatter,\r\n numberWithCommasFormatter,\r\n orgLabelFormatter,\r\n videoDurationFormatter,\r\n formatPhoneNumber\r\n};\r\n","import _ from 'lodash';\r\n\r\nimport { isLoggingDisabled } from '@appCore/utility/masquerading';\r\n\r\nfunction hasOptionSet(options, optionName) {\r\n return typeof options !== 'undefined' && options.hasOwnProperty(optionName);\r\n}\r\n\r\nexport function updateData(data) {\r\n // dataLayer is a global object defined by the GA script\r\n if (typeof dataLayer !== 'undefined' && dataLayer.push !== undefined) {\r\n dataLayer.push(data);\r\n }\r\n}\r\n\r\nexport function logImpression(action, category, options) {\r\n let mergedOptions = Object.assign({ isNonInteraction: true }, options);\r\n logEvent(action, category, mergedOptions);\r\n}\r\n\r\nexport function logEvent(action, category, options) {\r\n if (!isLoggingDisabled()) {\r\n // Do not log if there is no action.\r\n if (typeof action === 'undefined' || !action) {\r\n return;\r\n }\r\n\r\n let data = { event: 'fl.event' };\r\n\r\n data['fl.event.action'] = action;\r\n data['fl.event.category'] = typeof category !== 'undefined' && category ? category : 'General';\r\n data['fl.event.label'] = hasOptionSet(options, 'label') ? options.label : undefined;\r\n data['fl.event.value'] = hasOptionSet(options, 'value') ? options.value : undefined;\r\n data['fl.event.isNonInteraction'] =\r\n hasOptionSet(options, 'isNonInteraction') && options.isNonInteraction ? true : undefined;\r\n\r\n // console.group('logEvent');\r\n // console.log(category);\r\n // console.log(action);\r\n // console.log(options);\r\n // console.log(data);\r\n // console.groupEnd('logEvent');\r\n\r\n updateData(data);\r\n }\r\n}\r\n\r\nexport function logVirtualPageView(virtualPageUrl, eventAttributes) {\r\n if (!isLoggingDisabled()) {\r\n if (typeof eventAttributes === 'undefined') {\r\n eventAttributes = {};\r\n }\r\n\r\n let defaultAttributes = {\r\n event: 'sendVirtualPageView',\r\n vpv: virtualPageUrl,\r\n UserIdForGA: dataLayerUserIdForGA\r\n };\r\n\r\n _.merge(eventAttributes, defaultAttributes);\r\n updateData(eventAttributes);\r\n }\r\n}\r\n","export const isMasquerading = () => window.FLAuthOptions && window.FLAuthOptions.isMasquerading;\r\nexport const isLoggingDisabled = () => window.FLAuthOptions && window.FLAuthOptions.disableLogging;\r\n","import http from '@appCore/services/http';\r\n\r\nconst baseUrl = '/api/videoapi';\r\nconst videoUrl = '/api/video';\r\nconst detailUrl = '/api/athletevideodetail';\r\n\r\nexport const UpdateDuration = ({ videoId, duration }) =>\r\n http.post(`${baseUrl}/updateduration/${videoId}`, { duration });\r\n\r\nexport const GetAllVideosForAthlete = ({ athleteUsername, sportEnum }) =>\r\n http.get(`${videoUrl}/getall/${athleteUsername}`, { sportEnum });\r\n\r\nexport const GetVideoForAthlete = ({ athleteUsername, sportEnum, videoId }) =>\r\n http.get(`${detailUrl}/get/${athleteUsername}`, { sportEnum, videoId });\r\n"],"names":["Image","_ref","src","loading","_jsx","className","alt","referrerPolicy","getMuxOptimizedUrl","_ref3","ext","muxParams","split","splice","concat","join","params","arguments","length","undefined","Object","keys","reduce","acc","key","getQueryString","_OptimizedVideoThumbnail","_ref4","imgDef","sourceDefs","includeHighRes","imgLoading","_ref2","url","test","getIsMuxThumbnail","webPSourceDefs","map","_ref5","media","srcSetDefs","width","height","push","jpgSourceDefs","some","_ref6","sourceDef","def","replace","_jsxs","children","srcSet","type","muxParamsPropType","time","PropTypes","rotate","fit_mode","flip_v","flip_h","propTypes","isRequired","dayOfTheWeek","date","format","toLocaleString","weekday","monthOfTheYear","month","adjustDateToLocalizedDate","newDate","Date","offsetInMiilis","getTimezoneOffset","getTime","convertToDate","utcDateString","setTime","parse","fromNowVerbose","utcDate","withoutSuffix","compareDate","baseDate","diffInMs","isFuture","relativeLookupTable","future","past","s","m","mm","h","hh","d","dd","w","ww","M","MM","y","yy","differenceLookup","diffInSeconds","Math","abs","diffInMinutes","diffInHours","diffInDays","diffInMonths","min","diffInYears","differentialString","ceil","momentFrom","fromNow","inputDate","now","secondsApart","secondsSinceMidnight","setHours","yesterday","setDate","getDate","getFullYear","options","day","year","formatDate","dateOptions","excludeYear","simpleFromNow","withTime","todayDate","today","messageDate","secondsAgo","isToday","isYesterday","isSameYear","dateString","hour","minute","hour12","videoDurationFormatter","seconds","rounded","round","hours","floor","remainingSeconds","minutes","toString","padStart","truncatedStringFormatter","originalString","truncateLength","truncated","substring","lastSpaceIndex","lastIndexOf","numberWithCommasFormatter","num","isNaN","formatPhoneNumber","phoneNumberString","match","hasOptionSet","optionName","hasOwnProperty","updateData","data","dataLayer","logImpression","action","category","logEvent","assign","isNonInteraction","isLoggingDisabled","event","label","value","window","FLAuthOptions","disableLogging","UpdateDuration","videoId","duration","http","post","GetAllVideosForAthlete","athleteUsername","sportEnum","get","GetVideoForAthlete"],"sourceRoot":""}