@clickview/lite 0.49.0-rc.2 → 0.49.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/bundles.json +1 -1
  2. package/dist/css/4291-lite-69960aaab9.chunk.css +23 -0
  3. package/dist/css/6723-lite-69960aaab9.chunk.css +23 -0
  4. package/dist/css/9437-lite-69960aaab9.chunk.css +23 -0
  5. package/dist/languages/en.json +1 -1
  6. package/dist/scripts/{6375-f6cac7d19c-lite.chunk.js → 1539-df427c5b98-lite.chunk.js} +2 -2
  7. package/dist/scripts/1539-df427c5b98-lite.chunk.js.map +1 -0
  8. package/dist/scripts/194-918a27a783-lite.chunk.js +2 -0
  9. package/dist/scripts/194-918a27a783-lite.chunk.js.map +1 -0
  10. package/dist/scripts/{3042-d531f193aa-lite.chunk.js → 3042-32e303014a-lite.chunk.js} +2 -2
  11. package/dist/scripts/{3042-d531f193aa-lite.chunk.js.map → 3042-32e303014a-lite.chunk.js.map} +1 -1
  12. package/dist/scripts/32-cf9b8ba599-lite.chunk.js +2 -0
  13. package/dist/scripts/32-cf9b8ba599-lite.chunk.js.map +1 -0
  14. package/dist/scripts/{3854-6b20ca6c3b-lite.chunk.js → 3854-9e1422da99-lite.chunk.js} +2 -2
  15. package/dist/scripts/3854-9e1422da99-lite.chunk.js.map +1 -0
  16. package/dist/scripts/4291-4ea61b3610-lite.chunk.js +2 -0
  17. package/dist/scripts/4291-4ea61b3610-lite.chunk.js.map +1 -0
  18. package/dist/scripts/6723-ece2125bab-lite.chunk.js +2 -0
  19. package/dist/scripts/6723-ece2125bab-lite.chunk.js.map +1 -0
  20. package/dist/scripts/{7268-d9bf6e2c2a-lite.chunk.js → 7268-a8484f7697-lite.chunk.js} +2 -2
  21. package/dist/scripts/{7268-d9bf6e2c2a-lite.chunk.js.map → 7268-a8484f7697-lite.chunk.js.map} +1 -1
  22. package/dist/scripts/{9087-48c8bfbc09-lite.chunk.js → 9087-55e2aad6ad-lite.chunk.js} +2 -2
  23. package/dist/scripts/{9087-48c8bfbc09-lite.chunk.js.map → 9087-55e2aad6ad-lite.chunk.js.map} +1 -1
  24. package/dist/scripts/9437-d9c671743c-lite.chunk.js +2 -0
  25. package/dist/scripts/9437-d9c671743c-lite.chunk.js.map +1 -0
  26. package/dist/scripts/{bundle-1335ff3786.min.js → bundle-0f5cfcd378.min.js} +3 -3
  27. package/dist/scripts/bundle-0f5cfcd378.min.js.map +1 -0
  28. package/package.json +1 -1
  29. package/dist/scripts/194-6131a555c8-lite.chunk.js +0 -2
  30. package/dist/scripts/194-6131a555c8-lite.chunk.js.map +0 -1
  31. package/dist/scripts/32-5739e73587-lite.chunk.js +0 -2
  32. package/dist/scripts/32-5739e73587-lite.chunk.js.map +0 -1
  33. package/dist/scripts/3854-6b20ca6c3b-lite.chunk.js.map +0 -1
  34. package/dist/scripts/6375-f6cac7d19c-lite.chunk.js.map +0 -1
  35. package/dist/scripts/bundle-1335ff3786.min.js.map +0 -1
  36. /package/dist/css/{6375-lite-69960aaab9.chunk.css → 1539-lite-69960aaab9.chunk.css} +0 -0
  37. /package/dist/scripts/{bundle-1335ff3786.min.js.LICENSE.txt → bundle-0f5cfcd378.min.js.LICENSE.txt} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clickview/lite",
3
- "version": "0.49.0-rc.2",
3
+ "version": "0.49.0-rc.4",
4
4
  "description": "ClickView Lite",
5
5
  "main": "dist/scripts/bundle.js",
6
6
  "types": "dist/projects/lite/src/index.d.ts",
@@ -1,2 +0,0 @@
1
- "use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[194],{93978:(e,a,t)=>{t.r(a),t.d(a,{PlaySharedVideoView:()=>B});var d=t(32735),i=t(20354),s=t(65858),n=t(16714),o=t(89454),c=t(39151),r=t(1666),l=t(28907),u=t(31949),v=t(1575),m=t(27995),h=t(22902),p=t(79612),I=t(76753),g=t(3042),y=t(82817),C=t(7179),P=t(49948),F=t(36873),V=t(27638),b=t(86698),k=t(35014),f=t(97816),x=t(33192),w=t(16857);function B(e){var a,t,B,q,j,A,L,M,T,U=(0,V.u)(s.LZ.VideoThumbnail),G=U.setFavourite,N=U.canFavourite,_=(0,h.T)().hasPermissions,E=(0,b.y)().activePresentation,O=i.a.useBasicFetch(u.N.currentUser()),S=i.a.useBasicFetch((null===(a=O.data)||void 0===a?void 0:a.id)&&v.R.sharedVideo(e.objectId,e.shareId,O.data.id)),R=i.a.useBasicFetch(c.L.config()),Z=(0,F.k)({video:S.data,context:e.queryParams.context,contextId:e.queryParams.contextId,moviesAndTv:e.queryParams.mtv,currentUser:O.data}),z=(0,P.l)(e.objectId),D=i.a.useBasicFetch((null===(B=null===(t=S.data)||void 0===t?void 0:t.glance)||void 0===B?void 0:B.theme)?l.r.themeImages(S.data.glance.theme,S.data.glance.type):null),H=i.a.useBasicFetch(!!E&&o.O.audiencesByPresentationId(E.id)),J=i.a.useBasicFetch((null===(q=O.data)||void 0===q?void 0:q.isAuthenticated)&&r.h.yearGroups(O.data.customerId)),K=_(n.C.ViewVideoGlance)&&(null===(A=null===(j=S.data)||void 0===j?void 0:j.glance)||void 0===A?void 0:A.theme);(0,p.M)(I.CG.getVideoMetadata({content:S.data,canonicalLink:x.f.getCanonicalLink({stripPresentationSlug:!0}),allowIndexing:!1})),(0,f.V)(null!==(L=Z.videos)&&void 0!==L?L:[]),(0,m.b)(S,{private:w.m}),(0,C.P)({id:e.objectId,app:"videos",shareId:e.shareId});var Q=(0,y.M)(e.objectId),W=S.data&&O.hasCompleted&&R.hasCompleted&&z.hasCompleted,X=(0,k.I)();return W?d.createElement("div",{className:"px-3"},d.createElement(g.j,{video:S.data,yearGroups:J.data,curriculums:Q,imageCdnUrl:R.data.imageCdnUrl,relatedVideos:Z,currentUser:O.data,setFavourite:G,canFavourite:N,pointsOfInterest:null==z?void 0:z.items,playNext:null===(M=e.queryParams)||void 0===M?void 0:M.playNext,shareId:e.shareId,glanceTheme:D.data,glanceLoaded:!K||D.hasCompleted,featureAccess:X,audiences:H.data,params:e.queryParams,canManageVideoAccess:_(n.C.ManageVideoAccess),tableOfContentsId:null===(T=e.queryParams)||void 0===T?void 0:T.scrollTo})):d.createElement(d.Fragment,null)}}}]);
2
- //# sourceMappingURL=194-6131a555c8-lite.chunk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scripts/194-6131a555c8-lite.chunk.js","mappings":"+aAiCM,SAAUA,EAAoBC,G,sBAClC,GAAuC,IAAAC,GAAkB,qBAAjDC,EAAY,EAAZA,aAAcC,EAAY,EAAZA,aAEdC,GAAmB,SAAnBA,eAGNC,GACE,SADFA,mBAIIC,EAAc,kBAAkC,mBAChDC,EAAQ,mBACI,QAAhB,EAAAD,EAAYE,YAAI,eAAEC,KAAM,gBAA0BT,EAAMU,SAAUV,EAAMW,QAASL,EAAYE,KAAKC,KAE9FG,EAAS,kBAA6B,cACtCC,GAAgB,OAAoB,CACxCN,MAAOA,EAAMC,KACbM,QAASd,EAAMe,YAAYD,QAC3BE,UAAWhB,EAAMe,YAAYC,UAC7BC,YAAajB,EAAMe,YAAYG,IAC/BZ,YAAaA,EAAYE,OAErBW,GAAmB,OAAyBnB,EAAMU,UAClDU,EAAc,mBAA8C,QAAlB,EAAU,QAAV,EAAAb,EAAMC,YAAI,eAAEa,cAAM,eAAEC,OAChE,gBAA0Bf,EAAMC,KAAKa,OAAOC,MAAOf,EAAMC,KAAKa,OAAOE,MAAQ,MAC3EC,EAAY,oBACdnB,GACF,8BAA2CA,EAAmBI,KAE1DgB,EAAa,mBACD,QAAhB,EAAAnB,EAAYE,YAAI,eAAEkB,kBAAmB,eAA4BpB,EAAYE,KAAKmB,aAG9EC,EAAmBxB,EAAe,uBACpB,QAAlB,EAAU,QAAV,EAAAG,EAAMC,YAAI,eAAEa,cAAM,eAAEC,QAEtB,OAAmB,sBAAoC,CACrDO,QAAStB,EAAMC,KACfsB,cAAe,qBAA2B,CAAEC,uBAAuB,IACnEC,eAAe,MAGjB,OAAkC,QAApB,EAAAnB,EAAcoB,cAAM,QAAI,KACtC,OAAsB1B,EAAO,CAAE2B,QAAS,OACxC,OAAa,CAAEzB,GAAIT,EAAMU,SAAUyB,IAAK,SAAUxB,QAASX,EAAMW,UAEjE,IAAMyB,GAAc,OAAepC,EAAMU,UAEnC2B,EACJ9B,EAAMC,MACNF,EAAYgC,cACZ1B,EAAO0B,cACPnB,EAAiBmB,aAGbC,GAAgB,SAEtB,OAAKF,EAIH,uBAAKG,UAAU,QACb,gBAAC,IAAQ,CACPjC,MAAOA,EAAMC,KACbiB,WAAYA,EAAWjB,KACvB4B,YAAaA,EACbK,YAAa7B,EAAOJ,KAAKiC,YACzB5B,cAAeA,EACfP,YAAaA,EAAYE,KACzBN,aAAcA,EACdC,aAAcA,EACdgB,iBAAkBA,aAAgB,EAAhBA,EAAkBuB,MACpCC,SAA2B,QAAjB,EAAA3C,EAAMe,mBAAW,eAAE4B,SAC7BhC,QAASX,EAAMW,QACfS,YAAaA,EAAYZ,KACzBoC,cAAehB,GAAoBR,EAAYkB,aAC/CC,cAAeA,EACff,UAAWA,EAAUhB,KACrBqC,OAAQ7C,EAAMe,YACd+B,qBAAsB1C,EAAe,uBACrC2C,kBAAoC,QAAjB,EAAA/C,EAAMe,mBAAW,eAAEiC,YAtBnC,gCA0BX,C","sources":["file:///app/packages/projects/lite/src/apps/share/views/play-shared-video/PlaySharedVideoView.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Flight } from 'libs/common/flight';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { CustomerRequests } from 'libs/shared/flight-requests/CustomerRequests';\nimport { ThemeRequests } from 'libs/shared/flight-requests/ThemeRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { VideoRequests } from 'libs/shared/flight-requests/VideoRequests';\nimport { useCannotConsumeError } from 'libs/shared/hooks/useCannotConsumeError';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { Config, CurrentUser, PresentationAudience, Theme, Video, YearGroup } from 'libs/shared/interfaces';\nimport { PageMetadataHelper } from 'libs/shared/utils/PageMetadataHelper';\n\nimport { PlayPage } from 'shared/components/play-page/PlayPage';\nimport { useCurriculums } from 'shared/hooks/useCurriculums';\nimport { useDeepLinks } from 'shared/hooks/useDeepLinks';\nimport { useFetchPointsOfInterest } from 'shared/hooks/useFetchPointsOfInterest';\nimport { useGetRelatedVideos } from 'shared/hooks/useGetRelatedVideos';\nimport { useLiteFavourites } from 'shared/hooks/useLiteFavourites';\nimport { usePresentation } from 'shared/hooks/usePresentation';\nimport { useVideoFeatureAccess } from 'shared/hooks/useVideoFeatureAccess';\nimport { useVideoMixin } from 'shared/hooks/useVideoMixin';\nimport { SeoHelper } from 'shared/utils/SeoHelper';\n\nimport { ShareLinkPrivateError } from 'apps/share/errors/share-link-private/ShareLinkPrivateError';\nimport { ShareLinkViewProps } from 'apps/share/interfaces/ShareLinkViewProps';\n\nexport function PlaySharedVideoView(props: ShareLinkViewProps): React.ReactElement {\n const { setFavourite, canFavourite } = useLiteFavourites(LocationContext.VideoThumbnail);\n\n const { hasPermissions } = usePermissions();\n\n const {\n activePresentation\n } = usePresentation();\n\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const video = Flight.useBasicFetch<Video>(\n currentUser.data?.id && VideoRequests.sharedVideo(props.objectId, props.shareId, currentUser.data.id)\n );\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const relatedVideos = useGetRelatedVideos({\n video: video.data,\n context: props.queryParams.context,\n contextId: props.queryParams.contextId,\n moviesAndTv: props.queryParams.mtv,\n currentUser: currentUser.data\n });\n const pointsOfInterest = useFetchPointsOfInterest(props.objectId);\n const glanceTheme = Flight.useBasicFetch<Theme>(video.data?.glance?.theme\n ? ThemeRequests.themeImages(video.data.glance.theme, video.data.glance.type) : null);\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n !!activePresentation &&\n AudienceRequests.audiencesByPresentationId(activePresentation.id)\n );\n const yearGroups = Flight.useBasicFetch<YearGroup[]>(\n currentUser.data?.isAuthenticated && CustomerRequests.yearGroups(currentUser.data.customerId)\n );\n\n const shouldFetchTheme = hasPermissions(PermissionName.ViewVideoGlance) &&\n video.data?.glance?.theme;\n\n useSetPageMetadata(PageMetadataHelper.getVideoMetadata({\n content: video.data,\n canonicalLink: SeoHelper.getCanonicalLink({ stripPresentationSlug: true }),\n allowIndexing: false\n }));\n\n useVideoMixin(relatedVideos.videos ?? []);\n useCannotConsumeError(video, { private: ShareLinkPrivateError });\n useDeepLinks({ id: props.objectId, app: 'videos', shareId: props.shareId });\n\n const curriculums = useCurriculums(props.objectId);\n\n const dataLoaded = (\n video.data &&\n currentUser.hasCompleted &&\n config.hasCompleted &&\n pointsOfInterest.hasCompleted\n );\n\n const featureAccess = useVideoFeatureAccess();\n\n if (!dataLoaded)\n return <></>;\n\n return (\n <div className='px-3'>\n <PlayPage\n video={video.data}\n yearGroups={yearGroups.data}\n curriculums={curriculums}\n imageCdnUrl={config.data.imageCdnUrl}\n relatedVideos={relatedVideos}\n currentUser={currentUser.data}\n setFavourite={setFavourite}\n canFavourite={canFavourite}\n pointsOfInterest={pointsOfInterest?.items}\n playNext={props.queryParams?.playNext}\n shareId={props.shareId}\n glanceTheme={glanceTheme.data}\n glanceLoaded={!shouldFetchTheme || glanceTheme.hasCompleted}\n featureAccess={featureAccess}\n audiences={audiences.data}\n params={props.queryParams}\n canManageVideoAccess={hasPermissions(PermissionName.ManageVideoAccess)}\n tableOfContentsId={props.queryParams?.scrollTo}\n />\n </div>\n );\n}"],"names":["PlaySharedVideoView","props","u","setFavourite","canFavourite","hasPermissions","activePresentation","currentUser","video","data","id","objectId","shareId","config","relatedVideos","context","queryParams","contextId","moviesAndTv","mtv","pointsOfInterest","glanceTheme","glance","theme","type","audiences","yearGroups","isAuthenticated","customerId","shouldFetchTheme","content","canonicalLink","stripPresentationSlug","allowIndexing","videos","private","app","curriculums","dataLoaded","hasCompleted","featureAccess","className","imageCdnUrl","items","playNext","glanceLoaded","params","canManageVideoAccess","tableOfContentsId","scrollTo"],"sourceRoot":""}
@@ -1,2 +0,0 @@
1
- "use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[32],{94644:(e,a,t)=>{t.d(a,{r:()=>u});var i=t(50242),d=t(81886),r=t(67058),n=t(14553),o=t(49267),s=t(49075),c={notFound:r.d,forbidden:{rating:n.q,yearLevel:n.q,region:o.a,privacy:n.q},badRequest:s._};function u(e){var a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(e){var r;r="number"==typeof e?e:e.status;var n=Object.assign(Object.assign({},c),a);r&&d.Q.Ry.isStatusCodeError(r)&&(r!==i.o.NotFound?r!==i.o.Forbidden?t.badRequest||d.Q.Ry.throw(new n.badRequest):t.forbidden||d.Q.Ry.throw(new n.forbidden.privacy):t.notFound||d.Q.Ry.throw(new n.notFound))}}},91286:(e,a,t)=>{t.d(a,{v:()=>n});var i=t(32735),d=t(94644);function r(e){return e.map((function(e){return e.statusCode})).join(":")}function n(e,a,t){var n=Array.isArray(e)?e:[e];(0,i.useEffect)((function(){n.forEach((function(e){(0,d.r)(e.statusCode,a,t)}))}),[r(n),a,t])}},27478:(e,a,t)=>{t.r(a),t.d(a,{PlayClipView:()=>j});var i=t(32735),d=t(50242),r=t(23481),n=t(20354),o=t(65858),s=t(78417),c=t(16714),u=t(67058),l=t(33803),v=t(43012),p=t(39151),h=t(1666),m=t(28907),f=t(31949),g=t(1575),y=t(27995),C=t(91286),b=t(22902),F=t(15311),P=t(79612),w=t(76753),q=t(56871),V=t(7179),R=t(49948),k=t(36873),A=t(27638),B=t(44110),I=t(35014),_=t(97816),O=r.T.encloseNamespace("shared.playClip"),T={notFound:u.d,forbidden:{privacy:l.G}};function j(e){var a,t,r,u,l,j,x=e.queryParams,E=x.context,G=x.contextId,M=x.mtv,U=(0,F.r)().hasProduct,L=(0,A.u)(o.LZ.PlayClip),N=L.setFavourite,Q=L.canFavourite,S=(0,b.T)().hasPermissions,D=n.a.useBasicFetch(f.N.currentUser()),H=n.a.useBasicFetch(p.L.config()),Z=n.a.useBasicFetch(v.e.clip(e.id)),z=n.a.useBasicFetch(!!(null===(a=Z.data)||void 0===a?void 0:a._parentVideo)&&g.R.video(Z.data._parentVideo.id)),J=n.a.useBasicFetch(Z.statusCode===d.o.Forbidden&&v.e.clip(e.id,s.r.StripMetadata)),K=(0,k.k)({video:z.data,context:E,contextId:G,moviesAndTv:M,currentUser:D.data}),W=(0,B.i)(),X=n.a.useBasicFetch((null===(t=D.data)||void 0===t?void 0:t.isAuthenticated)&&h.h.yearGroups(D.data.customerId)),Y=S(c.C.ViewVideoGlance)&&(null===(u=null===(r=Z.data)||void 0===r?void 0:r.glance)||void 0===u?void 0:u.theme),$=n.a.useBasicFetch(Y&&m.r.themeImages(Z.data.glance.theme,Z.data.glance.type)),ee=(0,R.l)(e.id,!0),ae=(0,I.I)();return(0,P.M)(w.CG.getClipMetadata({content:Z.data,phraseContext:{phraseHandler:O,titlePhrase:"pageTitle",descriptionPhrase:"pageDescription"}})),(0,C.v)(Z,T,{forbidden:!0}),(0,_.V)(null!==(l=K.videos)&&void 0!==l?l:[]),(0,y.b)(J),(0,V.P)({id:e.id,app:"clips"}),Z.data&&D.hasCompleted&&H.hasCompleted&&ee.hasCompleted?i.createElement(q.N,{clip:Z.data,originalVideo:z.data,currentUser:D.data,yearGroups:X.data,relatedVideos:"playlist"===E?K:Object.assign(Object.assign({},K),{videos:[]}),canFavourite:Q,setFavourite:N,hasProduct:U,queryParams:e.queryParams,audiences:W.data,imageCdnUrl:H.data.imageCdnUrl,canManageVideoAccess:S(c.C.ManageVideoAccess),pointsOfInterest:ee.items,glanceTheme:$.data,glanceLoaded:!Y||$.hasCompleted,featureAccess:ae,tableOfContentsId:null===(j=e.queryParams)||void 0===j?void 0:j.scrollTo}):i.createElement(i.Fragment,null)}j.defaultProps={queryParams:{}}}}]);
2
- //# sourceMappingURL=32-5739e73587-lite.chunk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scripts/32-5739e73587-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/errors/handlers/HttpErrorHandlers.ts","file:///app/packages/libs/shared/src/hooks/UseHandleObjectError.ts","file:///app/packages/projects/lite/src/shared/views/play-clip/PlayClipView.tsx"],"sourcesContent":["import { BaseError } from 'libs/common/backbone/core/BaseError';\nimport { HttpStatus } from 'libs/common/backbone/enums/HttpStatus';\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { Core } from 'libs/common/core';\n\nimport { NotFoundError } from 'libs/shared/errors/general/not-found/NotFoundError';\nimport { PrivateResourceError } from 'libs/shared/errors/general/private-resource/PrivateResourceError';\nimport { RegionLockedResourceError } from 'libs/shared/errors/general/region-locked-resource/RegionLockedResourceError';\nimport { UnspecifiedError } from 'libs/shared/errors/general/unspecified-error/UnspecifiedError';\nimport { VideoTypes } from 'libs/shared/interfaces';\n\nexport interface HttpErrorMap {\n notFound?: new () => BaseError;\n forbidden?: {\n rating?: new (description: string) => BaseError;\n yearLevel?: new (description: string) => BaseError;\n region?: new () => BaseError;\n privacy?: new (video?: VideoTypes) => BaseError;\n };\n badRequest?: new () => BaseError;\n}\n\nexport type IgnoreHttpErrorMap = {\n [key in keyof HttpErrorMap]: boolean;\n};\n\nconst defaultErrors: HttpErrorMap = {\n notFound: NotFoundError,\n forbidden: {\n rating: PrivateResourceError,\n yearLevel: PrivateResourceError,\n region: RegionLockedResourceError,\n privacy: PrivateResourceError\n },\n badRequest: UnspecifiedError\n};\n\nexport function handleHttpError(\n info: HttpStatus | Xhr,\n customErrorMap: HttpErrorMap = {},\n /**\n * Prevent certain errors in the errorMap from being thrown\n * so that you may implement your own handler\n */\n ignoreMap: IgnoreHttpErrorMap = {}\n): void {\n if (!info)\n return;\n\n let statusCode: HttpStatus;\n\n if (typeof(info) === 'number') {\n statusCode = info;\n } else {\n statusCode = info.status;\n }\n\n const errorMap = {\n ...defaultErrors,\n ...customErrorMap\n };\n\n if (!statusCode)\n return;\n\n if (!Core.ErrorHelper.isStatusCodeError(statusCode))\n return;\n\n if (statusCode === HttpStatus.NotFound) {\n if (!ignoreMap.notFound)\n Core.ErrorHelper.throw(new errorMap.notFound());\n return;\n }\n\n if (statusCode === HttpStatus.Forbidden) {\n /**\n * TODO: Work out how to go about handling all forbidden errors, such as region locking, year levels,\n * ratings, and privacy.\n */\n if (!ignoreMap.forbidden)\n Core.ErrorHelper.throw(new errorMap.forbidden.privacy());\n return;\n }\n\n if (!ignoreMap.badRequest)\n Core.ErrorHelper.throw(new errorMap.badRequest());\n}\n\nexport function handleXhrError(xhr: Xhr, customErrorMap?: HttpErrorMap): void {\n handleHttpError(xhr.status, customErrorMap);\n}","import { useEffect } from 'react';\n\nimport { Flight } from 'libs/common/flight';\n\nimport { handleHttpError, HttpErrorMap, IgnoreHttpErrorMap } from 'libs/shared/errors/handlers/HttpErrorHandlers';\n\nfunction generateCacheKey(flightObjs: Array<Flight.Response<any>>): string {\n return flightObjs.map(obj => obj.statusCode).join(':');\n}\n\n// TODO: Change this to just `useHandleHttpError` and only accept a status code.\nexport function useHandleObjectError(\n _flightObjs: Flight.Response<any> | Array<Flight.Response<any>>,\n customErrors?: HttpErrorMap,\n ignoreErrors?: IgnoreHttpErrorMap\n): void {\n const flightObjs = Array.isArray(_flightObjs) ? _flightObjs : [_flightObjs];\n\n useEffect(() => {\n flightObjs.forEach(obj => {\n handleHttpError(obj.statusCode, customErrors, ignoreErrors);\n });\n }, [ generateCacheKey(flightObjs), customErrors, ignoreErrors ]);\n}","import * as React from 'react';\n\nimport { HttpStatus } from 'libs/common/backbone/enums/HttpStatus';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { PermissionFilterOption } from 'libs/shared/enums/PermissionFilterOption';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { NotFoundError } from 'libs/shared/errors/general/not-found/NotFoundError';\nimport { VideoPrivateError } from 'libs/shared/errors/videos/video-private/VideoPrivateError';\nimport { ClipRequests } from 'libs/shared/flight-requests/ClipRequests';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { CustomerRequests } from 'libs/shared/flight-requests/CustomerRequests';\nimport { ThemeRequests } from 'libs/shared/flight-requests/ThemeRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { VideoRequests } from 'libs/shared/flight-requests/VideoRequests';\nimport { useCannotConsumeError } from 'libs/shared/hooks/useCannotConsumeError';\nimport { useHandleObjectError } from 'libs/shared/hooks/UseHandleObjectError';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { Clip, Config, CurrentUser, Theme, Video, YearGroup } from 'libs/shared/interfaces';\nimport { PlayViewQueryParams } from 'libs/shared/interfaces/query-params/PlayViewQueryParams';\nimport { PageMetadataHelper } from 'libs/shared/utils/PageMetadataHelper';\n\nimport { PlayClip } from 'shared/components/play-clip/PlayClip';\nimport { useDeepLinks } from 'shared/hooks/useDeepLinks';\nimport { useFetchPointsOfInterest } from 'shared/hooks/useFetchPointsOfInterest';\nimport { useGetRelatedVideos } from 'shared/hooks/useGetRelatedVideos';\nimport { useLiteFavourites } from 'shared/hooks/useLiteFavourites';\nimport { usePresentationAudiences } from 'shared/hooks/usePresentationAudiences';\nimport { useVideoFeatureAccess } from 'shared/hooks/useVideoFeatureAccess';\nimport { useVideoMixin } from 'shared/hooks/useVideoMixin';\n\nconst namespace = 'shared.playClip';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst clipErrors = {\n notFound: NotFoundError,\n forbidden: {\n privacy: VideoPrivateError\n }\n};\n\ninterface PlayClipViewProps {\n id: string;\n queryParams: PlayViewQueryParams;\n}\n\nPlayClipView.defaultProps = {\n queryParams: {}\n};\n\nexport function PlayClipView(props: PlayClipViewProps): JSX.Element {\n const { context, contextId, mtv } = props.queryParams;\n\n const { hasProduct } = useProducts();\n const { setFavourite, canFavourite } = useLiteFavourites(LocationContext.PlayClip);\n const { hasPermissions } = usePermissions();\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const clip = Flight.useBasicFetch<Clip>(ClipRequests.clip(props.id));\n const video = Flight.useBasicFetch<Video>(!!clip.data?._parentVideo &&\n VideoRequests.video(clip.data._parentVideo.id));\n const strippedClip = Flight.useBasicFetch<Clip>(clip.statusCode === HttpStatus.Forbidden &&\n ClipRequests.clip(props.id, PermissionFilterOption.StripMetadata));\n const relatedVideos = useGetRelatedVideos({\n video: video.data,\n context,\n contextId,\n moviesAndTv: mtv,\n currentUser: currentUser.data\n });\n const audiences = usePresentationAudiences();\n const yearGroups = Flight.useBasicFetch<YearGroup[]>(\n currentUser.data?.isAuthenticated && CustomerRequests.yearGroups(currentUser.data.customerId)\n );\n\n const shouldFetchTheme = hasPermissions(PermissionName.ViewVideoGlance) &&\n clip.data?.glance?.theme;\n \n const glanceTheme = Flight.useBasicFetch<Theme>(\n shouldFetchTheme &&\n ThemeRequests.themeImages(clip.data.glance.theme, clip.data.glance.type)\n );\n const pointsOfInterest = useFetchPointsOfInterest(props.id, true);\n \n const featureAccess = useVideoFeatureAccess();\n\n useSetPageMetadata(PageMetadataHelper.getClipMetadata({\n content: clip.data,\n phraseContext: {\n phraseHandler: getPhrase,\n titlePhrase: 'pageTitle',\n descriptionPhrase: 'pageDescription'\n }\n }));\n\n useHandleObjectError(clip, clipErrors, { forbidden: true });\n useVideoMixin(relatedVideos.videos ?? []);\n useCannotConsumeError(strippedClip);\n useDeepLinks({ id: props.id, app: 'clips' });\n\n const hasLoaded = (\n clip.data &&\n currentUser.hasCompleted &&\n config.hasCompleted &&\n pointsOfInterest.hasCompleted\n );\n\n if (!hasLoaded)\n return <></>;\n\n return (\n <PlayClip\n clip={clip.data}\n originalVideo={video.data}\n currentUser={currentUser.data}\n yearGroups={yearGroups.data}\n // we only show up next videos for clips in a playlist\n relatedVideos={context === 'playlist' ? relatedVideos : { ...relatedVideos, videos: []}}\n canFavourite={canFavourite}\n setFavourite={setFavourite}\n hasProduct={hasProduct}\n queryParams={props.queryParams}\n audiences={audiences.data}\n imageCdnUrl={config.data.imageCdnUrl}\n canManageVideoAccess={hasPermissions(PermissionName.ManageVideoAccess)}\n pointsOfInterest={pointsOfInterest.items}\n glanceTheme={glanceTheme.data}\n glanceLoaded={!shouldFetchTheme || glanceTheme.hasCompleted}\n featureAccess={featureAccess}\n tableOfContentsId={props.queryParams?.scrollTo}\n />\n );\n}"],"names":["defaultErrors","notFound","forbidden","rating","yearLevel","region","privacy","badRequest","handleHttpError","info","customErrorMap","ignoreMap","statusCode","status","errorMap","generateCacheKey","flightObjs","map","obj","join","useHandleObjectError","_flightObjs","customErrors","ignoreErrors","Array","isArray","useEffect","forEach","getPhrase","clipErrors","PlayClipView","props","queryParams","context","contextId","mtv","hasProduct","u","setFavourite","canFavourite","hasPermissions","currentUser","config","clip","id","video","data","_parentVideo","strippedClip","relatedVideos","moviesAndTv","audiences","yearGroups","isAuthenticated","customerId","shouldFetchTheme","glance","theme","glanceTheme","type","pointsOfInterest","featureAccess","content","phraseContext","phraseHandler","titlePhrase","descriptionPhrase","videos","app","hasCompleted","originalVideo","imageCdnUrl","canManageVideoAccess","items","glanceLoaded","tableOfContentsId","scrollTo","defaultProps"],"sourceRoot":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"scripts/3854-6b20ca6c3b-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/components/infinite-scroll-footer/infinite-scroll-footer.scss","file:///app/packages/libs/shared/src/components/infinite-scroll-footer/InfiniteScrollFooter.tsx","file:///app/packages/libs/shared/src/components/play-page/resources/PlayPageResources.tsx","file:///app/packages/libs/shared/src/components/points-of-interest-list/points-of-interest-list.scss","file:///app/packages/libs/shared/src/components/points-of-interest-list/PointsOfInterestList.tsx","file:///app/packages/libs/shared/src/components/video-at-a-glance/video-at-a-glance.scss","file:///app/packages/libs/shared/src/components/video-at-a-glance/VideoAtAGlance.tsx","file:///app/packages/libs/shared/src/components/video-at-a-glance/VideoAtAGlanceUtils.ts","file:///app/packages/libs/shared/src/components/video-details/VideoDetailsPartial.tsx","file:///app/packages/libs/shared/src/components/video-list/partial-loading/partial-video-list.scss","file:///app/packages/libs/shared/src/components/video-list/partial-loading/PartialVideoList.tsx","file:///app/packages/libs/shared/src/components/widgets/items/interactive-widget-item/InteractiveWidgetItem.tsx","file:///app/packages/libs/shared/src/components/widgets/items/interactive-widget-item/interactive-widget-item.scss","file:///app/packages/libs/shared/src/components/resource-thumbnail/resource-thumbnail.scss","file:///app/packages/libs/shared/src/components/resource-thumbnail/ResourceThumbnail.tsx","file:///app/packages/libs/shared/src/utils/ResourceHelper.ts","file:///app/packages/libs/shared/src/components/widgets/items/resource-widget-item/resource-widget-item.scss","file:///app/packages/libs/shared/src/components/widgets/items/resource-widget-item/ResourceWidgetItem.tsx","file:///app/packages/libs/shared/src/flight-requests/ThemeRequests.ts","file:///app/packages/libs/shared/src/hooks/usePrevious.ts","file:///app/packages/libs/shared/src/hooks/useTableOfContentsScroll.tsx","file:///app/packages/libs/shared/src/utils/DownloadHelper.ts","file:///app/packages/projects/lite/src/shared/components/play-page/ArchivedBanner.tsx","file:///app/packages/projects/lite/src/shared/components/play-page/RestrictionBanner.tsx","file:///app/packages/libs/shared/src/components/widgets/items/clip-widget-item/ClipWidgetItem.tsx","file:///app/packages/libs/shared/src/components/widgets/items/clip-widget-item/clip-widget-item.scss","file:///app/packages/projects/lite/src/shared/components/play-page/components/clips/PlayPageClips.tsx","file:///app/packages/projects/lite/src/shared/components/play-page/components/interactives/PlayPageInteractives.tsx","file:///app/packages/projects/lite/src/shared/components/play-page/components/title-and-actions/title-and-actions.scss","file:///app/packages/projects/lite/src/shared/components/play-page/components/title-and-actions/PlayPageTitleAndActions.tsx","file:///app/packages/projects/lite/src/shared/components/player-placeholder/player-placeholder.scss","file:///app/packages/projects/lite/src/shared/components/player-placeholder/PlayerPlaceholder.tsx","file:///app/packages/projects/lite/src/shared/components/related-videos/RelatedVideos.tsx","file:///app/packages/projects/lite/src/shared/hooks/useVideoFeatureAccess.ts","file:///app/packages/projects/lite/src/shared/hooks/useVideoMixin.ts"],"sourcesContent":["// extracted by mini-css-extract-plugin\nexport default {\"container\":\"VwD1b\",\"spinner\":\"eJ85e\"};","import * as React from 'react';\nimport { Spinner } from 'react-bootstrap';\nimport { useInView } from 'react-intersection-observer';\n\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport styles from './infinite-scroll-footer.scss';\n\ninterface InfiniteScrollFooterProps {\n isFetching: boolean;\n fetchNext?: (nextCursor: string) => void;\n nextCursor?: string;\n fetchOnScroll?: boolean;\n}\n\nInfiniteScrollFooter.defaultProps = {\n fetchOnScroll: false\n};\n\nexport function InfiniteScrollFooter(props: InfiniteScrollFooterProps): React.ReactElement {\n const [ ref, inView ] = useInView();\n\n React.useEffect(() => {\n if (!props.fetchOnScroll)\n return;\n\n if (!inView || props.isFetching)\n return;\n\n props.fetchNext?.(props.nextCursor);\n }, [ inView, props.isFetching ]);\n\n return (\n <div className={`p-3 text-center ${styles.container}`} ref={ref}>\n {props.isFetching\n ? <Spinner as='span' animation='border' role='status' className={styles.spinner} />\n : (\n <SvgContainer\n svgName={cvSvgLibrary.ChevronDown}\n className='svg-container cursor-pointer'\n size={SvgContainerSize.Large}\n onClick={() => props.fetchNext?.(props.nextCursor)}\n />\n )\n }\n </div>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { EntityType, LocationContext, SignUpDescriptors, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { FixedWidget } from 'libs/shared/components/widgets/fixed-widget';\nimport { ResourceWidgetItem, ResourceWidgetItemProps } from 'libs/shared/components/widgets/items/resource-widget-item/ResourceWidgetItem';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { WidgetContents } from 'libs/shared/enums/WidgetContents';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { Clip, Link, Resource, Video } from 'libs/shared/interfaces';\nimport { PlayPageAnchor } from 'libs/shared/interfaces/PlayPageAnchor';\nimport { DownloadHelper } from 'libs/shared/utils/DownloadHelper';\n\nconst namespace = 'shared.playPageResources';\n\nfunction getResources(\n video: Video,\n isLearner: boolean\n): Array<Resource | Link> {\n const resources = video.resources?.data ?? [];\n const links = video.links?.data ?? [];\n\n if (!isLearner)\n return [ ...resources, ...links ];\n\n const filteredResources = resources.filter(r => {\n return [ 'additional-materials', 'student-activity' ].includes(r.metadata?.resourceType);\n });\n\n return [ ...filteredResources, ...links ];\n}\n\ninterface PlayPageResourcesProps {\n video: Video | Clip;\n imageCdnUrl: string;\n canViewResources: boolean;\n getAppLink: (resource: Resource) => Core.AppLink;\n analyticsData: HashObject;\n resourceThumbnailFallbackUrl: string;\n containerRef?: React.RefObject<HTMLDivElement>;\n}\n\nexport function PlayPageResources(props: PlayPageResourcesProps): JSX.Element {\n const { hasPermissions } = usePermissions();\n\n function onClickDownload(resource: Resource): void {\n DownloadHelper.downloadResource(\n resource,\n props.analyticsData,\n { location: LocationContext.PlayPage, actionType: UserAction.Download, entity: EntityType.Resource }\n );\n }\n\n const resources = getResources(props.video, hasPermissions(PermissionName.StudentExperience));\n\n if (!resources.length)\n return <></>;\n\n return (\n <section id={PlayPageAnchor.Resources} className='pb-3' ref={props.containerRef}>\n <FixedWidget<ResourceWidgetItemProps>\n name={LanguageService.getPhrase(namespace, 'resources', { count: resources.length })}\n contents={WidgetContents.PlayPageResources}\n collection={resources}\n prefetched\n childComponent={ResourceWidgetItem}\n extraChildComponentProps={{\n imageCdnUrl: props.imageCdnUrl,\n imageErrorFallbackUrl: props.resourceThumbnailFallbackUrl,\n actionBehaviour: props.canViewResources ? 'normal' : 'public',\n location: 'play-page',\n titlePosition: 'below',\n onClickDownload: props.canViewResources ? onClickDownload : null\n }}\n getChildAppLink={props.getAppLink}\n analyticsOptions={(() => {\n if (props.canViewResources)\n return {};\n \n return {\n workflowPhase: WorkflowPhase.Start,\n descriptor: SignUpDescriptors.SignUp\n };\n })()}\n analyticsData={props.analyticsData}\n />\n </section>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"poiEntry\":\"Nmm9o\",\"poiText\":\"c75aW\",\"public\":\"R689i\",\"poiTimeStamp\":\"Wad94\"};","import React from 'react';\n\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { PointOfInterest } from 'libs/shared/interfaces';\nimport { DurationHelper } from 'libs/shared/utils/DurationHelper';\n\nimport styles from './points-of-interest-list.scss';\n\ninterface PointOfInterestListProps{\n pointsOfInterest: PointOfInterest[];\n suppressInteractivity?: boolean;\n onClickPoiItem: (time: number) => void\n}\n\nconst namespace = 'shared.pointsOfInterestList';\n\nexport function PointOfInterestList(props: PointOfInterestListProps) {\n return (\n <div>\n <h2 className='h6 my-2'><Text namespace={namespace} phrase='heading' /></h2>\n\n <div>\n {props.pointsOfInterest.map(poi => {\n const timeStamp = DurationHelper.ToDisplayDuration(poi.startTime * 1000);\n if (props.suppressInteractivity)\n return (\n <div key={poi.startTime} className={`d-flex ${styles.poiEntry} mb-2`}>\n <span className={`d-flex rounded-pill justify-content-center align-items-center fw-semibold ${styles.poiTimeStamp}`}>{timeStamp}</span>\n <div className={`${styles.public}`}>{poi.description}</div>\n </div>\n );\n\n return (\n <DivButton\n key={poi.startTime}\n className={`d-flex ${styles.poiEntry} mb-2 cursor-pointer`}\n onClick={() => props.onClickPoiItem(poi.startTime)}\n >\n <div className={`d-flex rounded-pill justify-content-center align-items-center fw-semibold ${styles.poiTimeStamp}`}>{timeStamp}</div>\n <div className={`ms-2 ${styles.poiText}`}>{poi.description}</div>\n </DivButton>\n );\n })}\n\n </div>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"learningIntention\":\"T2LIU\"};","import * as React from 'react';\nimport Scrollbars from 'react-custom-scrollbars-2';\n\nimport { Core } from 'libs/common/core';\n\nimport { PointOfInterestList } from 'libs/shared/components/points-of-interest-list/PointsOfInterestList';\nimport { TagHelper } from 'libs/shared/components/tags/TagHelper';\nimport { TagList } from 'libs/shared/components/tags/TagList';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { TagType } from 'libs/shared/enums/TagType';\nimport { PointOfInterest, Tag, Video } from 'libs/shared/interfaces';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { hasGlanceData, useLearningIntentionMarkdown } from './VideoAtAGlanceUtils';\n\nimport styles from './video-at-a-glance.scss';\n\nconst namespace = 'shared.videoAtAGlance';\n\nconst SCROLL_HEIGHT_MAX = 350; // in px\n\ninterface VideoAtAGlanceProps {\n video: Video;\n pointsOfInterest?: PointOfInterest[];\n suppressInteractivity?: boolean;\n setStartTime?: (time: number) => void;\n getTagAppLink?: (tag: Tag) => Core.AppLink;\n height?: number;\n}\n\nexport function VideoAtAGlance(props: VideoAtAGlanceProps): JSX.Element {\n const canViewGlance = hasGlanceData(props.video);\n\n const learningIntentionMarkdownHTML = useLearningIntentionMarkdown(props.video, canViewGlance);\n \n function getTags(): Tag[] {\n if (VideoHelper.isInteractive(props.video) || !props.video.tags?.data?.length)\n return null;\n\n return props.video.tags?.data?.filter(tag => tag.tagType === TagType.Pedagogy || tag.tagType === TagType.Skill);\n }\n const tags = getTags();\n\n if (!canViewGlance)\n return <></>;\n\n function onClickPoiItem(time: number) {\n props.setStartTime(time);\n }\n\n return (\n <div className='rounded border mb-3 bg-white'>\n <Scrollbars autoHeight autoHeightMax={props.height ?? SCROLL_HEIGHT_MAX} >\n <div className='px-3 px-3 pt-3 pb-2'>\n\n <h2 className='h6 mb-2'><Text namespace={namespace} phrase='learningIntention' /></h2>\n <div className={`${styles.learningIntention} mb-3`}>\n <div dangerouslySetInnerHTML={{ __html: learningIntentionMarkdownHTML }}/>\n </div>\n\n {!!tags?.length && (\n <div className='mb-1'>\n <TagList\n tags={tags}\n {...TagHelper.getTagActionProps(props.getTagAppLink, props.suppressInteractivity)}\n className='mt-2'\n />\n </div>\n )}\n\n {!!props.pointsOfInterest.length && (\n <PointOfInterestList\n pointsOfInterest={props.pointsOfInterest}\n suppressInteractivity={props.suppressInteractivity}\n onClickPoiItem={onClickPoiItem}\n />\n )}\n </div>\n </Scrollbars>\n </div>\n );\n}","import { useEffect, useState } from 'react';\nimport * as marked from 'marked';\n\nimport { Clip, Glance, Video } from 'libs/shared/interfaces';\n\nconst POI_LINK_LINE = /\\[\\]\\(cv:\\/\\/poi\\?id=\\d+\\)\\n*/g;\n\nfunction stripPoisFromGlanceContent(glanceContent: string): string {\n return glanceContent.replace(POI_LINK_LINE, '');\n}\n\nfunction getLearningIntentionHTML(glance: Glance): string {\n const learningIntention = stripPoisFromGlanceContent(glance.content);\n\n return marked(learningIntention);\n}\n\nexport function useLearningIntentionMarkdown(\n video: Video,\n hasGlanceData?: boolean\n): string {\n const [ markdownHTML, setMarkdownHTML ] = useState('');\n\n useEffect(() => {\n if (!hasGlanceData)\n return;\n\n const content = getLearningIntentionHTML(video.glance);\n\n setMarkdownHTML(content);\n }, [ video.glance?.content, hasGlanceData ]);\n\n return markdownHTML;\n}\n\nexport function hasGlanceData(video: Video | Clip): boolean {\n return video.glance?.content && video.glance?.format === 'text/markdown';\n}","import React from 'react';\n\nexport function VideoDetailsPartial(): JSX.Element {\n return (\n <div className='p-3 mb-3 border rounded'>\n <div className='row'>\n <div className='pe-3 col-md-7 border-right'>\n <div className='partial-loading-background mb-2' style={{ height: '1.5rem', width: '12rem' }}></div>\n <div className='partial-loading-background mb-2' style={{ height: '4.5rem' }}></div>\n <div className='partial-loading-background' style={{ height: '1.5rem', width: '15rem' }}></div>\n </div>\n <div className='col-md-5 ps-md-3 pt-3 pt-md-0'>\n <div className='partial-loading-background mb-2' style={{ height: '1.5rem', width: '7rem' }}></div>\n <div className='partial-loading-background mb-2' style={{ height: '1.5rem', width: '10rem' }}></div>\n <div className='partial-loading-background mb-2' style={{ height: '1.5rem', width: '12rem' }}></div>\n <div className='partial-loading-background mb-2 me-2 d-inline-block' style={{ height: '1.5rem', width: '3rem' }}></div>\n <div className='partial-loading-background mb-2 me-2 d-inline-block' style={{ height: '1.5rem', width: '4rem' }}></div>\n <div className='partial-loading-background mb-2 me-2 d-inline-block' style={{ height: '1.5rem', width: '3.5rem' }}></div>\n <div className='partial-loading-background mb-2 me-2 d-inline-block' style={{ height: '1.5rem', width: '4.5rem' }}></div>\n </div>\n </div>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"partialOptions\":\"Gufgq\",\"partialName\":\"SicQQ\",\"partialDescription\":\"dPGMq\",\"partialThumbnail\":\"vZrnb\",\"partialDragHandle\":\"iq73R\"};","import React from 'react';\nimport { Col, Row } from 'react-bootstrap';\n\nimport { VideoListHelper } from 'libs/shared/components/video-list/VideoListHelper';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\n\nimport styles from './partial-video-list.scss';\n\ninterface PartialVideoListProps {\n withReordering?: boolean;\n numVideos?: number;\n allowBulkActions?: boolean;\n}\n\nPartialVideoList.defaultProps = {\n numVideos: 15\n};\n\nexport function PartialVideoList(props: PartialVideoListProps): JSX.Element {\n return (\n <div className='mx-2'>\n {Array(props.numVideos).fill(null).map((_, i) => (\n <div className='d-flex' key={i}>\n {props.allowBulkActions && <div className='form-check pe-3 pe-sm-2 mx-0 mx-md-2' />}\n <PartialVideoItem {...props} />\n </div>\n ))}\n </div>\n );\n}\n\nexport function PartialVideoItem(props: PartialVideoListProps): JSX.Element {\n const breakpoints = useBreakpoints();\n\n const size = VideoListHelper.getSize(breakpoints, 'md');\n const isSmall = size === 'sm';\n\n const withDragHandle = props.withReordering && !breakpoints.xs;\n\n return (\n <Row className={`${isSmall ? '' : 'py-2'} flex-grow-1`}>\n <Col {...VideoListHelper.getThumbnailColumns()} className={`flex-column align-items-flex-start ${isSmall ? `pb-2 pe-1` : 'mb-1 pe-3 pe-md-2'}`}>\n <Row>\n {!!withDragHandle && (\n <div className='d-flex align-items-center justify-content-center col-2'>\n <div className={`partial-loading-background ${styles.partialDragHandle}`} />\n </div>\n )}\n <Col xs={VideoListHelper.getThumbnailColSize(withDragHandle)}>\n <div className={`partial-loading-background ${isSmall ? 'rounded' : 'rounded-3'} ${styles.partialThumbnail}`} />\n </Col>\n </Row>\n </Col>\n <Col {...VideoListHelper.getDetailsColumns()} className={isSmall ? 'pb-2' : 'px-2'}>\n <div className={`partial-loading-background mb-1 ${styles.partialName}`} />\n <div className={`partial-loading-background ${styles.partialDescription}`} />\n </Col>\n </Row>\n );\n}\n\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { ThumbnailText } from 'libs/shared/components/thumbnails/thumbnail-text/ThumbnailText';\nimport { VideoThumbnail } from 'libs/shared/components/thumbnails/video/VideoThumbnail';\nimport { FixedWidgetItemProps } from 'libs/shared/components/widgets/items/FixedWidgetItemProps';\nimport { ThumbnailTextPosition } from 'libs/shared/enums/ThumbnailTextPosition';\nimport { CanFavouriteFunc, FavouriteFunc, InteractiveMetadata, YearGroup } from 'libs/shared/interfaces';\n\nimport styles from './interactive-widget-item.scss';\n\nconst namespace = 'shared.interactiveWidgetItem';\n\nexport interface InteractiveWidgetItemProps extends FixedWidgetItemProps<InteractiveMetadata> {\n imageCdnUrl: string;\n questionsAppLink: Core.AppLink;\n setFavourite?: FavouriteFunc;\n canFavourite?: CanFavouriteFunc;\n yearGroups: YearGroup[];\n}\n\nexport const InteractiveWidgetItem = React.memo(function(props: InteractiveWidgetItemProps): JSX.Element {\n const { data: interactive, thumbnailSize, preloadImage } = props;\n\n const questionsAppLink: Core.AppLink = {\n ...props.questionsAppLink,\n args: [props.data.id]\n };\n\n const questionsNumber = interactive._timepoints?.value?.length;\n\n return (\n <div className={`flex-shrink-0 px-1 ${styles.item}`}>\n <VideoThumbnail\n type='cosmetic'\n textPosition={ThumbnailTextPosition.Independent}\n video={interactive}\n appLink={props.getAppLink(interactive)}\n imageOptions={{ size: thumbnailSize }}\n preload={preloadImage}\n analyticsData={props.analyticsData}\n analyticsOptions={props.analyticsOptions}\n setFavourite={props.setFavourite}\n canFavourite={props.canFavourite}\n hideDuration={false}\n imageCdnUrl={props.imageCdnUrl}\n />\n\n <div className='mt-2'>\n <ThumbnailText\n {...props}\n video={interactive}\n appLink={props.getAppLink(interactive)}\n />\n </div>\n\n <div className='mt-1'>\n <AppLink appLink={questionsAppLink} className='cursor-pointer'>\n <Text namespace={namespace} phrase='previewQuestions' options={{ count: questionsNumber, smartCount: questionsNumber }}/>\n </AppLink>\n </div>\n\n </div>\n );\n});\n","// extracted by mini-css-extract-plugin\nexport default {\"item\":\"rXatl\",\"thumbnail\":\"WHqSi\",\"smallItemIconWidth\":\"Pq45z\",\"smallItemInfoWidth\":\"rjvTM\",\"smallProgressBarContainer\":\"W_aym\"};","// extracted by mini-css-extract-plugin\nexport default {\"imageStyle\":\"FFgf3\",\"imageTypeResource\":\"z4O5p\",\"fallBackImage\":\"Xy4zX\"};","import React from 'react';\n\nimport { UrlHelper } from 'libs/analytics/utils/UrlHelper';\n\nimport { ImageSize, ImageType, ResizeType } from 'libs/shared/enums/Images';\nimport { ResourceFileType } from 'libs/shared/enums/ResourceFileType';\nimport { Link, Resource } from 'libs/shared/interfaces';\nimport { ImageHelper, ImageOptions } from 'libs/shared/utils/ImageHelper';\nimport { MasterTypeHelper } from 'libs/shared/utils/MasterTypeHelper';\n\nimport { BaseImage } from '../image/BaseImage';\n\nimport styles from './resource-thumbnail.scss';\n\n// Used for both PDFs and Links where we don't know the image ratio\nconst DYNAMIC_RATIO_IMAGE_OPTIONS: ImageOptions = {\n width: 200,\n resizeType: ResizeType.Cover\n};\n\nfunction getThumbnailUrl(imageCdnUrl: string, resource: Resource | Link): string {\n const imageType = getImageType(resource);\n\n // Use the thumbnail if defined\n if ('thumbnail' in resource && resource.thumbnail?.url)\n return ImageHelper.createUrl(resource.thumbnail?.url, { ...DYNAMIC_RATIO_IMAGE_OPTIONS });\n \n const previewUrl = UrlHelper.safeUrlConcat(imageCdnUrl, '/v1/previews');\n\n if (!MasterTypeHelper.isResource(resource))\n return ImageHelper.createResourceImage(previewUrl, resource.url, { ...DYNAMIC_RATIO_IMAGE_OPTIONS });\n\n if (imageType === ImageType.Pdf) {\n return resource.metadata.type === ResourceFileType.Pdf\n ? ImageHelper.createResourceImage(previewUrl, resource.url, { ...DYNAMIC_RATIO_IMAGE_OPTIONS })\n : ImageHelper.createResourceImage(previewUrl, resource.pdf?.url, { ...DYNAMIC_RATIO_IMAGE_OPTIONS });\n }\n\n if (resource.metadata.type !== ResourceFileType.Zip)\n return ImageHelper.createUrl(resource.url, { size: ImageSize.Medium, resizeType: ResizeType.Cover });\n\n return '/images/zip-resource.png';\n}\n\nfunction getImageType(resource: Resource | Link): ImageType {\n if (!MasterTypeHelper.isResource(resource))\n return ImageType.Link;\n\n if (resource.metadata.type === ResourceFileType.Pdf || resource.pdf?.url)\n return ImageType.Pdf;\n\n return ImageType.Thumbnails;\n}\n\ninterface ResourceThumbnailProps {\n imageCdnUrl: string;\n resource: Resource | Link;\n imageErrorFallbackUrl: string;\n preloadImage: boolean;\n}\n\nexport function ResourceThumbnail(props: ResourceThumbnailProps): JSX.Element {\n let metadata = null;\n let rotation = 0;\n\n if (MasterTypeHelper.isResource(props.resource)) {\n metadata = props.resource.metadata;\n rotation = props.resource.thumbnail?.metadata?.rotation ?? 0;\n }\n\n const thumbnailUrl = getThumbnailUrl(props.imageCdnUrl, props.resource);\n\n return (\n <BaseImage\n data={thumbnailUrl}\n imageType={getImageType(props.resource)}\n imageStyle={{ transform: `rotate(${rotation}deg)` }}\n alt={props.resource.name}\n errorFallbackImageSrc={props.imageErrorFallbackUrl}\n errorFallbackImageClassName={styles.fallBackImage}\n imageClassName={metadata?.type === ResourceFileType.Image ? `${styles.imageTypeResource} ${styles.imageStyle}` : ''}\n preload={props.preloadImage}\n preventLoad={!props.preloadImage}\n >\n </BaseImage>\n );\n}","import { ResourceType } from 'libs/shared/interfaces';\n\nexport const ResourceHelper = {\n getResourceTypeName(resourceType: ResourceType): string {\n switch (resourceType) {\n case 'additional-materials':\n return 'Additional Materials';\n\n case 'atom-guide':\n return 'ATOM Guide';\n\n case 'teacher-pack':\n return 'Teacher Pack';\n\n case 'student-activity':\n return 'Student Activity';\n\n default:\n return 'N/A';\n }\n }\n};","// extracted by mini-css-extract-plugin\nexport default {\"imageStyle\":\"I9E5O\",\"item\":\"tqUFn\",\"dashboard\":\"o7j7p\",\"playPage\":\"V2RwX\",\"aspectRatio\":\"OnJDH\",\"outerContainer\":\"CIFy7\",\"innerContainer\":\"oUZPD\",\"actions\":\"jzGAm\",\"titleBelow\":\"Cpjs3\",\"thumbnailContainer\":\"EDiGi\",\"titleAbove\":\"e9ejn\",\"teacherPack\":\"_tdVE\",\"text\":\"g5NWS\",\"hoverState\":\"xRYhX\",\"atomGuide\":\"X39wU\",\"studentActivity\":\"X9pMl\",\"additionalMaterials\":\"qRVUo\",\"userUploaded\":\"_18JaV\",\"imageTypeResource\":\"KYtZL\",\"download\":\"fbb_e\"};","import React from 'react';\n\nimport { AppLinkHelper } from 'libs/common/backbone/core';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions, EntityType, UserAction } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { ResourceThumbnail } from 'libs/shared/components/resource-thumbnail/ResourceThumbnail';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { TitleSubText } from 'libs/shared/components/title-sub-text/TitleSubText';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { TypeBadge } from 'libs/shared/components/type-badge/TypeBadge';\nimport { FixedWidgetItemProps } from 'libs/shared/components/widgets/items/FixedWidgetItemProps';\nimport { SeoConstants } from 'libs/shared/constants/SeoConstants';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { ResourceFileType } from 'libs/shared/enums/ResourceFileType';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Link, Resource, ResourceType } from 'libs/shared/interfaces';\nimport { MasterTypeHelper } from 'libs/shared/utils/MasterTypeHelper';\nimport { ResourceHelper } from 'libs/shared/utils/ResourceHelper';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport styles from './resource-widget-item.scss';\n\nfunction getColour(resourceType?: ResourceType): string {\n switch (resourceType) {\n case 'atom-guide':\n return styles.atomGuide;\n case 'student-activity':\n return styles.studentActivity;\n case 'teacher-pack':\n return styles.teacherPack;\n case 'additional-materials':\n return styles.additionalMaterials;\n default:\n return styles.userUploaded;\n }\n}\n\nfunction useCanPreview(data: Resource | Link, actionBehaviour: 'normal' | 'public'): boolean {\n const breakpoints = useBreakpoints();\n\n /**\n * When viewing publicly, the resource applink will\n * prompt the user to sign-up (not preview the underlying resource)\n */\n if (actionBehaviour === 'public')\n return true;\n\n if (breakpoints.xs || breakpoints.sm)\n return false;\n\n if (data.type !== 'resource')\n return false;\n \n // Require metadata\n if (!('metadata' in data))\n return false;\n\n // We can preview images\n if (data.metadata.type === ResourceFileType.Image)\n return true;\n\n // If we are a pdf and have a url\n if (data.metadata.type === ResourceFileType.Pdf)\n return !!data.url;\n\n // If we have a pdf assoc\n return !!data.pdf?.url;\n}\n\ninterface ResourceTheme {\n containerClass?: string;\n thumbnailContainerClass?: string;\n}\n\nexport interface ResourceTileProps {\n data: Resource | Link;\n imageCdnUrl: string;\n imageErrorFallbackUrl?: string;\n theme?: ResourceTheme;\n\n titlePosition: 'above' | 'below' | 'none';\n hideTypeBadge?: boolean;\n onClickDownload?: (resource: Resource) => void;\n applyHoverState?: boolean;\n preloadImage: boolean;\n actionBehaviour?: 'normal' | 'public';\n}\n\nResourceTile.defaultProps = {\n preloadImage: true,\n actionBehaviour: 'normal'\n};\n\n/**\n * This component intentionally doesn't contain an appLink/download link\n * so that the resource download behaviour can be handled differently depending\n * on where this is rendered (e.g. primary play page vs embedded player)\n */\nexport function ResourceTile(props: ResourceTileProps): JSX.Element {\n let metadata = null;\n\n if ('metadata' in props.data) {\n metadata = props.data.metadata;\n }\n\n const isResource = MasterTypeHelper.isType<Resource>(props.data, MasterType.Resource);\n\n function getInnerContainerClass(resourceType: ResourceType): string {\n let baseClass = `\n d-flex flex-column align-items-center justify-content-end rounded-3 h-100\n position-relative ${getColour(resourceType)} ${styles.innerContainer}`;\n\n if (props.theme?.containerClass) {\n baseClass += ` ${props.theme.containerClass}`;\n } else {\n baseClass += ` pt-3 px-3`;\n }\n\n if (props.applyHoverState) {\n baseClass += ` ${styles.hoverState}`;\n }\n\n return baseClass;\n }\n\n function onDownload() {\n if (!MasterTypeHelper.isResource(props.data))\n return;\n\n if (typeof props.onClickDownload === 'function') {\n props.onClickDownload(props.data);\n }\n }\n\n return (\n <>\n <div className={styles.aspectRatio}>\n <div className={styles.outerContainer}>\n <div className={getInnerContainerClass(metadata?.resourceType)}>\n {props.titlePosition === 'above' && (\n <Tooltip title={props.data.name}>\n <h3 className={`text-center text-break h5 mb-3 ${styles.text}`}>\n <span className='clamp-1'>{props.data.name}</span>\n </h3>\n </Tooltip>\n )}\n\n <div className={`\n ${props.theme?.thumbnailContainerClass ?? ''} w-75 overflow-hidden \n ${styles.thumbnailContainer} ${props.titlePosition === 'above' ? styles.titleAbove : ''} \n ${styles.imageStyle}\n `}>\n <ResourceThumbnail\n resource={props.data}\n imageCdnUrl={props.imageCdnUrl}\n imageErrorFallbackUrl={props.imageErrorFallbackUrl}\n preloadImage={props.preloadImage}\n />\n </div>\n\n {isResource && props.onClickDownload && props.actionBehaviour === 'normal' && (\n <div className={styles.actions}>\n <DivButton\n onClick={e => {\n e.preventDefault();\n e.stopPropagation();\n onDownload();\n }}\n className={`${styles.download} d-flex align-items-center justify-content-center`}\n >\n <SvgContainer svgName={cvSvgLibrary.Download} />\n </DivButton>\n </div>\n )}\n\n {!props.hideTypeBadge && isResource && (\n <TypeBadge typeId={MasterType.Resource} />\n )}\n </div>\n </div>\n </div>\n {props.titlePosition === 'below' && MasterTypeHelper.isType<Resource>(props.data, MasterType.Resource) && (\n <div className={`mt-1 ${styles.titleBelow}`}>\n {!!props.data?.metadata?.resourceType && (\n <TitleSubText>\n {ResourceHelper.getResourceTypeName(props.data.metadata.resourceType)}\n </TitleSubText>\n )}\n <h3 className='h6 clamp-2'>\n {props.data.name}\n </h3>\n </div>\n )}\n </>\n );\n}\n\nexport interface ResourceWidgetItemProps extends ResourceTileProps, FixedWidgetItemProps<Resource | Link> {\n location: 'play-page' | 'dashboard';\n}\n\nexport const ResourceWidgetItem = React.memo(function(props: ResourceWidgetItemProps): JSX.Element {\n // Mobile is not allowed to preview\n const canPreview = useCanPreview(props.data, props.actionBehaviour);\n\n function getLocationClass(): string {\n if (props.location === 'play-page')\n return styles.playPage;\n\n return styles.dashboard;\n }\n\n const analyticsData = { ...props.analyticsData, ...props.data };\n\n const analyticsOptions: AnalyticsOptions = {\n ...props.analyticsOptions,\n actionType: UserAction.Click,\n entity: props.data.typeId === MasterType.Resource ? EntityType.Resource : EntityType.Link\n };\n\n function logAction(): void {\n AnalyticsHelper.logUserAction(analyticsData, analyticsOptions);\n }\n\n const tileProps: ResourceTileProps = {\n ...props,\n // Apply the hover state if we have a url or the resource can be previewed\n applyHoverState: canPreview || !!props.data.url\n };\n\n return (\n <div className={`px-1 flex-shrink-0 ${styles.item} ${getLocationClass()} ${SeoConstants.RESOURCE_ITEM_SELECTOR}`}>\n {(() => {\n const className = `d-block ${props.titlePosition === 'above' ? 'no-decoration' : ''}`;\n\n // Handle resource links\n if (props.data.type === 'link') {\n return (\n <a href={props.data.url} target='_blank' className={className} onClick={logAction}>\n <ResourceTile {...tileProps} />\n </a>\n );\n }\n\n if (canPreview) {\n /**\n * Previewing resources in a public context will always display the sign-up popup, so there \n * will never be a full URL. For SEO purposes, we deliberately use a span over an anchor\n * to ensure we're not creating self-referencing elements that will burn crawl budget.\n */\n if (props.actionBehaviour === 'public') {\n return (\n <div className={`${className} cursor-pointer d-inline`} onClick={() => {\n logAction();\n AppLinkHelper.trigger(props.getAppLink(props.data));\n }}>\n <ResourceTile {...tileProps} />\n </div>\n );\n }\n\n return (\n <AppLink\n appLink={props.getAppLink(props.data)}\n className={className}\n analyticsData={analyticsData}\n analyticsOptions={analyticsOptions}\n >\n <ResourceTile {...tileProps} />\n </AppLink>\n );\n }\n\n // URLs cannot be previewed\n if (props.data.url) {\n return (\n <a href={props.data.url} className={className} onClick={logAction}>\n <ResourceTile {...tileProps} />\n </a>\n );\n }\n\n // Theres no url, so don't render an <a>\n return (\n <div className={className}>\n <ResourceTile {...tileProps} />\n </div>\n );\n })()}\n </div>\n );\n});","import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { HashObject } from 'libs/common/react/interfaces/HashObject';\n\nimport { Theme } from 'libs/shared/interfaces';\n\nimport { ThemeType } from '../enums/ThemeType';\n\nexport const ThemeRequests = {\n theme(id: string): Flight.Request {\n return {\n url: `/api/domain/v1/themes/${id}`,\n key: `themes:${id}`\n };\n },\n\n themeImages(name: string, type: ThemeType): Flight.Request {\n return {\n url: UrlHelper.urlBuilder('/api/domain/v1/themes', { name, type }),\n key: `themes:${name}:${type}`\n };\n },\n\n themes(type?: string): Flight.Request {\n let url = '/api/domain/v1/themes';\n let key = 'themes';\n\n if (type) {\n url += `?type=${type}`;\n key += `:type:${type}`;\n }\n\n return {\n url,\n key,\n formatData: (themes: Theme[]) => {\n return themes.sort((a, b) => a.name.localeCompare(b.name));\n }\n };\n },\n\n createTheme(\n data: Theme,\n success?: (data: HashObject) => void,\n error?: (xhr: Xhr) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: '/api/domain/v1/themes',\n key: 'theme',\n data,\n type: HttpVerbs.POST,\n invalidationKeys: 'themes',\n success,\n error,\n always\n };\n },\n\n updateTheme(\n id: string,\n data: Theme,\n success?: (data: HashObject) => void,\n error?: (xhr: Xhr) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: `/api/domain/v1/themes/${id}`,\n key: `update:theme:${id}`,\n data,\n type: HttpVerbs.PUT,\n success,\n error,\n always\n };\n },\n\n deleteTheme(\n id: string,\n success?: (data: HashObject) => void,\n error?: (xhr: Xhr) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: `/api/domain/v1/themes/${id}`,\n key: `delete:theme:${id}`,\n type: HttpVerbs.DELETE,\n invalidationKeys: 'themes',\n success,\n error,\n always\n };\n }\n};","import React from 'react';\n\n// https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state\nexport function usePrevious<T>(value: T): T {\n const ref = React.useRef<T>();\n React.useEffect(() => {\n ref.current = value;\n });\n return ref.current;\n}","import React from 'react';\n\nimport { usePrevious } from './usePrevious';\n\nconst HEADER_OFFSET = 80; // Size of header + some extra spacing\n\nexport const useTableOfContentsScroll = (elements: Element[], activeId: string) => {\n const [ hasDoneInitialScroll, setHasDoneInitialScroll ] = React.useState(false);\n\n const previousId = usePrevious(activeId);\n const currentId = activeId;\n\n React.useLayoutEffect(() => {\n if (!hasDoneInitialScroll || previousId !== currentId) {\n const target = elements.find(heading => heading && (heading?.id === currentId));\n\n if (target) {\n const rec = target.getBoundingClientRect();\n\n window.scrollBy({\n top: rec.top - HEADER_OFFSET,\n behavior: 'smooth'\n });\n \n if (!hasDoneInitialScroll)\n setHasDoneInitialScroll(true);\n }\n }\n }, [ elements, previousId, currentId, hasDoneInitialScroll ]);\n};","import { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions, EntityType, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { Resource } from '../interfaces';\n\nlet downloadRef: HTMLIFrameElement = null;\n\nexport const DownloadHelper = {\n getVideoDownloadUrl(downloadProxyUrl: string, token: string): string {\n return UrlHelper.safeUrlConcat(UrlHelper.makeHttps(downloadProxyUrl), `/download?token=${token}`);\n },\n\n downloadResource(\n resource: Resource,\n analyticsData: HashObject,\n analyticsOptions: AnalyticsOptions\n ): void {\n let iframe = downloadRef;\n\n if (!downloadRef) {\n iframe = downloadRef = document.createElement('iframe');\n document.body.appendChild(iframe);\n\n iframe.style.display = 'none';\n }\n\n iframe.src = resource.url;\n\n AnalyticsHelper.logUserAction({\n id: resource?.id,\n name: resource?.name,\n resourceType: resource?.metadata?.resourceType,\n ...analyticsData\n }, {\n actionType: UserAction.Download,\n entity: EntityType.Resource,\n workflowPhase: WorkflowPhase.Complete,\n ...analyticsOptions\n });\n }\n};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EntityType } from 'libs/analytics/interfaces';\n\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'shared.playPage';\n\ninterface ArchivedBannerProps {\n typeId: MasterType;\n hasStudentExperience: boolean;\n}\n\nfunction mapTypeId(typeId: MasterType): string {\n switch (typeId) {\n case MasterType.Video:\n return 'video';\n case MasterType.Clip:\n return 'clip';\n case MasterType.Interactive:\n return 'interactive';\n default:\n return '';\n }\n}\n\nexport function ArchivedBanner(props: ArchivedBannerProps): JSX.Element {\n const getPhrase = LanguageService.encloseNamespace(namespace);\n const type = mapTypeId(props.typeId);\n\n return (\n <div className='alert bg-light-blue p-3 rounded-3 d-flex justify-content-between align-items-center'>\n <SvgContainer\n svgName={cvSvgLibrary.Archive}\n size={SvgContainerSize.Standard}\n className='me-2 svg-container'\n />\n \n <div className='w-100'>\n <p className='fw-semibold mb-0'>{getPhrase('archivedInfoTitle', { type })}</p>\n {(!props.hasStudentExperience || type === EntityType.Video) && (\n <p className='mb-1'>{getPhrase('archivedInfo', { type: `${type}s` })}</p>\n )}\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { RestrictionType } from 'libs/shared/enums/RestrictionType';\nimport { Restrictions, YearGroup } from 'libs/shared/interfaces';\nimport { RestrictionHelper } from 'libs/shared/utils/RestrictionHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nconst namespace = 'shared.playPage';\n\ninterface RestrictionBannerProps {\n restrictions: Restrictions;\n yearGroups: YearGroup[];\n objectId: string;\n objectTypeId: MasterType;\n canManageVideoAccess: boolean;\n}\n\nexport function RestrictionBanner(props: RestrictionBannerProps): JSX.Element {\n if (!props.restrictions?.value?.length || !props.yearGroups || !props.canManageVideoAccess)\n return <></>;\n\n const restriction = RestrictionHelper.getWeightedRestriction(props.restrictions.value);\n\n if (restriction.type !== RestrictionType.Custom)\n return <></>;\n\n const baseClassName = RestrictionHelper.mapRestrictionToClass(props.restrictions);\n const className = `${baseClassName} fw-semibold p-2 rounded mb-3 d-flex justify-content-between align-items-center`;\n\n return (\n <div className={className}>\n <div className='d-flex align-items-center'>\n <SvgContainer\n svgName={RestrictionHelper.mapRestrictionToSvg(props.restrictions)}\n size={SvgContainerSize.Large}\n />\n <span className='ps-1'>\n {RestrictionHelper.mapRestrictionToText(props.restrictions, props.yearGroups)}\n </span>\n </div>\n \n <AppLink\n appLink={{\n application: AppChannels.DEFAULT,\n action: Actions.Default.APPROVE_VIDEO,\n params: {\n objectId: props.objectId,\n objectTypeId: props.objectTypeId\n }\n }}\n className='btn btn-outline-dark'\n >\n <Text namespace={namespace} phrase='approve' />\n </AppLink>\n </div>\n );\n}","import React from 'react';\n\nimport { ThumbnailText } from 'libs/shared/components/thumbnails/thumbnail-text/ThumbnailText';\nimport { VideoThumbnail } from 'libs/shared/components/thumbnails/video/VideoThumbnail';\nimport { FixedWidgetItemProps } from 'libs/shared/components/widgets/items/FixedWidgetItemProps';\nimport { ThumbnailTextPosition } from 'libs/shared/enums/ThumbnailTextPosition';\nimport { CanFavouriteFunc, Clip, FavouriteFunc, YearGroup } from 'libs/shared/interfaces';\n\nimport styles from './clip-widget-item.scss';\n\nexport interface ClipWidgetItemProps extends FixedWidgetItemProps<Clip> {\n imageCdnUrl: string;\n setFavourite: FavouriteFunc;\n canFavourite: CanFavouriteFunc;\n yearGroups: YearGroup[];\n}\n\nexport const ClipWidgetItem = React.memo(function(props: ClipWidgetItemProps): JSX.Element {\n const { data: clip, thumbnailSize, preloadImage, getAppLink } = props;\n\n return (\n <div className={`flex-shrink-0 px-1 ${styles.item}`}>\n <VideoThumbnail\n type='cosmetic'\n textPosition={ThumbnailTextPosition.Independent}\n video={clip}\n appLink={getAppLink(clip)}\n imageOptions={{ size: thumbnailSize }}\n preload={preloadImage}\n analyticsData={props.analyticsData}\n analyticsOptions={props.analyticsOptions}\n setFavourite={props.setFavourite}\n canFavourite={props.canFavourite}\n imageCdnUrl={props.imageCdnUrl}\n hideDuration={false}\n />\n\n <div className='mt-2'>\n <ThumbnailText\n {...props}\n video={clip}\n appLink={props.getAppLink(clip)}\n />\n </div>\n </div>\n );\n});","// extracted by mini-css-extract-plugin\nexport default {\"item\":\"hzP5u\",\"thumbnail\":\"z2JjL\",\"smallItemIconWidth\":\"PfCrs\",\"smallItemInfoWidth\":\"AHFZu\",\"smallProgressBarContainer\":\"WfOtB\",\"smallItemNameWidth\":\"Rq6Cd\"};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { FixedWidget } from 'libs/shared/components/widgets/fixed-widget';\nimport { ClipWidgetItem, ClipWidgetItemProps } from 'libs/shared/components/widgets/items/clip-widget-item/ClipWidgetItem';\nimport { WidgetContents } from 'libs/shared/enums/WidgetContents';\nimport { CanFavouriteFunc, Clip, FavouriteFunc, Video, YearGroup } from 'libs/shared/interfaces';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nconst namespace = 'shared.playPageClips';\n\ninterface PlayPageClipsProps {\n video: Video | Clip;\n clips: Clip[];\n canViewClips: boolean;\n yearGroups: YearGroup[];\n imageCdnUrl: string;\n setFavourite: FavouriteFunc;\n canFavourite: CanFavouriteFunc;\n analyticsData: HashObject;\n}\n\nexport function PlayPageClips(props: PlayPageClipsProps): JSX.Element {\n if (!props.canViewClips || !props.clips?.length)\n return <></>;\n\n return (\n <section className='pb-3'>\n <FixedWidget<ClipWidgetItemProps>\n name={LanguageService.getPhrase(namespace, 'clips', { count: props.clips.length })}\n contents={WidgetContents.Clips}\n collection={props.clips}\n prefetched\n getChildAppLink={(clip: Clip) => {\n return {\n application: AppChannels.CLIPS,\n action: Actions.Clips.PLAY_CLIP,\n args: [ clip.id, TextHelper.slugify(clip.name) ]\n };\n }}\n appLink={{\n action: Actions.Videos.VIDEO_CLIPS,\n application: AppChannels.VIDEOS,\n args: [props.video.id],\n params: {\n parentType: VideoHelper.isClip(props.video) ? 'clip' : 'video'\n }\n }}\n childComponent={ClipWidgetItem}\n extraChildComponentProps={{\n yearGroups: props.yearGroups,\n imageCdnUrl: props.imageCdnUrl,\n setFavourite: props.setFavourite,\n canFavourite: props.canFavourite\n }}\n analyticsData={props.analyticsData}\n />\n </section>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { FixedWidget } from 'libs/shared/components/widgets/fixed-widget';\nimport { InteractiveWidgetItem, InteractiveWidgetItemProps } from 'libs/shared/components/widgets/items/interactive-widget-item/InteractiveWidgetItem';\nimport { WidgetContents } from 'libs/shared/enums/WidgetContents';\nimport { CanFavouriteFunc, Clip, FavouriteFunc, Interactive, Video, YearGroup } from 'libs/shared/interfaces';\nimport { PlayPageAnchor } from 'libs/shared/interfaces/PlayPageAnchor';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nconst namespace = 'shared.playPageInteractives';\n\ninterface PlayPageInteractivesProps {\n canViewInteractives: boolean;\n video: Video | Clip;\n imageCdnUrl: string;\n analyticsData: HashObject;\n containerRef: React.RefObject<HTMLDivElement>;\n yearGroups: YearGroup[];\n setFavourite: FavouriteFunc;\n canFavourite: CanFavouriteFunc;\n}\n\nexport function PlayPageInteractives(props: PlayPageInteractivesProps): JSX.Element {\n if (!props.canViewInteractives || !props.video.interactives?.data?.length)\n return <></>;\n\n return (\n <section className='pb-3' ref={props.containerRef} id={PlayPageAnchor.Interactives}>\n <FixedWidget<InteractiveWidgetItemProps>\n name={LanguageService.getPhrase(namespace, 'interactives', { count: props.video.interactives.data.length })}\n contents={WidgetContents.Interactives}\n collection={props.video.interactives.data}\n prefetched\n getChildAppLink={(interactive: Interactive) => {\n return {\n application: AppChannels.INTERACTIVES,\n action: Actions.Interactives.VIEW_INTERACTIVE,\n args: [ interactive.id, TextHelper.slugify(interactive.name) ]\n };\n }}\n appLink={{\n action: Actions.Videos.VIDEO_INTERACTIVES,\n application: AppChannels.VIDEOS,\n args: [props.video.id],\n params: {\n parentType: VideoHelper.isClip(props.video) ? 'clip' : 'video'\n }\n }}\n childComponent={InteractiveWidgetItem}\n extraChildComponentProps={{\n yearGroups: props.yearGroups,\n setFavourite: props.setFavourite,\n canFavourite: props.canFavourite,\n imageCdnUrl: props.imageCdnUrl,\n questionsAppLink: {\n application: AppChannels.INTERACTIVES,\n action: Actions.Interactives.PREVIEW_QUESTIONS\n }\n }}\n analyticsData={props.analyticsData}\n />\n </section>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"series\":\"wTlJJ\",\"badgeListContainer\":\"Vaout\"};","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { Actions } from 'libs/shared/components/actions/Actions';\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { AudienceLabel } from 'libs/shared/components/audience-label/AudienceLabel';\nimport { Badge, BadgeType } from 'libs/shared/components/badges/Badge';\nimport { BadgeListContainer } from 'libs/shared/components/badges/BadgeListContainer';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { RestrictionPadlock } from 'libs/shared/components/video-list/components/restriction-padlock/RestrictionPadlock';\nimport { VideoSubText } from 'libs/shared/components/video-sub-text/VideoSubText';\nimport { useMergeAudiences } from 'libs/shared/hooks/UseMergeAudiences';\nimport { Clip, PresentationAudience, Series, Video, YearGroup } from 'libs/shared/interfaces';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { useVideoActions, VideoActionsLocation } from 'shared/hooks/use-video-actions/useVideoActions';\nimport { VideoFeaturesHash } from 'shared/hooks/useVideoFeatureAccess';\n\nimport styles from './title-and-actions.scss';\n\nconst namespace = 'shared.playPage';\n\ninterface PlayPageTitleAndActionsProps {\n media: Clip | Video;\n yearGroups: YearGroup[];\n audiences: PresentationAudience[];\n featureAccess: VideoFeaturesHash;\n getSeriesAppLink?: (series: Series) => Core.AppLink;\n originalVideoAppLink?: Core.AppLink;\n shareId: string;\n}\n\nexport function PlayPageTitleAndActions(props: PlayPageTitleAndActionsProps): JSX.Element {\n const mergedAudience = useMergeAudiences(props.media.subjectPresentationAudiences?.data, props.audiences);\n\n const containerRef = React.useRef<HTMLDivElement>(null);\n const titleContainerRef = React.useRef<HTMLDivElement>(null);\n\n const hasBadges = (\n (VideoHelper.isVideo(props.media) && !!props.media.rating?.value) ||\n (VideoHelper.isVideo(props.media) && !!props.media.productionYear) ||\n !!props.media.subjectPresentationAudiences?.data?.length\n );\n\n const videoActions = useVideoActions({\n location: VideoActionsLocation.PlayPage,\n shareId: props.shareId\n });\n\n const canViewOriginal = !!props.originalVideoAppLink &&\n VideoHelper.isClip(props.media) &&\n VideoHelper.canViewOriginalVideo(props.media);\n\n return (\n <section className='mb-3 position-relative' ref={containerRef}>\n <div className='d-inline-block w-100' ref={titleContainerRef}>\n {props.featureAccess.canNavigate &&\n <div className='ms-2 float-end'>\n <Actions\n actions={videoActions.getVideoActions(props.media)}\n actionsDropdownClassName='btn btn-outline-dark'\n fetchMore={() => videoActions.fetchMoreActions(props.media)}\n />\n </div>\n }\n\n {!!VideoHelper.isVideo(props.media) && (\n <VideoSubText\n type='series'\n video={props.media}\n appLink={props.getSeriesAppLink?.(props.media.series)}\n className={`${styles.series} text-truncate mw-100`}\n analyticsOptions={{ location: LocationContext.PlayPage }}\n />\n )}\n <h1 className='h4 mb-2 mw-100'>\n <span className='align-self-center'>{props.media.name}</span>\n <RestrictionPadlock\n tooltipPlacement='right'\n className='d-inline-block ps-1'\n video={props.media}\n yearGroups={props.yearGroups}\n />\n </h1>\n\n {hasBadges && (\n <BadgeListContainer className={styles.badgeListContainer}>\n <AudienceLabel\n audience={mergedAudience}\n className='bg-white text-dark'\n border='dark'\n />\n {VideoHelper.isVideo(props.media) && (\n <Badge type={BadgeType.Rating} data={props.media.rating} />\n )}\n {VideoHelper.isVideo(props.media) && (\n <Badge type={BadgeType.ProductionYear} data={props.media.productionYear} />\n )}\n </BadgeListContainer>\n )}\n </div>\n\n {VideoHelper.isClip(props.media) && canViewOriginal && (\n <p className='clamp-1'>\n <Text namespace={namespace} phrase='viewOriginal' />\n &nbsp;\n <AppLink className='info-link' appLink={props.originalVideoAppLink}>\n {props.media._parentVideo?.name}\n </AppLink>\n </p>\n )}\n </section>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"mask\":\"LL7My\",\"centeredIcon\":\"x_1f6\",\"bgImage\":\"QoLgZ\",\"centeredOverlay\":\"BcnSH\"};","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { EntityType, LocationContext, SignUpDescriptors, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { ImageSize } from 'libs/shared/enums/Images';\nimport { VideoTypes } from 'libs/shared/interfaces';\nimport { ImageHelper } from 'libs/shared/utils/ImageHelper';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport styles from './player-placeholder.scss';\n\nconst namespace = 'shared.playerPlaceholder';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface PlayerPlaceholderProps {\n video: VideoTypes;\n type: 'pip' | 'public';\n appLink?: Core.AppLink;\n}\n\nexport function PlayerPlaceholder(props: PlayerPlaceholderProps): JSX.Element {\n switch (props.type) {\n case 'pip':\n return <PipPlaceholder {...props} />;\n case 'public':\n return <PublicPlaceholder {...props} />;\n default:\n return <></>;\n }\n}\n\nconst PipPlaceholder = (props: PlayerPlaceholderProps) => (\n <div\n className={`position-relative responsive-img ${styles.bgImage}`}\n style={{ backgroundImage: `url('${VideoHelper.getThumbnail(props.video)?.url ?? ''}')` }}\n >\n <p className={`m-0 text-white h3 ${styles.centeredOverlay}`}>{getPhrase('playingPiP')}</p>\n <div className={styles.mask} />\n </div>\n);\n\nconst PublicPlaceholder = (props: PlayerPlaceholderProps) => {\n const thumbnailUrl = ImageHelper.createUrl(VideoHelper.getThumbnail(props.video)?.url ?? '', {\n size: ImageSize.Large\n });\n\n return (\n <div\n className={`position-relative responsive-img ${styles.bgImage}`}\n style={{ backgroundImage: `url('${thumbnailUrl}')` }}\n >\n <AppLink\n appLink={props.appLink}\n analyticsOptions={{\n actionType: UserAction.Click,\n location: LocationContext.PlayPage,\n entity: EntityType.AppLink,\n workflowPhase: WorkflowPhase.Start,\n descriptor: SignUpDescriptors.SignUp\n }}\n analyticsData={{}}\n >\n <SvgContainer\n svgName={cvSvgLibrary.PlayCircle}\n className={styles.centeredIcon}\n />\n <div className={styles.mask} />\n </AppLink>\n </div>\n );\n};","import React from 'react';\n\nimport { Core } from 'libs/common/core';\n\nimport { InfiniteScrollFooter } from 'libs/shared/components/infinite-scroll-footer/InfiniteScrollFooter';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { PartialVideoList } from 'libs/shared/components/video-list/partial-loading/PartialVideoList';\nimport { VideoList } from 'libs/shared/components/video-list/VideoList';\nimport { VideoActionsContext } from 'libs/shared/context/VideoActionsContext';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { CanFavouriteFunc, CurrentUser, FavouriteFunc, PresentationAudience, VideoTypes, YearGroup } from 'libs/shared/interfaces';\nimport { GetVideoAppLinkOptions } from 'libs/shared/interfaces/VideoAppLinkOptions';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { useVideoActions, VideoActionsLocation } from 'shared/hooks/use-video-actions/useVideoActions';\nimport { RelatedVideosHash } from 'shared/hooks/useGetRelatedVideos';\nimport { InteractiveHelpers } from 'shared/utils/InteractiveHelper';\n\nimport { SeriesAppLinkHelper } from 'apps/series/SeriesAppLinkHelper';\n\nconst namespace = 'shared.relatedVideos';\n\ninterface RelatedVideosProps {\n currentVideo: VideoTypes;\n yearGroups: YearGroup[];\n relatedVideos: RelatedVideosHash;\n setFavourite: FavouriteFunc;\n canFavourite: CanFavouriteFunc;\n currentUser: CurrentUser;\n audiences: PresentationAudience[];\n getVideoAppLink: (video: VideoTypes, opts: GetVideoAppLinkOptions) => Core.AppLink;\n moviesAndTv: boolean;\n}\n\nexport function RelatedVideos(props: RelatedVideosProps): JSX.Element {\n const videoActions = useVideoActions({ location: VideoActionsLocation.VideoItem });\n const { hasPermissions } = usePermissions();\n\n if (!props.currentUser?.isAuthenticated) // Don't render if user is unauthenticated\n return <></>;\n\n if (props.relatedVideos.hasError) // Don't render if request has errored\n return <></>;\n\n if (props.relatedVideos.hasCompleted && !props.relatedVideos.videos?.length) // Don't render if response is empty\n return <></>;\n\n if (!props.relatedVideos.isFetching && !props.relatedVideos.hasCompleted) // Don't render if request is never made\n return <></>;\n\n // We don't support autoplaying from interactives. This means the related videos heading won't say \"Up next\"\n const canAutoplay = !VideoHelper.isInteractive(props.currentVideo);\n\n return (\n <VideoActionsContext.Provider value={videoActions}>\n <h2 className='h4 mb-0'>\n <Text namespace={namespace} phrase={canAutoplay ? 'upNext' : 'relatedVideos'} />\n </h2>\n {props.relatedVideos.hasCompleted\n ? (\n <VideoList\n videos={props.relatedVideos.videos}\n yearGroups={props.yearGroups}\n getSubTextAppLink={video => {\n return SeriesAppLinkHelper.getSeriesAppLink(video.series, props.moviesAndTv ? { mtv: true } : null);\n }}\n getVideoAppLink={props.getVideoAppLink}\n hasPermissions={hasPermissions}\n setFavourite={props.setFavourite}\n canFavourite={props.canFavourite}\n presentationAudiences={props.audiences}\n getPreviewQuestionsAppLink={interactive => InteractiveHelpers.getPreviewQuestionsAppLink(interactive)}\n />\n ) : <PartialVideoList />\n }\n {props.relatedVideos.hasMore &&\n <InfiniteScrollFooter\n isFetching={props.relatedVideos.isFetching}\n fetchNext={props.relatedVideos.fetchNext}\n />\n }\n </VideoActionsContext.Provider>\n );\n}","import { Flight } from 'libs/common/react/index';\n\nimport { LocalPermissionName, PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { Config } from 'libs/shared/interfaces/models/Config';\n\nimport { LiteRouteHelper } from 'shared/utils/LiteRouteHelper';\n\nexport interface VideoFeaturesHash {\n canViewGlance: boolean;\n canViewResources: boolean;\n canViewInteractives: boolean;\n canViewClips: boolean;\n canUseActions: boolean;\n canViewPublicLayout: boolean;\n canNavigate: boolean;\n canViewCurriculumLinks: boolean;\n canViewResourceItems: boolean;\n canWatchPublicly: (videoId: string) => boolean;\n}\n\nexport function useVideoFeatureAccess() {\n const { hasPermissions, hasLocalPermissions } = usePermissions();\n const { hasProduct } = useProducts();\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n\n const hasNP = hasProduct(ProductId.Primary);\n\n function showPublicLayout(): boolean {\n /**\n * Authenticated users should never see the placeholder\n */\n if (hasLocalPermissions(LocalPermissionName.WatchVideos))\n return false;\n\n /**\n * Accessing a play page unathenticated will have different contextual behabviours:\n * - For a share page, the user should see the video and never the placeholder\n * - For a public browsing page (ie. using a route-prefix) they should see the placeholder\n */\n return LiteRouteHelper.hasRegionPrefix();\n }\n\n /**\n * Publicly available video ids are maintained on the backend config. \n */\n function canWatchPublicly(videoId: string): boolean {\n if (!videoId)\n return false;\n\n return !!config.data?.allowedPublicVideos?.[videoId];\n }\n\n return {\n canWatchPublicly,\n canViewGlance: hasPermissions(PermissionName.ViewVideoGlance),\n canViewResources: true,\n canViewInteractives: hasNP && hasPermissions(PermissionName.ViewVideoInteractives),\n canViewClips: hasNP && hasPermissions(PermissionName.ViewVideoClips),\n canViewCurriculumLinks: hasPermissions(PermissionName.ViewCurriculums),\n canUseActions: hasLocalPermissions(LocalPermissionName.UseVideoActions),\n canViewPublicLayout: showPublicLayout(),\n canViewResourceItems: hasLocalPermissions(LocalPermissionName.ViewVideoResourceItems),\n canNavigate: hasNP\n };\n}","import React from 'react';\n\nimport { Flight } from 'libs/common/flight';\n\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { VideoRequests } from 'libs/shared/flight-requests/VideoRequests';\nimport { CurrentUser, Video, VideoCollection } from 'libs/shared/interfaces';\n\ninterface VideoMixinOptions {\n /**\n * If the videos that are having new data mixed into are sitting on an explicit Flight namespace,\n * providing that namespace here is required\n */\n flightNamespace?: string;\n}\n\nexport function useVideoMixin(videos: VideoCollection | Video[], options: VideoMixinOptions = {}): void {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n\n const hydratedVideos = React.useRef<Set<string>>(new Set<string>());\n\n const videoIds = videos && (Array.isArray(videos)\n ? videos.filter(Boolean).map(v => v.id)\n : videos.data.filter(Boolean).map(v => v.id));\n\n const [ request, setRequest ] = React.useState<Flight.Request[]>([]);\n\n React.useEffect(() => {\n if (!videoIds?.length || !currentUser.data?.isAuthenticated)\n return;\n\n const unhydratedVideos: string[] = [];\n\n videoIds.forEach(id => {\n if (!hydratedVideos.current.has(id)) {\n unhydratedVideos.push(id);\n hydratedVideos.current.add(id);\n }\n });\n \n if (!unhydratedVideos.length)\n return;\n\n setRequest(r => [\n ...r,\n ClassificationRequests.hasCurriculumLinks(unhydratedVideos, null, options.flightNamespace),\n VideoRequests.videoMixinAssocs(unhydratedVideos, options.flightNamespace)\n ]);\n }, [ videoIds?.length, currentUser.data?.isAuthenticated ]);\n\n Flight.useBasicFetchAll(request);\n}"],"names":["InfiniteScrollFooter","props","ref","inView","fetchOnScroll","isFetching","fetchNext","nextCursor","className","Spinner","as","animation","role","SvgContainer","svgName","size","S","onClick","defaultProps","namespace","PlayPageResources","hasPermissions","resources","video","isLearner","data","links","filteredResources","filter","r","includes","metadata","resourceType","getResources","length","id","containerRef","name","count","contents","collection","prefetched","childComponent","R","extraChildComponentProps","imageCdnUrl","imageErrorFallbackUrl","resourceThumbnailFallbackUrl","actionBehaviour","canViewResources","location","titlePosition","onClickDownload","resource","analyticsData","actionType","entity","getChildAppLink","getAppLink","analyticsOptions","workflowPhase","descriptor","SignUp","PointOfInterestList","Text","phrase","pointsOfInterest","map","poi","timeStamp","DurationHelper","startTime","suppressInteractivity","key","description","DivButton","onClickPoiItem","SCROLL_HEIGHT_MAX","VideoAtAGlance","canViewGlance","learningIntentionMarkdownHTML","tags","VideoHelper","tag","tagType","TagType","getTags","autoHeight","autoHeightMax","height","dangerouslySetInnerHTML","__html","TagList","TagHelper","getTagAppLink","time","setStartTime","POI_LINK_LINE","useLearningIntentionMarkdown","hasGlanceData","useState","markdownHTML","setMarkdownHTML","useEffect","content","glance","learningIntention","replace","format","VideoDetailsPartial","style","width","PartialVideoList","Array","numVideos","fill","_","i","allowBulkActions","PartialVideoItem","breakpoints","useBreakpoints","isSmall","VideoListHelper","withDragHandle","withReordering","xs","Row","Col","InteractiveWidgetItem","interactive","thumbnailSize","preloadImage","questionsAppLink","args","questionsNumber","_timepoints","value","VideoThumbnail","type","textPosition","ThumbnailTextPosition","appLink","imageOptions","preload","setFavourite","canFavourite","hideDuration","ThumbnailText","AppLink","options","smartCount","DYNAMIC_RATIO_IMAGE_OPTIONS","resizeType","getImageType","MasterTypeHelper","ResourceFileType","pdf","url","ResourceThumbnail","rotation","thumbnail","thumbnailUrl","imageType","ImageHelper","previewUrl","UrlHelper","getThumbnailUrl","BaseImage","imageStyle","transform","alt","errorFallbackImageSrc","errorFallbackImageClassName","imageClassName","preventLoad","ResourceHelper","getResourceTypeName","ResourceTile","isResource","MasterType","baseClass","getColour","theme","containerClass","applyHoverState","getInnerContainerClass","Tooltip","title","thumbnailContainerClass","e","preventDefault","stopPropagation","hideTypeBadge","TypeBadge","typeId","TitleSubText","ResourceWidgetItem","canPreview","sm","logAction","AnalyticsHelper","tileProps","SeoConstants","href","target","ThemeRequests","themeImages","themes","formatData","sort","a","b","localeCompare","createTheme","success","error","always","invalidationKeys","updateTheme","deleteTheme","usePrevious","current","useTableOfContentsScroll","elements","activeId","hasDoneInitialScroll","setHasDoneInitialScroll","previousId","currentId","find","heading","rec","getBoundingClientRect","window","scrollBy","top","behavior","downloadRef","DownloadHelper","getVideoDownloadUrl","downloadProxyUrl","token","downloadResource","iframe","document","createElement","body","appendChild","display","src","ArchivedBanner","getPhrase","mapTypeId","hasStudentExperience","RestrictionBanner","restrictions","yearGroups","canManageVideoAccess","baseClassName","application","action","params","objectId","objectTypeId","ClipWidgetItem","clip","PlayPageClips","canViewClips","clips","LanguageService","WidgetContents","TextHelper","parentType","PlayPageInteractives","canViewInteractives","interactives","PlayPageTitleAndActions","mergedAudience","media","subjectPresentationAudiences","audiences","titleContainerRef","hasBadges","rating","productionYear","videoActions","useVideoActions","shareId","canViewOriginal","originalVideoAppLink","featureAccess","canNavigate","Actions","actions","getVideoActions","actionsDropdownClassName","fetchMore","fetchMoreActions","VideoSubText","getSeriesAppLink","series","RestrictionPadlock","tooltipPlacement","BadgeListContainer","AudienceLabel","audience","border","Badge","_parentVideo","PlayerPlaceholder","PipPlaceholder","PublicPlaceholder","backgroundImage","RelatedVideos","currentUser","isAuthenticated","relatedVideos","hasError","hasCompleted","videos","canAutoplay","currentVideo","getSubTextAppLink","moviesAndTv","mtv","getVideoAppLink","presentationAudiences","getPreviewQuestionsAppLink","hasMore","useVideoFeatureAccess","hasLocalPermissions","hasProduct","config","hasNP","canWatchPublicly","videoId","allowedPublicVideos","canViewCurriculumLinks","canUseActions","canViewPublicLayout","canViewResourceItems","useVideoMixin","hydratedVideos","Set","videoIds","isArray","Boolean","v","request","setRequest","unhydratedVideos","forEach","has","push","add","flightNamespace"],"sourceRoot":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"scripts/6375-f6cac7d19c-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/components/breadcrumbs/Breadcrumbs.tsx","file:///app/packages/libs/shared/src/components/video-list/partial-loading/partial-video-list.scss","file:///app/packages/libs/shared/src/components/video-list/partial-loading/PartialVideoList.tsx","file:///app/packages/libs/shared/src/utils/PartialLoadingHelper.ts","file:///app/packages/projects/lite/src/shared/hooks/usePresentationAudiences.ts","file:///app/packages/projects/lite/src/shared/hooks/useVideoFeatureAccess.ts","file:///app/packages/projects/lite/src/shared/views/video-media/partial-loading/partial-video-media-view.scss","file:///app/packages/projects/lite/src/shared/views/video-media/partial-loading/PartialVideoMediaView.tsx","file:///app/packages/projects/lite/src/shared/views/video-media/VideoMediaView.tsx","file:///app/node_modules/react-bootstrap/esm/Row.js"],"sourcesContent":["import * as React from 'react';\n\nimport { Core } from 'libs/common/core';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { useMediaQuery } from 'libs/shared/hooks/UseMediaQuery';\nimport { PartialLoadingHelper } from 'libs/shared/utils/PartialLoadingHelper';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { SvgContainer, SvgContainerSize } from '../svg-container/SvgContainer';\n\nexport interface Breadcrumb {\n name: string;\n appLink?: Core.AppLink;\n active?: boolean;\n}\n\ninterface BreadcrumbItemProps {\n breadcrumb: Breadcrumb;\n withBackIcon?: boolean;\n}\n\nexport const BreadcrumbItem = ({ breadcrumb: { name, appLink, active }, withBackIcon }: BreadcrumbItemProps) => (\n <li className={`breadcrumb-item${active ? ' active' : ''}`}>\n {active\n ? <strong>{name}</strong>\n : <AppLink appLink={appLink}>\n {withBackIcon && <SvgContainer svgName={cvSvgLibrary.ChevronLeft} size={SvgContainerSize.Small} />}\n <span className={withBackIcon ? 'ms-2' : ''}>{name}</span>\n </AppLink>\n }\n </li>\n);\n\ninterface BreadcrumbsProps {\n breadcrumbs: Breadcrumb[];\n}\n\nexport const Breadcrumbs = ({ breadcrumbs }: BreadcrumbsProps) => {\n const isMobile = useMediaQuery(MediaQueryStrings.XS);\n\n const length = breadcrumbs?.length;\n\n if (!length || (isMobile && length < 2))\n return <></>;\n\n if (isMobile)\n return (\n <nav aria-label='breadcrumb'>\n <ol className='breadcrumb m-0 p-0'>\n <BreadcrumbItem breadcrumb={breadcrumbs[length - 2]} withBackIcon />\n </ol>\n </nav>\n );\n\n return (\n <nav aria-label='breadcrumb'>\n <ol className='breadcrumb m-0 p-0'>\n {breadcrumbs.map((b, idx) => <BreadcrumbItem key={idx} breadcrumb={b} />)}\n </ol>\n </nav>\n );\n};\n\nexport const PartialBreadcrumbs = React.memo(function({ numItems = 3 }: { numItems?: number; }) {\n const isMobile = useMediaQuery(MediaQueryStrings.XS);\n\n if (isMobile) {\n return (\n <div className='partial-loading-background' style={{ height: '1.3125rem', width: '6rem' }} />\n );\n }\n\n return (\n <nav aria-label='breadcrumb'>\n <ol className='breadcrumb m-0 p-0'>\n {PartialLoadingHelper.getPartialLoadingItems({ numItems }).map(({ width }, idx) => (\n <li key={idx} className='breadcrumb-item'>\n <span className='d-inline-block partial-loading-background' style={{ width }} dangerouslySetInnerHTML={{ __html: '&nbsp' }} />\n </li>\n ))}\n </ol>\n </nav>\n );\n});","// extracted by mini-css-extract-plugin\nexport default {\"partialOptions\":\"Gufgq\",\"partialName\":\"SicQQ\",\"partialDescription\":\"dPGMq\",\"partialThumbnail\":\"vZrnb\",\"partialDragHandle\":\"iq73R\"};","import React from 'react';\nimport { Col, Row } from 'react-bootstrap';\n\nimport { VideoListHelper } from 'libs/shared/components/video-list/VideoListHelper';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\n\nimport styles from './partial-video-list.scss';\n\ninterface PartialVideoListProps {\n withReordering?: boolean;\n numVideos?: number;\n allowBulkActions?: boolean;\n}\n\nPartialVideoList.defaultProps = {\n numVideos: 15\n};\n\nexport function PartialVideoList(props: PartialVideoListProps): JSX.Element {\n return (\n <div className='mx-2'>\n {Array(props.numVideos).fill(null).map((_, i) => (\n <div className='d-flex' key={i}>\n {props.allowBulkActions && <div className='form-check pe-3 pe-sm-2 mx-0 mx-md-2' />}\n <PartialVideoItem {...props} />\n </div>\n ))}\n </div>\n );\n}\n\nexport function PartialVideoItem(props: PartialVideoListProps): JSX.Element {\n const breakpoints = useBreakpoints();\n\n const size = VideoListHelper.getSize(breakpoints, 'md');\n const isSmall = size === 'sm';\n\n const withDragHandle = props.withReordering && !breakpoints.xs;\n\n return (\n <Row className={`${isSmall ? '' : 'py-2'} flex-grow-1`}>\n <Col {...VideoListHelper.getThumbnailColumns()} className={`flex-column align-items-flex-start ${isSmall ? `pb-2 pe-1` : 'mb-1 pe-3 pe-md-2'}`}>\n <Row>\n {!!withDragHandle && (\n <div className='d-flex align-items-center justify-content-center col-2'>\n <div className={`partial-loading-background ${styles.partialDragHandle}`} />\n </div>\n )}\n <Col xs={VideoListHelper.getThumbnailColSize(withDragHandle)}>\n <div className={`partial-loading-background ${isSmall ? 'rounded' : 'rounded-3'} ${styles.partialThumbnail}`} />\n </Col>\n </Row>\n </Col>\n <Col {...VideoListHelper.getDetailsColumns()} className={isSmall ? 'pb-2' : 'px-2'}>\n <div className={`partial-loading-background mb-1 ${styles.partialName}`} />\n <div className={`partial-loading-background ${styles.partialDescription}`} />\n </Col>\n </Row>\n );\n}\n\n","const DEFAULT_PARTIAL_LOADING_OPTIONS: PartialLoadingOptions = {\n numItems: 5,\n minWidth: 50, // px\n maxWidth: 100 // px\n};\n\nexport interface PartialLoadingOptions {\n numItems?: number;\n minWidth?: number;\n maxWidth?: number;\n}\n\ninterface PartialLoadingItem {\n width: string;\n}\n\nexport const PartialLoadingHelper = {\n getPartialLoadingItems(options: PartialLoadingOptions = {}): PartialLoadingItem[] {\n const opts = {\n ...DEFAULT_PARTIAL_LOADING_OPTIONS,\n ...options\n };\n\n const getRandomFilterWidth = () => Math.max(Math.floor(Math.random() * opts.maxWidth), opts.minWidth);\n\n return [...Array(opts.numItems)].map(() => ({ width: `${getRandomFilterWidth()}px` }));\n }\n};","import { Flight } from 'libs/common/react/index';\n\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { PresentationAudience } from 'libs/shared/interfaces';\n\nimport { usePresentation } from 'shared/hooks/usePresentation';\n\nexport const usePresentationAudiences = () => {\n const { activePresentation, getFallbackPresentation } = usePresentation({ redirectOnError: true });\n\n const presentation = activePresentation || getFallbackPresentation();\n\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n !!presentation &&\n AudienceRequests.presentationAudiences(presentation.id)\n );\n\n return audiences;\n};","import { Flight } from 'libs/common/react/index';\n\nimport { LocalPermissionName, PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { Config } from 'libs/shared/interfaces/models/Config';\n\nimport { LiteRouteHelper } from 'shared/utils/LiteRouteHelper';\n\nexport interface VideoFeaturesHash {\n canViewGlance: boolean;\n canViewResources: boolean;\n canViewInteractives: boolean;\n canViewClips: boolean;\n canUseActions: boolean;\n canViewPublicLayout: boolean;\n canNavigate: boolean;\n canViewCurriculumLinks: boolean;\n canViewResourceItems: boolean;\n canWatchPublicly: (videoId: string) => boolean;\n}\n\nexport function useVideoFeatureAccess() {\n const { hasPermissions, hasLocalPermissions } = usePermissions();\n const { hasProduct } = useProducts();\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n\n const hasNP = hasProduct(ProductId.Primary);\n\n function showPublicLayout(): boolean {\n /**\n * Authenticated users should never see the placeholder\n */\n if (hasLocalPermissions(LocalPermissionName.WatchVideos))\n return false;\n\n /**\n * Accessing a play page unathenticated will have different contextual behabviours:\n * - For a share page, the user should see the video and never the placeholder\n * - For a public browsing page (ie. using a route-prefix) they should see the placeholder\n */\n return LiteRouteHelper.hasRegionPrefix();\n }\n\n /**\n * Publicly available video ids are maintained on the backend config. \n */\n function canWatchPublicly(videoId: string): boolean {\n if (!videoId)\n return false;\n\n return !!config.data?.allowedPublicVideos?.[videoId];\n }\n\n return {\n canWatchPublicly,\n canViewGlance: hasPermissions(PermissionName.ViewVideoGlance),\n canViewResources: true,\n canViewInteractives: hasNP && hasPermissions(PermissionName.ViewVideoInteractives),\n canViewClips: hasNP && hasPermissions(PermissionName.ViewVideoClips),\n canViewCurriculumLinks: hasPermissions(PermissionName.ViewCurriculums),\n canUseActions: hasLocalPermissions(LocalPermissionName.UseVideoActions),\n canViewPublicLayout: showPublicLayout(),\n canViewResourceItems: hasLocalPermissions(LocalPermissionName.ViewVideoResourceItems),\n canNavigate: hasNP\n };\n}","// extracted by mini-css-extract-plugin\nexport default {\"partialHeading\":\"okxfx\"};","import React from 'react';\n\nimport { PartialBreadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { PartialVideoList } from 'libs/shared/components/video-list/partial-loading/PartialVideoList';\n\nimport styles from './partial-video-media-view.scss';\n\nexport function PartialVideoMediaView(): JSX.Element {\n return (\n <div className='px-3'>\n <div className={`partial-loading-background mb-2 ${styles.partialHeading}`} />\n <div className='mb-2'>\n <PartialBreadcrumbs/>\n </div>\n <PartialVideoList />\n </div>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { Breadcrumb, Breadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { VideoList } from 'libs/shared/components/video-list/VideoList';\nimport { VideoActionsContext } from 'libs/shared/context/VideoActionsContext';\nimport { RelatedVideosContext } from 'libs/shared/enums/RelatedVideosContext';\nimport { ClipRequests } from 'libs/shared/flight-requests/ClipRequests';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { CustomerRequests } from 'libs/shared/flight-requests/CustomerRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { VideoRequests } from 'libs/shared/flight-requests/VideoRequests';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { Config, CurrentUser, Video, YearGroup } from 'libs/shared/interfaces';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\nimport { useVideoActions, VideoActionsLocation } from 'shared/hooks/use-video-actions/useVideoActions';\nimport { useLiteFavourites } from 'shared/hooks/useLiteFavourites';\nimport { usePresentationAudiences } from 'shared/hooks/usePresentationAudiences';\nimport { useVideoFeatureAccess } from 'shared/hooks/useVideoFeatureAccess';\nimport { InteractiveHelpers } from 'shared/utils/InteractiveHelper';\nimport { VideoAppLinkHelper } from 'shared/utils/VideoAppLinkHelper';\n\nimport { SeriesAppLinkHelper } from 'apps/series/SeriesAppLinkHelper';\n\nimport { PartialVideoMediaView } from './partial-loading/PartialVideoMediaView';\n\nconst namespace = 'shared.videoMedia';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface VideoMediaViewQueryParams {\n parentType?: 'clip' | 'video';\n}\ninterface VideoMediaViewProps extends VideoMediaViewQueryParams {\n videoId: string;\n isClip?: boolean;\n}\n\nexport function VideoMediaView(props: VideoMediaViewProps): JSX.Element {\n const { videoId, parentType = 'video' } = props;\n const { setFavourite, canFavourite } = useLiteFavourites(LocationContext.VideoThumbnail);\n \n const videoActions = useVideoActions({ location: VideoActionsLocation.VideoItem });\n const featureAccess = useVideoFeatureAccess();\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const yearGroups = Flight.useBasicFetch<YearGroup[]>(\n currentUser.data.isAuthenticated && CustomerRequests.yearGroups(currentUser.data.customerId)\n );\n\n function getRequest() {\n switch (parentType) {\n case 'video':\n return VideoRequests.video;\n case 'clip':\n return ClipRequests.clip;\n }\n }\n const parentRequest = getRequest();\n\n const video = Flight.useBasicFetch<Video>(\n currentUser.data?.id &&\n parentRequest(videoId, null, currentUser.data.id)\n );\n const content = video.data?.[props.isClip ? 'clips' : 'interactives']?.data;\n const count = content?.length || 0;\n\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n\n const title = `${getPhrase(props.isClip ? 'clipHeading' : 'interactivesHeading')} (${count || ''})`;\n\n const audiences = usePresentationAudiences();\n const { hasPermissions } = usePermissions();\n\n const breadcrumbs: Breadcrumb[] = [{\n name: video.data?.name,\n appLink: {\n application: AppChannels.VIDEOS,\n action: Actions.Videos.PLAY_VIDEO,\n args: [ videoId, TextHelper.slugify(video.data?.name) ]\n }\n }, {\n name: title,\n appLink: {\n application: AppChannels.VIDEOS,\n action: props.isClip ? Actions.Videos.VIDEO_CLIPS : Actions.Videos.VIDEO_INTERACTIVES,\n args: [videoId]\n },\n active: true\n }];\n\n function redirectToPlaypage(): void {\n Core.AppLinkHelper.trigger({\n application: AppChannels.VIDEOS,\n action: Actions.Videos.PLAY_VIDEO,\n args: [ videoId, TextHelper.slugify(video.data?.name) ]\n }, { replace: true });\n }\n\n React.useEffect(() => {\n if (!featureAccess.canViewInteractives) {\n redirectToPlaypage();\n }\n }, [featureAccess.canViewInteractives]);\n\n if (!video.data || !content?.length || !config.hasCompleted)\n return <PartialVideoMediaView />;\n\n return (\n <VideoActionsContext.Provider value={videoActions}>\n <div className='px-3'>\n <h1 className='h2 mb-2'>{title}</h1>\n \n <div className='mb-2'>\n <Breadcrumbs breadcrumbs={breadcrumbs}/>\n </div>\n\n <VideoList\n videos={content.map(c => ({ ...c, subjectPresentationAudiences: video.data?.subjectPresentationAudiences }))}\n yearGroups={yearGroups.data}\n getVideoAppLink={(video, opts) => VideoAppLinkHelper.getAppLink(video, {\n ...opts,\n context: RelatedVideosContext.Widget,\n contextId: props.videoId\n })}\n hasPermissions={hasPermissions}\n getSubTextAppLink={video => SeriesAppLinkHelper.getSeriesAppLink(video.series)}\n setFavourite={setFavourite}\n canFavourite={canFavourite}\n presentationAudiences={audiences.data}\n getPreviewQuestionsAppLink={!props.isClip ?\n interactive => InteractiveHelpers.getPreviewQuestionsAppLink(interactive) : null}\n imageCdnUrl={config.data?.imageCdnUrl}\n />\n </div>\n </VideoActionsContext.Provider>\n );\n}","\"use client\";\n\nimport classNames from 'classnames';\nimport * as React from 'react';\nimport { useBootstrapPrefix, useBootstrapBreakpoints, useBootstrapMinBreakpoint } from './ThemeProvider';\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst Row = /*#__PURE__*/React.forwardRef(({\n bsPrefix,\n className,\n // Need to define the default \"as\" during prop destructuring to be compatible with styled-components github.com/react-bootstrap/react-bootstrap/issues/3595\n as: Component = 'div',\n ...props\n}, ref) => {\n const decoratedBsPrefix = useBootstrapPrefix(bsPrefix, 'row');\n const breakpoints = useBootstrapBreakpoints();\n const minBreakpoint = useBootstrapMinBreakpoint();\n const sizePrefix = `${decoratedBsPrefix}-cols`;\n const classes = [];\n breakpoints.forEach(brkPoint => {\n const propValue = props[brkPoint];\n delete props[brkPoint];\n let cols;\n if (propValue != null && typeof propValue === 'object') {\n ({\n cols\n } = propValue);\n } else {\n cols = propValue;\n }\n const infix = brkPoint !== minBreakpoint ? `-${brkPoint}` : '';\n if (cols != null) classes.push(`${sizePrefix}${infix}-${cols}`);\n });\n return /*#__PURE__*/_jsx(Component, {\n ref: ref,\n ...props,\n className: classNames(className, decoratedBsPrefix, ...classes)\n });\n});\nRow.displayName = 'Row';\nexport default Row;"],"names":["BreadcrumbItem","breadcrumb","name","appLink","active","withBackIcon","className","svgName","size","S","Breadcrumbs","breadcrumbs","isMobile","length","map","b","idx","key","PartialBreadcrumbs","numItems","style","height","width","dangerouslySetInnerHTML","__html","PartialVideoList","props","Array","numVideos","fill","_","i","allowBulkActions","PartialVideoItem","breakpoints","useBreakpoints","isSmall","VideoListHelper","withDragHandle","withReordering","xs","Row","Col","defaultProps","DEFAULT_PARTIAL_LOADING_OPTIONS","minWidth","maxWidth","PartialLoadingHelper","getPartialLoadingItems","options","opts","Math","max","floor","random","usePresentationAudiences","redirectOnError","activePresentation","getFallbackPresentation","presentation","id","useVideoFeatureAccess","hasPermissions","hasLocalPermissions","hasProduct","config","hasNP","canWatchPublicly","videoId","data","allowedPublicVideos","canViewGlance","canViewResources","canViewInteractives","canViewClips","canViewCurriculumLinks","canUseActions","canViewPublicLayout","canViewResourceItems","canNavigate","PartialVideoMediaView","getPhrase","LanguageService","VideoMediaView","parentType","useLiteFavourites","u","setFavourite","canFavourite","videoActions","useVideoActions","location","featureAccess","currentUser","UserRequests","yearGroups","isAuthenticated","CustomerRequests","customerId","parentRequest","VideoRequests","ClipRequests","getRequest","video","content","isClip","count","ConfigRequests","title","audiences","usePermissions","application","action","args","TextHelper","replace","redirectToPlaypage","hasCompleted","VideoActionsContext","value","VideoList","videos","c","subjectPresentationAudiences","getVideoAppLink","VideoAppLinkHelper","context","RelatedVideosContext","contextId","getSubTextAppLink","SeriesAppLinkHelper","series","presentationAudiences","getPreviewQuestionsAppLink","interactive","InteractiveHelper","imageCdnUrl","bsPrefix","as","Component","ref","decoratedBsPrefix","minBreakpoint","sizePrefix","classes","forEach","brkPoint","propValue","cols","infix","push","displayName"],"sourceRoot":""}