@maestro_io/maestro-web-sdk 3.3.1 → 4.0.0-beta.2

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 (269) hide show
  1. package/dist/f8820fca3a2a7957f753167da0884f9d.png +0 -0
  2. package/dist/maestro-web-sdk.esm.js +12 -12
  3. package/dist/maestro-web-sdk.esm.js.map +1 -1
  4. package/dist/maestro-web-sdk.umd.js +12 -12
  5. package/dist/maestro-web-sdk.umd.js.map +1 -1
  6. package/dist/package.json +87 -0
  7. package/dist/src/__mocks__/sentry.d.ts +4 -0
  8. package/dist/src/components/atoms/BaseButton/BaseButton.js +11 -0
  9. package/dist/src/components/atoms/BaseButton/index.js +2 -0
  10. package/dist/src/components/atoms/Image/index.js +34 -0
  11. package/dist/src/components/atoms/Rive/index.js +53 -0
  12. package/dist/src/components/atoms/SvgIcon/BetGeneralIcon.js +9 -0
  13. package/dist/src/components/atoms/SvgIcon/BetsIcon.js +11 -0
  14. package/dist/src/components/atoms/SvgIcon/BetsWarningIcon.js +11 -0
  15. package/dist/src/components/atoms/SvgIcon/CheckmarkIcon.js +6 -0
  16. package/dist/src/components/atoms/SvgIcon/CollapseIcon.js +6 -0
  17. package/dist/src/components/atoms/SvgIcon/ExpandIcon.js +6 -0
  18. package/dist/src/components/atoms/SvgIcon/FantasyIcon.js +15 -0
  19. package/dist/src/components/atoms/SvgIcon/FlameIcon.js +11 -0
  20. package/dist/src/components/atoms/SvgIcon/Icon.js +44 -0
  21. package/dist/src/components/atoms/SvgIcon/KeyPlaysIcon.js +10 -0
  22. package/dist/src/components/atoms/SvgIcon/MobilePhoneIcon.js +11 -0
  23. package/dist/src/components/atoms/SvgIcon/PlayIcon.js +8 -0
  24. package/dist/src/components/atoms/SvgIcon/ShopIcon.js +7 -0
  25. package/dist/src/components/atoms/SvgIcon/StatsIcon.js +12 -0
  26. package/dist/src/components/atoms/SvgIcon/TimesIcon.js +6 -0
  27. package/dist/src/components/atoms/SvgIcon/WarningIcon.js +8 -0
  28. package/dist/src/components/atoms/SvgIcon/index.js +2 -0
  29. package/dist/src/components/core/App/App.js +35 -0
  30. package/dist/src/components/core/App/index.js +2 -0
  31. package/dist/src/components/core/OverlayContainer.js +58 -0
  32. package/dist/src/components/core/PanelManager/PanelManager.js +86 -0
  33. package/dist/src/components/core/PanelManager/index.js +2 -0
  34. package/dist/src/components/core/ScrollableContainer/FocusableItem.js +38 -0
  35. package/dist/src/components/core/ScrollableContainer/ScrollableContainer.js +168 -0
  36. package/dist/src/components/core/ScrollableContainer/index.js +2 -0
  37. package/dist/src/components/molecules/ActionButton/ActionButton.js +10 -0
  38. package/dist/src/components/molecules/ActionButton/index.js +2 -0
  39. package/dist/src/components/molecules/HeadshotImage/HeadshotImage.js +50 -0
  40. package/dist/src/components/molecules/HeadshotImage/index.js +2 -0
  41. package/dist/src/components/molecules/Overlay/Overlay.js +139 -0
  42. package/dist/src/components/molecules/Overlay/index.js +2 -0
  43. package/dist/src/components/molecules/PanelNavButton/PanelNavButton.js +27 -0
  44. package/dist/src/components/molecules/PanelNavButton/index.js +2 -0
  45. package/dist/src/components/molecules/SegmentButton/SegmentButton.js +10 -0
  46. package/dist/src/components/molecules/SegmentButton/index.js +2 -0
  47. package/dist/src/components/molecules/TabLoadError/TabLoadError.js +14 -0
  48. package/dist/src/components/molecules/TabLoadError/index.js +2 -0
  49. package/dist/src/components/molecules/WatchButton/WatchButton.js +15 -0
  50. package/dist/src/components/molecules/WatchButton/index.js +2 -0
  51. package/dist/src/components/organisms/PanelNavigation/PanelNavigation.js +60 -0
  52. package/dist/src/components/organisms/PanelNavigation/index.js +2 -0
  53. package/dist/src/components/organisms/SegmentController/SegmentController.js +76 -0
  54. package/dist/src/components/organisms/SegmentController/index.js +2 -0
  55. package/dist/src/development/MaestroEventDelegate.js +109 -0
  56. package/dist/src/development/TimeSeek.js +218 -0
  57. package/dist/src/development/development.js +33 -0
  58. package/dist/src/external/AxiosNetworkClient.js +110 -0
  59. package/dist/src/external/LocalStorageCacheManager.js +213 -0
  60. package/dist/src/external/ReactRenderer.js +53 -0
  61. package/dist/src/external/mocks/MockExternalNetworkClient.js +187 -0
  62. package/dist/src/external/ports/cacheManager.js +1 -0
  63. package/dist/src/external/ports/networkClient.js +1 -0
  64. package/dist/src/external/ports/renderer.d.ts +1 -2
  65. package/dist/src/external/ports/renderer.js +1 -0
  66. package/dist/src/external/spatial-navigation/__mocks__/withFocusable.d.ts +8 -0
  67. package/dist/src/external/spatial-navigation/__mocks__/withFocusable.js +7 -0
  68. package/dist/src/external/spatial-navigation/index.js +3 -0
  69. package/dist/src/external/spatial-navigation/measureLayout.js +30 -0
  70. package/dist/src/external/spatial-navigation/spatialNavigation.js +876 -0
  71. package/dist/src/external/spatial-navigation/utils.js +6 -0
  72. package/dist/src/external/spatial-navigation/visualDebugger.js +76 -0
  73. package/dist/src/external/spatial-navigation/withFocusable.js +245 -0
  74. package/dist/src/helpers/Observable.js +37 -0
  75. package/dist/src/helpers/strings.js +14 -0
  76. package/dist/src/helpers/url.js +12 -0
  77. package/dist/src/index.d.ts +5 -5
  78. package/dist/src/index.js +165 -0
  79. package/dist/src/interfaces/IMaestroEvent.d.ts +12 -0
  80. package/dist/src/interfaces/IMaestroEvent.js +18 -0
  81. package/dist/src/interfaces/IMaestroEventDelegate.js +1 -0
  82. package/dist/src/interfaces/IMaestroManager.js +1 -0
  83. package/dist/src/interfaces/IUserSettings.js +20 -0
  84. package/dist/src/models/IModel.js +1 -0
  85. package/dist/src/models/IPanel.js +40 -0
  86. package/dist/src/models/ITheme.js +20 -0
  87. package/dist/src/models/IWinningBet.js +1 -0
  88. package/dist/src/modules/bets/interfaces/IBets.js +1 -0
  89. package/dist/src/modules/bets/mocks.js +573 -0
  90. package/dist/src/modules/bets/types/BetsAnalyticsTypes.js +1 -0
  91. package/dist/src/modules/bets/view/BetsView.js +143 -0
  92. package/dist/src/modules/bets/view/HotProps/HotPropsView.js +150 -0
  93. package/dist/src/modules/bets/view/SixPack/SixPackView.js +110 -0
  94. package/dist/src/modules/bets/view/UserBets/BetResult/BetResult.js +6 -0
  95. package/dist/src/modules/bets/view/UserBets/BetsCard/BetsCard.js +149 -0
  96. package/dist/src/modules/bets/view/UserBets/BetsCard/BetsCardEvent.js +34 -0
  97. package/dist/src/modules/bets/view/UserBets/BetsCard/BetsCardFooter.js +18 -0
  98. package/dist/src/modules/bets/view/UserBets/Boost/Boost.js +6 -0
  99. package/dist/src/modules/bets/view/UserBets/OutcomeBadge/OutcomeBadge.js +9 -0
  100. package/dist/src/modules/bets/view/UserBets/Parlay/Parlay.js +13 -0
  101. package/dist/src/modules/bets/view/UserBets/Straight/Straight.js +6 -0
  102. package/dist/src/modules/bets/view/UserBets/Teaser/Teaser.js +13 -0
  103. package/dist/src/modules/bets/view/UserBets/UserBetsView.js +107 -0
  104. package/dist/src/modules/bets/view/components/Bet/Bet.js +32 -0
  105. package/dist/src/modules/bets/view/components/BetPill/BetPill.js +6 -0
  106. package/dist/src/modules/bets/view/components/BetsCard/BetsCard.js +15 -0
  107. package/dist/src/modules/bets/view/components/BetsCard/BetsCardHeader.js +20 -0
  108. package/dist/src/modules/bets/view/components/GamblingDisclaimer/GamblingDisclaimer.js +14 -0
  109. package/dist/src/modules/bets/view/components/LocationWarning/LocationWarning.js +16 -0
  110. package/dist/src/modules/bets/view/components/PromoCodeBanner/PromoCodeBanner.js +78 -0
  111. package/dist/src/modules/bets/view/components/PromoCodeBanner/index.js +1 -0
  112. package/dist/src/modules/bets/view-model/BetsViewModel.js +974 -0
  113. package/dist/src/modules/fantasy/components/ExpandedAthleteList/ExpandedAthletesList.js +107 -0
  114. package/dist/src/modules/fantasy/components/ExpandedAthleteList/index.js +1 -0
  115. package/dist/src/modules/fantasy/components/LeagueCard/LeagueCard.js +20 -0
  116. package/dist/src/modules/fantasy/components/LeagueCard/index.js +2 -0
  117. package/dist/src/modules/fantasy/components/TopPlayerCard/TopPlayerCard.js +29 -0
  118. package/dist/src/modules/fantasy/components/TopPlayerCard/index.js +2 -0
  119. package/dist/src/modules/fantasy/mocks.js +3682 -0
  120. package/dist/src/modules/fantasy/types.js +6 -0
  121. package/dist/src/modules/fantasy/view/ActiveAthletesMarquee/ActiveAthletesMarquee.js +74 -0
  122. package/dist/src/modules/fantasy/view/ActiveAthletesMarquee/index.js +2 -0
  123. package/dist/src/modules/fantasy/view/ErrorBoundary.d.ts +13 -0
  124. package/dist/src/modules/fantasy/view/FantasyItemView.js +74 -0
  125. package/dist/src/modules/fantasy/view/FantasyView.js +133 -0
  126. package/dist/src/modules/fantasy/view/InactiveLeague/DraftDateCountdown.js +95 -0
  127. package/dist/src/modules/fantasy/view/InactiveLeague/InactiveLeague.js +13 -0
  128. package/dist/src/modules/fantasy/view/InactiveLeague/index.js +2 -0
  129. package/dist/src/modules/fantasy/view/LoginView/LoginView.js +27 -0
  130. package/dist/src/modules/fantasy/view/LoginView/index.js +2 -0
  131. package/dist/src/modules/fantasy/view/MatchupPair/DoubleAthleteCard/DoubleAthleteCard.js +25 -0
  132. package/dist/src/modules/fantasy/view/MatchupPair/DoubleAthleteCard/index.js +2 -0
  133. package/dist/src/modules/fantasy/view/MatchupPair/ExpandedDoubleAthleteCards.js +9 -0
  134. package/dist/src/modules/fantasy/view/MatchupPair/MatchupPair.js +118 -0
  135. package/dist/src/modules/fantasy/view/MatchupPair/index.js +2 -0
  136. package/dist/src/modules/fantasy/view/MatchupSingle/ExpandedSingleAthleteCards.js +9 -0
  137. package/dist/src/modules/fantasy/view/MatchupSingle/MatchupSingle.js +108 -0
  138. package/dist/src/modules/fantasy/view/MatchupSingle/SingleAthleteCard/SingleAthleteCard.js +18 -0
  139. package/dist/src/modules/fantasy/view/MatchupSingle/SingleAthleteCard/index.js +2 -0
  140. package/dist/src/modules/fantasy/view/MatchupSingle/index.js +2 -0
  141. package/dist/src/modules/fantasy/view/PromoView/PromoView.js +12 -0
  142. package/dist/src/modules/fantasy/view/PromoView/index.js +2 -0
  143. package/dist/src/modules/fantasy/view/index.js +2 -0
  144. package/dist/src/modules/fantasy/view-model/FantasyViewModel.FantasyPolling.js +132 -0
  145. package/dist/src/modules/fantasy/view-model/FantasyViewModel.LeagueManagerPolling.js +141 -0
  146. package/dist/src/modules/fantasy/view-model/FantasyViewModel.js +534 -0
  147. package/dist/src/modules/key-plays/constants.js +292 -0
  148. package/dist/src/modules/key-plays/interfaces/IKeyPlays.js +14 -0
  149. package/dist/src/modules/key-plays/interfaces/IKeyPlaysResponse.js +1 -0
  150. package/dist/src/modules/key-plays/view/KeyPlayCardScoreTagView.js +16 -0
  151. package/dist/src/modules/key-plays/view/KeyPlayCardView.js +144 -0
  152. package/dist/src/modules/key-plays/view/KeyPlayErrorStateView.js +65 -0
  153. package/dist/src/modules/key-plays/view/KeyPlaysView.js +151 -0
  154. package/dist/src/modules/key-plays/view-model/KeyPlaysViewModel.js +246 -0
  155. package/dist/src/modules/shop/mocks.js +390 -0
  156. package/dist/src/modules/shop/types.js +7 -0
  157. package/dist/src/modules/shop/view/ProductDetailView/ProductDetailView.js +56 -0
  158. package/dist/src/modules/shop/view/ProductDetailView/index.js +2 -0
  159. package/dist/src/modules/shop/view/ShopView.js +182 -0
  160. package/dist/src/modules/shop/view/components/BrowseCard/BrowseCard.js +23 -0
  161. package/dist/src/modules/shop/view/components/BrowseCard/index.js +2 -0
  162. package/dist/src/modules/shop/view/components/ProductSummaryCard/ProductSummaryCard.js +26 -0
  163. package/dist/src/modules/shop/view/components/ProductSummaryCard/index.js +1 -0
  164. package/dist/src/modules/shop/view/components/ShopPromoView/ShopPromoView.js +19 -0
  165. package/dist/src/modules/shop/view/components/ShopPromoView/index.js +1 -0
  166. package/dist/src/modules/shop/view/components/ShopSection/ShopSection.d.ts +1 -0
  167. package/dist/src/modules/shop/view/components/ShopSection/ShopSection.js +61 -0
  168. package/dist/src/modules/shop/view/components/ShopSection/ShopSectionItem.d.ts +18 -0
  169. package/dist/src/modules/shop/view/components/ShopSection/ShopSectionItem.js +22 -0
  170. package/dist/src/modules/shop/view/components/ShopSection/index.js +1 -0
  171. package/dist/src/modules/shop/view/index.js +2 -0
  172. package/dist/src/modules/shop/view-model/ShopViewModel.ShopPolling.js +111 -0
  173. package/dist/src/modules/shop/view-model/ShopViewModel.js +353 -0
  174. package/dist/src/modules/stats/interfaces/IStats.js +1 -0
  175. package/dist/src/modules/stats/mocks.js +746 -0
  176. package/dist/src/modules/stats/utils/driveSummaryUtils.js +48 -0
  177. package/dist/src/modules/stats/utils/renderTeamStatistic.js +16 -0
  178. package/dist/src/modules/stats/utils.js +62 -0
  179. package/dist/src/modules/stats/view/ActiveAthletes/ActiveAthletes.js +98 -0
  180. package/dist/src/modules/stats/view/ActiveAthletes/CollapsedAthletes/CollapsedAthletes.js +27 -0
  181. package/dist/src/modules/stats/view/ActiveAthletes/ExpandedAthletes/ExpandedAthletes.js +89 -0
  182. package/dist/src/modules/stats/view/ActiveAthletes/index.js +2 -0
  183. package/dist/src/modules/stats/view/DriveSummary/DrivePlayCard.js +70 -0
  184. package/dist/src/modules/stats/view/DriveSummary/DriveSummary.js +87 -0
  185. package/dist/src/modules/stats/view/DriveSummary/ExpandedItems/DriveSummaryExpanded.js +129 -0
  186. package/dist/src/modules/stats/view/DriveSummary/Header/DriveSummaryHeader.js +26 -0
  187. package/dist/src/modules/stats/view/DriveSummary/MainStat/MainStat.js +24 -0
  188. package/dist/src/modules/stats/view/DriveSummary/index.js +2 -0
  189. package/dist/src/modules/stats/view/GameLeaders/GameLeaders.js +48 -0
  190. package/dist/src/modules/stats/view/GameLeaders/index.js +2 -0
  191. package/dist/src/modules/stats/view/MatchPredictor/DonutChart/DonutChart.js +55 -0
  192. package/dist/src/modules/stats/view/MatchPredictor/DonutChart/index.js +1 -0
  193. package/dist/src/modules/stats/view/MatchPredictor/MatchPredictorView.js +60 -0
  194. package/dist/src/modules/stats/view/MatchPredictor/index.js +2 -0
  195. package/dist/src/modules/stats/view/Penalties/Penalties.js +6 -0
  196. package/dist/src/modules/stats/view/Penalties/index.js +2 -0
  197. package/dist/src/modules/stats/view/RecentGames/RecentGames.js +23 -0
  198. package/dist/src/modules/stats/view/RecentGames/index.js +2 -0
  199. package/dist/src/modules/stats/view/ScoringSummary/ExpandedScores/ExpandedScores.js +121 -0
  200. package/dist/src/modules/stats/view/ScoringSummary/ExpandedScores/index.js +2 -0
  201. package/dist/src/modules/stats/view/ScoringSummary/ScoreItem/ScoreItem.js +62 -0
  202. package/dist/src/modules/stats/view/ScoringSummary/ScoreItem/index.js +2 -0
  203. package/dist/src/modules/stats/view/ScoringSummary/ScoresSection/ScoresSection.js +23 -0
  204. package/dist/src/modules/stats/view/ScoringSummary/ScoresSection/index.js +2 -0
  205. package/dist/src/modules/stats/view/ScoringSummary/ScoringSummary.js +106 -0
  206. package/dist/src/modules/stats/view/ScoringSummary/index.js +2 -0
  207. package/dist/src/modules/stats/view/StatsItemView.js +92 -0
  208. package/dist/src/modules/stats/view/StatsQRCode/StatsQRCodeView.js +36 -0
  209. package/dist/src/modules/stats/view/StatsQRCode/index.js +1 -0
  210. package/dist/src/modules/stats/view/StatsView.js +137 -0
  211. package/dist/src/modules/stats/view/TeamStats/TeamStatsView.js +43 -0
  212. package/dist/src/modules/stats/view/TeamStats/index.js +1 -0
  213. package/dist/src/modules/stats/view/Teams/StatsCarousel.js +83 -0
  214. package/dist/src/modules/stats/view/Teams/StatsProgressBar.js +19 -0
  215. package/dist/src/modules/stats/view/Teams/Teams.js +27 -0
  216. package/dist/src/modules/stats/view/Teams/index.js +2 -0
  217. package/dist/src/modules/stats/view/WinProbability/WinProbability.js +28 -0
  218. package/dist/src/modules/stats/view/WinProbability/index.js +2 -0
  219. package/dist/src/modules/stats/view/components/AthletesStatistics/AthletesStatistics.js +89 -0
  220. package/dist/src/modules/stats/view/components/AthletesStatistics/StatisticTable.js +12 -0
  221. package/dist/src/modules/stats/view/components/AthletesStatistics/index.js +2 -0
  222. package/dist/src/modules/stats/view/index.js +2 -0
  223. package/dist/src/modules/stats/view-model/StatsViewModel.d.ts +5 -0
  224. package/dist/src/modules/stats/view-model/StatsViewModel.js +989 -0
  225. package/dist/src/sentry.js +31 -0
  226. package/dist/src/services/AnalyticsService/AnalyticsService.d.ts +12 -7
  227. package/dist/src/services/AnalyticsService/AnalyticsService.js +402 -0
  228. package/dist/src/services/AnalyticsService/types.js +1 -0
  229. package/dist/src/services/BetsService.js +122 -0
  230. package/dist/src/services/FantasyService.js +92 -0
  231. package/dist/src/services/GlobalService/GlobalService.d.ts +9 -0
  232. package/dist/src/services/GlobalService/PageService.d.ts +9 -0
  233. package/dist/src/services/GlobalService/index.d.ts +2 -0
  234. package/dist/src/services/GlobalService/mocks.d.ts +2 -0
  235. package/dist/src/services/GlobalService/types.d.ts +11 -0
  236. package/dist/src/services/InsightsService/InsightsPayloadBuilder.d.ts +1 -2
  237. package/dist/src/services/InsightsService/InsightsPayloadBuilder.js +386 -0
  238. package/dist/src/services/InsightsService/InsightsService.js +74 -0
  239. package/dist/src/services/NetworkManager/NetworkManager.js +457 -0
  240. package/dist/src/services/NetworkManager/NetworkManagerFactory.js +101 -0
  241. package/dist/src/services/NetworkManager/errors.js +45 -0
  242. package/dist/src/services/NetworkManager/types.js +10 -0
  243. package/dist/src/services/PageService/PageService.d.ts +9 -0
  244. package/dist/src/services/PageService/PageService.js +39 -0
  245. package/dist/src/services/PageService/index.d.ts +2 -0
  246. package/dist/src/services/PageService/index.js +2 -0
  247. package/dist/src/services/PageService/mocks.d.ts +2 -0
  248. package/dist/src/services/PageService/mocks.js +104 -0
  249. package/dist/src/services/PageService/types.d.ts +76 -0
  250. package/dist/src/services/PageService/types.js +1 -0
  251. package/dist/src/services/ShopService.js +46 -0
  252. package/dist/src/services/StaticService/PageService.d.ts +9 -0
  253. package/dist/src/services/StaticService/StaticService.d.ts +3 -1
  254. package/dist/src/services/StaticService/StaticService.js +59 -0
  255. package/dist/src/services/StaticService/index.js +2 -0
  256. package/dist/src/services/StaticService/mocks.js +104 -0
  257. package/dist/src/services/StaticService/types.js +1 -0
  258. package/dist/src/services/StatsService.d.ts +1 -0
  259. package/dist/src/services/StatsService.js +147 -0
  260. package/dist/src/services/ThemeManager/constants.js +47 -0
  261. package/dist/src/services/UserSettingsManager.js +155 -0
  262. package/dist/src/test-polyfills.js +15 -0
  263. package/dist/src/types/OverlayTypes.js +4 -0
  264. package/dist/src/view-models/MaestroEventViewModel.d.ts +1 -2
  265. package/dist/src/view-models/MaestroEventViewModel.js +307 -0
  266. package/dist/src/view-models/OverlayViewModel.js +222 -0
  267. package/dist/src/view-models/PanelManagerViewModel.js +212 -0
  268. package/dist/src/view-models/ViewModel.js +32 -0
  269. package/package.json +1 -1
@@ -0,0 +1,6 @@
1
+ export const DIRECTION_LEFT = 'left';
2
+ export const DIRECTION_RIGHT = 'right';
3
+ export const DIRECTION_UP = 'up';
4
+ export const DIRECTION_DOWN = 'down';
5
+ export const KEY_ENTER = 'enter';
6
+ export const KEY_BACK = 'back';
@@ -0,0 +1,76 @@
1
+ // We'll make VisualDebugger no-op for any environments lacking a DOM (e.g. SSR and React Native non-web platforms).
2
+ const hasDOM = typeof window !== 'undefined' && window.document;
3
+ const WIDTH = hasDOM ? window.innerWidth : 0;
4
+ const HEIGHT = hasDOM ? window.innerHeight : 0;
5
+ class VisualDebugger {
6
+ constructor() {
7
+ Object.defineProperty(this, "debugCtx", {
8
+ enumerable: true,
9
+ configurable: true,
10
+ writable: true,
11
+ value: void 0
12
+ });
13
+ Object.defineProperty(this, "layoutsCtx", {
14
+ enumerable: true,
15
+ configurable: true,
16
+ writable: true,
17
+ value: void 0
18
+ });
19
+ if (hasDOM) {
20
+ this.debugCtx = VisualDebugger.createCanvas('sn-debug', 1010);
21
+ this.layoutsCtx = VisualDebugger.createCanvas('sn-layouts', 1000);
22
+ }
23
+ else {
24
+ this.debugCtx = null;
25
+ this.layoutsCtx = null;
26
+ }
27
+ }
28
+ static createCanvas(id, zIndex) {
29
+ const canvas = (document.querySelector(`#${id}`) ||
30
+ document.createElement('canvas'));
31
+ canvas.setAttribute('id', id);
32
+ const ctx = canvas.getContext('2d');
33
+ if (!ctx) {
34
+ throw new Error('Could not get 2d context from canvas');
35
+ }
36
+ canvas.style.cssText = `position: fixed; top: 0; left: 0; z-index: ${zIndex}`;
37
+ document.body.appendChild(canvas);
38
+ canvas.width = WIDTH;
39
+ canvas.height = HEIGHT;
40
+ return ctx;
41
+ }
42
+ clear() {
43
+ if (!hasDOM || !this.debugCtx) {
44
+ return;
45
+ }
46
+ this.debugCtx.clearRect(0, 0, WIDTH, HEIGHT);
47
+ }
48
+ clearLayouts() {
49
+ if (!hasDOM || !this.layoutsCtx) {
50
+ return;
51
+ }
52
+ this.layoutsCtx.clearRect(0, 0, WIDTH, HEIGHT);
53
+ }
54
+ drawLayout(layout, focusKey, parentFocusKey) {
55
+ if (!hasDOM || !this.layoutsCtx) {
56
+ return;
57
+ }
58
+ this.layoutsCtx.strokeStyle = 'green';
59
+ this.layoutsCtx.strokeRect(layout.left, layout.top, layout.width, layout.height);
60
+ this.layoutsCtx.font = '8px monospace';
61
+ this.layoutsCtx.fillStyle = 'red';
62
+ this.layoutsCtx.fillText(focusKey, layout.left, layout.top + 10);
63
+ this.layoutsCtx.fillText(parentFocusKey, layout.left, layout.top + 25);
64
+ this.layoutsCtx.fillText(`left: ${layout.left}`, layout.left, layout.top + 40);
65
+ this.layoutsCtx.fillText(`top: ${layout.top}`, layout.left, layout.top + 55);
66
+ }
67
+ drawPoint(x, y, color = 'blue', size = 10) {
68
+ if (!hasDOM || !this.debugCtx) {
69
+ return;
70
+ }
71
+ this.debugCtx.strokeStyle = color;
72
+ this.debugCtx.lineWidth = 3;
73
+ this.debugCtx.strokeRect(x - size / 2, y - size / 2, size, size);
74
+ }
75
+ }
76
+ export default VisualDebugger;
@@ -0,0 +1,245 @@
1
+ /* eslint-disable react/no-find-dom-node */
2
+ import { findDOMNode } from 'react-dom';
3
+ import PropTypes from 'prop-types';
4
+ import { Component, createElement } from 'react';
5
+ import { ROOT_FOCUS_KEY } from './spatialNavigation';
6
+ import SDK from '@/index';
7
+ // Helper functions to replace lodash and recompose
8
+ const uniqueId = (prefix) => `${prefix}${Math.random().toString(36).substr(2, 9)}`;
9
+ const noop = () => { };
10
+ const omit = (obj, keys) => {
11
+ const result = { ...obj };
12
+ keys.forEach((key) => delete result[key]);
13
+ return result;
14
+ };
15
+ const withFocusable = ({ forgetLastFocusedChild: configForgetLastFocusedChild = false, trackChildren: configTrackChildren = false, autoRestoreFocus: configAutoRestoreFocus, blockNavigationOut: configBlockNavigationOut = false, } = {}) => {
16
+ return (WrappedComponent) => {
17
+ var _a;
18
+ return _a = class WithFocusable extends Component {
19
+ constructor() {
20
+ super(...arguments);
21
+ Object.defineProperty(this, "state", {
22
+ enumerable: true,
23
+ configurable: true,
24
+ writable: true,
25
+ value: {
26
+ realFocusKey: this.props.focusKey || uniqueId('sn:focusable-item-'),
27
+ focused: false,
28
+ hasFocusedChild: false,
29
+ parentFocusKey: this.props.parentFocusKey || ROOT_FOCUS_KEY,
30
+ }
31
+ });
32
+ Object.defineProperty(this, "navigation", {
33
+ enumerable: true,
34
+ configurable: true,
35
+ writable: true,
36
+ value: SDK.getMaestroEventViewModel().navigation
37
+ });
38
+ Object.defineProperty(this, "setFocus", {
39
+ enumerable: true,
40
+ configurable: true,
41
+ writable: true,
42
+ value: (focusKey) => {
43
+ if (!this.navigation.isNativeMode()) {
44
+ this.navigation.setFocus(focusKey);
45
+ }
46
+ }
47
+ });
48
+ Object.defineProperty(this, "navigateByDirection", {
49
+ enumerable: true,
50
+ configurable: true,
51
+ writable: true,
52
+ value: this.navigation.navigateByDirection
53
+ });
54
+ Object.defineProperty(this, "stealFocus", {
55
+ enumerable: true,
56
+ configurable: true,
57
+ writable: true,
58
+ value: () => {
59
+ this.navigation.setFocus(this.state.realFocusKey, {
60
+ focusKey: this.state.realFocusKey,
61
+ });
62
+ }
63
+ });
64
+ Object.defineProperty(this, "onUpdateFocus", {
65
+ enumerable: true,
66
+ configurable: true,
67
+ writable: true,
68
+ value: (focused) => {
69
+ this.setState({ focused });
70
+ }
71
+ });
72
+ Object.defineProperty(this, "onUpdateHasFocusedChild", {
73
+ enumerable: true,
74
+ configurable: true,
75
+ writable: true,
76
+ value: (hasFocusedChild) => {
77
+ this.setState({ hasFocusedChild });
78
+ }
79
+ });
80
+ Object.defineProperty(this, "onEnterPressHandler", {
81
+ enumerable: true,
82
+ configurable: true,
83
+ writable: true,
84
+ value: (details) => {
85
+ const { onEnterPress = noop, ...rest } = this.props;
86
+ onEnterPress(rest, details);
87
+ }
88
+ });
89
+ Object.defineProperty(this, "onEnterReleaseHandler", {
90
+ enumerable: true,
91
+ configurable: true,
92
+ writable: true,
93
+ value: () => {
94
+ const { onEnterRelease = noop, ...rest } = this.props;
95
+ onEnterRelease(rest);
96
+ }
97
+ });
98
+ Object.defineProperty(this, "onBackPressHandler", {
99
+ enumerable: true,
100
+ configurable: true,
101
+ writable: true,
102
+ value: (details) => {
103
+ const { onBackPress = noop, ...rest } = this.props;
104
+ onBackPress(rest, details);
105
+ }
106
+ });
107
+ Object.defineProperty(this, "onArrowPressHandler", {
108
+ enumerable: true,
109
+ configurable: true,
110
+ writable: true,
111
+ value: (direction, details) => {
112
+ const { onArrowPress = noop, ...rest } = this.props;
113
+ return onArrowPress(direction, rest, details);
114
+ }
115
+ });
116
+ Object.defineProperty(this, "onBecameFocusedHandler", {
117
+ enumerable: true,
118
+ configurable: true,
119
+ writable: true,
120
+ value: (layout, details) => {
121
+ const { onBecameFocused = noop, ...rest } = this.props;
122
+ onBecameFocused(layout, rest, details);
123
+ }
124
+ });
125
+ Object.defineProperty(this, "onBecameBlurredHandler", {
126
+ enumerable: true,
127
+ configurable: true,
128
+ writable: true,
129
+ value: (layout, details) => {
130
+ const { onBecameBlurred = noop, ...rest } = this.props;
131
+ onBecameBlurred(layout, rest, details);
132
+ }
133
+ });
134
+ }
135
+ getChildContext() {
136
+ return {
137
+ parentFocusKey: this.state.realFocusKey,
138
+ };
139
+ }
140
+ componentDidMount() {
141
+ const { realFocusKey: focusKey, parentFocusKey } = this.state;
142
+ const { preferredChildFocusKey, forgetLastFocusedChild = false, trackChildren, focusable = true, autoRestoreFocus = true, blockNavigationOut = false, } = this.props;
143
+ let node;
144
+ if (this.navigation.isNativeMode()) {
145
+ node = document.createElement('div');
146
+ }
147
+ else {
148
+ const domNode = findDOMNode(this);
149
+ if (!domNode) {
150
+ throw new Error('Could not find DOM node');
151
+ }
152
+ node = domNode;
153
+ }
154
+ this.navigation.addFocusable({
155
+ focusKey,
156
+ node,
157
+ parentFocusKey,
158
+ preferredChildFocusKey,
159
+ onEnterPressHandler: this.onEnterPressHandler,
160
+ onEnterReleaseHandler: this.onEnterReleaseHandler,
161
+ onBackPressHandler: this.onBackPressHandler,
162
+ onArrowPressHandler: this.onArrowPressHandler,
163
+ onBecameFocusedHandler: this.onBecameFocusedHandler,
164
+ onBecameBlurredHandler: this.onBecameBlurredHandler,
165
+ onUpdateFocus: this.onUpdateFocus,
166
+ onUpdateHasFocusedChild: this.onUpdateHasFocusedChild,
167
+ forgetLastFocusedChild: configForgetLastFocusedChild || forgetLastFocusedChild,
168
+ trackChildren: configTrackChildren || trackChildren,
169
+ blockNavigationOut: configBlockNavigationOut || blockNavigationOut,
170
+ autoRestoreFocus: configAutoRestoreFocus !== undefined
171
+ ? configAutoRestoreFocus
172
+ : autoRestoreFocus,
173
+ focusable,
174
+ });
175
+ }
176
+ componentDidUpdate() {
177
+ const { realFocusKey: focusKey } = this.state;
178
+ const { preferredChildFocusKey, focusable = true, blockNavigationOut = false, } = this.props;
179
+ let node;
180
+ if (this.navigation.isNativeMode()) {
181
+ node = document.createElement('div');
182
+ }
183
+ else {
184
+ const domNode = findDOMNode(this);
185
+ if (!domNode) {
186
+ throw new Error('Could not find DOM node');
187
+ }
188
+ node = domNode;
189
+ }
190
+ this.navigation.updateFocusable(focusKey, {
191
+ node,
192
+ preferredChildFocusKey,
193
+ focusable,
194
+ blockNavigationOut: configBlockNavigationOut || blockNavigationOut,
195
+ });
196
+ }
197
+ componentWillUnmount() {
198
+ const { realFocusKey: focusKey } = this.state;
199
+ this.navigation.removeFocusable({ focusKey });
200
+ }
201
+ render() {
202
+ const props = {
203
+ ...this.props,
204
+ ...this.state,
205
+ setFocus: this.setFocus,
206
+ navigateByDirection: this.navigateByDirection,
207
+ stealFocus: this.stealFocus,
208
+ onUpdateFocus: this.onUpdateFocus,
209
+ onUpdateHasFocusedChild: this.onUpdateHasFocusedChild,
210
+ };
211
+ const filteredProps = omit(props, [
212
+ 'onBecameFocusedHandler',
213
+ 'onBecameBlurredHandler',
214
+ 'onEnterPressHandler',
215
+ 'onEnterReleaseHandler',
216
+ 'onArrowPressHandler',
217
+ 'onUpdateFocus',
218
+ 'onUpdateHasFocusedChild',
219
+ 'forgetLastFocusedChild',
220
+ 'trackChildren',
221
+ 'autoRestoreFocus',
222
+ ]);
223
+ return createElement(WrappedComponent, filteredProps);
224
+ }
225
+ },
226
+ Object.defineProperty(_a, "contextTypes", {
227
+ enumerable: true,
228
+ configurable: true,
229
+ writable: true,
230
+ value: {
231
+ parentFocusKey: PropTypes.string,
232
+ }
233
+ }),
234
+ Object.defineProperty(_a, "childContextTypes", {
235
+ enumerable: true,
236
+ configurable: true,
237
+ writable: true,
238
+ value: {
239
+ parentFocusKey: PropTypes.string,
240
+ }
241
+ }),
242
+ _a;
243
+ };
244
+ };
245
+ export default withFocusable;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Basic observable implementation for view models
3
+ */
4
+ export class Observable {
5
+ constructor(initialValue) {
6
+ Object.defineProperty(this, "listeners", {
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true,
10
+ value: []
11
+ });
12
+ Object.defineProperty(this, "_value", {
13
+ enumerable: true,
14
+ configurable: true,
15
+ writable: true,
16
+ value: void 0
17
+ });
18
+ this._value = initialValue;
19
+ }
20
+ get value() {
21
+ return this._value;
22
+ }
23
+ set value(newValue) {
24
+ this._value = newValue;
25
+ this.notify();
26
+ }
27
+ subscribe(listener) {
28
+ this.listeners.push(listener);
29
+ // Return unsubscribe function
30
+ return () => {
31
+ this.listeners = this.listeners.filter((l) => l !== listener);
32
+ };
33
+ }
34
+ notify() {
35
+ this.listeners.forEach((listener) => listener(this._value));
36
+ }
37
+ }
@@ -0,0 +1,14 @@
1
+ export const slugify = (str) => str
2
+ .toLowerCase()
3
+ .trim()
4
+ .replace(/[\s\W-]+/g, '-')
5
+ .replace(/^-+|-+$/g, '');
6
+ export function stringHashCode(str) {
7
+ let hash = 0;
8
+ for (let i = 0; i < str.length; i++) {
9
+ const char = str.charCodeAt(i);
10
+ hash = (hash << 5) - hash + char;
11
+ hash = hash & hash; // Convert to 32bit integer
12
+ }
13
+ return hash;
14
+ }
@@ -0,0 +1,12 @@
1
+ export const setImageDimensions = (url, width, height) => {
2
+ try {
3
+ const urlObj = new URL(url);
4
+ urlObj.searchParams.set('w', width.toString());
5
+ urlObj.searchParams.set('h', height.toString());
6
+ return urlObj.toString();
7
+ }
8
+ catch (err) {
9
+ console.warn('Malformed URL:', url, err);
10
+ return url; // Return the original URL if it cannot be parsed
11
+ }
12
+ };
@@ -1,3 +1,4 @@
1
+ import { UnmountFn } from './external/ports/renderer';
1
2
  import IMaestroEventDelegate, { PanelEvent } from './interfaces/IMaestroEventDelegate';
2
3
  import IMaestroManager, { SDKConfigParams } from './interfaces/IMaestroManager';
3
4
  import IMaestroEvent from './interfaces/IMaestroEvent';
@@ -23,6 +24,9 @@ declare class MaestroWebSDK implements IMaestroManager {
23
24
  private maestroEventViewModel;
24
25
  private pageConfig;
25
26
  private globalConfig;
27
+ private globalConfigPoller;
28
+ private analyticsService;
29
+ private staticService;
26
30
  private constructor();
27
31
  /**
28
32
  * @description Returns the MaestroWebSDK instance
@@ -32,10 +36,6 @@ declare class MaestroWebSDK implements IMaestroManager {
32
36
  userDidStartWatchingEvent(eventID: string, delegate: IMaestroEventDelegate, userSettings?: IUserSettings): Promise<IMaestroEvent>;
33
37
  userDidStopWatchingEvent(_: string): Promise<void>;
34
38
  configure(configParams: SDKConfigParams): void;
35
- /**
36
- * Checks if this is an authorized client based on siteID
37
- */
38
- get isAuthorizedClient(): boolean;
39
39
  /**
40
40
  * Sets the site ID for the SDK
41
41
  * @param siteID The site ID to set
@@ -47,7 +47,7 @@ declare class MaestroWebSDK implements IMaestroManager {
47
47
  * @returns The current event view model
48
48
  */
49
49
  getMaestroEventViewModel(): MaestroEventViewModel;
50
- renderPanel(id: string): Promise<() => void>;
50
+ renderPanel(id: string): Promise<UnmountFn>;
51
51
  getPageConfig(): PageConfig | null;
52
52
  getGlobalConfig(): GlobalConfig | null;
53
53
  }
@@ -0,0 +1,165 @@
1
+ import ReactRenderer from './external/ReactRenderer';
2
+ import { MaestroEventViewModel } from './view-models/MaestroEventViewModel';
3
+ import { UserSettingsManager } from './services/UserSettingsManager';
4
+ import StaticService from './services/StaticService';
5
+ import { MaestroPanelType } from './models/IPanel';
6
+ import initSentry from './sentry';
7
+ import AnalyticsService from './services/AnalyticsService/AnalyticsService';
8
+ // Export overlay components and types for client apps
9
+ export { default as Overlay } from './components/molecules/Overlay/Overlay';
10
+ export { OverlayType, } from './types/OverlayTypes';
11
+ export { MaestroPanelType, };
12
+ export { DEFAULT_USER_SETTINGS, } from './interfaces/IUserSettings';
13
+ /**
14
+ * Main SDK class that serves as the entry point for the Maestro TV SDK
15
+ * Follows a singleton pattern similar to the Swift implementation
16
+ */
17
+ class MaestroWebSDK {
18
+ constructor(renderer) {
19
+ Object.defineProperty(this, "renderer", {
20
+ enumerable: true,
21
+ configurable: true,
22
+ writable: true,
23
+ value: void 0
24
+ });
25
+ Object.defineProperty(this, "siteID", {
26
+ enumerable: true,
27
+ configurable: true,
28
+ writable: true,
29
+ value: ''
30
+ });
31
+ Object.defineProperty(this, "maestroEventViewModel", {
32
+ enumerable: true,
33
+ configurable: true,
34
+ writable: true,
35
+ value: null
36
+ });
37
+ Object.defineProperty(this, "pageConfig", {
38
+ enumerable: true,
39
+ configurable: true,
40
+ writable: true,
41
+ value: null
42
+ });
43
+ Object.defineProperty(this, "globalConfig", {
44
+ enumerable: true,
45
+ configurable: true,
46
+ writable: true,
47
+ value: null
48
+ });
49
+ Object.defineProperty(this, "globalConfigPoller", {
50
+ enumerable: true,
51
+ configurable: true,
52
+ writable: true,
53
+ value: null
54
+ });
55
+ Object.defineProperty(this, "analyticsService", {
56
+ enumerable: true,
57
+ configurable: true,
58
+ writable: true,
59
+ value: new AnalyticsService()
60
+ });
61
+ Object.defineProperty(this, "staticService", {
62
+ enumerable: true,
63
+ configurable: true,
64
+ writable: true,
65
+ value: new StaticService()
66
+ });
67
+ this.renderer = renderer;
68
+ }
69
+ /**
70
+ * @description Returns the MaestroWebSDK instance
71
+ * @returns {MaestroWebSDK} - The MaestroWebSDK instance
72
+ */
73
+ static getInstance() {
74
+ if (!MaestroWebSDK.instance) {
75
+ const renderer = new ReactRenderer();
76
+ MaestroWebSDK.instance = new MaestroWebSDK(renderer);
77
+ }
78
+ return MaestroWebSDK.instance;
79
+ }
80
+ async userDidStartWatchingEvent(eventID, delegate, userSettings) {
81
+ // Fetch page config before initializing view models
82
+ const siteId = this.getSiteID();
83
+ if (!siteId || siteId.trim() === '') {
84
+ throw new Error('siteID must be set before calling userDidStartWatchingEvent.');
85
+ }
86
+ if (!eventID || eventID.trim() === '') {
87
+ throw new Error('eventID must be provided to watch an event.');
88
+ }
89
+ this.pageConfig = await this.staticService.fetchPageConfig(siteId, eventID);
90
+ if (!this.pageConfig) {
91
+ throw new Error(`Could not determine page configuration for siteId: ${siteId} and eventID: ${eventID}.`);
92
+ }
93
+ this.globalConfigPoller = this.staticService.pollGlobalConfig((data) => {
94
+ this.globalConfig = data;
95
+ });
96
+ // Initialize user settings if provided
97
+ if (userSettings) {
98
+ UserSettingsManager.getInstance().updateSettings(userSettings);
99
+ }
100
+ initSentry();
101
+ await this.analyticsService.SDKSessionStart();
102
+ this.maestroEventViewModel = new MaestroEventViewModel(eventID, delegate);
103
+ await this.analyticsService.pageSessionStart();
104
+ return this.maestroEventViewModel;
105
+ }
106
+ async userDidStopWatchingEvent(_) {
107
+ await this.analyticsService.pageSessionEnd();
108
+ if (this.maestroEventViewModel) {
109
+ await this.maestroEventViewModel.deinit();
110
+ this.maestroEventViewModel = null;
111
+ }
112
+ await this.analyticsService.SDKSessionEnd();
113
+ if (this.globalConfigPoller) {
114
+ this.globalConfigPoller.stop();
115
+ this.globalConfigPoller = null;
116
+ }
117
+ }
118
+ configure(configParams) {
119
+ this.setSiteID(configParams.siteID);
120
+ // Configure user settings if provided
121
+ if (configParams.userSettings) {
122
+ UserSettingsManager.getInstance().updateSettings(configParams.userSettings);
123
+ }
124
+ console.info('MaestroWebSDK configured', configParams);
125
+ }
126
+ /**
127
+ * Sets the site ID for the SDK
128
+ * @param siteID The site ID to set
129
+ */
130
+ setSiteID(siteID) {
131
+ if (!siteID || siteID.trim() === '') {
132
+ throw new Error('Site ID must be provided');
133
+ }
134
+ this.siteID = siteID;
135
+ }
136
+ getSiteID() {
137
+ return this.siteID;
138
+ }
139
+ /**
140
+ * Gets the event view model
141
+ * @returns The current event view model
142
+ */
143
+ getMaestroEventViewModel() {
144
+ if (!this.maestroEventViewModel) {
145
+ throw new Error('No Maestro Event View Model set');
146
+ }
147
+ return this.maestroEventViewModel;
148
+ }
149
+ async renderPanel(id) {
150
+ await this.analyticsService.pinchBackSessionStart();
151
+ const panelUnmountFn = await this.renderer.renderPanel(id);
152
+ return async () => {
153
+ panelUnmountFn();
154
+ await this.analyticsService.pinchBackSessionEnd();
155
+ };
156
+ }
157
+ getPageConfig() {
158
+ return this.pageConfig;
159
+ }
160
+ getGlobalConfig() {
161
+ return this.globalConfig;
162
+ }
163
+ }
164
+ const SDK = MaestroWebSDK.getInstance();
165
+ export default SDK;
@@ -87,6 +87,18 @@ export default interface IMaestroEvent {
87
87
  * https://developers.maestro.io/sdk/web/maestro-event-interface/state/getPlayerTimeCode
88
88
  */
89
89
  getPlayerTimeCode(): number | null;
90
+ /**
91
+ * @description Sets data on panel view models. Interface to pass any data to any panel.
92
+ * @param {Record<string, any>} panelData - Object with panel names as keys and their data as values
93
+ * @example
94
+ * setPanelData({
95
+ * [panelType]: {
96
+ * overrideUrl: 'https://...',
97
+ * customProperty: 'value'
98
+ * },
99
+ * })
100
+ */
101
+ setPanelData(panelData: Record<string, any>): void;
90
102
  simulateUseCase<T = any>(useCase: TestUseCase, panelType: MaestroPanelType, testData?: T): void;
91
103
  /**
92
104
  * @description Sets the active panel in the Maestro SDK, if the panel is available and not hidden.
@@ -0,0 +1,18 @@
1
+ const TEST_USE_CASES = {
2
+ betsTabLoadFailure: 'betsTabLoadFailure',
3
+ betsMockData: 'betsMockData',
4
+ betsLiveData: 'betsLiveData',
5
+ // Stats use cases
6
+ showBasketballPreGameStatsMockData: 'showBasketballPreGameStatsMockData',
7
+ showBasketballInGameStatsMockData: 'showBasketballInGameStatsMockData',
8
+ showFootballPreGameStatsMockData: 'showFootballPreGameStatsMockData',
9
+ showFootballInGameStatsMockData: 'showFootballInGameStatsMockData',
10
+ showHockeyPreGameStatsMockData: 'showHockeyPreGameStatsMockData',
11
+ showHockeyInGameStatsMockData: 'showHockeyInGameStatsMockData',
12
+ // Shop use cases
13
+ shopTabLoadFailure: 'shopTabLoadFailure',
14
+ shopEmptyState: 'shopEmptyState',
15
+ shopMockData: 'shopMockData',
16
+ shopLiveData: 'shopLiveData',
17
+ };
18
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Default user settings - all features enabled by default
3
+ */
4
+ export const DEFAULT_USER_SETTINGS = {
5
+ panels: {
6
+ bets: {
7
+ hidePanel: false,
8
+ hideWagers: false,
9
+ },
10
+ stats: {
11
+ hidePanel: false,
12
+ },
13
+ keyPlays: {
14
+ hidePanel: false,
15
+ },
16
+ fantasy: {
17
+ hidePanel: false,
18
+ },
19
+ },
20
+ };
@@ -0,0 +1 @@
1
+ export {};