@maestro_io/maestro-web-sdk 5.2.0 → 5.2.1

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 (102) hide show
  1. package/dist/10.maestro-web-sdk.esm.js +1 -1
  2. package/dist/10.maestro-web-sdk.esm.js.map +1 -1
  3. package/dist/11.maestro-web-sdk.esm.js +1 -1
  4. package/dist/11.maestro-web-sdk.esm.js.map +1 -1
  5. package/dist/12.maestro-web-sdk.esm.js +1 -1
  6. package/dist/12.maestro-web-sdk.esm.js.map +1 -1
  7. package/dist/13.maestro-web-sdk.esm.js +1 -1
  8. package/dist/13.maestro-web-sdk.esm.js.map +1 -1
  9. package/dist/14.maestro-web-sdk.esm.js +1 -1
  10. package/dist/14.maestro-web-sdk.esm.js.map +1 -1
  11. package/dist/15.maestro-web-sdk.esm.js +1 -1
  12. package/dist/15.maestro-web-sdk.esm.js.map +1 -1
  13. package/dist/16.maestro-web-sdk.esm.js +1 -1
  14. package/dist/16.maestro-web-sdk.esm.js.map +1 -1
  15. package/dist/17.maestro-web-sdk.esm.js +1 -1
  16. package/dist/17.maestro-web-sdk.esm.js.map +1 -1
  17. package/dist/18.maestro-web-sdk.esm.js +1 -1
  18. package/dist/18.maestro-web-sdk.esm.js.map +1 -1
  19. package/dist/19.maestro-web-sdk.esm.js +1 -1
  20. package/dist/19.maestro-web-sdk.esm.js.map +1 -1
  21. package/dist/20.maestro-web-sdk.esm.js +1 -1
  22. package/dist/20.maestro-web-sdk.esm.js.map +1 -1
  23. package/dist/21.maestro-web-sdk.esm.js +1 -1
  24. package/dist/21.maestro-web-sdk.esm.js.map +1 -1
  25. package/dist/22.maestro-web-sdk.esm.js +1 -1
  26. package/dist/22.maestro-web-sdk.esm.js.map +1 -1
  27. package/dist/23.maestro-web-sdk.esm.js +1 -1
  28. package/dist/23.maestro-web-sdk.esm.js.map +1 -1
  29. package/dist/24.maestro-web-sdk.esm.js +1 -1
  30. package/dist/24.maestro-web-sdk.esm.js.map +1 -1
  31. package/dist/25.maestro-web-sdk.esm.js +1 -1
  32. package/dist/25.maestro-web-sdk.esm.js.map +1 -1
  33. package/dist/26.maestro-web-sdk.esm.js +1 -1
  34. package/dist/26.maestro-web-sdk.esm.js.map +1 -1
  35. package/dist/27.maestro-web-sdk.esm.js +1 -1
  36. package/dist/27.maestro-web-sdk.esm.js.map +1 -1
  37. package/dist/28.maestro-web-sdk.esm.js +1 -1
  38. package/dist/28.maestro-web-sdk.esm.js.map +1 -1
  39. package/dist/29.maestro-web-sdk.esm.js +1 -1
  40. package/dist/29.maestro-web-sdk.esm.js.map +1 -1
  41. package/dist/3.maestro-web-sdk.esm.js +1 -1
  42. package/dist/3.maestro-web-sdk.esm.js.map +1 -1
  43. package/dist/30.maestro-web-sdk.esm.js +1 -1
  44. package/dist/30.maestro-web-sdk.esm.js.map +1 -1
  45. package/dist/31.maestro-web-sdk.esm.js +1 -1
  46. package/dist/31.maestro-web-sdk.esm.js.map +1 -1
  47. package/dist/32.maestro-web-sdk.esm.js +1 -1
  48. package/dist/32.maestro-web-sdk.esm.js.map +1 -1
  49. package/dist/33.maestro-web-sdk.esm.js +1 -1
  50. package/dist/33.maestro-web-sdk.esm.js.map +1 -1
  51. package/dist/34.maestro-web-sdk.esm.js +1 -1
  52. package/dist/34.maestro-web-sdk.esm.js.map +1 -1
  53. package/dist/35.maestro-web-sdk.esm.js +1 -1
  54. package/dist/35.maestro-web-sdk.esm.js.map +1 -1
  55. package/dist/36.maestro-web-sdk.esm.js +1 -1
  56. package/dist/36.maestro-web-sdk.esm.js.map +1 -1
  57. package/dist/37.maestro-web-sdk.esm.js +1 -1
  58. package/dist/37.maestro-web-sdk.esm.js.map +1 -1
  59. package/dist/38.maestro-web-sdk.esm.js +1 -1
  60. package/dist/38.maestro-web-sdk.esm.js.map +1 -1
  61. package/dist/39.maestro-web-sdk.esm.js +1 -1
  62. package/dist/39.maestro-web-sdk.esm.js.map +1 -1
  63. package/dist/6.maestro-web-sdk.esm.js +1 -1
  64. package/dist/7.maestro-web-sdk.esm.js +1 -1
  65. package/dist/8.maestro-web-sdk.esm.js +1 -1
  66. package/dist/8.maestro-web-sdk.esm.js.map +1 -1
  67. package/dist/9.maestro-web-sdk.esm.js +1 -1
  68. package/dist/maestro-web-sdk.esm.js +2 -2
  69. package/dist/maestro-web-sdk.umd.js +2 -2
  70. package/dist/maestro-web-sdk.umd.js.map +1 -1
  71. package/dist/package.json +1 -1
  72. package/dist/src/modules/espn/bets/services/BetsService.js +5 -5
  73. package/dist/src/modules/espn/fantasy/services/FantasyService.js +3 -0
  74. package/dist/src/modules/espn/fantasy/view/FantasyView.js +2 -1
  75. package/dist/src/modules/espn/fantasy/view-model/FantasyViewModel.FantasyPolling.d.ts +1 -1
  76. package/dist/src/modules/espn/fantasy/view-model/FantasyViewModel.FantasyPolling.js +10 -7
  77. package/dist/src/modules/espn/fantasy/view-model/FantasyViewModel.LeagueManagerPolling.d.ts +1 -1
  78. package/dist/src/modules/espn/fantasy/view-model/FantasyViewModel.LeagueManagerPolling.js +10 -7
  79. package/dist/src/modules/espn/fantasy/view-model/FantasyViewModel.TournamentPolling.d.ts +1 -1
  80. package/dist/src/modules/espn/fantasy/view-model/FantasyViewModel.TournamentPolling.js +10 -7
  81. package/dist/src/modules/espn/fantasy/view-model/FantasyViewModel.d.ts +1 -0
  82. package/dist/src/modules/espn/fantasy/view-model/FantasyViewModel.js +42 -32
  83. package/dist/src/modules/espn/shop/services/ShopService.js +1 -1
  84. package/dist/src/modules/espn/stats/services/StatsService.js +2 -2
  85. package/dist/src/modules/fox/multi-view/services/MultiViewService.d.ts +20 -15
  86. package/dist/src/modules/fox/multi-view/services/MultiViewService.js +6 -3
  87. package/dist/src/modules/fox/multi-view/types.d.ts +20 -0
  88. package/dist/src/modules/fox/multi-view/view/BuildYourOwn/BuildYourOwn.d.ts +7 -0
  89. package/dist/src/modules/fox/multi-view/view/BuildYourOwn/BuildYourOwn.js +99 -0
  90. package/dist/src/modules/fox/multi-view/view/BuildYourOwn/index.d.ts +2 -0
  91. package/dist/src/modules/fox/multi-view/view/BuildYourOwn/index.js +2 -0
  92. package/dist/src/modules/fox/multi-view/view/CuratedMultiview/CuratedMultiviews.js +2 -1
  93. package/dist/src/modules/fox/multi-view/view/FoxMultiView.js +3 -0
  94. package/dist/src/modules/fox/multi-view/view/components/BuildYourOwnTabs/BuildYourOwnTabs.d.ts +8 -0
  95. package/dist/src/modules/fox/multi-view/view/components/BuildYourOwnTabs/BuildYourOwnTabs.js +30 -0
  96. package/dist/src/modules/fox/multi-view/view/components/BuildYourOwnTabs/index.d.ts +2 -0
  97. package/dist/src/modules/fox/multi-view/view/components/BuildYourOwnTabs/index.js +2 -0
  98. package/dist/src/modules/fox/multi-view/view/components/CustomMultiviewStreamsCard/CustomMultiviewStreamsCard.d.ts +2 -6
  99. package/dist/src/modules/fox/multi-view/view/components/curated-multiview-card/CuratedMultiviewCard.js +27 -7
  100. package/dist/src/modules/fox/multi-view/view-model/MultiViewViewModel.d.ts +25 -4
  101. package/dist/src/modules/fox/multi-view/view-model/MultiViewViewModel.js +196 -15
  102. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["webpack:///./src/helpers/strings.ts","webpack:///./src/modules/espn/bets/services/BetsService.ts","webpack:///./src/modules/espn/bets/mocks.ts","webpack:///./src/modules/espn/bets/view-model/BetsViewModel.ts"],"names":["slugify","str","toLowerCase","trim","replace","stringHashCode","hash","i","length","charCodeAt","BetsService","constructor","delegate","_defineProperty","this","networkManager","NetworkManager","externalBaseURL","getBettingAPIBaseURL","eventID","externalApiRequest","endpoint","nonPersonalizedBetsEndpoint","method","HttpMethod","GET","params","headers","swid","jwt","personalizedBetsEndpoint","externalApiRequestWithHeaders","pollPersonalizedBets","interval","onData","onError","pollExternalApiRequest","pollPersonalizedBetsWithHeaders","pollExternalApiRequestWithHeaders","event","id","sport","date","gameState","featured","selections","icon","iconDark","odds","outcome","status","text","type","bets","displayName","abbreviation","state","values","team","line","MOCK_BETS_API_RESPONSE","entities","teams","uid","guid","slug","shortDisplayName","name","nickname","location","color","alternateColor","favored","betsModule","defaultTab","upcoming","live","betStatus","overrideOutcome","betAmount","payoutAmount","startTime","events","legs","marketId","marketSelectionId","marketType","boostType","selectionText","marketText","url","marketStatus","rewardInfo","legCount","isNoAction","betDisplayStatement","light","dark","settled","closedAtTime","points","accrued","goal","promotion","title","description","logo","qrCode","backgroundImage","disclaimers","gambling","isPersonalizedBetsResponse","data","BetsViewModel","ViewModel","eventId","analyticsService","options","super","Observable","betsService","pollingInterval","useMockData","userSettingsManager","UserSettingsManager","getInstance","hideWagers","value","shouldHideWagers","settingsSubscription","settings","subscribe","updateHideWagersFromSettings","trackPanelView","fetchNewData","refreshPolling","initialized","cleanup","stopPolling","betCounts","getUserBetCounts","panelView","error","captureException","context","console","cardType","betType","metadata","card","bet_type","panelClick","inGameBets","totalBets","item","betsItems","userBetsItem","in_game_bets","total_bets","pollingTask","stop","pollWithInterval","getUserSWID","getUserToken","updatePollingInterval","headerInterval","getResponseHeaderPollingIntervalValue","panelConfigInterval","getPanelConfigInterval","newInterval","log","_config$panels","_panel$renderer","_panel$renderer$block","config","SDK","getPageConfig","panel","panels","find","p","panel_type","oddsPollingInterval","renderer","block_data","odds_polling_interval","parsedInterval","parseInt","isNaN","warn","getUserCredentials","response","processPolledData","handlePollingError","bind","responseHash","JSON","stringify","lastPersonalizedResponseHash","hasEverSuccessfullyLoaded","lastNonPersonalizedResponseHash","errorState","processBetsData","newItems","Object","keys","sixPack","processSixPackData","push","locationDisclaimer","processLocationDisclaimer","userBets","processUserBetsData","hotProps","processHotProps","promoCode","processPromoCode","gamblingMessage","processGamblingMessage","_data$disclaimers","_data$event","_data$disclaimers2","_response$entities","_response$bets","_response$event","_response$event$bets","_response$event2","_response$event3","_response$event4","_response$event5","_awayTeam$abbreviatio","_homeTeam$abbreviatio","isPersonalized","isSoccer","teamArray","awayTeam","homeTeam","spreadOdds","odd","some","v","Error","isInProgress","isHomeFavoured","_homeTeam$favoredAtOp","favoredAtOpen","_homeTeam$favored","isAwayFavoured","_awayTeam$favoredAtOp","_awayTeam$favored","awayTeamStartGameFirstLine","awayTeamStartGameSecondLine","homeTeamStartGameFirstLine","homeTeamStartGameSecondLine","awaySpreadFirstLine","awaySpreadSecondLine","homeSpreadFirstLine","homeSpreadSecondLine","awayTotalFirstLine","awayTotalSecondLine","homeTotalFirstLine","homeTotalSecondLine","awayMoneylineFirstLine","homeMoneylineFirstLine","drawGameStateFirstLine","drawGameStateSecondLine","drawMoneylineFirstLine","itemTypeSet","Set","orderedColumns","oddsItem","has","add","isLive","isClose","isOpen","_value$line","_value$odds","_value$line2","_value$odds2","_value$line3","_value$odds3","_value$line4","_value$odds4","_value$line5","_value$odds5","_value$line6","_value$odds6","_value$line7","_value$odds7","_value$line8","_value$odds8","_value$line9","_value$odds9","_value$line0","_value$odds0","mlCorrectState","_value$odds1","_value$odds10","moneyLineStartOfGameCorrectState","_value$odds11","_value$odds12","_value$odds13","_oddsItem$abbreviatio","_value$odds14","_oddsItem$abbreviatio2","awayTeamOdds","teamAbbreviation","startOfGameFirstLine","startOfGameSecondLine","gameSpreadFirstLine","gameSpreadSecondLine","totalPointsFirstLine","totalPointsSecondLine","moneylineFirstLine","homeTeamOdds","topTeamOdds","bottomTeamOdds","drawOdds","undefined","teamInfo","home","away","filter","bet","_response$event6","Array","isArray","every","hotProp","Boolean","filteredHotProps","items","map","current","isDataLoading","fetchMockData","fetchPersonalizedData","getPersonalizedBets","clearTabLoadFailure","setTimeout","refreshBetItemsWithNewSettings"],"mappings":"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","file":"12.maestro-web-sdk.esm.js","sourcesContent":["export const slugify = (str: string) =>\n str\n .toLowerCase()\n .trim()\n .replace(/[\\s\\W-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n\nexport function stringHashCode(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return hash;\n}\n","import NetworkManager, {\n HttpMethod,\n} from '../../../../services/NetworkManager/NetworkManager';\nimport { IBetsResponse, IPersonalizedBetsResponse } from '../interfaces/IBets';\nimport IMaestroEventDelegate from '@/interfaces/IMaestroEventDelegate';\n\n/**\n * Service for handling bets-related API calls\n */\nclass BetsService {\n public networkManager: NetworkManager;\n\n constructor(delegate: IMaestroEventDelegate) {\n this.networkManager = new NetworkManager({\n externalBaseURL: delegate.getBettingAPIBaseURL(),\n });\n }\n\n /**\n * Get non-personalized bets for an event\n *\n * @deprecated Use getPersonalizedBets instead. This method is kept for backward compatibility.\n * @param eventID - The ID of the event\n * @returns Promise with the bets data\n */\n async getNonPersonalizedBets(eventID: string): Promise<IBetsResponse> {\n return this.networkManager.externalApiRequest({\n endpoint: this.nonPersonalizedBetsEndpoint(eventID),\n method: HttpMethod.GET,\n params: {},\n headers: {},\n });\n }\n\n /**\n * Get personalized bets for an event\n *\n * @param eventID - The ID of the event\n * @param swid - The ESPN SWID parameter (format provided by client app delegate)\n * @param jwt - The authorization JWT (empty string for anonymous users)\n * @returns Promise with the personalized bets data\n */\n async getPersonalizedBets(\n eventID: string,\n swid: string,\n jwt: string\n ): Promise<IPersonalizedBetsResponse> {\n return this.networkManager.externalApiRequest({\n endpoint: this.personalizedBetsEndpoint(eventID),\n method: HttpMethod.GET,\n params: { swid },\n headers: { 'x-p13n-auth': jwt },\n });\n }\n\n /**\n * Get personalized bets for an event with headers\n *\n * @param eventID - The ID of the event\n * @param swid - The ESPN SWID parameter (format provided by client app delegate)\n * @param jwt - The authorization JWT (empty string for anonymous users)\n * @returns Promise with the personalized bets data and headers\n */\n async getPersonalizedBetsWithHeaders(\n eventID: string,\n swid: string,\n jwt: string\n ): Promise<{\n data: IPersonalizedBetsResponse;\n headers: Record<string, string>;\n }> {\n return this.networkManager.externalApiRequestWithHeaders({\n endpoint: this.personalizedBetsEndpoint(eventID),\n method: HttpMethod.GET,\n params: { swid },\n headers: { 'x-p13n-auth': jwt },\n });\n }\n\n /**\n * Start polling for personalized bets\n *\n * @param eventID - The ID of the event\n * @param swid - The ESPN SWID parameter\n * @param jwt - The authorization JWT\n * @param interval - The polling interval in milliseconds\n * @param onData - Callback for successful data fetch\n * @param onError - Callback for errors\n * @returns Object with a stop function to stop polling\n */\n pollPersonalizedBets(\n eventID: string,\n swid: string,\n jwt: string,\n interval: number,\n onData: (data: IPersonalizedBetsResponse) => void,\n onError?: (error: Error) => void\n ): { stop: () => void } {\n return this.networkManager.pollExternalApiRequest({\n endpoint: this.personalizedBetsEndpoint(eventID),\n interval,\n method: HttpMethod.GET,\n params: { swid },\n headers: { 'x-p13n-auth': jwt },\n onData,\n onError,\n });\n }\n\n /**\n * Start polling for personalized bets and return both data and headers\n *\n * @param eventID - The ID of the event\n * @param swid - The ESPN SWID parameter\n * @param jwt - The authorization JWT\n * @param interval - The polling interval in milliseconds\n * @param onData - Callback for successful data fetch with headers\n * @param onError - Callback for errors\n * @returns Object with a stop function to stop polling\n */\n pollPersonalizedBetsWithHeaders(\n eventID: string,\n swid: string,\n jwt: string,\n interval: number,\n onData: (response: {\n data: IPersonalizedBetsResponse;\n headers: Record<string, string>;\n }) => void,\n onError?: (error: Error) => void\n ): { stop: () => void } {\n return this.networkManager.pollExternalApiRequestWithHeaders({\n endpoint: this.personalizedBetsEndpoint(eventID),\n interval,\n method: HttpMethod.GET,\n params: { swid },\n headers: { 'x-p13n-auth': jwt },\n onData,\n onError,\n });\n }\n\n /**\n * Get the endpoint for non-personalized bets\n *\n * @deprecated This endpoint is no longer used.\n */\n nonPersonalizedBetsEndpoint(eventID: string): string {\n return `/site/v2/events/${eventID}/odds`;\n }\n\n /**\n * Get the endpoint for personalized bets\n */\n personalizedBetsEndpoint(eventID: string): string {\n return `/personalized/site/v2/events/${eventID}/odds`;\n }\n}\n\nexport default BetsService;\n","import { BetLiveEvent, IPersonalizedBetsResponse } from './interfaces/IBets';\n\nconst event: BetLiveEvent = {\n id: '401721458',\n sport: 'basketball',\n date: '2025-02-28T02:00Z',\n gameState: 'post',\n featured: [\n {\n date: '2024-06-09T17:35Z',\n id: '00015c79-3454-4356-bab6-af050554b761',\n selections: [\n {\n icon: 'https://a.espncdn.com/i/espnbet/mybets_under_caret_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_under_caret_icon.png',\n id: 'f54ad0791-304e-43fe-a45a-96bd237c9c78',\n odds: {},\n outcome: 'PENDING',\n status: 'upcoming',\n text: 'Under 5.5',\n type: 'under',\n },\n {\n icon: 'https://a.espncdn.com/i/espnbet/mybets_under_caret_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_under_caret_icon.png',\n id: 'f54ad079-3604e-43fe-a45a-96bd237c9c78',\n odds: {},\n outcome: 'PENDING',\n status: 'upcoming',\n text: 'Under 5.5',\n type: 'under',\n },\n {\n icon: 'https://a.espncdn.com/i/espnbet/mybets_under_caret_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_under_caret_icon.png',\n id: 'f54ad079-5304e-43fe-a45a-96bd237c9c78',\n odds: {},\n outcome: 'PENDING',\n status: 'upcoming',\n text: 'Under 5.5',\n type: 'under',\n },\n {\n icon: 'https://a.espncdn.com/i/espnbet/mybets_under_caret_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_under_caret_icon.png',\n id: 'f54ad079-3044e-43fe-a45a-96bd237c9c78',\n odds: {},\n outcome: 'PENDING',\n status: 'upcoming',\n text: 'Under 5.5',\n type: 'under',\n },\n {\n icon: 'https://a.espncdn.com/i/espnbet/mybets_under_caret_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_under_caret_icon.png',\n id: 'f54ad079-304e-43fe-a45a-96bd237c9c278',\n odds: {},\n outcome: 'PENDING',\n status: 'upcoming',\n text: 'Under 5.5',\n type: 'under',\n },\n {\n icon: 'https://a.espncdn.com/i/espnbet/mybets_under_caret_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_under_caret_icon.png',\n id: 'f54ad079-304e-43fe-a45a-96bd1237c9c78',\n odds: {},\n outcome: 'PENDING',\n status: 'upcoming',\n text: 'Under 5.5',\n type: 'under',\n },\n ],\n text: 'Carlos Santana Total Hits + Runs + RBIs',\n },\n ],\n bets: {\n odds: [\n {\n displayName: 'Moneyline',\n abbreviation: 'ML',\n type: 'moneyline',\n state: 'close',\n values: [\n { odds: '-500', outcome: 'WIN', team: '130', type: 'home' },\n { odds: '+360', outcome: 'LOSS', team: '164', type: 'away' },\n ],\n },\n {\n displayName: 'Moneyline',\n abbreviation: 'ML',\n type: 'moneyline',\n state: 'open',\n values: [\n { odds: '-700', team: '130', type: 'home' },\n { odds: '+450', team: '164', type: 'away' },\n ],\n },\n {\n displayName: 'Total Points',\n abbreviation: 'Total',\n type: 'total',\n state: 'close',\n values: [\n { line: 'o154.5', odds: '-115', outcome: 'WIN', type: 'over' },\n { line: 'u154.5', odds: '-105', outcome: 'LOSS', type: 'under' },\n ],\n },\n {\n displayName: 'Total Points',\n abbreviation: 'Total',\n type: 'total',\n state: 'open',\n values: [\n { line: 'o154.5', odds: '-105', type: 'over' },\n { line: 'u154.5', odds: '-115', type: 'under' },\n ],\n },\n {\n displayName: 'Spread',\n abbreviation: 'Spread',\n type: 'pointSpread',\n state: 'close',\n values: [\n {\n line: '-9.5',\n odds: '-105',\n outcome: 'LOSS',\n team: '130',\n type: 'home',\n },\n {\n line: '+9.5',\n odds: '-115',\n outcome: 'WIN',\n team: '164',\n type: 'away',\n },\n ],\n },\n {\n displayName: 'Spread',\n abbreviation: 'Spread',\n type: 'pointSpread',\n state: 'open',\n values: [\n { line: '-11.5', odds: '-105', team: '130', type: 'home' },\n { line: '+11.5', odds: '-115', team: '164', type: 'away' },\n ],\n },\n ],\n },\n};\n\nexport const MOCK_BETS_API_RESPONSE: IPersonalizedBetsResponse = {\n entities: {\n teams: {\n '130': {\n id: '130',\n uid: 's:40~l:41~t:130',\n guid: 'c00151c6-cdd4-5aab-0130-37416052eb2a',\n slug: 'michigan-wolverines',\n abbreviation: 'MICH',\n displayName: 'Michigan Wolverines',\n shortDisplayName: 'Michigan',\n name: 'Wolverines',\n nickname: 'Michigan',\n location: 'Michigan',\n color: '00274c',\n alternateColor: 'ffcb05',\n favored: true,\n },\n '164': {\n id: '164',\n uid: 's:40~l:41~t:164',\n guid: '425c8e51-59d0-75a1-0815-dc3556c5cfda',\n slug: 'rutgers-scarlet-knights',\n abbreviation: 'RUTG',\n displayName: 'Rutgers Scarlet Knights',\n shortDisplayName: 'Rutgers',\n name: 'Scarlet Knights',\n nickname: 'Rutgers',\n location: 'Rutgers',\n color: 'd21034',\n alternateColor: 'ffffff',\n favored: false,\n },\n },\n },\n event,\n betsModule: {\n defaultTab: 'live',\n upcoming: [],\n live: [\n {\n id: 'emnPo+hN/Q7CzX/obYcJZCYGql4=',\n type: 'PARLAY',\n betStatus: 'OPEN',\n outcome: 'PENDING',\n overrideOutcome: 'NOT_SET',\n betAmount: '10',\n payoutAmount: '171.55',\n odds: '+1616',\n startTime: '2022-11-29T17:54Z',\n events: [\n {\n displayName: 'Investec South African Open Championship Future',\n legs: [\n {\n id: '71acdfe8-611e-47ae-b7ee-ba6684c6fefa',\n marketId: 'fc47f9f9-2852-4f63-9a70-4adf5b4addd2',\n marketSelectionId: '92803c34-a8b7-476e-9136-b88729c7e51e',\n marketType: 'list',\n status: 'PENDING',\n odds: '+370',\n boostType: 'NONE',\n selectionText: 'Aaron Baddeley',\n type: 'list',\n marketText: 'Tournament Winner',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/golf/organization/dp-world-tour/competition/investec-south-african-open-championship/event/56773312-5fdb-4cb5-b387-df8c18a2c857&market_selection_id[0]=92803c34-a8b7-476e-9136-b88729c7e51e&odds_numerator[0]=11&odds_denominator[0]=2',\n marketStatus: 'LIVE',\n },\n ],\n },\n {\n displayName: 'Lorem Ipsum Dolor Sit Amet',\n legs: [\n {\n id: '472f176b-7575-4d1d-ac63-bcb2d4ec6da9',\n marketId: '2e5fdfdf-7021-464f-939d-5497030fe765',\n marketSelectionId: '3727a3f5-5143-4616-ab4f-713bcf40aa21',\n marketType: 'list',\n status: 'PENDING',\n odds: '+265',\n boostType: 'NONE',\n selectionText: 'Aaron Pike',\n type: 'list',\n marketText: 'Tournament Winner',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/golf/organization/dp-world-tour/competition/isps-handa-australian-open/event/df8ba72f-4be8-4569-840e-954dbd9a7806&market_selection_id[0]=3727a3f5-5143-4616-ab4f-713bcf40aa21&odds_numerator[0]=73&odds_denominator[0]=20',\n marketStatus: 'LIVE',\n },\n ],\n },\n {\n displayName: 'Australian Open Future',\n legs: [\n {\n id: '472f176b-7575-4d1d-ac63-bcb2d4ec6da9',\n marketId: '2e5fdfdf-7021-464f-939d-5497030fe765',\n marketSelectionId: '3727a3f5-5143-4616-ab4f-713bcf40aa21',\n marketType: 'list',\n status: 'PENDING',\n odds: '+265',\n boostType: 'NONE',\n selectionText: 'Aaron Pike',\n type: 'list',\n marketText: 'Tournament Winner',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/golf/organization/dp-world-tour/competition/isps-handa-australian-open/event/df8ba72f-4be8-4569-840e-954dbd9a7806&market_selection_id[0]=3727a3f5-5143-4616-ab4f-713bcf40aa21&odds_numerator[0]=73&odds_denominator[0]=20',\n marketStatus: 'LIVE',\n },\n ],\n },\n {\n displayName: 'USA vs. Australia Future',\n legs: [\n {\n id: '472f176b-7575-4d1d-ac63-bcb2d4ec6da9',\n marketId: '2e5fdfdf-7021-464f-939d-5497030fe765',\n marketSelectionId: '3727a3f5-5143-4616-ab4f-713bcf40aa21',\n marketType: 'list',\n status: 'PENDING',\n odds: '+265',\n boostType: 'NONE',\n selectionText: 'Aaron Pike',\n type: 'list',\n marketText: 'Tournament Winner',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/golf/organization/dp-world-tour/competition/isps-handa-australian-open/event/df8ba72f-4be8-4569-840e-954dbd9a7806&market_selection_id[0]=3727a3f5-5143-4616-ab4f-713bcf40aa21&odds_numerator[0]=73&odds_denominator[0]=20',\n marketStatus: 'LIVE',\n },\n ],\n },\n {\n displayName: 'Championship Future',\n legs: [\n {\n id: '472f176b-7575-4d1d-ac63-bcb2d4ec6da9',\n marketId: '2e5fdfdf-7021-464f-939d-5497030fe765',\n marketSelectionId: '3727a3f5-5143-4616-ab4f-713bcf40aa21',\n marketType: 'list',\n status: 'PENDING',\n odds: '+265',\n boostType: 'NONE',\n selectionText: 'Aaron Pike',\n type: 'list',\n marketText: 'Tournament Winner',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/golf/organization/dp-world-tour/competition/isps-handa-australian-open/event/df8ba72f-4be8-4569-840e-954dbd9a7806&market_selection_id[0]=3727a3f5-5143-4616-ab4f-713bcf40aa21&odds_numerator[0]=73&odds_denominator[0]=20',\n marketStatus: 'LIVE',\n },\n ],\n },\n ],\n rewardInfo: { type: 'NONE' },\n legCount: 5,\n isNoAction: false,\n betDisplayStatement: 'to win',\n },\n {\n id: '9m1bBxUYPyPPjkpzT6buDlcuQng=',\n type: 'STRAIGHT',\n betStatus: 'OPEN',\n outcome: 'PENDING',\n overrideOutcome: 'NOT_SET',\n betAmount: '2',\n payoutAmount: '10.80',\n odds: '+440',\n startTime: '2025-04-30T15:12Z',\n events: [\n {\n displayName: 'SBG/SBE Odds Boost Test',\n legs: [\n {\n id: '8061671d-6d38-4193-a5a6-beab37855840',\n marketId: '567d2a44-ba70-4881-86d7-d25fca94b592',\n marketSelectionId: '59b2b7ee-46c1-4cbc-9286-77fd8670cf9d',\n marketType: 'list',\n status: 'PENDING',\n odds: '+440',\n boostType: 'ODDS_BOOST',\n selectionText:\n 'Lauri Markkanen and Anfernee Simons to Each Record 20+ Points',\n type: 'list',\n marketText: 'SBG/SBE Odds Boost (Was +100)',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/odds-boost/organization/odds-boosts/competition/odds-boosts/event/218e1dca-f68d-4d61-9d79-394e7d752cae&market_selection_id[0]=59b2b7ee-46c1-4cbc-9286-77fd8670cf9d&odds_numerator[0]=27&odds_denominator[0]=5',\n marketStatus: 'LIVE',\n },\n ],\n },\n ],\n rewardInfo: {\n type: 'ODDS_BOOST',\n icon: {\n light: 'https://a.espncdn.com/i/espnbet/boost.png',\n dark: 'https://a.espncdn.com/i/espnbet/boost.png',\n },\n },\n legCount: 1,\n isNoAction: false,\n betDisplayStatement: 'to win',\n },\n {\n id: 'MCH06SyVYvu1UZkhj4KutmL9qKY=',\n type: 'STRAIGHT',\n betStatus: 'OPEN',\n outcome: 'PENDING',\n overrideOutcome: 'NOT_SET',\n betAmount: '3',\n payoutAmount: '16.20',\n odds: '+440',\n startTime: '2025-04-30T15:12Z',\n events: [\n {\n displayName: 'SBG/SBE Odds Boost Test',\n legs: [\n {\n id: '020d7a12-3aa8-459e-8aa2-34eaced4ad7d',\n marketId: '567d2a44-ba70-4881-86d7-d25fca94b592',\n marketSelectionId: '59b2b7ee-46c1-4cbc-9286-77fd8670cf9d',\n marketType: 'list',\n status: 'PENDING',\n odds: '+440',\n boostType: 'ODDS_BOOST',\n selectionText:\n 'Lauri Markkanen and Anfernee Simons to Each Record 20+ Points',\n type: 'list',\n marketText: 'SBG/SBE Odds Boost (Was +100)',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/odds-boost/organization/odds-boosts/competition/odds-boosts/event/218e1dca-f68d-4d61-9d79-394e7d752cae&market_selection_id[0]=59b2b7ee-46c1-4cbc-9286-77fd8670cf9d&odds_numerator[0]=27&odds_denominator[0]=5',\n marketStatus: 'LIVE',\n },\n ],\n },\n ],\n rewardInfo: {\n type: 'ODDS_BOOST',\n icon: {\n light: 'https://a.espncdn.com/i/espnbet/boost.png',\n dark: 'https://a.espncdn.com/i/espnbet/boost.png',\n },\n },\n legCount: 1,\n isNoAction: false,\n betDisplayStatement: 'to win',\n },\n {\n id: 'xfFjqsLCjaFx93eH6c8bOQ9mEkI=',\n type: 'STRAIGHT',\n betStatus: 'OPEN',\n outcome: 'PENDING',\n overrideOutcome: 'NOT_SET',\n betAmount: '2',\n payoutAmount: '12.00',\n odds: '+500',\n startTime: '2025-04-30T17:11Z',\n events: [\n {\n displayName: 'SBG NHL In The News Test',\n legs: [\n {\n id: '910a1ebf-592d-4ae6-9471-6f648786b7e6',\n marketId: 'c5252e65-0999-40af-b366-11967f009871',\n marketSelectionId: 'c9b1446c-26af-43c4-9705-3a2275dc0ee5',\n marketType: 'list',\n status: 'PENDING',\n odds: '+500',\n boostType: 'NONE',\n selectionText:\n 'Long Desc Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus non gravida mi. Aliquam volutpat felis ut tempor dictum.',\n type: 'list',\n marketText: 'SBG In The News NHL',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/odds-boost/organization/in-the-news/competition/in-the-news/event/4cd8e64d-472c-412f-b786-dd91c98ab74e&market_selection_id[0]=c9b1446c-26af-43c4-9705-3a2275dc0ee5&odds_numerator[0]=6&odds_denominator[0]=1',\n marketStatus: 'LIVE',\n },\n ],\n },\n ],\n rewardInfo: { type: 'NONE' },\n legCount: 1,\n isNoAction: false,\n betDisplayStatement: 'to win',\n },\n {\n id: 'A0RLmTR8mjEFSwaa21JeOhyVdXc=',\n type: 'STRAIGHT',\n betStatus: 'OPEN',\n outcome: 'PENDING',\n overrideOutcome: 'NOT_SET',\n betAmount: '1',\n payoutAmount: '3.00',\n odds: '+200',\n startTime: '2025-04-30T17:13Z',\n events: [\n {\n displayName: 'SBG NBA Special Test',\n legs: [\n {\n id: '1aa22098-57b7-4a77-bbf2-ca7ebf812083',\n marketId: 'bc783144-0a2c-465b-9e8f-2ef55a17705c',\n marketSelectionId: '7a91fb3d-1291-4163-b5e0-07fe63e8e706',\n marketType: 'list',\n status: 'PENDING',\n odds: '+200',\n boostType: 'NONE',\n selectionText: 'Tyrese Haliburton to Record 12+ Assists',\n type: 'list',\n marketText: 'SBG NBA Special Test',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/odds-boost/organization/specials/competition/specials/event/d53171e2-f821-4da8-9b1c-ce1a4b735914&market_selection_id[0]=7a91fb3d-1291-4163-b5e0-07fe63e8e706&odds_numerator[0]=33&odds_denominator[0]=10',\n marketStatus: 'LIVE',\n },\n ],\n },\n ],\n rewardInfo: { type: 'NONE' },\n legCount: 1,\n isNoAction: false,\n betDisplayStatement: 'to win',\n },\n {\n id: 'Qhelx5np79zhAchzXXTL1HdDb80=',\n type: 'STRAIGHT',\n betStatus: 'OPEN',\n outcome: 'PENDING',\n overrideOutcome: 'NOT_SET',\n betAmount: '2',\n payoutAmount: '10.00',\n odds: '+400',\n startTime: '2025-04-30T17:13Z',\n events: [\n {\n displayName: 'SBG NBA Special Test',\n legs: [\n {\n id: '73f3af25-5e1a-47eb-bcec-5b23e911c14e',\n marketId: 'bc783144-0a2c-465b-9e8f-2ef55a17705c',\n marketSelectionId: '0a898e16-2a0a-44dd-a580-3ae3bade3684',\n marketType: 'list',\n status: 'PENDING',\n odds: '+400',\n boostType: 'NONE',\n selectionText:\n 'Long Desc Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus non gravida mi. Aliquam volutpat felis ut tempor dictum.',\n type: 'list',\n marketText: 'SBG NBA Special Test',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/odds-boost/organization/specials/competition/specials/event/d53171e2-f821-4da8-9b1c-ce1a4b735914&market_selection_id[0]=0a898e16-2a0a-44dd-a580-3ae3bade3684&odds_numerator[0]=37&odds_denominator[0]=10',\n marketStatus: 'LIVE',\n },\n ],\n },\n ],\n rewardInfo: { type: 'NONE' },\n legCount: 1,\n isNoAction: false,\n betDisplayStatement: 'to win',\n },\n ],\n settled: [\n {\n id: 'z/WEFT7NDVjgb0d/+Elr45MfuRg=',\n type: 'STRAIGHT',\n betStatus: 'SETTLED',\n outcome: 'WIN',\n overrideOutcome: 'NOT_SET',\n closedAtTime: '2025-03-08T05:33Z',\n betAmount: '1',\n payoutAmount: '1.91',\n odds: '-110',\n startTime: '2025-03-08T03:00Z',\n events: [\n {\n displayName: 'San Antonio Spurs @ Sacramento Kings',\n legs: [\n {\n id: '05011199-c88f-4c0d-be31-1b1c7549e273',\n marketId: '728792c6-d2da-435b-920a-eb86bdc45e8c',\n marketSelectionId: '60f8aef9-4c98-4ce2-b861-34e72c2ad13b',\n marketType: 'total',\n status: 'WIN',\n odds: '-110',\n boostType: 'NONE',\n selectionText: 'Over 235',\n type: 'over',\n points: '235.0',\n marketText: 'Total Points',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_green_check_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_green_check_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/basketball/organization/united-states/competition/nba/event/e1163795-ddfa-4bfc-9d52-018e8259e4b5&market_selection_id[0]=60f8aef9-4c98-4ce2-b861-34e72c2ad13b&odds_numerator[0]=2&odds_denominator[0]=1',\n marketStatus: 'SETTLED',\n accrued: { goal: 235.0 },\n },\n ],\n },\n ],\n rewardInfo: { type: 'NONE' },\n legCount: 1,\n isNoAction: false,\n betDisplayStatement: 'you won',\n },\n ],\n },\n promotion: {\n title: 'The official sportsbook of ESPN',\n description: 'Open the ESPN BET app on a mobile device and start betting!',\n logo: 'https://a.espncdn.com/i/espnbet/ESPN_Bet_Sportsbook_Light.svg',\n qrCode: 'https://assets.geo.hosted.espnsb.com/api/ext_mocks/qr.png',\n backgroundImage:\n 'https://www.espn.com/redesign/assets/img/ictv/bkg_qr_bet.png',\n },\n disclaimers: {\n location: 'Use a translation with a key based on location here',\n gambling: 'Use a translation with some key based on gambling here',\n },\n ...event,\n};\n","import { Observable } from '../../../../helpers/Observable';\nimport BetsService from '../services/BetsService';\nimport { UserSettingsManager } from '../../../../services/UserSettingsManager';\nimport AnalyticsService from '@/services/AnalyticsService/AnalyticsService';\nimport {\n IBetsResponse,\n IPersonalizedBetsResponse,\n ITeam,\n IUserBet,\n IBetLeg,\n} from '../interfaces/IBets';\n\n// Import ViewModel with correct path\nimport { ViewModel } from '../../../../view-models/ViewModel';\nimport { MOCK_BETS_API_RESPONSE } from '../mocks';\n\nimport IMaestroEventDelegate from '@/interfaces/IMaestroEventDelegate';\nimport { BetCardType, BetType } from '../types/BetsAnalyticsTypes';\nimport SDK from '@/index';\nimport { captureException } from '@/sentry';\nimport { stringHashCode } from '@/helpers/strings';\n\n// The interval for polling bet data (in milliseconds)\nconst DEFAULT_POLLING_INTERVAL = 30000; // 30 seconds\n\nconst BET_ITEM_TYPE = {\n ODDS: 'odds',\n USER_BETS: 'userBets',\n PROMO: 'promo',\n HOT_PROPS: 'hotProps',\n LOCATION_DISCLAIMER: 'locationDisclaimer',\n GAMBLING_MESSAGE: 'gamblingMessage',\n} as const;\n\nexport type BetItemType = typeof BET_ITEM_TYPE[keyof typeof BET_ITEM_TYPE];\n\ntype TeamOdd = {\n teamAbbreviation: string;\n startOfGameFirstLine: string;\n startOfGameSecondLine: string;\n gameSpreadFirstLine: string;\n gameSpreadSecondLine: string;\n totalPointsFirstLine: string;\n totalPointsSecondLine: string;\n moneylineFirstLine: string;\n};\n\nexport type ISixPackOdds = {\n topTeamOdds: TeamOdd;\n bottomTeamOdds: TeamOdd;\n drawOdds?: TeamOdd;\n orderedColumns: { abbreviation: string; type: string }[];\n gameState: string; // 'in', 'pre', 'post'\n};\n\nexport type IUserBets = {\n defaultTab: string;\n bets: {\n live: IUserBet[];\n upcoming: IUserBet[];\n settled: IUserBet[];\n };\n};\n\nexport type IHotProps = {\n items: IBetLeg[];\n};\n\nexport type ILocationDisclaimer = {\n text: string;\n};\n\nexport type IGamblingMessage = {\n text: string;\n};\n\nexport type IBetPromo = {\n title: string;\n description: string;\n logo: string;\n qrCode: string;\n backgroundImage: string;\n};\n\nexport type PromoBetItem = {\n id: string;\n type: 'promo';\n data: IBetPromo;\n};\n\nexport type LocationDisclaimerBetItem = {\n type: 'locationDisclaimer';\n id: string;\n data: ILocationDisclaimer;\n};\n\nexport type GamblingMessageBetItem = {\n type: 'gamblingMessage';\n id: string;\n data: IGamblingMessage;\n};\n\nexport type SixPackBetItem = {\n type: 'sixPack';\n data: ISixPackOdds;\n teamInfo?: {\n home: ITeam;\n away: ITeam;\n };\n id: string;\n hideWagers: boolean;\n};\n\nexport type UserBetsBetItem = {\n type: 'userBets';\n data: IUserBets;\n id: string;\n hideWagers: boolean;\n};\n\nexport type HotPropsBetItem = {\n type: 'hotProps';\n data: IHotProps;\n id: string;\n hideWagers: boolean;\n};\n\nexport type BetItem =\n | SixPackBetItem\n | UserBetsBetItem\n | PromoBetItem\n | HotPropsBetItem\n | LocationDisclaimerBetItem\n | GamblingMessageBetItem;\n\nconst BET_ERROR_STATE = {\n NONE: 'none',\n TAB_LOAD_FAILURE: 'tabLoadFailure',\n} as const;\nexport type BetsErrorState = typeof BET_ERROR_STATE[keyof typeof BET_ERROR_STATE];\n\nexport interface IBetsViewModelDelegate {\n userIsAuthenticated(): Promise<boolean>;\n getUserSWID(): Promise<string | null>;\n getUserToken(): Promise<string | null>;\n}\n\nconst isPersonalizedBetsResponse = (\n data: any\n): data is IPersonalizedBetsResponse => {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'event' in data &&\n typeof data.event === 'object'\n );\n};\n\nexport class BetsViewModel extends ViewModel {\n // Observable properties\n public betsItems = new Observable<BetItem[]>([]);\n public isDataLoading = new Observable<boolean>(true);\n public errorState = new Observable<BetsErrorState>('none');\n public hasEverSuccessfullyLoaded = new Observable<boolean>(false);\n public hideWagers = new Observable<boolean>(false);\n\n // Properties\n private eventId: string;\n private delegate: IBetsViewModelDelegate;\n private betsService: BetsService;\n private analyticsService: AnalyticsService;\n private pollingInterval: number;\n private pollingTask: { stop: () => void } | null = null;\n private lastNonPersonalizedResponseHash: number | null = null;\n private lastPersonalizedResponseHash: number | null = null;\n private useMockData: boolean = false;\n private userSettingsManager: UserSettingsManager;\n private settingsSubscription: (() => void) | null = null;\n initialized = false;\n\n constructor(\n eventId: string,\n delegate: IMaestroEventDelegate,\n analyticsService: AnalyticsService,\n options: {\n useMockData?: boolean;\n } = {}\n ) {\n super();\n this.eventId = eventId;\n this.delegate = delegate;\n this.betsService = new BetsService(delegate);\n this.analyticsService = analyticsService;\n this.pollingInterval = DEFAULT_POLLING_INTERVAL;\n this.useMockData = options.useMockData || false;\n this.userSettingsManager = UserSettingsManager.getInstance();\n\n // Initialize hide_wagers setting\n this.hideWagers.value = this.userSettingsManager.shouldHideWagers();\n\n // Subscribe to settings changes\n this.settingsSubscription = this.userSettingsManager.settings.subscribe(\n () => {\n this.updateHideWagersFromSettings();\n }\n );\n\n this.betsService = new BetsService(delegate);\n }\n\n /**\n * Initialize the ViewModel and start data fetching\n */\n async init(): Promise<void> {\n // Track panel view on initialization\n this.trackPanelView();\n\n await this.fetchNewData();\n this.refreshPolling();\n this.initialized = true;\n }\n\n /**\n * Clean up resources when the ViewModel is no longer needed\n */\n cleanup(): void {\n this.stopPolling();\n\n // Clean up settings subscription\n if (this.settingsSubscription) {\n this.settingsSubscription();\n this.settingsSubscription = null;\n }\n\n this.initialized = false;\n }\n\n /**\n * Track panel view event\n */\n private async trackPanelView(): Promise<void> {\n try {\n const betCounts = this.getUserBetCounts();\n await this.analyticsService.panelView('espnBet', betCounts);\n } catch (error) {\n captureException(error, {\n context: 'BetsViewModel.trackPanelView',\n });\n console.error('[BET] Error tracking panel view:', error);\n }\n }\n\n /**\n * Track card click event\n */\n async trackCardClick(\n cardType: BetCardType,\n betType?: BetType | null\n ): Promise<void> {\n try {\n const betCounts = this.getUserBetCounts();\n\n const metadata = {\n ...betCounts,\n card: cardType,\n bet_type: betType || null,\n };\n\n await this.analyticsService.panelClick({\n type: 'espnBet',\n name: 'bets_item_clicked',\n metadata,\n });\n } catch (error) {\n captureException(error, {\n context: 'BetsViewModel.trackCardClick',\n cardType,\n betType,\n });\n console.error('[BET] Error tracking card click:', error);\n }\n }\n\n /**\n * Get user bet counts for analytics\n */\n private getUserBetCounts(): {\n in_game_bets: number;\n total_bets: number;\n } {\n try {\n let inGameBets = 0;\n let totalBets = 0;\n\n // Count bets from current data\n for (const item of this.betsItems.value) {\n if (item.type === 'userBets') {\n const userBetsItem = item as UserBetsBetItem;\n const allBets = [\n ...userBetsItem.data.bets.live,\n ...userBetsItem.data.bets.settled,\n ...userBetsItem.data.bets.upcoming,\n ];\n\n totalBets = allBets.length;\n\n inGameBets = userBetsItem.data.bets.live.length;\n break;\n }\n }\n\n return {\n in_game_bets: inGameBets,\n total_bets: totalBets,\n };\n } catch (error) {\n captureException(error, {\n context: 'BetsViewModel.getUserBetCounts',\n });\n console.error('[BET] Error getting user bet counts:', error);\n return {\n in_game_bets: 0,\n total_bets: 0,\n };\n }\n }\n\n /**\n * Refresh polling for bet data\n */\n refreshPolling(): void {\n // First stop any existing polling\n this.stopPolling();\n\n if (this.useMockData) {\n return;\n }\n\n // We'll determine whether to use authenticated polling in the polling task\n this.pollingTask = {\n stop: () => {\n // This will be replaced when actual polling starts\n },\n };\n\n // Start the poll loop\n this.pollWithInterval();\n }\n\n /**\n * Get user credentials from delegate\n */\n private async getUserCredentials(): Promise<{ swid: string; jwt: string }> {\n const swid = (await this.delegate.getUserSWID()) || '';\n const jwt = (await this.delegate.getUserToken()) || '';\n return { swid, jwt };\n }\n\n /**\n * @description Update polling interval checking either response header or panel config.\n * Refresh polling if necessary.\n */\n private updatePollingInterval(headers: Record<string, string>): void {\n const headerInterval = this.getResponseHeaderPollingIntervalValue(headers);\n const panelConfigInterval = this.getPanelConfigInterval();\n\n const newInterval = headerInterval || panelConfigInterval; // order matters here\n if (newInterval && newInterval !== this.pollingInterval) {\n this.pollingInterval = newInterval;\n console.log(\n `[BET] Updating polling interval to ${this.pollingInterval} milliseconds`\n );\n // If we have an active polling task, restart it with the new interval\n this.refreshPolling();\n }\n }\n\n private getPanelConfigInterval() {\n const config = SDK.getPageConfig();\n const panel = config?.panels?.find((p) => p.panel_type === 'espnBet');\n if (!panel) {\n return null;\n }\n\n const oddsPollingInterval =\n panel.renderer?.block_data?.odds_polling_interval;\n if (!oddsPollingInterval) {\n return null;\n }\n\n const parsedInterval = parseInt(oddsPollingInterval, 10);\n if (isNaN(parsedInterval) || parsedInterval <= 0) {\n console.warn(\n `[BET] Invalid polling interval from panel config: ${oddsPollingInterval}.`\n );\n return null;\n }\n\n return parsedInterval * 1000; // Convert seconds to milliseconds\n }\n\n private getResponseHeaderPollingIntervalValue(\n headers: Record<string, string>\n ): number | null {\n const newInterval = headers['polling-interval'];\n if (!newInterval) {\n return null;\n }\n\n const parsedInterval = parseInt(newInterval, 10);\n if (isNaN(parsedInterval) || parsedInterval <= 0) {\n console.warn(\n `[BET] Invalid polling interval header received: ${newInterval}.`\n );\n return null;\n }\n\n return parsedInterval * 1000; // Convert seconds to milliseconds\n }\n\n /**\n * Poll with the personalized endpoint for both authenticated and anonymous users\n *\n * SWID format is provided by the client app delegate:\n * - Logged in: {6D201B58-440C-47A6-970B-0F8C78C0BAB8} (with curly braces)\n * - Anonymous: 6D201B58-440C-47A6-970B-0F8C78C0BAB8 (without curly braces)\n * - Failsafe: Empty string if local storage fails\n */\n private async pollWithInterval(): Promise<void> {\n try {\n // Always use personalized endpoint\n const { swid, jwt } = await this.getUserCredentials();\n\n // Start personalized polling for both authenticated and anonymous users with headers\n this.pollingTask = this.betsService.pollPersonalizedBetsWithHeaders(\n this.eventId,\n swid,\n jwt,\n this.pollingInterval,\n (response) => {\n this.updatePollingInterval(response.headers);\n this.processPolledData(response.data);\n },\n this.handlePollingError.bind(this)\n );\n } catch (error) {\n captureException(error, {\n context: 'BetsViewModel.pollWithInterval',\n });\n console.error('[BET] Error setting up polling:', error);\n }\n }\n\n /**\n * Process data received from polling\n */\n private processPolledData(\n data: IBetsResponse | IPersonalizedBetsResponse\n ): void {\n // Calculate hash for the response to check if it's different from the last one\n const responseHash = stringHashCode(JSON.stringify(data));\n const isPersonalized = isPersonalizedBetsResponse(data);\n\n if (isPersonalized) {\n // Check if this is the same as the last successful response\n if (\n this.lastPersonalizedResponseHash === responseHash &&\n this.hasEverSuccessfullyLoaded.value\n ) {\n console.log(\n '[BET] Response hash is the same as last successful response - skipping update'\n );\n return;\n }\n\n // Update tracking variables\n this.lastPersonalizedResponseHash = responseHash;\n // this.lastSuccessfulResponsePersonalized =\n // data as IPersonalizedBetsResponse;\n } else {\n // Check if this is the same as the last successful response\n if (\n this.lastNonPersonalizedResponseHash === responseHash &&\n this.hasEverSuccessfullyLoaded.value\n ) {\n console.log(\n '[BET] Response hash is the same as last successful response - skipping update'\n );\n return;\n }\n\n // Update tracking variables\n this.lastNonPersonalizedResponseHash = responseHash;\n // this.lastSuccessfulResponseNonPersonalized = data as IBetsResponse;\n }\n\n // Update state\n this.hasEverSuccessfullyLoaded.value = true;\n this.errorState.value = 'none';\n\n // Process the response and update betsItems\n // This is a placeholder - you would need to implement the actual logic\n // for parsing different parts of the response (sixPacks, hot props, etc.)\n this.processBetsData(data);\n }\n\n /**\n * Process the bets data and update the betsItems\n */\n private processBetsData(\n data: IBetsResponse | IPersonalizedBetsResponse\n ): void {\n // Clear current items\n const newItems: BetItem[] = [];\n if (!Object.keys(data).length) {\n return;\n }\n\n // 1. Process regular odds (always available in both response types)\n const sixPack = this.processSixPackData(data);\n if (sixPack) {\n newItems.push(sixPack);\n }\n\n // 2. Process location disclaimer if this is a personalized response\n const locationDisclaimer = this.processLocationDisclaimer(data);\n if (locationDisclaimer) {\n newItems.push(locationDisclaimer);\n }\n\n // 3. Process user bets if this is a personalized response\n const userBets = this.processUserBetsData(data);\n if (userBets) {\n newItems.push(userBets);\n }\n\n // 4. Process featured(hot props) bets if available\n const hotProps = this.processHotProps(data);\n if (hotProps) {\n newItems.push(hotProps);\n }\n\n // 5. Process promo code\n const promoCode = this.processPromoCode(data);\n if (promoCode) {\n newItems.push(promoCode);\n }\n\n // 6. Process gambling message if available\n const gamblingMessage = this.processGamblingMessage(data);\n if (gamblingMessage) {\n newItems.push(gamblingMessage);\n }\n\n // Update the observable\n this.betsItems.value = newItems;\n }\n\n private processLocationDisclaimer(\n data: IBetsResponse | IPersonalizedBetsResponse\n ): LocationDisclaimerBetItem | null {\n const isPersonalized = isPersonalizedBetsResponse(data);\n if (!isPersonalized || !data.disclaimers?.location) {\n return null;\n }\n\n return {\n type: 'locationDisclaimer',\n id: 'locationDisclaimer',\n data: {\n text: data.disclaimers.location,\n },\n };\n }\n\n private processPromoCode(\n data: IBetsResponse | IPersonalizedBetsResponse\n ): PromoBetItem | null {\n const isPersonalized = isPersonalizedBetsResponse(data);\n if (!isPersonalized || !data.promotion) {\n return null;\n }\n\n return {\n type: 'promo',\n data: {\n title: data.promotion.title || '',\n description: data.promotion.description || '',\n logo: data.promotion.logo || '',\n qrCode: data.promotion.qrCode || '',\n backgroundImage: data.promotion.backgroundImage || '',\n },\n id: `promo-${data.event?.id || data.id}`,\n };\n }\n\n private processGamblingMessage(\n data: IBetsResponse | IPersonalizedBetsResponse\n ): GamblingMessageBetItem | null {\n const isPersonalized = isPersonalizedBetsResponse(data);\n if (!isPersonalized || !data.disclaimers?.gambling) {\n return null;\n }\n\n return {\n type: 'gamblingMessage',\n id: 'gamblingMessage',\n data: {\n text: data.disclaimers.gambling,\n },\n };\n }\n\n private processSixPackData(\n response: IBetsResponse | IPersonalizedBetsResponse\n ): SixPackBetItem | null {\n const isPersonalized = isPersonalizedBetsResponse(response);\n const teams = response.entities?.teams;\n\n const odds = !isPersonalized\n ? response.bets?.odds\n : response.event?.bets?.odds;\n const gameState = !isPersonalized\n ? response.gameState\n : response.event?.gameState;\n\n const sport = !isPersonalized ? response.sport : response.event?.sport;\n const eventId = !isPersonalized ? response.id : response.event?.id;\n const isSoccer = !isPersonalized\n ? response.sport === 'soccer'\n : response.event?.sport === 'soccer';\n\n if (!odds || !gameState || !sport || !eventId || !teams) {\n return null;\n }\n\n const teamArray = Object.values(teams);\n let awayTeam: ITeam | undefined;\n let homeTeam: ITeam | undefined;\n\n // Find home and away teams from odds\n for (const team of Object.values(teams)) {\n const spreadOdds = odds.find((odd) => odd.type === 'pointSpread');\n if (spreadOdds) {\n if (\n spreadOdds.values.some((v) => v.team === team.id && v.type === 'home')\n ) {\n homeTeam = team;\n } else if (\n spreadOdds.values.some((v) => v.team === team.id && v.type === 'away')\n ) {\n awayTeam = team;\n }\n }\n }\n\n // Fallback logic if we couldn't determine from odds\n if (!homeTeam || !awayTeam) {\n console.warn(\n 'Could not determine home/away teams from odds, using first two teams'\n );\n switch (teamArray.length) {\n case 0:\n throw new Error('No teams found in response');\n case 1:\n // Only one team - unusual case, but handle gracefully\n homeTeam = teamArray[0];\n awayTeam = teamArray[0]; // Same team as both home and away (shouldn't happen)\n break;\n case 2:\n // Default to first team as home, second as away\n homeTeam = teamArray[0];\n awayTeam = teamArray[1];\n break;\n default:\n // More than 2 teams - take first two and log warning\n homeTeam = teamArray[0];\n awayTeam = teamArray[1];\n console.warn(\n `Warning: Unexpected team count (${teamArray.length}) in six pack response`\n );\n }\n }\n\n if (!awayTeam || !homeTeam) {\n throw new Error('Could not determine home or away team from response');\n }\n\n const isInProgress = gameState === 'in';\n const isHomeFavoured = (() => {\n if (isSoccer && !isInProgress) {\n return homeTeam.favoredAtOpen ?? true;\n }\n\n return homeTeam.favored ?? true;\n })();\n const isAwayFavoured = (() => {\n if (isSoccer && !isInProgress) {\n return awayTeam.favoredAtOpen ?? false;\n }\n\n return awayTeam.favored ?? false;\n })();\n\n let awayTeamStartGameFirstLine = '';\n let awayTeamStartGameSecondLine = '';\n let homeTeamStartGameFirstLine = '';\n let homeTeamStartGameSecondLine = '';\n\n let awaySpreadFirstLine = '';\n let awaySpreadSecondLine = '';\n let homeSpreadFirstLine = '';\n let homeSpreadSecondLine = '';\n\n let awayTotalFirstLine = '';\n let awayTotalSecondLine = '';\n let homeTotalFirstLine = '';\n let homeTotalSecondLine = '';\n\n let awayMoneylineFirstLine = '';\n let homeMoneylineFirstLine = '';\n\n let drawGameStateFirstLine = '';\n let drawGameStateSecondLine = '';\n\n let drawMoneylineFirstLine = '';\n\n const itemTypeSet = new Set<string>();\n const orderedColumns: { abbreviation: string; type: string }[] = [];\n for (const oddsItem of odds) {\n if (!itemTypeSet.has(oddsItem.type)) {\n orderedColumns.push({\n type: oddsItem.type,\n abbreviation: oddsItem.abbreviation,\n });\n itemTypeSet.add(oddsItem.type);\n }\n\n const isLive = oddsItem.state === 'live';\n const isClose = oddsItem.state === 'close';\n const isOpen = oddsItem.state === 'open';\n\n // For every odd type and using the correct state based on game state, get the odds and lines for the home and away team.\n // There are special handlings for the 'start of game' lines. It can be from 'spread', 'total' or 'moneyline' depending on which team is favoured, sport, etc.\n switch (oddsItem.type) {\n case 'pointSpread': {\n const spreadCorrectState = isInProgress ? isLive : isClose;\n if (spreadCorrectState) {\n for (const value of oddsItem.values) {\n if (value.type === 'home') {\n homeSpreadFirstLine = value.line ?? '';\n homeSpreadSecondLine = value.odds ?? '';\n }\n\n if (value.type === 'away') {\n awaySpreadFirstLine = value.line ?? '';\n awaySpreadSecondLine = value.odds ?? '';\n }\n }\n }\n\n const pointsSpreadStartOfGameCorrectState = isInProgress\n ? isClose\n : isOpen;\n if (pointsSpreadStartOfGameCorrectState && !isSoccer) {\n if (isHomeFavoured) {\n for (const value of oddsItem.values) {\n if (value.type === 'home') {\n homeTeamStartGameFirstLine = value.line ?? '';\n homeTeamStartGameSecondLine = value.odds ?? '';\n }\n }\n }\n\n if (isAwayFavoured) {\n for (const value of oddsItem.values) {\n if (value.type === 'away') {\n awayTeamStartGameFirstLine = value.line ?? '';\n awayTeamStartGameSecondLine = value.odds ?? '';\n }\n }\n }\n }\n break;\n }\n\n case 'total': {\n const totalCorrectState = isInProgress ? isLive : isClose;\n if (totalCorrectState) {\n for (const value of oddsItem.values) {\n if (value.type === 'over') {\n if (isSoccer) {\n homeTotalFirstLine = value.line ?? '';\n homeTotalSecondLine = value.odds ?? '';\n } else {\n awayTotalFirstLine = value.line ?? '';\n awayTotalSecondLine = value.odds ?? '';\n }\n }\n\n if (value.type === 'under') {\n if (isSoccer) {\n awayTotalFirstLine = value.line ?? '';\n awayTotalSecondLine = value.odds ?? '';\n } else {\n homeTotalFirstLine = value.line ?? '';\n homeTotalSecondLine = value.odds ?? '';\n }\n }\n }\n }\n\n const totalStartOfGameCorrectState = isInProgress ? isClose : isOpen;\n if (totalStartOfGameCorrectState) {\n // If home is not favoured, use total as the start of the game line\n if (!isHomeFavoured) {\n for (const value of oddsItem.values) {\n if (\n (isSoccer && value.type === 'over') ||\n (!isSoccer && value.type === 'under')\n ) {\n homeTeamStartGameFirstLine = value.line ?? '';\n homeTeamStartGameSecondLine = value.odds ?? '';\n }\n }\n }\n\n // If away is not favoured, use total as the start of the game line\n if (!isAwayFavoured) {\n for (const value of oddsItem.values) {\n if (\n (isSoccer && value.type === 'under') ||\n (!isSoccer && value.type === 'over')\n ) {\n awayTeamStartGameFirstLine = value.line ?? '';\n awayTeamStartGameSecondLine = value.odds ?? '';\n }\n }\n }\n }\n break;\n }\n\n case 'moneyline': {\n const mlCorrectState = isInProgress ? isLive : isClose;\n if (mlCorrectState) {\n for (const value of oddsItem.values) {\n if (value.type === 'home') {\n homeMoneylineFirstLine = value.odds ?? '';\n }\n if (value.type === 'away') {\n awayMoneylineFirstLine = value.odds ?? '';\n }\n }\n }\n\n // soccer logic\n if (isSoccer) {\n const moneyLineStartOfGameCorrectState = isInProgress\n ? isClose\n : isOpen;\n\n // find draw value\n for (const value of oddsItem.values) {\n if (value.type === 'draw') {\n if (moneyLineStartOfGameCorrectState) {\n drawGameStateFirstLine = value.odds ?? '';\n drawGameStateSecondLine = 'DRAW';\n }\n\n if (mlCorrectState) {\n drawMoneylineFirstLine = value.odds ?? '';\n }\n }\n }\n\n if (moneyLineStartOfGameCorrectState) {\n if (isHomeFavoured) {\n for (const value of oddsItem.values) {\n if (value.type === 'home') {\n homeTeamStartGameFirstLine = value.odds ?? '';\n homeTeamStartGameSecondLine = oddsItem.abbreviation ?? '';\n }\n }\n }\n\n if (isAwayFavoured) {\n for (const value of oddsItem.values) {\n if (value.type === 'away') {\n awayTeamStartGameFirstLine = value.odds ?? '';\n awayTeamStartGameSecondLine = oddsItem.abbreviation ?? '';\n }\n }\n }\n }\n }\n break;\n }\n }\n }\n\n // Create the six pack data structure\n const awayTeamOdds: TeamOdd = {\n teamAbbreviation: awayTeam.abbreviation ?? '',\n startOfGameFirstLine: awayTeamStartGameFirstLine,\n startOfGameSecondLine: awayTeamStartGameSecondLine,\n gameSpreadFirstLine: awaySpreadFirstLine,\n gameSpreadSecondLine: awaySpreadSecondLine,\n totalPointsFirstLine: awayTotalFirstLine,\n totalPointsSecondLine: awayTotalSecondLine,\n moneylineFirstLine: awayMoneylineFirstLine,\n };\n\n const homeTeamOdds: TeamOdd = {\n teamAbbreviation: homeTeam.abbreviation ?? '',\n startOfGameFirstLine: homeTeamStartGameFirstLine,\n startOfGameSecondLine: homeTeamStartGameSecondLine,\n gameSpreadFirstLine: homeSpreadFirstLine,\n gameSpreadSecondLine: homeSpreadSecondLine,\n totalPointsFirstLine: homeTotalFirstLine,\n totalPointsSecondLine: homeTotalSecondLine,\n moneylineFirstLine: homeMoneylineFirstLine,\n };\n\n const drawOdds: TeamOdd = {\n teamAbbreviation: 'DRAW',\n startOfGameFirstLine: drawGameStateFirstLine,\n startOfGameSecondLine: drawGameStateSecondLine,\n gameSpreadFirstLine: '',\n gameSpreadSecondLine: '',\n totalPointsFirstLine: '',\n totalPointsSecondLine: '',\n moneylineFirstLine: drawMoneylineFirstLine,\n };\n\n const sixPack: ISixPackOdds = {\n topTeamOdds: isSoccer ? homeTeamOdds : awayTeamOdds,\n bottomTeamOdds: isSoccer ? awayTeamOdds : homeTeamOdds,\n drawOdds:\n drawGameStateFirstLine &&\n drawGameStateSecondLine &&\n drawMoneylineFirstLine\n ? drawOdds\n : undefined,\n orderedColumns,\n gameState,\n };\n\n return {\n id: `sixpack-${eventId}`,\n type: 'sixPack',\n data: sixPack,\n teamInfo: {\n home: homeTeam,\n away: awayTeam,\n },\n hideWagers: this.hideWagers.value,\n };\n }\n\n private processUserBetsData(\n data: IBetsResponse | IPersonalizedBetsResponse\n ): UserBetsBetItem | null {\n const isPersonalized = isPersonalizedBetsResponse(data);\n if (!isPersonalized || !data.event || !data.betsModule) {\n return null;\n }\n\n const betItems: IUserBets['bets'] = {\n live: data.betsModule.live.filter((bet) => bet.type !== 'promo'),\n settled: data.betsModule.settled.filter((bet) => bet.type !== 'promo'),\n upcoming: data.betsModule.upcoming.filter((bet) => bet.type !== 'promo'),\n };\n\n return {\n data: {\n bets: betItems,\n defaultTab: data.betsModule.defaultTab,\n },\n id: `userBets-${data.event.id}`,\n type: 'userBets',\n hideWagers: this.hideWagers.value,\n };\n }\n\n private processHotProps(\n response: IBetsResponse | IPersonalizedBetsResponse\n ): HotPropsBetItem | null {\n const isPersonalized = isPersonalizedBetsResponse(response);\n const hotProps = isPersonalized\n ? response.event?.featured\n : response.featured;\n\n if (!hotProps || !Array.isArray(hotProps)) {\n return null;\n }\n\n const hasData = hotProps.every((hotProp) => Boolean(hotProp && hotProp.id));\n if (!hasData) {\n return null;\n }\n\n const filteredHotProps = hotProps.filter(\n (hotProp) => hotProp.selections.length > 0\n );\n\n return {\n type: 'hotProps',\n hideWagers: this.hideWagers.value,\n id: 'hotProps',\n data: {\n items: filteredHotProps.map((hotProp) => {\n const bet = hotProp.selections[0];\n\n return {\n id: bet.id,\n odds: bet.odds.current || '',\n marketText: bet.text,\n selectionText: hotProp.text,\n status: bet.status,\n type: bet.type,\n icon: bet.icon,\n iconDark: bet.iconDark,\n outcome: bet.outcome,\n };\n }),\n },\n };\n }\n\n /**\n * Handle errors that occur during polling\n */\n private handlePollingError(error: Error): void {\n console.error('Polling error:', error);\n\n if (!this.hasEverSuccessfullyLoaded.value) {\n // If we've never had a successful load, show an error state\n this.errorState.value = 'tabLoadFailure';\n this.betsItems.value = [];\n } else {\n // If we had a previous successful load, keep showing the old data\n // No need to update errorState or betsItems\n }\n }\n\n /**\n * Stop polling for bet data\n */\n stopPolling(): void {\n if (this.pollingTask) {\n this.pollingTask.stop();\n this.pollingTask = null;\n }\n\n if (this.isDataLoading.value) {\n this.isDataLoading.value = false;\n }\n }\n\n /**\n * Fetch new bet data immediately (one-time)\n */\n async fetchNewData(): Promise<void> {\n this.isDataLoading.value = true;\n\n try {\n // Handle mock data if enabled\n if (this.useMockData) {\n this.betsItems.value = [];\n await this.fetchMockData();\n return;\n }\n\n // Always use personalized endpoint for both authenticated and anonymous users\n await this.fetchPersonalizedData();\n this.isDataLoading.value = false;\n } catch (error) {\n captureException(error, {\n context: 'BetsViewModel.fetchNewData',\n });\n console.error('[BET] Error fetching bet data:', error);\n\n if (!this.hasEverSuccessfullyLoaded.value) {\n this.errorState.value = 'tabLoadFailure';\n this.betsItems.value = [];\n }\n\n this.isDataLoading.value = false;\n }\n }\n\n /**\n * Fetch personalized bet data\n */\n private async fetchPersonalizedData(): Promise<void> {\n try {\n const { swid, jwt } = await this.getUserCredentials();\n\n const response = await this.betsService.getPersonalizedBets(\n this.eventId,\n swid,\n jwt\n );\n\n // Process the response\n this.processPolledData(response);\n } catch (error) {\n captureException(error, {\n context: 'BetsViewModel.fetchPersonalizedData',\n });\n console.error('[BET] Error fetching personalized bets:', error);\n throw error;\n }\n }\n\n /**\n * Fetch mock data for testing\n */\n private async fetchMockData(): Promise<void> {\n this.processBetsData(MOCK_BETS_API_RESPONSE);\n this.hasEverSuccessfullyLoaded.value = true;\n this.errorState.value = 'none';\n this.isDataLoading.value = false;\n }\n\n clearTabLoadFailure() {\n this.errorState.value = 'none';\n setTimeout(() => {\n this.refreshPolling();\n }, 100);\n }\n\n /**\n * Check if wagers should be hidden based on user settings\n */\n shouldHideWagers(): boolean {\n return this.hideWagers.value;\n }\n\n /**\n * Update hideWagers Observable from current settings\n */\n private updateHideWagersFromSettings(): void {\n this.hideWagers.value = this.userSettingsManager.shouldHideWagers();\n this.refreshBetItemsWithNewSettings();\n }\n\n private refreshBetItemsWithNewSettings(): void {\n this.betsItems.value = this.betsItems.value.map((item) => {\n if (item.type === 'sixPack') {\n return {\n ...item,\n hideWagers: this.hideWagers.value,\n };\n }\n if (item.type === 'userBets') {\n return {\n ...item,\n hideWagers: this.hideWagers.value,\n };\n }\n if (item.type === 'hotProps') {\n return {\n ...item,\n hideWagers: this.hideWagers.value,\n };\n }\n return item;\n });\n }\n}\n\nexport default BetsViewModel;\n"],"sourceRoot":""}
1
+ {"version":3,"sources":["webpack:///./src/helpers/strings.ts","webpack:///./src/modules/espn/bets/services/BetsService.ts","webpack:///./src/modules/espn/bets/mocks.ts","webpack:///./src/modules/espn/bets/view-model/BetsViewModel.ts"],"names":["slugify","str","toLowerCase","trim","replace","stringHashCode","hash","i","length","charCodeAt","BetsService","constructor","delegate","_defineProperty","this","networkManager","NetworkManager","externalBaseURL","getBettingAPIBaseURL","eventID","externalApiRequest","endpoint","nonPersonalizedBetsEndpoint","method","HttpMethod","GET","params","deviceType","headers","swid","jwt","personalizedBetsEndpoint","externalApiRequestWithHeaders","pollPersonalizedBets","interval","onData","onError","pollExternalApiRequest","pollPersonalizedBetsWithHeaders","pollExternalApiRequestWithHeaders","event","id","sport","date","gameState","featured","selections","icon","iconDark","odds","outcome","status","text","type","bets","displayName","abbreviation","state","values","team","line","MOCK_BETS_API_RESPONSE","entities","teams","uid","guid","slug","shortDisplayName","name","nickname","location","color","alternateColor","favored","betsModule","defaultTab","upcoming","live","betStatus","overrideOutcome","betAmount","payoutAmount","startTime","events","legs","marketId","marketSelectionId","marketType","boostType","selectionText","marketText","url","marketStatus","rewardInfo","legCount","isNoAction","betDisplayStatement","light","dark","settled","closedAtTime","points","accrued","goal","promotion","title","description","logo","qrCode","backgroundImage","disclaimers","gambling","isPersonalizedBetsResponse","data","BetsViewModel","ViewModel","eventId","analyticsService","options","super","Observable","betsService","pollingInterval","useMockData","userSettingsManager","UserSettingsManager","getInstance","hideWagers","value","shouldHideWagers","settingsSubscription","settings","subscribe","updateHideWagersFromSettings","trackPanelView","fetchNewData","refreshPolling","initialized","cleanup","stopPolling","betCounts","getUserBetCounts","panelView","error","captureException","context","console","cardType","betType","metadata","card","bet_type","panelClick","inGameBets","totalBets","item","betsItems","userBetsItem","in_game_bets","total_bets","pollingTask","stop","pollWithInterval","getUserSWID","getUserToken","updatePollingInterval","headerInterval","getResponseHeaderPollingIntervalValue","panelConfigInterval","getPanelConfigInterval","newInterval","log","_config$panels","_panel$renderer","_panel$renderer$block","config","SDK","getPageConfig","panel","panels","find","p","panel_type","oddsPollingInterval","renderer","block_data","odds_polling_interval","parsedInterval","parseInt","isNaN","warn","getUserCredentials","response","processPolledData","handlePollingError","bind","responseHash","JSON","stringify","lastPersonalizedResponseHash","hasEverSuccessfullyLoaded","lastNonPersonalizedResponseHash","errorState","processBetsData","newItems","Object","keys","sixPack","processSixPackData","push","locationDisclaimer","processLocationDisclaimer","userBets","processUserBetsData","hotProps","processHotProps","promoCode","processPromoCode","gamblingMessage","processGamblingMessage","_data$disclaimers","_data$event","_data$disclaimers2","_response$entities","_response$bets","_response$event","_response$event$bets","_response$event2","_response$event3","_response$event4","_response$event5","_awayTeam$abbreviatio","_homeTeam$abbreviatio","isPersonalized","isSoccer","teamArray","awayTeam","homeTeam","spreadOdds","odd","some","v","Error","isInProgress","isHomeFavoured","_homeTeam$favoredAtOp","favoredAtOpen","_homeTeam$favored","isAwayFavoured","_awayTeam$favoredAtOp","_awayTeam$favored","awayTeamStartGameFirstLine","awayTeamStartGameSecondLine","homeTeamStartGameFirstLine","homeTeamStartGameSecondLine","awaySpreadFirstLine","awaySpreadSecondLine","homeSpreadFirstLine","homeSpreadSecondLine","awayTotalFirstLine","awayTotalSecondLine","homeTotalFirstLine","homeTotalSecondLine","awayMoneylineFirstLine","homeMoneylineFirstLine","drawGameStateFirstLine","drawGameStateSecondLine","drawMoneylineFirstLine","itemTypeSet","Set","orderedColumns","oddsItem","has","add","isLive","isClose","isOpen","_value$line","_value$odds","_value$line2","_value$odds2","_value$line3","_value$odds3","_value$line4","_value$odds4","_value$line5","_value$odds5","_value$line6","_value$odds6","_value$line7","_value$odds7","_value$line8","_value$odds8","_value$line9","_value$odds9","_value$line0","_value$odds0","mlCorrectState","_value$odds1","_value$odds10","moneyLineStartOfGameCorrectState","_value$odds11","_value$odds12","_value$odds13","_oddsItem$abbreviatio","_value$odds14","_oddsItem$abbreviatio2","awayTeamOdds","teamAbbreviation","startOfGameFirstLine","startOfGameSecondLine","gameSpreadFirstLine","gameSpreadSecondLine","totalPointsFirstLine","totalPointsSecondLine","moneylineFirstLine","homeTeamOdds","topTeamOdds","bottomTeamOdds","drawOdds","undefined","teamInfo","home","away","filter","bet","_response$event6","Array","isArray","every","hotProp","Boolean","filteredHotProps","items","map","current","isDataLoading","fetchMockData","fetchPersonalizedData","getPersonalizedBets","clearTabLoadFailure","setTimeout","refreshBetItemsWithNewSettings"],"mappings":"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","file":"12.maestro-web-sdk.esm.js","sourcesContent":["export const slugify = (str: string) =>\n str\n .toLowerCase()\n .trim()\n .replace(/[\\s\\W-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n\nexport function stringHashCode(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return hash;\n}\n","import NetworkManager, {\n HttpMethod,\n} from '../../../../services/NetworkManager/NetworkManager';\nimport { IBetsResponse, IPersonalizedBetsResponse } from '../interfaces/IBets';\nimport IMaestroEventDelegate from '@/interfaces/IMaestroEventDelegate';\n\n/**\n * Service for handling bets-related API calls\n */\nclass BetsService {\n public networkManager: NetworkManager;\n\n constructor(delegate: IMaestroEventDelegate) {\n this.networkManager = new NetworkManager({\n externalBaseURL: delegate.getBettingAPIBaseURL(),\n });\n }\n\n /**\n * Get non-personalized bets for an event\n *\n * @deprecated Use getPersonalizedBets instead. This method is kept for backward compatibility.\n * @param eventID - The ID of the event\n * @returns Promise with the bets data\n */\n async getNonPersonalizedBets(eventID: string): Promise<IBetsResponse> {\n return this.networkManager.externalApiRequest({\n endpoint: this.nonPersonalizedBetsEndpoint(eventID),\n method: HttpMethod.GET,\n params: { deviceType: 'ictv' },\n headers: {},\n });\n }\n\n /**\n * Get personalized bets for an event\n *\n * @param eventID - The ID of the event\n * @param swid - The ESPN SWID parameter (format provided by client app delegate)\n * @param jwt - The authorization JWT (empty string for anonymous users)\n * @returns Promise with the personalized bets data\n */\n async getPersonalizedBets(\n eventID: string,\n swid: string,\n jwt: string\n ): Promise<IPersonalizedBetsResponse> {\n return this.networkManager.externalApiRequest({\n endpoint: this.personalizedBetsEndpoint(eventID),\n method: HttpMethod.GET,\n params: { swid, deviceType: 'ictv' },\n headers: { 'x-p13n-auth': jwt },\n });\n }\n\n /**\n * Get personalized bets for an event with headers\n *\n * @param eventID - The ID of the event\n * @param swid - The ESPN SWID parameter (format provided by client app delegate)\n * @param jwt - The authorization JWT (empty string for anonymous users)\n * @returns Promise with the personalized bets data and headers\n */\n async getPersonalizedBetsWithHeaders(\n eventID: string,\n swid: string,\n jwt: string\n ): Promise<{\n data: IPersonalizedBetsResponse;\n headers: Record<string, string>;\n }> {\n return this.networkManager.externalApiRequestWithHeaders({\n endpoint: this.personalizedBetsEndpoint(eventID),\n method: HttpMethod.GET,\n params: { swid, deviceType: 'ictv' },\n headers: { 'x-p13n-auth': jwt },\n });\n }\n\n /**\n * Start polling for personalized bets\n *\n * @param eventID - The ID of the event\n * @param swid - The ESPN SWID parameter\n * @param jwt - The authorization JWT\n * @param interval - The polling interval in milliseconds\n * @param onData - Callback for successful data fetch\n * @param onError - Callback for errors\n * @returns Object with a stop function to stop polling\n */\n pollPersonalizedBets(\n eventID: string,\n swid: string,\n jwt: string,\n interval: number,\n onData: (data: IPersonalizedBetsResponse) => void,\n onError?: (error: Error) => void\n ): { stop: () => void } {\n return this.networkManager.pollExternalApiRequest({\n endpoint: this.personalizedBetsEndpoint(eventID),\n interval,\n method: HttpMethod.GET,\n params: { swid, deviceType: 'ictv' },\n headers: { 'x-p13n-auth': jwt },\n onData,\n onError,\n });\n }\n\n /**\n * Start polling for personalized bets and return both data and headers\n *\n * @param eventID - The ID of the event\n * @param swid - The ESPN SWID parameter\n * @param jwt - The authorization JWT\n * @param interval - The polling interval in milliseconds\n * @param onData - Callback for successful data fetch with headers\n * @param onError - Callback for errors\n * @returns Object with a stop function to stop polling\n */\n pollPersonalizedBetsWithHeaders(\n eventID: string,\n swid: string,\n jwt: string,\n interval: number,\n onData: (response: {\n data: IPersonalizedBetsResponse;\n headers: Record<string, string>;\n }) => void,\n onError?: (error: Error) => void\n ): { stop: () => void } {\n return this.networkManager.pollExternalApiRequestWithHeaders({\n endpoint: this.personalizedBetsEndpoint(eventID),\n interval,\n method: HttpMethod.GET,\n params: { swid, deviceType: 'ictv' },\n headers: { 'x-p13n-auth': jwt },\n onData,\n onError,\n });\n }\n\n /**\n * Get the endpoint for non-personalized bets\n *\n * @deprecated This endpoint is no longer used.\n */\n nonPersonalizedBetsEndpoint(eventID: string): string {\n return `/site/v2/events/${eventID}/odds`;\n }\n\n /**\n * Get the endpoint for personalized bets\n */\n personalizedBetsEndpoint(eventID: string): string {\n return `/personalized/site/v2/events/${eventID}/odds`;\n }\n}\n\nexport default BetsService;\n","import { BetLiveEvent, IPersonalizedBetsResponse } from './interfaces/IBets';\n\nconst event: BetLiveEvent = {\n id: '401721458',\n sport: 'basketball',\n date: '2025-02-28T02:00Z',\n gameState: 'post',\n featured: [\n {\n date: '2024-06-09T17:35Z',\n id: '00015c79-3454-4356-bab6-af050554b761',\n selections: [\n {\n icon: 'https://a.espncdn.com/i/espnbet/mybets_under_caret_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_under_caret_icon.png',\n id: 'f54ad0791-304e-43fe-a45a-96bd237c9c78',\n odds: {},\n outcome: 'PENDING',\n status: 'upcoming',\n text: 'Under 5.5',\n type: 'under',\n },\n {\n icon: 'https://a.espncdn.com/i/espnbet/mybets_under_caret_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_under_caret_icon.png',\n id: 'f54ad079-3604e-43fe-a45a-96bd237c9c78',\n odds: {},\n outcome: 'PENDING',\n status: 'upcoming',\n text: 'Under 5.5',\n type: 'under',\n },\n {\n icon: 'https://a.espncdn.com/i/espnbet/mybets_under_caret_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_under_caret_icon.png',\n id: 'f54ad079-5304e-43fe-a45a-96bd237c9c78',\n odds: {},\n outcome: 'PENDING',\n status: 'upcoming',\n text: 'Under 5.5',\n type: 'under',\n },\n {\n icon: 'https://a.espncdn.com/i/espnbet/mybets_under_caret_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_under_caret_icon.png',\n id: 'f54ad079-3044e-43fe-a45a-96bd237c9c78',\n odds: {},\n outcome: 'PENDING',\n status: 'upcoming',\n text: 'Under 5.5',\n type: 'under',\n },\n {\n icon: 'https://a.espncdn.com/i/espnbet/mybets_under_caret_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_under_caret_icon.png',\n id: 'f54ad079-304e-43fe-a45a-96bd237c9c278',\n odds: {},\n outcome: 'PENDING',\n status: 'upcoming',\n text: 'Under 5.5',\n type: 'under',\n },\n {\n icon: 'https://a.espncdn.com/i/espnbet/mybets_under_caret_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_under_caret_icon.png',\n id: 'f54ad079-304e-43fe-a45a-96bd1237c9c78',\n odds: {},\n outcome: 'PENDING',\n status: 'upcoming',\n text: 'Under 5.5',\n type: 'under',\n },\n ],\n text: 'Carlos Santana Total Hits + Runs + RBIs',\n },\n ],\n bets: {\n odds: [\n {\n displayName: 'Moneyline',\n abbreviation: 'ML',\n type: 'moneyline',\n state: 'close',\n values: [\n { odds: '-500', outcome: 'WIN', team: '130', type: 'home' },\n { odds: '+360', outcome: 'LOSS', team: '164', type: 'away' },\n ],\n },\n {\n displayName: 'Moneyline',\n abbreviation: 'ML',\n type: 'moneyline',\n state: 'open',\n values: [\n { odds: '-700', team: '130', type: 'home' },\n { odds: '+450', team: '164', type: 'away' },\n ],\n },\n {\n displayName: 'Total Points',\n abbreviation: 'Total',\n type: 'total',\n state: 'close',\n values: [\n { line: 'o154.5', odds: '-115', outcome: 'WIN', type: 'over' },\n { line: 'u154.5', odds: '-105', outcome: 'LOSS', type: 'under' },\n ],\n },\n {\n displayName: 'Total Points',\n abbreviation: 'Total',\n type: 'total',\n state: 'open',\n values: [\n { line: 'o154.5', odds: '-105', type: 'over' },\n { line: 'u154.5', odds: '-115', type: 'under' },\n ],\n },\n {\n displayName: 'Spread',\n abbreviation: 'Spread',\n type: 'pointSpread',\n state: 'close',\n values: [\n {\n line: '-9.5',\n odds: '-105',\n outcome: 'LOSS',\n team: '130',\n type: 'home',\n },\n {\n line: '+9.5',\n odds: '-115',\n outcome: 'WIN',\n team: '164',\n type: 'away',\n },\n ],\n },\n {\n displayName: 'Spread',\n abbreviation: 'Spread',\n type: 'pointSpread',\n state: 'open',\n values: [\n { line: '-11.5', odds: '-105', team: '130', type: 'home' },\n { line: '+11.5', odds: '-115', team: '164', type: 'away' },\n ],\n },\n ],\n },\n};\n\nexport const MOCK_BETS_API_RESPONSE: IPersonalizedBetsResponse = {\n entities: {\n teams: {\n '130': {\n id: '130',\n uid: 's:40~l:41~t:130',\n guid: 'c00151c6-cdd4-5aab-0130-37416052eb2a',\n slug: 'michigan-wolverines',\n abbreviation: 'MICH',\n displayName: 'Michigan Wolverines',\n shortDisplayName: 'Michigan',\n name: 'Wolverines',\n nickname: 'Michigan',\n location: 'Michigan',\n color: '00274c',\n alternateColor: 'ffcb05',\n favored: true,\n },\n '164': {\n id: '164',\n uid: 's:40~l:41~t:164',\n guid: '425c8e51-59d0-75a1-0815-dc3556c5cfda',\n slug: 'rutgers-scarlet-knights',\n abbreviation: 'RUTG',\n displayName: 'Rutgers Scarlet Knights',\n shortDisplayName: 'Rutgers',\n name: 'Scarlet Knights',\n nickname: 'Rutgers',\n location: 'Rutgers',\n color: 'd21034',\n alternateColor: 'ffffff',\n favored: false,\n },\n },\n },\n event,\n betsModule: {\n defaultTab: 'live',\n upcoming: [],\n live: [\n {\n id: 'emnPo+hN/Q7CzX/obYcJZCYGql4=',\n type: 'PARLAY',\n betStatus: 'OPEN',\n outcome: 'PENDING',\n overrideOutcome: 'NOT_SET',\n betAmount: '10',\n payoutAmount: '171.55',\n odds: '+1616',\n startTime: '2022-11-29T17:54Z',\n events: [\n {\n displayName: 'Investec South African Open Championship Future',\n legs: [\n {\n id: '71acdfe8-611e-47ae-b7ee-ba6684c6fefa',\n marketId: 'fc47f9f9-2852-4f63-9a70-4adf5b4addd2',\n marketSelectionId: '92803c34-a8b7-476e-9136-b88729c7e51e',\n marketType: 'list',\n status: 'PENDING',\n odds: '+370',\n boostType: 'NONE',\n selectionText: 'Aaron Baddeley',\n type: 'list',\n marketText: 'Tournament Winner',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/golf/organization/dp-world-tour/competition/investec-south-african-open-championship/event/56773312-5fdb-4cb5-b387-df8c18a2c857&market_selection_id[0]=92803c34-a8b7-476e-9136-b88729c7e51e&odds_numerator[0]=11&odds_denominator[0]=2',\n marketStatus: 'LIVE',\n },\n ],\n },\n {\n displayName: 'Lorem Ipsum Dolor Sit Amet',\n legs: [\n {\n id: '472f176b-7575-4d1d-ac63-bcb2d4ec6da9',\n marketId: '2e5fdfdf-7021-464f-939d-5497030fe765',\n marketSelectionId: '3727a3f5-5143-4616-ab4f-713bcf40aa21',\n marketType: 'list',\n status: 'PENDING',\n odds: '+265',\n boostType: 'NONE',\n selectionText: 'Aaron Pike',\n type: 'list',\n marketText: 'Tournament Winner',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/golf/organization/dp-world-tour/competition/isps-handa-australian-open/event/df8ba72f-4be8-4569-840e-954dbd9a7806&market_selection_id[0]=3727a3f5-5143-4616-ab4f-713bcf40aa21&odds_numerator[0]=73&odds_denominator[0]=20',\n marketStatus: 'LIVE',\n },\n ],\n },\n {\n displayName: 'Australian Open Future',\n legs: [\n {\n id: '472f176b-7575-4d1d-ac63-bcb2d4ec6da9',\n marketId: '2e5fdfdf-7021-464f-939d-5497030fe765',\n marketSelectionId: '3727a3f5-5143-4616-ab4f-713bcf40aa21',\n marketType: 'list',\n status: 'PENDING',\n odds: '+265',\n boostType: 'NONE',\n selectionText: 'Aaron Pike',\n type: 'list',\n marketText: 'Tournament Winner',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/golf/organization/dp-world-tour/competition/isps-handa-australian-open/event/df8ba72f-4be8-4569-840e-954dbd9a7806&market_selection_id[0]=3727a3f5-5143-4616-ab4f-713bcf40aa21&odds_numerator[0]=73&odds_denominator[0]=20',\n marketStatus: 'LIVE',\n },\n ],\n },\n {\n displayName: 'USA vs. Australia Future',\n legs: [\n {\n id: '472f176b-7575-4d1d-ac63-bcb2d4ec6da9',\n marketId: '2e5fdfdf-7021-464f-939d-5497030fe765',\n marketSelectionId: '3727a3f5-5143-4616-ab4f-713bcf40aa21',\n marketType: 'list',\n status: 'PENDING',\n odds: '+265',\n boostType: 'NONE',\n selectionText: 'Aaron Pike',\n type: 'list',\n marketText: 'Tournament Winner',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/golf/organization/dp-world-tour/competition/isps-handa-australian-open/event/df8ba72f-4be8-4569-840e-954dbd9a7806&market_selection_id[0]=3727a3f5-5143-4616-ab4f-713bcf40aa21&odds_numerator[0]=73&odds_denominator[0]=20',\n marketStatus: 'LIVE',\n },\n ],\n },\n {\n displayName: 'Championship Future',\n legs: [\n {\n id: '472f176b-7575-4d1d-ac63-bcb2d4ec6da9',\n marketId: '2e5fdfdf-7021-464f-939d-5497030fe765',\n marketSelectionId: '3727a3f5-5143-4616-ab4f-713bcf40aa21',\n marketType: 'list',\n status: 'PENDING',\n odds: '+265',\n boostType: 'NONE',\n selectionText: 'Aaron Pike',\n type: 'list',\n marketText: 'Tournament Winner',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/golf/organization/dp-world-tour/competition/isps-handa-australian-open/event/df8ba72f-4be8-4569-840e-954dbd9a7806&market_selection_id[0]=3727a3f5-5143-4616-ab4f-713bcf40aa21&odds_numerator[0]=73&odds_denominator[0]=20',\n marketStatus: 'LIVE',\n },\n ],\n },\n ],\n rewardInfo: { type: 'NONE' },\n legCount: 5,\n isNoAction: false,\n betDisplayStatement: 'to win',\n },\n {\n id: '9m1bBxUYPyPPjkpzT6buDlcuQng=',\n type: 'STRAIGHT',\n betStatus: 'OPEN',\n outcome: 'PENDING',\n overrideOutcome: 'NOT_SET',\n betAmount: '2',\n payoutAmount: '10.80',\n odds: '+440',\n startTime: '2025-04-30T15:12Z',\n events: [\n {\n displayName: 'SBG/SBE Odds Boost Test',\n legs: [\n {\n id: '8061671d-6d38-4193-a5a6-beab37855840',\n marketId: '567d2a44-ba70-4881-86d7-d25fca94b592',\n marketSelectionId: '59b2b7ee-46c1-4cbc-9286-77fd8670cf9d',\n marketType: 'list',\n status: 'PENDING',\n odds: '+440',\n boostType: 'ODDS_BOOST',\n selectionText:\n 'Lauri Markkanen and Anfernee Simons to Each Record 20+ Points',\n type: 'list',\n marketText: 'SBG/SBE Odds Boost (Was +100)',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/odds-boost/organization/odds-boosts/competition/odds-boosts/event/218e1dca-f68d-4d61-9d79-394e7d752cae&market_selection_id[0]=59b2b7ee-46c1-4cbc-9286-77fd8670cf9d&odds_numerator[0]=27&odds_denominator[0]=5',\n marketStatus: 'LIVE',\n },\n ],\n },\n ],\n rewardInfo: {\n type: 'ODDS_BOOST',\n icon: {\n light: 'https://a.espncdn.com/i/espnbet/boost.png',\n dark: 'https://a.espncdn.com/i/espnbet/boost.png',\n },\n },\n legCount: 1,\n isNoAction: false,\n betDisplayStatement: 'to win',\n },\n {\n id: 'MCH06SyVYvu1UZkhj4KutmL9qKY=',\n type: 'STRAIGHT',\n betStatus: 'OPEN',\n outcome: 'PENDING',\n overrideOutcome: 'NOT_SET',\n betAmount: '3',\n payoutAmount: '16.20',\n odds: '+440',\n startTime: '2025-04-30T15:12Z',\n events: [\n {\n displayName: 'SBG/SBE Odds Boost Test',\n legs: [\n {\n id: '020d7a12-3aa8-459e-8aa2-34eaced4ad7d',\n marketId: '567d2a44-ba70-4881-86d7-d25fca94b592',\n marketSelectionId: '59b2b7ee-46c1-4cbc-9286-77fd8670cf9d',\n marketType: 'list',\n status: 'PENDING',\n odds: '+440',\n boostType: 'ODDS_BOOST',\n selectionText:\n 'Lauri Markkanen and Anfernee Simons to Each Record 20+ Points',\n type: 'list',\n marketText: 'SBG/SBE Odds Boost (Was +100)',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/odds-boost/organization/odds-boosts/competition/odds-boosts/event/218e1dca-f68d-4d61-9d79-394e7d752cae&market_selection_id[0]=59b2b7ee-46c1-4cbc-9286-77fd8670cf9d&odds_numerator[0]=27&odds_denominator[0]=5',\n marketStatus: 'LIVE',\n },\n ],\n },\n ],\n rewardInfo: {\n type: 'ODDS_BOOST',\n icon: {\n light: 'https://a.espncdn.com/i/espnbet/boost.png',\n dark: 'https://a.espncdn.com/i/espnbet/boost.png',\n },\n },\n legCount: 1,\n isNoAction: false,\n betDisplayStatement: 'to win',\n },\n {\n id: 'xfFjqsLCjaFx93eH6c8bOQ9mEkI=',\n type: 'STRAIGHT',\n betStatus: 'OPEN',\n outcome: 'PENDING',\n overrideOutcome: 'NOT_SET',\n betAmount: '2',\n payoutAmount: '12.00',\n odds: '+500',\n startTime: '2025-04-30T17:11Z',\n events: [\n {\n displayName: 'SBG NHL In The News Test',\n legs: [\n {\n id: '910a1ebf-592d-4ae6-9471-6f648786b7e6',\n marketId: 'c5252e65-0999-40af-b366-11967f009871',\n marketSelectionId: 'c9b1446c-26af-43c4-9705-3a2275dc0ee5',\n marketType: 'list',\n status: 'PENDING',\n odds: '+500',\n boostType: 'NONE',\n selectionText:\n 'Long Desc Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus non gravida mi. Aliquam volutpat felis ut tempor dictum.',\n type: 'list',\n marketText: 'SBG In The News NHL',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/odds-boost/organization/in-the-news/competition/in-the-news/event/4cd8e64d-472c-412f-b786-dd91c98ab74e&market_selection_id[0]=c9b1446c-26af-43c4-9705-3a2275dc0ee5&odds_numerator[0]=6&odds_denominator[0]=1',\n marketStatus: 'LIVE',\n },\n ],\n },\n ],\n rewardInfo: { type: 'NONE' },\n legCount: 1,\n isNoAction: false,\n betDisplayStatement: 'to win',\n },\n {\n id: 'A0RLmTR8mjEFSwaa21JeOhyVdXc=',\n type: 'STRAIGHT',\n betStatus: 'OPEN',\n outcome: 'PENDING',\n overrideOutcome: 'NOT_SET',\n betAmount: '1',\n payoutAmount: '3.00',\n odds: '+200',\n startTime: '2025-04-30T17:13Z',\n events: [\n {\n displayName: 'SBG NBA Special Test',\n legs: [\n {\n id: '1aa22098-57b7-4a77-bbf2-ca7ebf812083',\n marketId: 'bc783144-0a2c-465b-9e8f-2ef55a17705c',\n marketSelectionId: '7a91fb3d-1291-4163-b5e0-07fe63e8e706',\n marketType: 'list',\n status: 'PENDING',\n odds: '+200',\n boostType: 'NONE',\n selectionText: 'Tyrese Haliburton to Record 12+ Assists',\n type: 'list',\n marketText: 'SBG NBA Special Test',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/odds-boost/organization/specials/competition/specials/event/d53171e2-f821-4da8-9b1c-ce1a4b735914&market_selection_id[0]=7a91fb3d-1291-4163-b5e0-07fe63e8e706&odds_numerator[0]=33&odds_denominator[0]=10',\n marketStatus: 'LIVE',\n },\n ],\n },\n ],\n rewardInfo: { type: 'NONE' },\n legCount: 1,\n isNoAction: false,\n betDisplayStatement: 'to win',\n },\n {\n id: 'Qhelx5np79zhAchzXXTL1HdDb80=',\n type: 'STRAIGHT',\n betStatus: 'OPEN',\n outcome: 'PENDING',\n overrideOutcome: 'NOT_SET',\n betAmount: '2',\n payoutAmount: '10.00',\n odds: '+400',\n startTime: '2025-04-30T17:13Z',\n events: [\n {\n displayName: 'SBG NBA Special Test',\n legs: [\n {\n id: '73f3af25-5e1a-47eb-bcec-5b23e911c14e',\n marketId: 'bc783144-0a2c-465b-9e8f-2ef55a17705c',\n marketSelectionId: '0a898e16-2a0a-44dd-a580-3ae3bade3684',\n marketType: 'list',\n status: 'PENDING',\n odds: '+400',\n boostType: 'NONE',\n selectionText:\n 'Long Desc Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus non gravida mi. Aliquam volutpat felis ut tempor dictum.',\n type: 'list',\n marketText: 'SBG NBA Special Test',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_allsports_green_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_allsports_green_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/odds-boost/organization/specials/competition/specials/event/d53171e2-f821-4da8-9b1c-ce1a4b735914&market_selection_id[0]=0a898e16-2a0a-44dd-a580-3ae3bade3684&odds_numerator[0]=37&odds_denominator[0]=10',\n marketStatus: 'LIVE',\n },\n ],\n },\n ],\n rewardInfo: { type: 'NONE' },\n legCount: 1,\n isNoAction: false,\n betDisplayStatement: 'to win',\n },\n ],\n settled: [\n {\n id: 'z/WEFT7NDVjgb0d/+Elr45MfuRg=',\n type: 'STRAIGHT',\n betStatus: 'SETTLED',\n outcome: 'WIN',\n overrideOutcome: 'NOT_SET',\n closedAtTime: '2025-03-08T05:33Z',\n betAmount: '1',\n payoutAmount: '1.91',\n odds: '-110',\n startTime: '2025-03-08T03:00Z',\n events: [\n {\n displayName: 'San Antonio Spurs @ Sacramento Kings',\n legs: [\n {\n id: '05011199-c88f-4c0d-be31-1b1c7549e273',\n marketId: '728792c6-d2da-435b-920a-eb86bdc45e8c',\n marketSelectionId: '60f8aef9-4c98-4ce2-b861-34e72c2ad13b',\n marketType: 'total',\n status: 'WIN',\n odds: '-110',\n boostType: 'NONE',\n selectionText: 'Over 235',\n type: 'over',\n points: '235.0',\n marketText: 'Total Points',\n icon:\n 'https://a.espncdn.com/i/espnbet/mybets_green_check_icon.png',\n iconDark:\n 'https://a.espncdn.com/i/espnbet/dark/mybets_green_check_icon.png',\n url:\n 'https://espnbet.test-app.link/qa_integrations?%243p=a_espn&clr=espnbettingintegration&$canonical_url=/sport/basketball/organization/united-states/competition/nba/event/e1163795-ddfa-4bfc-9d52-018e8259e4b5&market_selection_id[0]=60f8aef9-4c98-4ce2-b861-34e72c2ad13b&odds_numerator[0]=2&odds_denominator[0]=1',\n marketStatus: 'SETTLED',\n accrued: { goal: 235.0 },\n },\n ],\n },\n ],\n rewardInfo: { type: 'NONE' },\n legCount: 1,\n isNoAction: false,\n betDisplayStatement: 'you won',\n },\n ],\n },\n promotion: {\n title: 'The official sportsbook of ESPN',\n description: 'Open the ESPN BET app on a mobile device and start betting!',\n logo: 'https://a.espncdn.com/i/espnbet/ESPN_Bet_Sportsbook_Light.svg',\n qrCode: 'https://assets.geo.hosted.espnsb.com/api/ext_mocks/qr.png',\n backgroundImage:\n 'https://www.espn.com/redesign/assets/img/ictv/bkg_qr_bet.png',\n },\n disclaimers: {\n location: 'Use a translation with a key based on location here',\n gambling: 'Use a translation with some key based on gambling here',\n },\n ...event,\n};\n","import { Observable } from '../../../../helpers/Observable';\nimport BetsService from '../services/BetsService';\nimport { UserSettingsManager } from '../../../../services/UserSettingsManager';\nimport AnalyticsService from '@/services/AnalyticsService/AnalyticsService';\nimport {\n IBetsResponse,\n IPersonalizedBetsResponse,\n ITeam,\n IUserBet,\n IBetLeg,\n} from '../interfaces/IBets';\n\n// Import ViewModel with correct path\nimport { ViewModel } from '../../../../view-models/ViewModel';\nimport { MOCK_BETS_API_RESPONSE } from '../mocks';\n\nimport IMaestroEventDelegate from '@/interfaces/IMaestroEventDelegate';\nimport { BetCardType, BetType } from '../types/BetsAnalyticsTypes';\nimport SDK from '@/index';\nimport { captureException } from '@/sentry';\nimport { stringHashCode } from '@/helpers/strings';\n\n// The interval for polling bet data (in milliseconds)\nconst DEFAULT_POLLING_INTERVAL = 30000; // 30 seconds\n\nconst BET_ITEM_TYPE = {\n ODDS: 'odds',\n USER_BETS: 'userBets',\n PROMO: 'promo',\n HOT_PROPS: 'hotProps',\n LOCATION_DISCLAIMER: 'locationDisclaimer',\n GAMBLING_MESSAGE: 'gamblingMessage',\n} as const;\n\nexport type BetItemType = typeof BET_ITEM_TYPE[keyof typeof BET_ITEM_TYPE];\n\ntype TeamOdd = {\n teamAbbreviation: string;\n startOfGameFirstLine: string;\n startOfGameSecondLine: string;\n gameSpreadFirstLine: string;\n gameSpreadSecondLine: string;\n totalPointsFirstLine: string;\n totalPointsSecondLine: string;\n moneylineFirstLine: string;\n};\n\nexport type ISixPackOdds = {\n topTeamOdds: TeamOdd;\n bottomTeamOdds: TeamOdd;\n drawOdds?: TeamOdd;\n orderedColumns: { abbreviation: string; type: string }[];\n gameState: string; // 'in', 'pre', 'post'\n};\n\nexport type IUserBets = {\n defaultTab: string;\n bets: {\n live: IUserBet[];\n upcoming: IUserBet[];\n settled: IUserBet[];\n };\n};\n\nexport type IHotProps = {\n items: IBetLeg[];\n};\n\nexport type ILocationDisclaimer = {\n text: string;\n};\n\nexport type IGamblingMessage = {\n text: string;\n};\n\nexport type IBetPromo = {\n title: string;\n description: string;\n logo: string;\n qrCode: string;\n backgroundImage: string;\n};\n\nexport type PromoBetItem = {\n id: string;\n type: 'promo';\n data: IBetPromo;\n};\n\nexport type LocationDisclaimerBetItem = {\n type: 'locationDisclaimer';\n id: string;\n data: ILocationDisclaimer;\n};\n\nexport type GamblingMessageBetItem = {\n type: 'gamblingMessage';\n id: string;\n data: IGamblingMessage;\n};\n\nexport type SixPackBetItem = {\n type: 'sixPack';\n data: ISixPackOdds;\n teamInfo?: {\n home: ITeam;\n away: ITeam;\n };\n id: string;\n hideWagers: boolean;\n};\n\nexport type UserBetsBetItem = {\n type: 'userBets';\n data: IUserBets;\n id: string;\n hideWagers: boolean;\n};\n\nexport type HotPropsBetItem = {\n type: 'hotProps';\n data: IHotProps;\n id: string;\n hideWagers: boolean;\n};\n\nexport type BetItem =\n | SixPackBetItem\n | UserBetsBetItem\n | PromoBetItem\n | HotPropsBetItem\n | LocationDisclaimerBetItem\n | GamblingMessageBetItem;\n\nconst BET_ERROR_STATE = {\n NONE: 'none',\n TAB_LOAD_FAILURE: 'tabLoadFailure',\n} as const;\nexport type BetsErrorState = typeof BET_ERROR_STATE[keyof typeof BET_ERROR_STATE];\n\nexport interface IBetsViewModelDelegate {\n userIsAuthenticated(): Promise<boolean>;\n getUserSWID(): Promise<string | null>;\n getUserToken(): Promise<string | null>;\n}\n\nconst isPersonalizedBetsResponse = (\n data: any\n): data is IPersonalizedBetsResponse => {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'event' in data &&\n typeof data.event === 'object'\n );\n};\n\nexport class BetsViewModel extends ViewModel {\n // Observable properties\n public betsItems = new Observable<BetItem[]>([]);\n public isDataLoading = new Observable<boolean>(true);\n public errorState = new Observable<BetsErrorState>('none');\n public hasEverSuccessfullyLoaded = new Observable<boolean>(false);\n public hideWagers = new Observable<boolean>(false);\n\n // Properties\n private eventId: string;\n private delegate: IBetsViewModelDelegate;\n private betsService: BetsService;\n private analyticsService: AnalyticsService;\n private pollingInterval: number;\n private pollingTask: { stop: () => void } | null = null;\n private lastNonPersonalizedResponseHash: number | null = null;\n private lastPersonalizedResponseHash: number | null = null;\n private useMockData: boolean = false;\n private userSettingsManager: UserSettingsManager;\n private settingsSubscription: (() => void) | null = null;\n initialized = false;\n\n constructor(\n eventId: string,\n delegate: IMaestroEventDelegate,\n analyticsService: AnalyticsService,\n options: {\n useMockData?: boolean;\n } = {}\n ) {\n super();\n this.eventId = eventId;\n this.delegate = delegate;\n this.betsService = new BetsService(delegate);\n this.analyticsService = analyticsService;\n this.pollingInterval = DEFAULT_POLLING_INTERVAL;\n this.useMockData = options.useMockData || false;\n this.userSettingsManager = UserSettingsManager.getInstance();\n\n // Initialize hide_wagers setting\n this.hideWagers.value = this.userSettingsManager.shouldHideWagers();\n\n // Subscribe to settings changes\n this.settingsSubscription = this.userSettingsManager.settings.subscribe(\n () => {\n this.updateHideWagersFromSettings();\n }\n );\n\n this.betsService = new BetsService(delegate);\n }\n\n /**\n * Initialize the ViewModel and start data fetching\n */\n async init(): Promise<void> {\n // Track panel view on initialization\n this.trackPanelView();\n\n await this.fetchNewData();\n this.refreshPolling();\n this.initialized = true;\n }\n\n /**\n * Clean up resources when the ViewModel is no longer needed\n */\n cleanup(): void {\n this.stopPolling();\n\n // Clean up settings subscription\n if (this.settingsSubscription) {\n this.settingsSubscription();\n this.settingsSubscription = null;\n }\n\n this.initialized = false;\n }\n\n /**\n * Track panel view event\n */\n private async trackPanelView(): Promise<void> {\n try {\n const betCounts = this.getUserBetCounts();\n await this.analyticsService.panelView('espnBet', betCounts);\n } catch (error) {\n captureException(error, {\n context: 'BetsViewModel.trackPanelView',\n });\n console.error('[BET] Error tracking panel view:', error);\n }\n }\n\n /**\n * Track card click event\n */\n async trackCardClick(\n cardType: BetCardType,\n betType?: BetType | null\n ): Promise<void> {\n try {\n const betCounts = this.getUserBetCounts();\n\n const metadata = {\n ...betCounts,\n card: cardType,\n bet_type: betType || null,\n };\n\n await this.analyticsService.panelClick({\n type: 'espnBet',\n name: 'bets_item_clicked',\n metadata,\n });\n } catch (error) {\n captureException(error, {\n context: 'BetsViewModel.trackCardClick',\n cardType,\n betType,\n });\n console.error('[BET] Error tracking card click:', error);\n }\n }\n\n /**\n * Get user bet counts for analytics\n */\n private getUserBetCounts(): {\n in_game_bets: number;\n total_bets: number;\n } {\n try {\n let inGameBets = 0;\n let totalBets = 0;\n\n // Count bets from current data\n for (const item of this.betsItems.value) {\n if (item.type === 'userBets') {\n const userBetsItem = item as UserBetsBetItem;\n const allBets = [\n ...userBetsItem.data.bets.live,\n ...userBetsItem.data.bets.settled,\n ...userBetsItem.data.bets.upcoming,\n ];\n\n totalBets = allBets.length;\n\n inGameBets = userBetsItem.data.bets.live.length;\n break;\n }\n }\n\n return {\n in_game_bets: inGameBets,\n total_bets: totalBets,\n };\n } catch (error) {\n captureException(error, {\n context: 'BetsViewModel.getUserBetCounts',\n });\n console.error('[BET] Error getting user bet counts:', error);\n return {\n in_game_bets: 0,\n total_bets: 0,\n };\n }\n }\n\n /**\n * Refresh polling for bet data\n */\n refreshPolling(): void {\n // First stop any existing polling\n this.stopPolling();\n\n if (this.useMockData) {\n return;\n }\n\n // We'll determine whether to use authenticated polling in the polling task\n this.pollingTask = {\n stop: () => {\n // This will be replaced when actual polling starts\n },\n };\n\n // Start the poll loop\n this.pollWithInterval();\n }\n\n /**\n * Get user credentials from delegate\n */\n private async getUserCredentials(): Promise<{ swid: string; jwt: string }> {\n const swid = (await this.delegate.getUserSWID()) || '';\n const jwt = (await this.delegate.getUserToken()) || '';\n return { swid, jwt };\n }\n\n /**\n * @description Update polling interval checking either response header or panel config.\n * Refresh polling if necessary.\n */\n private updatePollingInterval(headers: Record<string, string>): void {\n const headerInterval = this.getResponseHeaderPollingIntervalValue(headers);\n const panelConfigInterval = this.getPanelConfigInterval();\n\n const newInterval = headerInterval || panelConfigInterval; // order matters here\n if (newInterval && newInterval !== this.pollingInterval) {\n this.pollingInterval = newInterval;\n console.log(\n `[BET] Updating polling interval to ${this.pollingInterval} milliseconds`\n );\n // If we have an active polling task, restart it with the new interval\n this.refreshPolling();\n }\n }\n\n private getPanelConfigInterval() {\n const config = SDK.getPageConfig();\n const panel = config?.panels?.find((p) => p.panel_type === 'espnBet');\n if (!panel) {\n return null;\n }\n\n const oddsPollingInterval =\n panel.renderer?.block_data?.odds_polling_interval;\n if (!oddsPollingInterval) {\n return null;\n }\n\n const parsedInterval = parseInt(oddsPollingInterval, 10);\n if (isNaN(parsedInterval) || parsedInterval <= 0) {\n console.warn(\n `[BET] Invalid polling interval from panel config: ${oddsPollingInterval}.`\n );\n return null;\n }\n\n return parsedInterval * 1000; // Convert seconds to milliseconds\n }\n\n private getResponseHeaderPollingIntervalValue(\n headers: Record<string, string>\n ): number | null {\n const newInterval = headers['polling-interval'];\n if (!newInterval) {\n return null;\n }\n\n const parsedInterval = parseInt(newInterval, 10);\n if (isNaN(parsedInterval) || parsedInterval <= 0) {\n console.warn(\n `[BET] Invalid polling interval header received: ${newInterval}.`\n );\n return null;\n }\n\n return parsedInterval * 1000; // Convert seconds to milliseconds\n }\n\n /**\n * Poll with the personalized endpoint for both authenticated and anonymous users\n *\n * SWID format is provided by the client app delegate:\n * - Logged in: {6D201B58-440C-47A6-970B-0F8C78C0BAB8} (with curly braces)\n * - Anonymous: 6D201B58-440C-47A6-970B-0F8C78C0BAB8 (without curly braces)\n * - Failsafe: Empty string if local storage fails\n */\n private async pollWithInterval(): Promise<void> {\n try {\n // Always use personalized endpoint\n const { swid, jwt } = await this.getUserCredentials();\n\n // Start personalized polling for both authenticated and anonymous users with headers\n this.pollingTask = this.betsService.pollPersonalizedBetsWithHeaders(\n this.eventId,\n swid,\n jwt,\n this.pollingInterval,\n (response) => {\n this.updatePollingInterval(response.headers);\n this.processPolledData(response.data);\n },\n this.handlePollingError.bind(this)\n );\n } catch (error) {\n captureException(error, {\n context: 'BetsViewModel.pollWithInterval',\n });\n console.error('[BET] Error setting up polling:', error);\n }\n }\n\n /**\n * Process data received from polling\n */\n private processPolledData(\n data: IBetsResponse | IPersonalizedBetsResponse\n ): void {\n // Calculate hash for the response to check if it's different from the last one\n const responseHash = stringHashCode(JSON.stringify(data));\n const isPersonalized = isPersonalizedBetsResponse(data);\n\n if (isPersonalized) {\n // Check if this is the same as the last successful response\n if (\n this.lastPersonalizedResponseHash === responseHash &&\n this.hasEverSuccessfullyLoaded.value\n ) {\n console.log(\n '[BET] Response hash is the same as last successful response - skipping update'\n );\n return;\n }\n\n // Update tracking variables\n this.lastPersonalizedResponseHash = responseHash;\n // this.lastSuccessfulResponsePersonalized =\n // data as IPersonalizedBetsResponse;\n } else {\n // Check if this is the same as the last successful response\n if (\n this.lastNonPersonalizedResponseHash === responseHash &&\n this.hasEverSuccessfullyLoaded.value\n ) {\n console.log(\n '[BET] Response hash is the same as last successful response - skipping update'\n );\n return;\n }\n\n // Update tracking variables\n this.lastNonPersonalizedResponseHash = responseHash;\n // this.lastSuccessfulResponseNonPersonalized = data as IBetsResponse;\n }\n\n // Update state\n this.hasEverSuccessfullyLoaded.value = true;\n this.errorState.value = 'none';\n\n // Process the response and update betsItems\n // This is a placeholder - you would need to implement the actual logic\n // for parsing different parts of the response (sixPacks, hot props, etc.)\n this.processBetsData(data);\n }\n\n /**\n * Process the bets data and update the betsItems\n */\n private processBetsData(\n data: IBetsResponse | IPersonalizedBetsResponse\n ): void {\n // Clear current items\n const newItems: BetItem[] = [];\n if (!Object.keys(data).length) {\n return;\n }\n\n // 1. Process regular odds (always available in both response types)\n const sixPack = this.processSixPackData(data);\n if (sixPack) {\n newItems.push(sixPack);\n }\n\n // 2. Process location disclaimer if this is a personalized response\n const locationDisclaimer = this.processLocationDisclaimer(data);\n if (locationDisclaimer) {\n newItems.push(locationDisclaimer);\n }\n\n // 3. Process user bets if this is a personalized response\n const userBets = this.processUserBetsData(data);\n if (userBets) {\n newItems.push(userBets);\n }\n\n // 4. Process featured(hot props) bets if available\n const hotProps = this.processHotProps(data);\n if (hotProps) {\n newItems.push(hotProps);\n }\n\n // 5. Process promo code\n const promoCode = this.processPromoCode(data);\n if (promoCode) {\n newItems.push(promoCode);\n }\n\n // 6. Process gambling message if available\n const gamblingMessage = this.processGamblingMessage(data);\n if (gamblingMessage) {\n newItems.push(gamblingMessage);\n }\n\n // Update the observable\n this.betsItems.value = newItems;\n }\n\n private processLocationDisclaimer(\n data: IBetsResponse | IPersonalizedBetsResponse\n ): LocationDisclaimerBetItem | null {\n const isPersonalized = isPersonalizedBetsResponse(data);\n if (!isPersonalized || !data.disclaimers?.location) {\n return null;\n }\n\n return {\n type: 'locationDisclaimer',\n id: 'locationDisclaimer',\n data: {\n text: data.disclaimers.location,\n },\n };\n }\n\n private processPromoCode(\n data: IBetsResponse | IPersonalizedBetsResponse\n ): PromoBetItem | null {\n const isPersonalized = isPersonalizedBetsResponse(data);\n if (!isPersonalized || !data.promotion) {\n return null;\n }\n\n return {\n type: 'promo',\n data: {\n title: data.promotion.title || '',\n description: data.promotion.description || '',\n logo: data.promotion.logo || '',\n qrCode: data.promotion.qrCode || '',\n backgroundImage: data.promotion.backgroundImage || '',\n },\n id: `promo-${data.event?.id || data.id}`,\n };\n }\n\n private processGamblingMessage(\n data: IBetsResponse | IPersonalizedBetsResponse\n ): GamblingMessageBetItem | null {\n const isPersonalized = isPersonalizedBetsResponse(data);\n if (!isPersonalized || !data.disclaimers?.gambling) {\n return null;\n }\n\n return {\n type: 'gamblingMessage',\n id: 'gamblingMessage',\n data: {\n text: data.disclaimers.gambling,\n },\n };\n }\n\n private processSixPackData(\n response: IBetsResponse | IPersonalizedBetsResponse\n ): SixPackBetItem | null {\n const isPersonalized = isPersonalizedBetsResponse(response);\n const teams = response.entities?.teams;\n\n const odds = !isPersonalized\n ? response.bets?.odds\n : response.event?.bets?.odds;\n const gameState = !isPersonalized\n ? response.gameState\n : response.event?.gameState;\n\n const sport = !isPersonalized ? response.sport : response.event?.sport;\n const eventId = !isPersonalized ? response.id : response.event?.id;\n const isSoccer = !isPersonalized\n ? response.sport === 'soccer'\n : response.event?.sport === 'soccer';\n\n if (!odds || !gameState || !sport || !eventId || !teams) {\n return null;\n }\n\n const teamArray = Object.values(teams);\n let awayTeam: ITeam | undefined;\n let homeTeam: ITeam | undefined;\n\n // Find home and away teams from odds\n for (const team of Object.values(teams)) {\n const spreadOdds = odds.find((odd) => odd.type === 'pointSpread');\n if (spreadOdds) {\n if (\n spreadOdds.values.some((v) => v.team === team.id && v.type === 'home')\n ) {\n homeTeam = team;\n } else if (\n spreadOdds.values.some((v) => v.team === team.id && v.type === 'away')\n ) {\n awayTeam = team;\n }\n }\n }\n\n // Fallback logic if we couldn't determine from odds\n if (!homeTeam || !awayTeam) {\n console.warn(\n 'Could not determine home/away teams from odds, using first two teams'\n );\n switch (teamArray.length) {\n case 0:\n throw new Error('No teams found in response');\n case 1:\n // Only one team - unusual case, but handle gracefully\n homeTeam = teamArray[0];\n awayTeam = teamArray[0]; // Same team as both home and away (shouldn't happen)\n break;\n case 2:\n // Default to first team as home, second as away\n homeTeam = teamArray[0];\n awayTeam = teamArray[1];\n break;\n default:\n // More than 2 teams - take first two and log warning\n homeTeam = teamArray[0];\n awayTeam = teamArray[1];\n console.warn(\n `Warning: Unexpected team count (${teamArray.length}) in six pack response`\n );\n }\n }\n\n if (!awayTeam || !homeTeam) {\n throw new Error('Could not determine home or away team from response');\n }\n\n const isInProgress = gameState === 'in';\n const isHomeFavoured = (() => {\n if (isSoccer && !isInProgress) {\n return homeTeam.favoredAtOpen ?? true;\n }\n\n return homeTeam.favored ?? true;\n })();\n const isAwayFavoured = (() => {\n if (isSoccer && !isInProgress) {\n return awayTeam.favoredAtOpen ?? false;\n }\n\n return awayTeam.favored ?? false;\n })();\n\n let awayTeamStartGameFirstLine = '';\n let awayTeamStartGameSecondLine = '';\n let homeTeamStartGameFirstLine = '';\n let homeTeamStartGameSecondLine = '';\n\n let awaySpreadFirstLine = '';\n let awaySpreadSecondLine = '';\n let homeSpreadFirstLine = '';\n let homeSpreadSecondLine = '';\n\n let awayTotalFirstLine = '';\n let awayTotalSecondLine = '';\n let homeTotalFirstLine = '';\n let homeTotalSecondLine = '';\n\n let awayMoneylineFirstLine = '';\n let homeMoneylineFirstLine = '';\n\n let drawGameStateFirstLine = '';\n let drawGameStateSecondLine = '';\n\n let drawMoneylineFirstLine = '';\n\n const itemTypeSet = new Set<string>();\n const orderedColumns: { abbreviation: string; type: string }[] = [];\n for (const oddsItem of odds) {\n if (!itemTypeSet.has(oddsItem.type)) {\n orderedColumns.push({\n type: oddsItem.type,\n abbreviation: oddsItem.abbreviation,\n });\n itemTypeSet.add(oddsItem.type);\n }\n\n const isLive = oddsItem.state === 'live';\n const isClose = oddsItem.state === 'close';\n const isOpen = oddsItem.state === 'open';\n\n // For every odd type and using the correct state based on game state, get the odds and lines for the home and away team.\n // There are special handlings for the 'start of game' lines. It can be from 'spread', 'total' or 'moneyline' depending on which team is favoured, sport, etc.\n switch (oddsItem.type) {\n case 'pointSpread': {\n const spreadCorrectState = isInProgress ? isLive : isClose;\n if (spreadCorrectState) {\n for (const value of oddsItem.values) {\n if (value.type === 'home') {\n homeSpreadFirstLine = value.line ?? '';\n homeSpreadSecondLine = value.odds ?? '';\n }\n\n if (value.type === 'away') {\n awaySpreadFirstLine = value.line ?? '';\n awaySpreadSecondLine = value.odds ?? '';\n }\n }\n }\n\n const pointsSpreadStartOfGameCorrectState = isInProgress\n ? isClose\n : isOpen;\n if (pointsSpreadStartOfGameCorrectState && !isSoccer) {\n if (isHomeFavoured) {\n for (const value of oddsItem.values) {\n if (value.type === 'home') {\n homeTeamStartGameFirstLine = value.line ?? '';\n homeTeamStartGameSecondLine = value.odds ?? '';\n }\n }\n }\n\n if (isAwayFavoured) {\n for (const value of oddsItem.values) {\n if (value.type === 'away') {\n awayTeamStartGameFirstLine = value.line ?? '';\n awayTeamStartGameSecondLine = value.odds ?? '';\n }\n }\n }\n }\n break;\n }\n\n case 'total': {\n const totalCorrectState = isInProgress ? isLive : isClose;\n if (totalCorrectState) {\n for (const value of oddsItem.values) {\n if (value.type === 'over') {\n if (isSoccer) {\n homeTotalFirstLine = value.line ?? '';\n homeTotalSecondLine = value.odds ?? '';\n } else {\n awayTotalFirstLine = value.line ?? '';\n awayTotalSecondLine = value.odds ?? '';\n }\n }\n\n if (value.type === 'under') {\n if (isSoccer) {\n awayTotalFirstLine = value.line ?? '';\n awayTotalSecondLine = value.odds ?? '';\n } else {\n homeTotalFirstLine = value.line ?? '';\n homeTotalSecondLine = value.odds ?? '';\n }\n }\n }\n }\n\n const totalStartOfGameCorrectState = isInProgress ? isClose : isOpen;\n if (totalStartOfGameCorrectState) {\n // If home is not favoured, use total as the start of the game line\n if (!isHomeFavoured) {\n for (const value of oddsItem.values) {\n if (\n (isSoccer && value.type === 'over') ||\n (!isSoccer && value.type === 'under')\n ) {\n homeTeamStartGameFirstLine = value.line ?? '';\n homeTeamStartGameSecondLine = value.odds ?? '';\n }\n }\n }\n\n // If away is not favoured, use total as the start of the game line\n if (!isAwayFavoured) {\n for (const value of oddsItem.values) {\n if (\n (isSoccer && value.type === 'under') ||\n (!isSoccer && value.type === 'over')\n ) {\n awayTeamStartGameFirstLine = value.line ?? '';\n awayTeamStartGameSecondLine = value.odds ?? '';\n }\n }\n }\n }\n break;\n }\n\n case 'moneyline': {\n const mlCorrectState = isInProgress ? isLive : isClose;\n if (mlCorrectState) {\n for (const value of oddsItem.values) {\n if (value.type === 'home') {\n homeMoneylineFirstLine = value.odds ?? '';\n }\n if (value.type === 'away') {\n awayMoneylineFirstLine = value.odds ?? '';\n }\n }\n }\n\n // soccer logic\n if (isSoccer) {\n const moneyLineStartOfGameCorrectState = isInProgress\n ? isClose\n : isOpen;\n\n // find draw value\n for (const value of oddsItem.values) {\n if (value.type === 'draw') {\n if (moneyLineStartOfGameCorrectState) {\n drawGameStateFirstLine = value.odds ?? '';\n drawGameStateSecondLine = 'DRAW';\n }\n\n if (mlCorrectState) {\n drawMoneylineFirstLine = value.odds ?? '';\n }\n }\n }\n\n if (moneyLineStartOfGameCorrectState) {\n if (isHomeFavoured) {\n for (const value of oddsItem.values) {\n if (value.type === 'home') {\n homeTeamStartGameFirstLine = value.odds ?? '';\n homeTeamStartGameSecondLine = oddsItem.abbreviation ?? '';\n }\n }\n }\n\n if (isAwayFavoured) {\n for (const value of oddsItem.values) {\n if (value.type === 'away') {\n awayTeamStartGameFirstLine = value.odds ?? '';\n awayTeamStartGameSecondLine = oddsItem.abbreviation ?? '';\n }\n }\n }\n }\n }\n break;\n }\n }\n }\n\n // Create the six pack data structure\n const awayTeamOdds: TeamOdd = {\n teamAbbreviation: awayTeam.abbreviation ?? '',\n startOfGameFirstLine: awayTeamStartGameFirstLine,\n startOfGameSecondLine: awayTeamStartGameSecondLine,\n gameSpreadFirstLine: awaySpreadFirstLine,\n gameSpreadSecondLine: awaySpreadSecondLine,\n totalPointsFirstLine: awayTotalFirstLine,\n totalPointsSecondLine: awayTotalSecondLine,\n moneylineFirstLine: awayMoneylineFirstLine,\n };\n\n const homeTeamOdds: TeamOdd = {\n teamAbbreviation: homeTeam.abbreviation ?? '',\n startOfGameFirstLine: homeTeamStartGameFirstLine,\n startOfGameSecondLine: homeTeamStartGameSecondLine,\n gameSpreadFirstLine: homeSpreadFirstLine,\n gameSpreadSecondLine: homeSpreadSecondLine,\n totalPointsFirstLine: homeTotalFirstLine,\n totalPointsSecondLine: homeTotalSecondLine,\n moneylineFirstLine: homeMoneylineFirstLine,\n };\n\n const drawOdds: TeamOdd = {\n teamAbbreviation: 'DRAW',\n startOfGameFirstLine: drawGameStateFirstLine,\n startOfGameSecondLine: drawGameStateSecondLine,\n gameSpreadFirstLine: '',\n gameSpreadSecondLine: '',\n totalPointsFirstLine: '',\n totalPointsSecondLine: '',\n moneylineFirstLine: drawMoneylineFirstLine,\n };\n\n const sixPack: ISixPackOdds = {\n topTeamOdds: isSoccer ? homeTeamOdds : awayTeamOdds,\n bottomTeamOdds: isSoccer ? awayTeamOdds : homeTeamOdds,\n drawOdds:\n drawGameStateFirstLine &&\n drawGameStateSecondLine &&\n drawMoneylineFirstLine\n ? drawOdds\n : undefined,\n orderedColumns,\n gameState,\n };\n\n return {\n id: `sixpack-${eventId}`,\n type: 'sixPack',\n data: sixPack,\n teamInfo: {\n home: homeTeam,\n away: awayTeam,\n },\n hideWagers: this.hideWagers.value,\n };\n }\n\n private processUserBetsData(\n data: IBetsResponse | IPersonalizedBetsResponse\n ): UserBetsBetItem | null {\n const isPersonalized = isPersonalizedBetsResponse(data);\n if (!isPersonalized || !data.event || !data.betsModule) {\n return null;\n }\n\n const betItems: IUserBets['bets'] = {\n live: data.betsModule.live.filter((bet) => bet.type !== 'promo'),\n settled: data.betsModule.settled.filter((bet) => bet.type !== 'promo'),\n upcoming: data.betsModule.upcoming.filter((bet) => bet.type !== 'promo'),\n };\n\n return {\n data: {\n bets: betItems,\n defaultTab: data.betsModule.defaultTab,\n },\n id: `userBets-${data.event.id}`,\n type: 'userBets',\n hideWagers: this.hideWagers.value,\n };\n }\n\n private processHotProps(\n response: IBetsResponse | IPersonalizedBetsResponse\n ): HotPropsBetItem | null {\n const isPersonalized = isPersonalizedBetsResponse(response);\n const hotProps = isPersonalized\n ? response.event?.featured\n : response.featured;\n\n if (!hotProps || !Array.isArray(hotProps)) {\n return null;\n }\n\n const hasData = hotProps.every((hotProp) => Boolean(hotProp && hotProp.id));\n if (!hasData) {\n return null;\n }\n\n const filteredHotProps = hotProps.filter(\n (hotProp) => hotProp.selections.length > 0\n );\n\n return {\n type: 'hotProps',\n hideWagers: this.hideWagers.value,\n id: 'hotProps',\n data: {\n items: filteredHotProps.map((hotProp) => {\n const bet = hotProp.selections[0];\n\n return {\n id: bet.id,\n odds: bet.odds.current || '',\n marketText: bet.text,\n selectionText: hotProp.text,\n status: bet.status,\n type: bet.type,\n icon: bet.icon,\n iconDark: bet.iconDark,\n outcome: bet.outcome,\n };\n }),\n },\n };\n }\n\n /**\n * Handle errors that occur during polling\n */\n private handlePollingError(error: Error): void {\n console.error('Polling error:', error);\n\n if (!this.hasEverSuccessfullyLoaded.value) {\n // If we've never had a successful load, show an error state\n this.errorState.value = 'tabLoadFailure';\n this.betsItems.value = [];\n } else {\n // If we had a previous successful load, keep showing the old data\n // No need to update errorState or betsItems\n }\n }\n\n /**\n * Stop polling for bet data\n */\n stopPolling(): void {\n if (this.pollingTask) {\n this.pollingTask.stop();\n this.pollingTask = null;\n }\n\n if (this.isDataLoading.value) {\n this.isDataLoading.value = false;\n }\n }\n\n /**\n * Fetch new bet data immediately (one-time)\n */\n async fetchNewData(): Promise<void> {\n this.isDataLoading.value = true;\n\n try {\n // Handle mock data if enabled\n if (this.useMockData) {\n this.betsItems.value = [];\n await this.fetchMockData();\n return;\n }\n\n // Always use personalized endpoint for both authenticated and anonymous users\n await this.fetchPersonalizedData();\n this.isDataLoading.value = false;\n } catch (error) {\n captureException(error, {\n context: 'BetsViewModel.fetchNewData',\n });\n console.error('[BET] Error fetching bet data:', error);\n\n if (!this.hasEverSuccessfullyLoaded.value) {\n this.errorState.value = 'tabLoadFailure';\n this.betsItems.value = [];\n }\n\n this.isDataLoading.value = false;\n }\n }\n\n /**\n * Fetch personalized bet data\n */\n private async fetchPersonalizedData(): Promise<void> {\n try {\n const { swid, jwt } = await this.getUserCredentials();\n\n const response = await this.betsService.getPersonalizedBets(\n this.eventId,\n swid,\n jwt\n );\n\n // Process the response\n this.processPolledData(response);\n } catch (error) {\n captureException(error, {\n context: 'BetsViewModel.fetchPersonalizedData',\n });\n console.error('[BET] Error fetching personalized bets:', error);\n throw error;\n }\n }\n\n /**\n * Fetch mock data for testing\n */\n private async fetchMockData(): Promise<void> {\n this.processBetsData(MOCK_BETS_API_RESPONSE);\n this.hasEverSuccessfullyLoaded.value = true;\n this.errorState.value = 'none';\n this.isDataLoading.value = false;\n }\n\n clearTabLoadFailure() {\n this.errorState.value = 'none';\n setTimeout(() => {\n this.refreshPolling();\n }, 100);\n }\n\n /**\n * Check if wagers should be hidden based on user settings\n */\n shouldHideWagers(): boolean {\n return this.hideWagers.value;\n }\n\n /**\n * Update hideWagers Observable from current settings\n */\n private updateHideWagersFromSettings(): void {\n this.hideWagers.value = this.userSettingsManager.shouldHideWagers();\n this.refreshBetItemsWithNewSettings();\n }\n\n private refreshBetItemsWithNewSettings(): void {\n this.betsItems.value = this.betsItems.value.map((item) => {\n if (item.type === 'sixPack') {\n return {\n ...item,\n hideWagers: this.hideWagers.value,\n };\n }\n if (item.type === 'userBets') {\n return {\n ...item,\n hideWagers: this.hideWagers.value,\n };\n }\n if (item.type === 'hotProps') {\n return {\n ...item,\n hideWagers: this.hideWagers.value,\n };\n }\n return item;\n });\n }\n}\n\nexport default BetsViewModel;\n"],"sourceRoot":""}