{"version":3,"sources":["containers/login/Login.module.scss","components/chart/Chart.module.scss","containers/pitchClasssifierContainer/PitchClassifierContainer.module.scss","containers/chartingContainer/ChartingContainer.module.scss","components/classifierButton/ClassifierButton.module.scss","components/navigateByPitcher/NavigateByPitcher.module.scss","containers/header/Header.module.scss","App.module.scss","enums/routes.ts","containers/login/Login.tsx","enums/handedFilters.ts","util/normalize.ts","components/navigateByPitcher/NavigateByPitcher.tsx","components/navigateByDate/NavigateByDate.tsx","api/StatsApi.ts","api/PitchClassifierApi.ts","stores/NavigationStore.ts","constants/pitchTypes.tsx","stores/ChartingStore.ts","stores/PitchClassifierStore.ts","stores/MessageStore.ts","stores/AuthStore.ts","stores/RootStore.ts","contexts.ts","components/spinner/Spinner.tsx","components/classifierButton/ClassifierButton.tsx","containers/navigationContainer/NavigationContainer.tsx","components/chart/Chart.tsx","containers/chartingContainer/ChartingContainer.tsx","containers/footer/Footer.tsx","containers/header/Header.tsx","components/handednessFilter/HandednessFilter.tsx","containers/pitchClasssifierContainer/PitchClassifierContainer.tsx","App.tsx","Routing.tsx","serviceWorker.ts","index.tsx","containers/footer/Footer.module.scss","containers/navigationContainer/NavigationContainer.module.scss","components/navigateByDate/NavigateByDate.module.scss"],"names":["module","exports","Routes","Content","Layout","Login","HandednessFilters","useOktaAuth","authService","authState","params","URLSearchParams","window","location","search","isAuthenticated","to","Root","className","styles","title","onClick","login","get","normalizeStringOfDiacritics","playerName","normalize","replace","toLowerCase","Option","Select","MONTHS","NavigateByPitcher","props","onSearch","setPitcherData","setState","searched","state","checkAll","pitcherInput","this","setSportId","fetchAllPitchers","resetSelectedOptions","prevProps","undefined","currentPitcherId","gamePks","setSelectedGamePks","selectedGamePks","concat","filter","gamePk","includes","splits","sports","pitchers","gameTypes","seasons","sportSelections","map","item","key","id","value","abbreviation","seasonSelection","gameTypeSelection","description","pitcherOptions","p","lastFirstName","gamePkSelectionMap","date","isHome","opponent","team","game","split","year","month","day","homeTeam","awayTeam","label","reduce","prev","curr","push","selections","selection","labelInValue","defaultValue","size","placeholder","onSelect","sport","mode","currentSeason","allowClear","onChange","season","setSeason","gameType","setGameType","toString","pitcher","resetSelectedGamePks","selectedPitcherId","selectedPitcherName","setPitcherInfo","parseInt","options","filterOption","inputValue","option","toUpperCase","errorOccurred","message","e","availableGamePks","target","checked","length","indeterminate","Object","keys","sort","gamePkSelection","checkboxes","selectGamePks","deselectGamePks","x","style","marginBottom","o","every","Component","CheckboxWithValue","NavigateByDate","gameInput","fetchGamesForDate","currentDateInput","currentGamePkInput","allGames","gameOptions","abbrev","container","moment","setDate","selected","setGamePk","STATS_BASE_URL","process","StatsApi","fetchSportIds","a","fetch","resp","ok","Error","status","statusText","json","fetchGameTypes","fetchLatestSeason","fetchAllPitchersForSeason","sportId","fetchURL","fetchPitchersForDateNavigation","fetchPitcherArsenal","pitcherId","fetchUrls","Promise","all","url","then","response","BASE_URL","PitchClassifier","rootStore","playerId","pitchData","pitch","playId","pitchType","details","type","code","messageStore","method","headers","r","_processMessage","body","JSON","stringify","pitchUpdates","_transformPitchData","sortPitchersByReverseOrderOfAppearance","order","b","indexOf","NavigationStore","statsApi","dropdownSelectedOptions","selectedSportId","selectedSeasons","selectedGameType","allPitchers","loading","seasonRequests","data","pitchersPerSeason","stats","player","firstName","lastName","fullName","Array","prototype","apply","NavByPitcherDropdownOptions","pitchersDropdown","_","uniqBy","catch","err","console","error","selectedDate","dates","NavByDateDropdownOptions","games","awayTeamAbbrev","teams","away","homeTeamAbbrev","home","finally","awayTeamPitcherOrder","homeTeamPitcherOrder","awayTeamPitchers","homeTeamPitchers","ID","players","person","position","bullpen","observable","selectedPitcherInfo","gameTypesDropdown","allSportsDropdown","gamePksDropdown","seasonsDropdown","action","resetOptions","Date","format","assign","fetchGames","stat","sortByDate","earlierGame","laterGame","valueOf","s","allSports","allGameTypes","d","latestSeason","seasonId","seasonList","pitchTypes","color","labelToColorMap","acc","ChartingStore","hoverBorderColor","_pointBorderColor","context","dataset","dataIndex","isSelected","_pointBorderWidth","navigationStore","tempPitchCategoryBucket","Map","resetPitcherData","fetchLiveGameData","forEach","gameData","dateTime","datetime","isGameScheduledTBD","startTimeTBD","liveData","plays","allPlays","play","handednessFilter","All","matchup","batSide","playEvents","event","isPitch","defense","inningInfo","about","halfInning","inning","atBatIndex","has","set","pitchersDataByPitchType","pitchCount","pitchList","from","y","startSpeed","breaks","spinRate","pointRadius","pointBackgroundColor","pointBorderColor","pointBorderWidth","pointHoverBorderColor","coordinates","pfxX","pfxZ","allSelectedPitches","values","pitches","computed","dataSet","index","foundPitchesArray","isPitchAlreadySelected","k","selectAll","PitchClassifierStore","knownPitchTypes","log","MessageStore","m","notification","placement","messages","queueProcessor","AuthStore","tokenManager","getTokenManager","on","getAccessToken","accessToken","getAuthState","user","getUser","Authorization","protocol","host","AUTH_CONFIG","issuer","clientId","redirectUri","rootStoreContext","createContext","AuthService","pitchClassifierApi","PitchClassifierApi","chartingStore","pitchClassifierStore","authStore","reaction","fetchAndSortLiveGameData","resetPreviouslyPerformedSearch","loadingOutlined","LoadingOutlined","fontSize","spin","Spinner","PitcherArsenalValues","indicator","NavigationContainer","observer","navigationSelection","fetchingData","Group","buttons","Button","button","name","fetchGamesForSelectedPitcher","contextType","PitchingChart","chartReference","selectionReference","chartInstance","canvasCtx","selecting","chartMouseDownX","chartMouseDownY","chartMouseUpX","chartMouseUpY","rectangleMouseMoveStartX","rectangleMouseMoveStartY","numberOfSelections","drawRect","rectCoords","startingPointX","startingPointY","width","height","current","scale","devicePixelRatio","clearRect","beginPath","fillStyle","strokeStyle","lineWidth","rect","fill","stroke","getChartsXYAxisForMouseEvent","chart","yTop","chartArea","top","yBottom","bottom","yMin","scales","min","yMax","max","newY","nativeEvent","offsetY","Math","abs","xTop","left","xBottom","right","xMin","xMax","newX","offsetX","pointSelectionHandler","evt","updateSelectedPitches","selectedPoint","getElementAtEvent","selectedPointsChartDataSet","_chart","datasets","_datasetIndex","_index","deselectAllPitches","keepCanvasSizesInSync","React","createRef","addEventListener","debounce","xAxisTitle","yAxisTitle","storeData","getContext","Chart","animation","duration","display","text","legend","xAxes","scaleLabel","labelString","yAxes","hover","animationDuration","maintainAspectRatio","tooltips","enabled","custom","tooltipModel","tooltipEl","document","getElementById","createElement","innerHTML","appendChild","opacity","classList","remove","yAlign","add","point","dataPoints","dataSetIndex","datasetIndex","pointIndexWithinDataSet","pitchInfo","momentInstance","utc","displayPitchConfig","gameDate","atBat","pitchNumber","outcome","call","titleLines","innerHtml","lineOfInfo","tableRoot","querySelector","canvas","getBoundingClientRect","backgroundColor","borderRadius","pageXOffset","caretX","pageYOffset","caretY","fontFamily","_bodyFontFamily","bodyFontSize","fontStyle","_bodyFontStyle","padding","yPadding","xPadding","update","classNames","fullSizeChart","onContextMenu","preventDefault","resarchToolLink","open","onMouseDown","axisXY","onMouseMove","onMouseUp","onMouseOut","ref","ChartingContainer","chartsToRender","chartProperties","selectedSingleChart","singleChart","find","chartGenerator","horizontalMovementByVerticalMovement","horizontalMovementBySpeed","verticalMovementBySpeed","spinByReleaseSpeed","horizontalMovementBySpin","verticalMovementBySpin","Footer","href","link","rel","differentChartLabels","Header","selectChart","chartLabelSelections","pitcherIsSet","dataIsSet","section","RedoOutlined","disabled","selectAllPitches","classifyPitches","deleteTrainingData","trainPitcher","trainNeuralNet","Modal","info","content","whiteSpace","minWidth","ClassifierButton","Yes","cx","cy","pitchValue","No","Maybe","HandednessFilter","handedFilterValue","setHandednessFilter","Left","Right","PitchClassifierContainer","generateClassifierButtons","updateKnownPitchTypes","changePitchType","splice","findIndex","selectedPitch","removedFromThisBucket","addToThisPitchBucket","filterValue","App","app","sidebar","header","graphs","footer","Routing","exact","path","ImplicitCallback","Boolean","hostname","match","ReactDOM","render","navigator","serviceWorker","ready","registration","unregister"],"mappings":"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","file":"static/js/main.d6fd0ada.chunk.js","sourcesContent":["// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"Login_container__1PZWs\",\"title\":\"Login_title__1l0T1\",\"content\":\"Login_content__1oMWX\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"chart-container\":\"Chart_chart-container__1mJ1c\",\"selection\":\"Chart_selection__7qhNY\",\"full-size-chart\":\"Chart_full-size-chart__3vk6r\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"PitchClassifierContainer_container__12X8e\",\"buttons-container\":\"PitchClassifierContainer_buttons-container__2eLrO\",\"handedness-container\":\"PitchClassifierContainer_handedness-container__1ybtJ\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"ChartingContainer_container__3pu3V\",\"loading-container\":\"ChartingContainer_loading-container__3XYQC\",\"spinner\":\"ChartingContainer_spinner__3PZ0C\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"pitch-type\":\"ClassifierButton_pitch-type__1uM-b\",\"radio\":\"ClassifierButton_radio__1kA42\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"sidebar-container\":\"NavigateByPitcher_sidebar-container__2A_K6\",\"selections\":\"NavigateByPitcher_selections__2zVJa\",\"available-games\":\"NavigateByPitcher_available-games__1Geyo\",\"selection\":\"NavigateByPitcher_selection__swrEK\",\"message\":\"NavigateByPitcher_message__3xX4P\",\"game-select-all\":\"NavigateByPitcher_game-select-all__1ceK4\",\"games-title\":\"NavigateByPitcher_games-title__p06mq\",\"check-all\":\"NavigateByPitcher_check-all__KmqAA\",\"game-list\":\"NavigateByPitcher_game-list__238_x\",\"month-header\":\"NavigateByPitcher_month-header__1i0Dd\",\"month\":\"NavigateByPitcher_month__3dMbH\",\"year\":\"NavigateByPitcher_year__3oqc9\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"Header_container__19JCS\",\"pitcher\":\"Header_pitcher__eitX1\",\"chart-selection\":\"Header_chart-selection__DZiPX\",\"buttons\":\"Header_buttons__155Od\",\"button\":\"Header_button__jtAY1\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"app\":\"App_app__2ziFi\",\"content\":\"App_content__1Wt3K\",\"sidebar\":\"App_sidebar__3IISB\",\"header\":\"App_header__2L3DO\",\"graphs\":\"App_graphs__2mIB2\",\"buttons\":\"App_buttons__1l0RY\",\"footer\":\"App_footer__3csul\",\"item\":\"App_item__16P43\"};","export enum Routes {\n Root = \"/\",\n Login = \"/login\",\n ImplicitCallback = \"/implicit/callback\",\n}\n","import React from \"react\";\nimport { useOktaAuth } from \"@okta/okta-react\";\nimport { Redirect } from \"react-router-dom\";\nimport { Button, Layout } from \"antd\";\nimport styles from \"./Login.module.scss\";\nimport { Routes } from \"enums/routes\";\n\nconst Content = Layout.Content;\n\nfunction Login() {\n const { authService, authState } = useOktaAuth();\n const params = new URLSearchParams(window.location.search);\n\n if (authState.isAuthenticated) {\n return ;\n }\n\n return (\n \n \n
\n
\n
Pitch Classification
\n \n
\n
\n
\n
\n );\n}\n\nexport default Login;\n","export enum HandednessFilters {\n All = \"ALL\",\n Right = \"R\",\n Left = \"L\",\n}\n","export const normalizeStringOfDiacritics = (playerName: string) => {\n return playerName\n ? playerName\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .toLowerCase()\n : playerName;\n};\n","import React, { Component } from \"react\";\nimport styles from \"./NavigateByPitcher.module.scss\";\nimport { Select, Checkbox, AutoComplete, Button } from \"antd\";\nimport { CheckboxChangeEvent, CheckboxProps } from \"antd/lib/checkbox\";\nimport { normalizeStringOfDiacritics } from \"util/normalize\";\nimport { Pitcher, Split } from \"api/StatsApi\";\nimport { GameType } from \"stores/NavigationStore\";\nconst { Option } = Select;\n\nconst MONTHS = [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n];\n\ninterface NavigateByPitcherProps {\n errorOccurred: boolean;\n sports: { abbreviation: string; id: string }[];\n seasons: string[];\n splits: Split[];\n gameTypes: GameType[];\n availableGamePks: number[];\n selectedGamePks: number[];\n currentSeason?: string;\n pitchers: Pitcher[];\n currentPitcherId?: number;\n setGameType: (gameType: string) => void;\n setPitcherInfo: (id: number, name: string) => void;\n setSportId: (sportId: number) => void;\n setSeason: (season: string[]) => void;\n fetchAllPitchers: () => void;\n setSelectedGamePks: (selectedGamePks: number[]) => void;\n setPitcherData: () => void;\n resetSelectedOptions: () => void;\n resetSelectedGamePks: () => void;\n}\n\ninterface NavigateByPitcherState {\n searched: boolean;\n checkAll: boolean;\n pitcherInput?: string;\n}\n\nclass NavigateByPitcher extends Component<\n NavigateByPitcherProps,\n NavigateByPitcherState\n> {\n constructor(props: NavigateByPitcherProps) {\n super(props);\n this.state = {\n searched: false,\n checkAll: false,\n pitcherInput: \"\",\n };\n }\n\n componentDidMount() {\n const { setSportId, fetchAllPitchers, resetSelectedOptions } = this.props;\n resetSelectedOptions();\n setSportId(1);\n fetchAllPitchers();\n }\n\n componentDidUpdate(prevProps: NavigateByPitcherProps) {\n // If current props are coming in blank, we need to reset this controlled input field\n if (\n prevProps.currentPitcherId !== undefined &&\n this.props.currentPitcherId === undefined\n ) {\n this.setState({\n pitcherInput: \"\",\n checkAll: false,\n searched: false,\n });\n }\n }\n\n onSearch = () => {\n const { setPitcherData } = this.props;\n setPitcherData();\n this.setState({ searched: true });\n };\n\n selectGamePks(gamePks: number[]) {\n const { setSelectedGamePks, selectedGamePks } = this.props;\n const newSelectedGamePks = selectedGamePks.concat(gamePks);\n setSelectedGamePks(newSelectedGamePks);\n }\n\n deselectGamePks(gamePks: number[]) {\n const { setSelectedGamePks, selectedGamePks } = this.props;\n const newSelectedGamePks = selectedGamePks.filter(\n (gamePk) => !gamePks.includes(gamePk)\n );\n setSelectedGamePks(newSelectedGamePks);\n }\n\n render() {\n const {\n splits,\n sports,\n pitchers,\n gameTypes,\n seasons,\n selectedGamePks,\n setSelectedGamePks,\n } = this.props;\n\n const sportSelections = sports.map((item) => {\n return (\n \n );\n });\n const seasonSelection = seasons.map((item) => {\n return (\n \n );\n });\n const gameTypeSelection = gameTypes.map((item) => {\n return (\n \n );\n });\n\n const pitcherOptions = pitchers.map((p) => {\n return { value: `${p.lastFirstName} (${p.id})` };\n });\n\n const gamePkSelectionMap =\n splits &&\n splits\n .map((item) => {\n const {\n date,\n isHome,\n opponent,\n team,\n game: { gamePk },\n } = item;\n const [year, month, day] = date.split(\"-\");\n\n const homeTeam = isHome ? team : opponent;\n const awayTeam = isHome ? opponent : team;\n return {\n label: `${month}/${day} - ${awayTeam.abbreviation} @\n ${homeTeam.abbreviation}(${gamePk})`,\n value: gamePk,\n month: `${year}-${month}`,\n };\n })\n .reduce<{\n [key: string]: { label: string; value: number; month: string }[];\n }>((prev, curr) => {\n if (!prev[curr.month]) prev[curr.month] = [];\n prev[curr.month].push(curr);\n return prev;\n }, {});\n\n const onCheckAllChange = (e: CheckboxChangeEvent) => {\n const { availableGamePks } = this.props;\n this.setState({ checkAll: e.target.checked });\n if (e.target.checked) {\n setSelectedGamePks(availableGamePks);\n } else {\n setSelectedGamePks([]);\n }\n };\n\n return (\n
\n
\n {\n this.props.setSportId(sport.value);\n this.props.fetchAllPitchers();\n }}\n >\n {sportSelections}\n \n\n {\n this.props.setSeason(season);\n this.props.fetchAllPitchers();\n }}\n >\n {seasonSelection}\n \n\n {\n this.props.setGameType(gameType.toString());\n this.props.fetchAllPitchers();\n }}\n >\n {gameTypeSelection}\n \n\n {\n this.props.resetSelectedGamePks();\n let selectedPitcherId = pitcher.split(\"(\")[1].split(\")\")[0];\n let selectedPitcherName = pitcher.split(\"(\")[0];\n this.props.setPitcherInfo(\n parseInt(selectedPitcherId),\n selectedPitcherName\n );\n }}\n value={this.state.pitcherInput}\n onChange={(value) => this.setState({ pitcherInput: value })}\n allowClear={true}\n options={pitcherOptions}\n placeholder=\"Select a pitcher\"\n filterOption={(inputValue, option) =>\n normalizeStringOfDiacritics(option!.value.toUpperCase()).includes(\n normalizeStringOfDiacritics(inputValue.toUpperCase())\n )\n }\n />\n\n \n
\n {this.state.searched ? (\n this.props.errorOccurred ? (\n
\n There are no games available for the selections\n
\n ) : (\n
\n
\n

Games:

\n\n \n Select All\n \n
\n
\n {Object.keys(gamePkSelectionMap)\n .sort()\n .map((key) => {\n const gamePkSelection = gamePkSelectionMap[key];\n\n const checkboxes = gamePkSelection.map((option) => {\n return (\n
  • \n {\n if (e.target.checked === true) {\n this.selectGamePks([e.target.value]);\n } else {\n this.deselectGamePks([e.target.value]);\n }\n }}\n checked={selectedGamePks.includes(option.value)}\n value={option.value}\n >\n {option.label}\n \n
  • \n );\n });\n\n const [year, month] = key\n .split(\"-\")\n .map((x) => parseInt(x, 10));\n\n return (\n
    \n {\n if (\n !gamePkSelection\n .map((o) => o.value)\n .every((gamePk) =>\n selectedGamePks.includes(gamePk)\n )\n ) {\n this.selectGamePks(\n gamePkSelection.map((o) => o.value)\n );\n } else {\n this.deselectGamePks(\n gamePkSelection.map((o) => o.value)\n );\n }\n }}\n >\n \n {MONTHS[month - 1]}\n \n {year}\n \n
      {checkboxes}
    \n
    \n );\n })}\n
    \n
    \n )\n ) : null}\n
    \n );\n }\n}\n\nconst CheckboxWithValue = (\n props: CheckboxProps & { value: string | number }\n) => {\n return (\n {\n if (props.onChange) {\n e.target.value = props.value;\n props.onChange(e);\n }\n }}\n {...props}\n />\n );\n};\n\nexport default NavigateByPitcher;\n","import React, { Component } from \"react\";\nimport { DatePicker, Select, AutoComplete } from \"antd\";\nimport styles from \"./NavigateByDate.module.scss\";\nimport moment from \"moment\";\nimport { Pitcher } from \"api/StatsApi\";\nimport { normalizeStringOfDiacritics } from \"util/normalize\";\n\nconst { Option } = Select;\n\ninterface NavigateByDateProps {\n setDate: (date: moment.Moment) => void;\n setGamePk: (gamePk: string) => void;\n setGameType: (gameType: string) => void;\n allGames: { gamePk: string; gameType: string; abbrev: string }[];\n sports: { abbreviation: string; id: string }[];\n pitchers: Pitcher[];\n currentPitcherId?: number;\n currentDateInput: string;\n currentGamePkInput: number[];\n setSportId: (sportId: number) => void;\n setPitcherInfo: (id: number, name: string) => void;\n resetSelectedOptions: () => void;\n fetchGamesForDate: () => void;\n}\n\ninterface NavigateByDateState {\n pitcherInput?: string;\n gameInput?: string;\n}\n\nclass NavigateByDate extends Component<\n NavigateByDateProps,\n NavigateByDateState\n> {\n constructor(props: NavigateByDateProps) {\n super(props);\n this.state = {\n pitcherInput: \"\",\n gameInput: undefined,\n };\n }\n\n componentDidMount() {\n const { setSportId, resetSelectedOptions, fetchGamesForDate } = this.props;\n resetSelectedOptions();\n setSportId(1);\n fetchGamesForDate();\n }\n\n componentDidUpdate(prevProps: NavigateByDateProps) {\n // We need to reset some controlled input fields if props have changed.\n if (\n (prevProps.currentPitcherId !== undefined &&\n this.props.currentPitcherId === undefined) ||\n prevProps.currentDateInput !== this.props.currentDateInput\n ) {\n this.setState({\n pitcherInput: \"\",\n gameInput: undefined,\n });\n } else if (prevProps.currentGamePkInput !== this.props.currentGamePkInput) {\n this.setState({\n pitcherInput: \"\",\n });\n }\n }\n\n render() {\n const { pitchers, allGames, sports } = this.props;\n\n const sportSelections = sports.map((item) => {\n return (\n \n );\n });\n\n const gameOptions = allGames.map((game) => {\n return (\n \n );\n });\n\n const pitcherOptions = pitchers.map((item) => {\n return { value: `${item.lastFirstName} (${item.id})` };\n });\n\n return (\n
    \n {\n this.props.setSportId(sport.value);\n }}\n >\n {sportSelections}\n \n this.props.setDate(moment(date))}\n />\n {\n let [gamePk, gameType] = selected.split(\",\");\n this.props.setGamePk(gamePk);\n this.props.setGameType(gameType);\n }}\n value={this.state.gameInput}\n onChange={(value) => this.setState({ gameInput: value })}\n >\n {gameOptions}\n \n {\n let selectedPitcherId = pitcher.split(\"(\")[1].split(\")\")[0];\n let selectedPitcherName = pitcher.split(\"(\")[0];\n this.props.setPitcherInfo(\n parseInt(selectedPitcherId),\n selectedPitcherName\n );\n }}\n placeholder=\"Select a pitcher\"\n value={this.state.pitcherInput}\n onChange={(value) => this.setState({ pitcherInput: value })}\n allowClear={true}\n filterOption={(inputValue, option) =>\n normalizeStringOfDiacritics(option!.value.toUpperCase()).includes(\n normalizeStringOfDiacritics(inputValue.toUpperCase())\n )\n }\n />\n
    \n );\n }\n}\n\nexport default NavigateByDate;\n","interface GameLog {\n stats: Stats[];\n}\n\nexport interface Stats {\n splits: Split[];\n}\n\nexport interface Pitcher {\n firstName: string;\n lastName: string;\n lastFirstName: string;\n fullName: string;\n id: string;\n}\n\nexport interface Split {\n isHome: boolean;\n player: Pitcher;\n team: {\n id: number;\n name: string;\n link: string;\n abbreviation: string;\n };\n opponent: {\n id: number;\n name: string;\n link: string;\n abbreviation: string;\n };\n date: string;\n game: {\n gamePk: number;\n };\n}\n\ninterface LiveGame {\n gamePk: number;\n gameData: {\n datetime: {\n dateTime: string;\n };\n status: {\n startTimeTBD: boolean;\n };\n };\n liveData: {\n plays: {\n allPlays: Plays[];\n };\n };\n}\n\ninterface Plays {\n about: {\n halfInning: string;\n atBatIndex: number;\n inning: number;\n };\n matchup: {\n pitcher: {\n id: number;\n };\n batSide: {\n code: string;\n };\n };\n playEvents: PlayEvents[];\n}\n\nexport interface PlayEvents {\n playId: string;\n gamePk: number;\n atBatIndex: number;\n dateTime: string;\n isGameScheduledTBD: boolean;\n inningInfo: string;\n isPitch: boolean;\n pitchNumber: number;\n defense?: {\n pitcher: {\n id: number;\n };\n };\n details: {\n call: {\n description: string;\n };\n type: {\n code: string;\n };\n };\n count: {\n balls: number;\n strikes: number;\n };\n pitchData: {\n startSpeed: number;\n breaks: {\n spinRate: number;\n };\n coordinates: {\n pfxX: number; // Horizontal movement\n pfxZ: number; //Vertical movement\n };\n };\n isSelected: boolean;\n}\n\ninterface Sport {\n sports: [\n {\n abbreviation: string;\n id: string;\n }\n ];\n}\n\ninterface Schedule {\n dates: [\n {\n games: [\n {\n gamePk: string;\n gameType: string;\n teams: {\n away: {\n team: {\n id: string;\n abbreviation: string;\n };\n };\n home: {\n team: {\n id: string;\n abbreviation: string;\n };\n };\n };\n }\n ];\n }\n ];\n}\n\ninterface ArsenalStats {\n stats: PitcherArsenal[];\n}\n\ninterface PitcherArsenal {\n splits: PitcherArsenalSplit[];\n}\n\ninterface PitcherArsenalSplit {\n stat: {\n percentage: number;\n count: number;\n totalPitches: number;\n type: {\n code: string;\n description: string;\n };\n };\n}\n\nconst STATS_BASE_URL = process.env.REACT_APP_STATS_API_URL;\n\nexport default class StatsApi {\n fetchLiveGameData(gamePks: number[]): Promise {\n const fetchUrls = gamePks.map(\n (gamePk) =>\n `${STATS_BASE_URL}/api/v1.1/game/${gamePk}/feed/live?hydrate=alignment`\n );\n return Promise.all(\n fetchUrls.map((url) =>\n fetch(url).then((response: Response) => response.json())\n )\n );\n }\n\n fetchGames(\n sportId: number,\n season: string,\n gameType: string,\n pitcherId: number\n ): Promise {\n return fetch(\n `${STATS_BASE_URL}/api/v1/people/${pitcherId}/stats?stats=gameLog&season=${season}&sportId=${sportId}&gameType=${gameType}&group=pitching&hydrate=team`\n ).then((response) => response.json());\n }\n\n //fetches all Sport\n fetchSportIds = async (): Promise => {\n let resp = await fetch(`${STATS_BASE_URL}/api/v1/sports`);\n if (!resp.ok) {\n throw new Error(`${resp.status}, ${resp.statusText}`);\n }\n return await resp.json();\n };\n\n //fetches all gameTypes\n fetchGameTypes = async (): Promise<[{ id: string; description: string }]> => {\n let resp = await fetch(`${STATS_BASE_URL}/api/v1/gameTypes`);\n if (!resp.ok) {\n throw new Error(`${resp.status}, ${resp.statusText}`);\n }\n return await resp.json();\n };\n\n fetchLatestSeason = async (): Promise<{\n seasons: {\n seasonId: string;\n }[];\n }> => {\n let resp = await fetch(`${STATS_BASE_URL}/api/v1/seasons?sportId=1`);\n if (!resp.ok) {\n throw new Error(`${resp.status}, ${resp.statusText}`);\n }\n return await resp.json();\n };\n\n //NavigateByPitcher endpoint that fetches pitchers based on dropdown choices\n fetchAllPitchersForSeason = async (\n sportId: number,\n season: string,\n gameType: string\n ): Promise => {\n const fetchURL = `${STATS_BASE_URL}/api/v1/stats?stats=season&sportId=${sportId}&season=${season}&group=pitching&order=asc&playerPool=all&limit=5000&gameType=${gameType}&hydrate=person`;\n let resp = await fetch(fetchURL);\n if (!resp.ok) {\n throw new Error(`${resp.status}, ${resp.statusText}`);\n }\n return await resp.json();\n };\n\n //NavigateByDate endpt that fetches games for a selected date\n fetchGamesForDate = async (\n date: string,\n sportId: number\n ): Promise => {\n const fetchURL = `${STATS_BASE_URL}/api/v1/schedule?date=${date}&sportId=${sportId}&hydrate=team`;\n let resp = await fetch(fetchURL);\n if (!resp.ok) {\n throw new Error(`${resp.status}, ${resp.statusText}`);\n }\n return await resp.json();\n };\n\n //NavigateByDate endpt that fetches pitchers for a selected game\n fetchPitchersForDateNavigation = async (gamePk: string) => {\n const fetchURL = `${STATS_BASE_URL}/api/v1/game/${gamePk}/boxscore?hydrate=person`;\n let resp = await fetch(fetchURL);\n if (!resp.ok) {\n throw new Error(`${resp.status}, ${resp.statusText}`);\n }\n return await resp.json();\n };\n\n fetchPitcherArsenal = async (\n sportId: number,\n season: string,\n gameType: string,\n pitcherId: number\n ): Promise => {\n const fetchURL = `${STATS_BASE_URL}/api/v1/people/${pitcherId}/stats?stats=pitchArsenal&season=${season}&sportId=${sportId}&gameType=${gameType}&group=pitching`;\n let resp = await fetch(fetchURL);\n if (!resp.ok) {\n throw new Error(`${resp.status}, ${resp.statusText}`);\n }\n return await resp.json();\n };\n}\n","import RootStore from \"stores/RootStore\";\nimport { PlayEvents } from \"./StatsApi\";\nimport { MessageType } from \"stores/MessageStore\";\n\nconst BASE_URL = `${process.env.REACT_APP_API_URL}/api/v1`;\n\ninterface BinApiPitchEvent {\n playId: string;\n gamePk: number;\n pitchType: string;\n pitcherId: number;\n}\n\ninterface ApiResponse {\n data: T[];\n errors: string[];\n requestStatus: RequestStatus;\n}\n\ninterface RequestStatus {\n statusCode: number;\n msg: string;\n}\n\ntype BinApiResult = {\n requestId: string;\n response: string;\n statusCode: number;\n};\n\nexport default class PitchClassifier {\n rootStore: RootStore;\n\n constructor(rootStore: RootStore) {\n this.rootStore = rootStore;\n }\n\n private _transformPitchData(\n playerId: number,\n pitchData: PlayEvents[]\n ): BinApiPitchEvent[] {\n return pitchData.map((pitch) => ({\n gamePk: pitch.gamePk,\n playId: pitch.playId,\n pitchType: pitch.details.type?.code,\n pitcherId: playerId,\n }));\n }\n\n private _processMessage(message: string, type: MessageType) {\n const { messageStore } = this.rootStore;\n messageStore.push({ type, message });\n if (type === \"error\") {\n throw new Error(message);\n }\n }\n\n deleteTrainingData(playerId: number) {\n return fetch(`${BASE_URL}/player/${playerId}/deleteTrainingData`, {\n method: \"DELETE\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n }).then((r) => {\n if (r.ok) {\n this._processMessage(\"Delete training for \" + playerId, \"success\");\n return true;\n } else {\n this._processMessage(\n \"Failed to delete training for playerId \" + playerId,\n \"error\"\n );\n }\n });\n }\n\n classifyPitches(\n playerId: number,\n pitchData: PlayEvents[]\n ): Promise> {\n return fetch(`${BASE_URL}/player/${playerId}/classifyPitches`, {\n method: \"PUT\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n pitchUpdates: this._transformPitchData(playerId, pitchData),\n }),\n }).then((r) => {\n if (r.ok) {\n this._processMessage(\"Classify successful\", \"success\");\n return r.json();\n } else {\n this._processMessage(\"Failed to classify pitch events\", \"error\");\n }\n });\n }\n\n trainPitcher(\n playerId: number,\n pitchData: PlayEvents[]\n ): Promise> {\n return fetch(`${BASE_URL}/player/${playerId}/addToTrainingData`, {\n method: \"PUT\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n pitchUpdates: this._transformPitchData(playerId, pitchData),\n }),\n }).then((r) => {\n if (r.ok) {\n this._processMessage(\"Saved training data\", \"success\");\n return r.json();\n } else {\n this._processMessage(\"Failed to save training\", \"error\");\n }\n });\n }\n\n trainNeuralNet(playerId: number): Promise {\n return fetch(`${BASE_URL}/player/${playerId}/trainNeuralNetForPitcher`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n }).then((r) => {\n if (r.ok) {\n return r.json();\n } else {\n this._processMessage(\n \"Failed to train NN for playerId \" + playerId,\n \"error\"\n );\n }\n });\n }\n}\n","import { observable, action } from \"mobx\";\nimport RootStore from \"./RootStore\";\nimport { Stats, Pitcher, Split } from \"api/StatsApi\";\nimport moment from \"moment\";\nimport _ from \"lodash\";\n\ninterface PitcherInfo {\n name: string;\n id: number;\n}\n\nexport interface GameType {\n id: string;\n description: string;\n}\n\nexport interface NavigateByDateData {\n games: {\n gamePk: string;\n gameType: string;\n abbrev: string;\n }[];\n pitchers: Pitcher[];\n}\n\nexport interface NavigateByPitcherData {\n pitchersDropdown: Pitcher[];\n gameTypesDropdown: GameType[];\n allSportsDropdown: { abbreviation: string; id: string }[];\n seasonsDropdown: string[];\n gamePksDropdown: number[];\n}\n\nexport interface DropdownSelectedOptions {\n selectedGamePks: number[];\n selectedSportId: number;\n selectedSeasons: string[];\n selectedGameType: string;\n selectedPitcherInfo?: PitcherInfo;\n selectedDate: string;\n}\n\nconst sortPitchersByReverseOrderOfAppearance = (order: number[]) => (\n a: Pitcher,\n b: Pitcher\n) => (order.indexOf(parseInt(a.id)) > order.indexOf(parseInt(b.id)) ? -1 : 1);\n\nclass NavigationStore {\n rootStore: RootStore;\n constructor(rootStore: RootStore) {\n this.rootStore = rootStore;\n }\n\n @observable loading = false;\n @observable currentSeason?: string = undefined;\n @observable stats: Stats[] = [];\n @observable splits: Split[] = [];\n\n //holds ALL the selected options from the dropdown Menus for Both NavByPitcher & Date\n @observable dropdownSelectedOptions: DropdownSelectedOptions = {\n selectedGamePks: [],\n selectedSportId: 0,\n selectedSeasons: [],\n selectedGameType: \"R\",\n selectedPitcherInfo: undefined,\n selectedDate: \"\",\n };\n\n //holds ALL the necessary dropdown info for NavigateByPitcher\n @observable NavByPitcherDropdownOptions: NavigateByPitcherData = {\n pitchersDropdown: [],\n gameTypesDropdown: [],\n allSportsDropdown: [],\n gamePksDropdown: [],\n seasonsDropdown: [],\n };\n\n //holds ALL the necessary dropdown/select info for NavigateByDate\n @observable NavByDateDropdownOptions: NavigateByDateData = {\n games: [],\n pitchers: [],\n };\n\n @observable errorOccurred: boolean = false;\n\n @action resetSelectedGamePks = () => {\n this.dropdownSelectedOptions.selectedGamePks = [];\n this.NavByPitcherDropdownOptions.gamePksDropdown = [];\n };\n\n @action resetSelectedOptions = () => {\n const { dropdownSelectedOptions } = this;\n const resetOptions: DropdownSelectedOptions = {\n selectedGamePks: [],\n selectedSportId: 0,\n selectedSeasons: this.currentSeason\n ? [this.currentSeason.toString()]\n : [],\n selectedGameType: \"R\",\n selectedPitcherInfo: undefined,\n selectedDate: moment(new Date()).format(\"MM/DD/YYYY\"),\n };\n Object.assign(dropdownSelectedOptions, resetOptions);\n this.stats = [];\n };\n\n @action resetPreviouslyPerformedSearch = () => {\n const { dropdownSelectedOptions, NavByPitcherDropdownOptions } = this;\n dropdownSelectedOptions.selectedGamePks = [];\n dropdownSelectedOptions.selectedPitcherInfo = undefined;\n NavByPitcherDropdownOptions.pitchersDropdown = [];\n NavByPitcherDropdownOptions.gamePksDropdown = [];\n this.splits = [];\n this.stats = [];\n };\n\n @action fetchGamesForSelectedPitcher = () => {\n const {\n selectedPitcherInfo,\n selectedSeasons,\n selectedGameType,\n selectedSportId,\n } = this.dropdownSelectedOptions;\n if (selectedPitcherInfo?.id) {\n this.splits = [];\n this.stats = [];\n this.loading = true;\n const seasonRequests = selectedSeasons.map((season) => {\n return this.rootStore.statsApi\n .fetchGames(\n selectedSportId,\n season,\n selectedGameType,\n selectedPitcherInfo?.id\n )\n .then((data) => {\n this.stats = data.stats;\n\n for (let stat of this.stats) {\n for (let item of stat.splits) {\n let sortByDate = [...this.splits, item];\n this.splits = [...sortByDate].sort((a, b) => {\n let earlierGame: Date = new Date(a.date);\n let laterGame: Date = new Date(b.date);\n return earlierGame.valueOf() - laterGame.valueOf();\n });\n this.NavByPitcherDropdownOptions.gamePksDropdown = [\n ...this.NavByPitcherDropdownOptions.gamePksDropdown,\n item.game.gamePk,\n ];\n }\n }\n })\n .catch(() => {\n this.errorOccurred = true;\n console.error(\"No data available\");\n });\n });\n Promise.all(seasonRequests).then(() => (this.loading = false));\n } else {\n this.errorOccurred = true;\n console.error(\"Can't fetch games with no pitcherId set\");\n }\n };\n\n //fetches all available sportIds, sportId 1 = Major League, etc\n @action fetchSportIds = async () => {\n const { statsApi } = this.rootStore;\n this.loading = true;\n await statsApi\n .fetchSportIds()\n .then((s) => {\n let allSports = s.sports.map((sport) => {\n return { abbreviation: sport.abbreviation, id: sport.id.toString() };\n });\n this.NavByPitcherDropdownOptions.allSportsDropdown = allSports;\n })\n .catch((err) => console.error(err))\n .finally(() => (this.loading = false));\n };\n\n //fetches all available gameTypes\n @action fetchGameTypes = async () => {\n const { statsApi } = this.rootStore;\n this.loading = true;\n await statsApi\n .fetchGameTypes()\n .then((data) => {\n let filteredGameTypes = data.filter((item) => {\n return item.id !== \"I\" && item.id !== \"N\";\n });\n\n let allGameTypes = filteredGameTypes.map((d) => {\n return {\n id: d.id,\n description: d.description,\n };\n });\n this.NavByPitcherDropdownOptions.gameTypesDropdown = allGameTypes;\n })\n .catch((err) => console.error(err))\n .finally(() => (this.loading = false));\n };\n\n fetchAllPitchersForSeason = () => {\n const { statsApi } = this.rootStore;\n const {\n selectedSportId,\n selectedSeasons,\n selectedGameType,\n } = this.dropdownSelectedOptions;\n\n let allPitchers: {\n firstName: string;\n lastName: string;\n lastFirstName: string;\n fullName: string;\n id: string;\n }[] = [];\n this.loading = true;\n const seasonRequests = selectedSeasons.map((season) => {\n return statsApi\n .fetchAllPitchersForSeason(selectedSportId, season, selectedGameType)\n .then((data) => {\n const pitchersPerSeason = data.stats[0].splits.map((split) => {\n const { player } = split;\n return {\n firstName: player.firstName,\n lastName: player.lastName,\n lastFirstName: player.lastFirstName,\n fullName: player.fullName,\n id: player.id.toString(),\n };\n });\n Array.prototype.push.apply(allPitchers, pitchersPerSeason);\n this.NavByPitcherDropdownOptions.pitchersDropdown = _.uniqBy(\n allPitchers,\n (pitcher) => pitcher.id\n );\n })\n .catch((err) => console.error(err));\n });\n Promise.all(seasonRequests).then(() => (this.loading = false));\n };\n\n //Fetches all games based on a chosen date\n fetchGamesForDate = async () => {\n const { statsApi } = this.rootStore;\n this.loading = true;\n await statsApi\n .fetchGamesForDate(\n this.dropdownSelectedOptions.selectedDate,\n this.dropdownSelectedOptions.selectedSportId\n )\n .then((data) => {\n if (data.dates[0]) {\n this.NavByDateDropdownOptions.games = data.dates[0].games.map(\n (game) => {\n const gamePk = game.gamePk;\n const gameType = game.gameType;\n const awayTeamAbbrev = game.teams.away.team.abbreviation;\n const homeTeamAbbrev = game.teams.home.team.abbreviation;\n const gameObject = {\n gamePk: gamePk.toString(),\n gameType,\n abbrev: `${awayTeamAbbrev} @ ${homeTeamAbbrev}`,\n };\n return gameObject;\n }\n );\n } else {\n this.NavByDateDropdownOptions.games = [];\n }\n })\n .catch((err) => console.error(err))\n .finally(() => (this.loading = false));\n };\n\n //Fetches for pitchers based on a chosen Game, and makes sure those pitchers were active\n //aka not in the bullpen.\n fetchPitchersForDateNavigation = async () => {\n const { statsApi } = this.rootStore;\n this.loading = true;\n await statsApi\n .fetchPitchersForDateNavigation(\n this.dropdownSelectedOptions.selectedGamePks[0].toString()\n )\n .then((data) => {\n const awayTeam = data.teams.away;\n const homeTeam = data.teams.home;\n const awayTeamPitcherOrder = data.teams.away.pitchers;\n const homeTeamPitcherOrder = data.teams.home.pitchers;\n const awayTeamPitchers: Pitcher[] = [];\n const homeTeamPitchers: Pitcher[] = [];\n for (let ID in awayTeam.players) {\n const player = awayTeam.players[ID].person;\n if (\n awayTeam.players[ID].position.code === \"1\" &&\n !awayTeam.bullpen.includes(player.id)\n ) {\n const p: Pitcher = {\n fullName: player.fullName,\n firstName: player.firstName,\n lastName: player.lastName,\n lastFirstName: player.lastFirstName,\n id: player.id.toString(),\n };\n awayTeamPitchers.push(p);\n }\n }\n for (let ID in homeTeam.players) {\n const player = homeTeam.players[ID].person;\n if (\n homeTeam.players[ID].position.code === \"1\" &&\n !homeTeam.bullpen.includes(player.id)\n ) {\n const p: Pitcher = {\n fullName: player.fullName,\n firstName: player.firstName,\n lastName: player.lastName,\n lastFirstName: player.lastFirstName,\n id: player.id.toString(),\n };\n homeTeamPitchers.push(p);\n }\n }\n // sort each team's pitchers by when they appeared in the game, reverse chron\n awayTeamPitchers.sort(\n sortPitchersByReverseOrderOfAppearance(awayTeamPitcherOrder)\n );\n homeTeamPitchers.sort(\n sortPitchersByReverseOrderOfAppearance(homeTeamPitcherOrder)\n );\n\n const allPitchers = homeTeamPitchers.concat(awayTeamPitchers);\n this.NavByDateDropdownOptions.pitchers = allPitchers;\n })\n .catch((err) => console.error(err))\n .finally(() => (this.loading = false));\n };\n\n @action fetchLatestSeason = async () => {\n const { statsApi } = this.rootStore;\n this.loading = true;\n await statsApi\n .fetchLatestSeason()\n .then((data) => {\n const latestSeason = parseInt(data.seasons[0].seasonId);\n const seasonList = [];\n for (let season = latestSeason; season >= 2007; season--) {\n seasonList.push(season.toString());\n }\n this.NavByPitcherDropdownOptions.seasonsDropdown = seasonList;\n this.currentSeason = latestSeason.toString();\n })\n .catch((err) => console.error(err))\n .finally(() => (this.loading = false));\n };\n}\n\nexport default NavigationStore;\n","export const pitchTypes = [\n {\n label: \"FA\",\n color: \"rgb(235, 229, 196)\",\n },\n {\n label: \"FT\",\n color: \"rgb(102, 148, 176)\",\n },\n {\n label: \"SI\",\n color: \"rgb(8, 100, 175)\",\n },\n {\n label: \"FF\",\n color: \"rgb(227, 132, 4)\",\n },\n {\n label: \"FC\",\n color: \"rgb(227, 247, 161)\",\n },\n {\n label: \"FS\",\n color: \"rgb(255, 211, 19)\",\n },\n {\n label: \"FO\",\n color: \"rgb(117, 176, 2)\",\n },\n {\n label: \"CH\",\n color: \"rgb(165, 186, 78)\",\n },\n {\n label: \"SC\",\n color: \"rgb(209, 222, 229)\",\n },\n {\n label: \"ST\",\n color: \"rgb(255, 20, 147)\",\n },\n {\n label: \"SL\",\n color: \"rgb(201, 201, 159)\",\n },\n {\n label: \"SV\",\n color: \"rgb(0, 255, 255)\",\n },\n {\n label: \"CU\",\n color: \"rgb(27, 151, 217)\",\n },\n {\n label: \"CS\",\n color: \"rgb(139, 0, 139)\",\n },\n {\n label: \"KC\",\n color: \"rgb(240, 94, 41)\",\n },\n {\n label: \"KN\",\n color: \"rgb(204, 51, 0)\",\n },\n {\n label: \"GY\",\n color: \"rgb(102, 148, 176)\",\n },\n {\n label: \"EP\",\n color: \"rgb(82, 212, 201)\",\n },\n];\n\nexport const labelToColorMap: {\n [key: string]: string;\n} = pitchTypes.reduce(\n (acc, pitchType) => ({\n ...acc,\n [pitchType.label]: pitchType.color,\n }),\n {}\n);\n\nexport const allPitchTypes: string[] = pitchTypes.map(\n (pitchType) => pitchType.label\n);\n","import { action, computed, observable } from \"mobx\";\nimport RootStore from \"./RootStore\";\nimport { ChartDataSets, ChartColor, Scriptable } from \"chart.js\";\nimport { PlayEvents } from \"api/StatsApi\";\nimport { labelToColorMap } from \"constants/pitchTypes\";\nimport { HandednessFilters } from \"enums/handedFilters\";\n\nclass ChartingStore {\n rootStore: RootStore;\n hoverBorderColor: ChartColor;\n\n constructor(rootStore: RootStore) {\n this.rootStore = rootStore;\n this.hoverBorderColor = \"rgb(54, 162, 235)\";\n }\n\n private _pointBorderColor: Scriptable = (context) => {\n const { dataset, dataIndex } = context;\n if (\n dataset === undefined ||\n dataset.data === undefined ||\n dataIndex === undefined\n ) {\n return \"black\";\n }\n const { pitch } = dataset.data[dataIndex] as {\n x: number;\n y: number;\n pitch: PlayEvents;\n };\n if (pitch.isSelected) return \"black\";\n\n const pitchType = pitch.details.type.code;\n return labelToColorMap[pitchType];\n };\n\n private _pointBorderWidth: Scriptable = (context) => {\n const { dataset, dataIndex } = context;\n if (\n dataset === undefined ||\n dataset.data === undefined ||\n dataIndex === undefined\n ) {\n return 1;\n }\n const { pitch } = dataset.data[dataIndex] as {\n x: number;\n y: number;\n pitch: PlayEvents;\n };\n return pitch.isSelected ? 3 : 1;\n };\n\n /*\n * A map of pitch type -> array of pitch events for a given pitcher.\n * ex: \"FF\" -> All PitchEvents that were all categorized as FF\n */\n @observable pitchersDataByPitchType: Map = new Map<\n string,\n PlayEvents[]\n >();\n\n @observable handednessFilter: HandednessFilters = HandednessFilters.All;\n @observable loading: boolean = false;\n @observable selectedSingleChart = \"View All\";\n\n @computed get totalNumberOfPitches(): number {\n let pitchCount = 0;\n this.pitchersDataByPitchType.forEach((pitchList) => {\n pitchCount += pitchList.length;\n });\n return pitchCount;\n }\n\n @computed get spinByReleaseSpeed(): ChartDataSets[] {\n return Array.from(this.pitchersDataByPitchType.keys()).map((pitchType) => {\n const dataSet = this.pitchersDataByPitchType\n .get(pitchType)\n ?.map((pitch) => ({\n y: pitch.pitchData.startSpeed,\n x: pitch.pitchData.breaks.spinRate,\n pitch: pitch,\n }));\n\n return {\n label: pitchType,\n data: dataSet,\n pointRadius: 4,\n pointBackgroundColor: labelToColorMap[pitchType],\n pointBorderColor: this._pointBorderColor,\n pointBorderWidth: this._pointBorderWidth,\n pointHoverBorderColor: this.hoverBorderColor,\n };\n });\n }\n\n @computed get horizontalMovementBySpeed(): ChartDataSets[] {\n return Array.from(this.pitchersDataByPitchType.keys()).map((pitchType) => {\n const dataSet = this.pitchersDataByPitchType\n .get(pitchType)\n ?.map((pitch) => ({\n y: pitch.pitchData.startSpeed,\n x: pitch.pitchData.coordinates.pfxX,\n pitch: pitch,\n }));\n\n return {\n label: pitchType,\n data: dataSet,\n pointRadius: 4,\n pointBackgroundColor: labelToColorMap[pitchType],\n pointBorderColor: this._pointBorderColor,\n pointBorderWidth: this._pointBorderWidth,\n pointHoverBorderColor: this.hoverBorderColor,\n };\n });\n }\n\n @computed get verticalMovementBySpeed(): ChartDataSets[] {\n return Array.from(this.pitchersDataByPitchType.keys()).map((pitchType) => {\n const dataSet = this.pitchersDataByPitchType\n .get(pitchType)\n ?.map((pitch) => ({\n y: pitch.pitchData.startSpeed,\n x: pitch.pitchData.coordinates.pfxZ,\n pitch: pitch,\n }));\n\n return {\n label: pitchType,\n data: dataSet,\n pointRadius: 4,\n pointBackgroundColor: labelToColorMap[pitchType],\n pointBorderColor: this._pointBorderColor,\n pointBorderWidth: this._pointBorderWidth,\n pointHoverBorderColor: this.hoverBorderColor,\n };\n });\n }\n\n @computed get horizontalMovementByVerticalMovement(): ChartDataSets[] {\n return Array.from(this.pitchersDataByPitchType.keys()).map((pitchType) => {\n const dataSet = this.pitchersDataByPitchType\n .get(pitchType)\n ?.map((pitch) => ({\n y: pitch.pitchData.coordinates.pfxZ,\n x: pitch.pitchData.coordinates.pfxX,\n pitch: pitch,\n }));\n\n return {\n label: pitchType,\n data: dataSet,\n pointRadius: 4,\n pointBackgroundColor: labelToColorMap[pitchType],\n pointBorderColor: this._pointBorderColor,\n pointBorderWidth: this._pointBorderWidth,\n pointHoverBorderColor: this.hoverBorderColor,\n };\n });\n }\n\n @computed get horizontalMovementBySpin(): ChartDataSets[] {\n return Array.from(this.pitchersDataByPitchType.keys()).map((pitchType) => {\n const dataSet = this.pitchersDataByPitchType\n .get(pitchType)\n ?.map((pitch) => ({\n x: pitch.pitchData.breaks.spinRate,\n y: pitch.pitchData.coordinates.pfxX,\n pitch: pitch,\n }));\n\n return {\n label: pitchType,\n data: dataSet,\n pointRadius: 4,\n pointBackgroundColor: labelToColorMap[pitchType],\n pointBorderColor: this._pointBorderColor,\n pointBorderWidth: this._pointBorderWidth,\n pointHoverBorderColor: this.hoverBorderColor,\n };\n });\n }\n\n @computed get verticalMovementBySpin(): ChartDataSets[] {\n return Array.from(this.pitchersDataByPitchType.keys()).map((pitchType) => {\n const dataSet = this.pitchersDataByPitchType\n .get(pitchType)\n ?.map((pitch) => ({\n x: pitch.pitchData.breaks.spinRate,\n y: pitch.pitchData.coordinates.pfxZ,\n pitch: pitch,\n }));\n\n return {\n label: pitchType,\n data: dataSet,\n pointRadius: 4,\n pointBackgroundColor: labelToColorMap[pitchType],\n pointBorderColor: this._pointBorderColor,\n pointBorderWidth: this._pointBorderWidth,\n pointHoverBorderColor: this.hoverBorderColor,\n };\n });\n }\n\n @action fetchAndSortLiveGameData(gamePks: number[]): Promise {\n const { statsApi, navigationStore } = this.rootStore;\n const { selectedPitcherInfo } = navigationStore.dropdownSelectedOptions;\n let tempPitchCategoryBucket: Map = new Map<\n string,\n PlayEvents[]\n >();\n this.loading = true;\n this.resetPitcherData();\n return statsApi.fetchLiveGameData(gamePks).then((data) => {\n data.forEach((gameData) => {\n const gamePk = gameData.gamePk;\n const dateTime = gameData.gameData.datetime.dateTime;\n const isGameScheduledTBD = gameData.gameData.status.startTimeTBD;\n // Limit data to the pitches for that selected pitcher and only show playEvents where isPitch === true\n gameData.liveData.plays.allPlays\n .filter(\n (play) =>\n (this.handednessFilter === HandednessFilters.All ||\n play.matchup.batSide.code === this.handednessFilter) &&\n play.playEvents.filter((event) => event.isPitch)\n )\n .forEach((play) => {\n play.playEvents\n .filter(\n (event) =>\n event.defense &&\n event.defense.pitcher.id === selectedPitcherInfo?.id\n )\n .forEach((event) => {\n const inningInfo = `${play.about.halfInning} ${play.about.inning}`;\n const atBatIndex = play.about.atBatIndex;\n if (event.isPitch && event.details.type) {\n event.gamePk = gamePk;\n event.inningInfo = inningInfo;\n event.atBatIndex = atBatIndex;\n event.dateTime = dateTime;\n event.isGameScheduledTBD = isGameScheduledTBD;\n event.isSelected = false;\n if (!tempPitchCategoryBucket.has(event.details.type.code)) {\n tempPitchCategoryBucket.set(event.details.type.code, [\n event,\n ]);\n } else {\n tempPitchCategoryBucket\n .get(event.details.type.code)\n ?.push(event);\n }\n }\n });\n });\n });\n // Set results to observable map for rendering\n this.pitchersDataByPitchType = tempPitchCategoryBucket;\n this.loading = false;\n });\n }\n\n /*\n Toggles the isSelected boolean on the found pitch object to true or false. If isSelected is already true,\n it then becomes false. Likewise if already false.\n */\n @action updateSelectedPitches = (dataSet: ChartDataSets, index: number) => {\n if (dataSet.label) {\n const foundPitchesArray =\n this.pitchersDataByPitchType.get(dataSet.label) || [];\n if (foundPitchesArray) {\n const isPitchAlreadySelected = foundPitchesArray[index].isSelected;\n foundPitchesArray[index].isSelected = isPitchAlreadySelected\n ? false\n : true;\n this.pitchersDataByPitchType.set(dataSet.label, [...foundPitchesArray]);\n }\n }\n };\n\n @action resetPitcherData() {\n this.pitchersDataByPitchType = new Map();\n }\n\n @action selectAllPitches = () => {\n for (let [k, v] of this.pitchersDataByPitchType) {\n let selectAll = v.map((pitch) => {\n return {\n ...pitch,\n isSelected: true,\n };\n });\n this.pitchersDataByPitchType.set(k, selectAll);\n }\n };\n\n @action deselectAllPitches = () => {\n for (let [k, v] of this.pitchersDataByPitchType) {\n let selectAll = v.map((pitch) => {\n return {\n ...pitch,\n isSelected: false,\n };\n });\n this.pitchersDataByPitchType.set(k, selectAll);\n }\n };\n\n //returns an [] of all currently selected pitches\n @computed get allSelectedPitches() {\n let allSelectedPitches: PlayEvents[] = [];\n for (let pitches of this.pitchersDataByPitchType.values()) {\n allSelectedPitches.push(...pitches.filter((p) => p.isSelected));\n }\n return allSelectedPitches;\n }\n}\n\nexport default ChartingStore;\n","import RootStore from \"./RootStore\";\nimport { action, observable } from \"mobx\";\n\nclass PitchClassifierStore {\n rootStore: RootStore;\n\n constructor(rootStore: RootStore) {\n this.rootStore = rootStore;\n }\n\n @observable knownPitchTypes: string[] = [];\n\n @action async fetchPitcherArsenal() {\n const { statsApi, navigationStore } = this.rootStore;\n this.knownPitchTypes = [];\n if (navigationStore.dropdownSelectedOptions.selectedPitcherInfo?.id) {\n await statsApi\n .fetchPitcherArsenal(\n navigationStore.dropdownSelectedOptions.selectedSportId,\n navigationStore.dropdownSelectedOptions.selectedSeasons[0],\n navigationStore.dropdownSelectedOptions.selectedGameType,\n navigationStore.dropdownSelectedOptions.selectedPitcherInfo?.id\n )\n .then((data) => {\n data.stats.forEach((stat) => {\n stat.splits.forEach((split) => {\n this.knownPitchTypes.push(split.stat.type.code);\n });\n });\n })\n .catch((err) => console.log(err));\n } else {\n console.error(\"No Pitcher selected!\");\n }\n }\n}\n\nexport default PitchClassifierStore;\n","import { notification } from \"antd\";\nimport { observable } from \"mobx\";\nimport { queueProcessor } from \"mobx-utils\";\n\nexport type MessageType = \"success\" | \"error\" | \"warning\";\n\ninterface Message {\n type: MessageType;\n message: string | React.ReactNode;\n description?: string;\n}\n\nclass MessageStore {\n @observable messages: Message[] = [];\n\n constructor() {\n queueProcessor(this.messages, (m: Message) => this.process(m));\n }\n\n process = (m: Message) => {\n notification[m.type]({\n message: m.message,\n description: m.description,\n placement: \"topRight\",\n });\n };\n\n push = (m: Message): void => {\n this.messages.push(m);\n if (m.type === \"error\") {\n console.error(m.message);\n }\n };\n}\n\nexport default MessageStore;\n","import { computed, observable } from \"mobx\";\nimport RootStore from \"./RootStore\";\n\ntype AuthHeader = { Authorization: string } | {};\n\nexport default class AuthStore {\n rootStore: RootStore;\n @observable user?: User = undefined;\n @observable accessToken?: string = undefined;\n\n constructor(rootStore: RootStore) {\n this.rootStore = rootStore;\n\n const authService = rootStore.authService;\n const tokenManager = authService.getTokenManager();\n\n if (tokenManager) {\n tokenManager.on(\"expired\", async () => {\n this.accessToken = await authService.getAccessToken();\n });\n }\n\n authService.on(\"authStateChange\", async () => {\n const state = authService.getAuthState();\n if (state.isAuthenticated) {\n this.user = authService.getUser();\n }\n });\n }\n\n @computed get authHeader(): AuthHeader {\n return this.accessToken\n ? { Authorization: `Bearer ${this.accessToken}` }\n : {};\n }\n}\n","import { reaction } from \"mobx\";\nimport { AuthService } from \"@okta/okta-react\";\nimport StatsApi from \"api/StatsApi\";\nimport PitchClassifierApi from \"api/PitchClassifierApi\";\nimport NavigationStore from \"./NavigationStore\";\nimport ChartingStore from \"./ChartingStore\";\nimport PitchClassifierStore from \"./PitchClassifierStore\";\nimport MessageStore from \"./MessageStore\";\nimport AuthStore from \"./AuthStore\";\n\nconst { protocol, host } = window.location;\n\nconst AUTH_CONFIG = {\n issuer: process.env.REACT_APP_OKTA_ISSUER,\n clientId: process.env.REACT_APP_OKTA_CLIENT_ID,\n redirectUri: `${protocol}//${host}/implicit/callback`,\n};\n\nexport default class RootStore {\n authService = new AuthService(AUTH_CONFIG) as AuthService;\n statsApi = new StatsApi();\n messageStore = new MessageStore();\n\n pitchClassifierApi = new PitchClassifierApi(this);\n navigationStore = new NavigationStore(this);\n chartingStore = new ChartingStore(this);\n pitchClassifierStore = new PitchClassifierStore(this);\n authStore = new AuthStore(this);\n\n constructor() {\n reaction(\n () => this.chartingStore.handednessFilter,\n () => {\n this.chartingStore.fetchAndSortLiveGameData(\n this.navigationStore.dropdownSelectedOptions.selectedGamePks\n );\n }\n );\n\n reaction(\n () => [\n this.navigationStore.dropdownSelectedOptions.selectedSportId,\n this.navigationStore.dropdownSelectedOptions.selectedSeasons,\n this.navigationStore.dropdownSelectedOptions.selectedDate,\n ],\n () => {\n this.navigationStore.resetPreviouslyPerformedSearch();\n }\n );\n\n reaction(\n () =>\n this.navigationStore.dropdownSelectedOptions.selectedPitcherInfo?.id,\n (pitcherId) => {\n this.chartingStore.resetPitcherData();\n if (pitcherId) {\n this.pitchClassifierStore.fetchPitcherArsenal();\n }\n }\n );\n }\n}\n","import { createContext } from \"react\";\nimport RootStore from \"./stores/RootStore\";\n\nexport const rootStoreContext = createContext(new RootStore());\n","import React from \"react\";\nimport { Spin } from \"antd\";\nimport { SpinProps } from \"antd/lib/spin\";\nimport { LoadingOutlined } from \"@ant-design/icons\";\n\nconst loadingOutlined = ;\n\nfunction Spinner(props: SpinProps) {\n return ;\n}\n\nexport default Spinner;\n","import React, { Component } from \"react\";\nimport { Select, Button } from \"antd\";\nimport styles from \"./ClassifierButton.module.scss\";\n\nconst { Option } = Select;\n\nexport enum PitcherArsenalValues {\n Yes = \"2\",\n Maybe = \"1\",\n No = \"0\",\n}\n\ninterface ButtonProps {\n item: {\n label: string;\n color: string;\n };\n value: string;\n onSelect(value: string, pitchType: string): void;\n onClick(value: string): void;\n}\n\nexport default class ClassifierButton extends Component {\n render() {\n const { item, value, onClick, onSelect } = this.props;\n\n return (\n
    \n onClick(item.label)}\n value={item.label}\n disabled={value !== PitcherArsenalValues.Yes}\n >\n
    {item.label}
    \n \n \n \n \n onSelect(pitchValue, item.label)}\n >\n \n \n \n \n
    \n );\n }\n}\n","import React, { Component, ContextType } from \"react\";\nimport NavigateByPitcher from \"components/navigateByPitcher\";\nimport NavigateByDate from \"components/navigateByDate\";\nimport { Radio } from \"antd\";\nimport styles from \"./NavigationContainer.module.scss\";\nimport { observer } from \"mobx-react\";\nimport { rootStoreContext } from \"contexts\";\nimport { RadioChangeEvent } from \"antd/lib/radio\";\nimport Spinner from \"components/spinner\";\n\ninterface NavigationState {\n navigationSelection: string;\n fetchingData: boolean;\n}\n\n@observer\nclass NavigationContainer extends Component<{}, NavigationState> {\n static contextType = rootStoreContext;\n context!: ContextType;\n\n state = {\n navigationSelection: \"pitcher\",\n fetchingData: false,\n };\n\n async componentDidMount() {\n const { navigationStore } = this.context;\n this.setState({ fetchingData: true });\n await navigationStore.fetchSportIds();\n await navigationStore.fetchGameTypes();\n await navigationStore\n .fetchLatestSeason()\n .then(() => this.setState({ fetchingData: false }));\n }\n\n navigationSelection = (type: string) => {\n this.setState({ navigationSelection: type });\n };\n\n render() {\n const { navigationStore, chartingStore } = this.context;\n const { dropdownSelectedOptions } = navigationStore;\n const {\n gameTypesDropdown,\n pitchersDropdown,\n seasonsDropdown,\n allSportsDropdown,\n gamePksDropdown,\n } = navigationStore.NavByPitcherDropdownOptions;\n\n return this.state.fetchingData ? null : (\n
    \n {navigationStore.loading ? (\n
    \n \n
    \n ) : null}\n {\n this.setState({ navigationSelection: e.target.value });\n }}\n value={this.state.navigationSelection}\n className={styles.buttons}\n >\n {\n this.navigationSelection(\"pitcher\");\n dropdownSelectedOptions.selectedGamePks = [];\n }}\n >\n Pitcher\n \n {\n this.navigationSelection(\"date\");\n dropdownSelectedOptions.selectedGamePks = [];\n }}\n >\n Date\n \n \n
    \n {this.state.navigationSelection === \"pitcher\" ? (\n \n (dropdownSelectedOptions.selectedSportId = sportId)\n }\n setPitcherInfo={(id: number, name: string) =>\n (dropdownSelectedOptions.selectedPitcherInfo = { id, name })\n }\n setGameType={(gameType) =>\n (dropdownSelectedOptions.selectedGameType = gameType)\n }\n setSeason={(season) =>\n (dropdownSelectedOptions.selectedSeasons = season)\n }\n setSelectedGamePks={(selectedGamePks) => {\n dropdownSelectedOptions.selectedGamePks = selectedGamePks;\n chartingStore.fetchAndSortLiveGameData(selectedGamePks);\n }}\n setPitcherData={() => {\n navigationStore.errorOccurred = false;\n navigationStore.fetchGamesForSelectedPitcher();\n }}\n fetchAllPitchers={() => {\n navigationStore.fetchAllPitchersForSeason();\n }}\n resetSelectedOptions={() => {\n navigationStore.resetSelectedOptions();\n }}\n resetSelectedGamePks={() => {\n navigationStore.resetSelectedGamePks();\n }}\n />\n ) : (\n \n (dropdownSelectedOptions.selectedSportId = sportId)\n }\n setDate={(date) => {\n dropdownSelectedOptions.selectedDate = date.format(\n \"MM/DD/YYYY\"\n );\n dropdownSelectedOptions.selectedSeasons = [date.format(\"YYYY\")];\n navigationStore.fetchGamesForDate();\n }}\n setGamePk={(gamePk: string) => {\n dropdownSelectedOptions.selectedGamePks = [parseInt(gamePk)];\n navigationStore.fetchPitchersForDateNavigation();\n }}\n setGameType={(gameType: string) => {\n dropdownSelectedOptions.selectedGameType = gameType;\n }}\n setPitcherInfo={(id: number, name: string) => {\n dropdownSelectedOptions.selectedPitcherInfo = { id, name };\n chartingStore.fetchAndSortLiveGameData(\n dropdownSelectedOptions.selectedGamePks\n );\n }}\n resetSelectedOptions={() => {\n navigationStore.resetSelectedOptions();\n }}\n fetchGamesForDate={() => navigationStore.fetchGamesForDate()}\n />\n )}\n
    \n
    \n );\n }\n}\n\nexport default NavigationContainer;\n","import React, { Component } from \"react\";\nimport Chart, { ChartPoint, ChartDataSets } from \"chart.js\";\nimport debounce from \"lodash.debounce\";\nimport moment from \"moment\";\nimport styles from \"./Chart.module.scss\";\nimport { PlayEvents } from \"api/StatsApi\";\nimport classNames from \"classnames\";\n\ninterface ChartProps {\n title: string;\n xAxisTitle: string;\n yAxisTitle: string;\n storeData: ChartDataSets[];\n updateSelectedPitches(dataSet: ChartDataSets, index: number): void;\n deselectAllPitches(): void;\n fullSizeChart: boolean;\n}\n\ninterface SelectionRectangle {\n startingPointX: number;\n startingPointY: number;\n width: number;\n height: number;\n}\n\nclass PitchingChart extends Component {\n chartReference: React.RefObject;\n selectionReference: React.RefObject;\n chartInstance: any;\n canvasCtx?: CanvasRenderingContext2D;\n selecting: boolean = false;\n chartMouseDownX: number = 0;\n chartMouseDownY: number = 0;\n chartMouseUpX: number = 0;\n chartMouseUpY: number = 0;\n rectangleMouseMoveStartX: number = 0;\n rectangleMouseMoveStartY: number = 0;\n numberOfSelections: number = 0; // Helps us decide if we selected/clicked on 'nothing'\n\n constructor(props: ChartProps) {\n super(props);\n this.chartReference = React.createRef();\n this.selectionReference = React.createRef();\n }\n\n drawRect = (rectCoords: SelectionRectangle) => {\n const { startingPointX, startingPointY, width, height } = rectCoords;\n if (this.canvasCtx && this.selectionReference.current) {\n const scale = window.devicePixelRatio;\n // Clear previous rectangle\n this.clearRect();\n\n // Draw selection rectangle based on mouse event coordinates passed in.\n this.canvasCtx.beginPath();\n this.canvasCtx.fillStyle = \"rgba(0, 157, 240, 0.2)\";\n this.canvasCtx.strokeStyle = \"rgba(0, 157, 240, 1.0)\";\n this.canvasCtx.lineWidth = 0.2;\n this.canvasCtx.rect(\n startingPointX * scale,\n startingPointY * scale,\n width * scale,\n height * scale\n );\n this.canvasCtx.fill();\n this.canvasCtx.stroke();\n }\n };\n\n clearRect = () => {\n if (this.canvasCtx && this.selectionReference.current) {\n this.canvasCtx.clearRect(\n 0,\n 0,\n this.selectionReference.current.width,\n this.selectionReference.current.height\n );\n }\n };\n\n getChartsXYAxisForMouseEvent = (\n event: React.MouseEvent,\n chart: any\n ) => {\n const yTop = chart.chartArea.top;\n const yBottom = chart.chartArea.bottom;\n const yMin = chart.scales[\"y-axis-1\"].min;\n const yMax = chart.scales[\"y-axis-1\"].max;\n let newY = 0;\n\n if (\n event.nativeEvent.offsetY <= yBottom &&\n event.nativeEvent.offsetY >= yTop\n ) {\n newY = Math.abs((event.nativeEvent.offsetY - yTop) / (yBottom - yTop));\n newY = (newY - 1) * -1;\n newY = newY * Math.abs(yMax - yMin) + yMin;\n }\n\n const xTop = chart.chartArea.left;\n const xBottom = chart.chartArea.right;\n const xMin = chart.scales[\"x-axis-1\"].min;\n const xMax = chart.scales[\"x-axis-1\"].max;\n let newX = 0;\n\n if (\n event.nativeEvent.offsetX <= xBottom &&\n event.nativeEvent.offsetX >= xTop\n ) {\n newX = Math.abs((event.nativeEvent.offsetX - xTop) / (xBottom - xTop));\n newX = newX * Math.abs(xMax - xMin) + xMin;\n }\n\n return { x: newX, y: newY };\n };\n\n pointSelectionHandler = (evt: MouseEvent) => {\n const { updateSelectedPitches } = this.props;\n const selectedPoint = this.chartInstance.getElementAtEvent(evt)[0];\n if (selectedPoint) {\n const selectedPointsChartDataSet =\n selectedPoint._chart.data.datasets[selectedPoint._datasetIndex];\n const value = selectedPointsChartDataSet.data[selectedPoint._index];\n updateSelectedPitches(selectedPointsChartDataSet, selectedPoint._index);\n console.log(\"You've clicked on play_id: \" + value.pitch.playId);\n } else {\n if (!this.numberOfSelections) {\n this.props.deselectAllPitches();\n }\n }\n };\n\n keepCanvasSizesInSync = () => {\n /*\n * Chart.js is responsively changing the size of the canvas element it manages (this.chartReference).\n * Let's make sure we mimic it's style adjustments over to the selection canvas (this.selectionReference).\n */\n if (this.selectionReference.current && this.chartReference.current) {\n this.selectionReference.current.style.width = this.chartReference.current.style.width;\n this.selectionReference.current.width = this.chartReference.current.width;\n this.selectionReference.current.style.height = this.chartReference.current.style.height;\n this.selectionReference.current.height = this.chartReference.current.height;\n }\n };\n\n componentDidMount() {\n window.addEventListener(\"resize\", debounce(this.keepCanvasSizesInSync, 10));\n if (this.chartReference.current && this.selectionReference.current) {\n const { title, xAxisTitle, yAxisTitle, storeData } = this.props;\n this.canvasCtx =\n this.selectionReference.current?.getContext(\"2d\") || undefined;\n\n const dataSet = {\n datasets: storeData,\n };\n\n this.chartInstance = new Chart(this.chartReference.current, {\n type: \"scatter\",\n data: dataSet,\n options: {\n onClick: this.pointSelectionHandler,\n animation: {\n duration: 0,\n },\n title: {\n display: true,\n text: title,\n },\n legend: {\n display: false,\n },\n scales: {\n xAxes: [\n {\n scaleLabel: {\n display: true,\n labelString: xAxisTitle,\n },\n position: \"bottom\",\n },\n ],\n yAxes: [\n {\n scaleLabel: {\n display: true,\n labelString: yAxisTitle,\n },\n position: \"bottom\",\n },\n ],\n },\n hover: {\n animationDuration: 0,\n mode: \"point\",\n },\n maintainAspectRatio: false,\n tooltips: {\n enabled: false,\n mode: \"point\",\n custom: (tooltipModel) => {\n // Tooltip Element\n let tooltipEl = document.getElementById(\"chartjs-tooltip\");\n\n // Create element on first render\n if (!tooltipEl) {\n tooltipEl = document.createElement(\"div\");\n tooltipEl.id = \"chartjs-tooltip\";\n tooltipEl.innerHTML = \"
    \";\n document.body.appendChild(tooltipEl);\n }\n\n // Hide if no tooltip\n if (tooltipModel.opacity === 0 || this.selecting) {\n tooltipEl.style.opacity = \"0\";\n tooltipEl.style.display = \"none\";\n return;\n }\n\n // Set caret Position\n tooltipEl.classList.remove(\"above\", \"below\", \"no-transform\");\n if (tooltipModel.yAlign) {\n tooltipEl.classList.add(tooltipModel.yAlign);\n } else {\n tooltipEl.classList.add(\"no-transform\");\n }\n\n // Grab proper dataSet and dataPoint from chartInstance\n const point = tooltipModel.dataPoints[0];\n const dataSetIndex: number =\n point.datasetIndex !== undefined ? point.datasetIndex : -1;\n const pointIndexWithinDataSet: number =\n point.index !== undefined ? point.index : -1;\n\n if (dataSetIndex < 0 || pointIndexWithinDataSet < 0) {\n console.error(\"Invalid dataSet/dataIndex\");\n return false;\n }\n\n const pitchInfo: PlayEvents = this.chartInstance.data.datasets[\n dataSetIndex\n ].data[pointIndexWithinDataSet].pitch;\n const momentInstance = pitchInfo.isGameScheduledTBD\n ? moment.utc\n : moment;\n\n const displayPitchConfig = {\n gamePk: [\"GamePk\", pitchInfo.gamePk],\n gameDate: [\n \"Game Date\",\n momentInstance(pitchInfo.dateTime).format(\"YYYY-MM-DD\"),\n ],\n inningInfo: [\"Inning\", pitchInfo.inningInfo],\n atBat: [\"AtBat\", pitchInfo.atBatIndex + 1],\n pitchNumber: [\"Pitch Num\", pitchInfo.pitchNumber],\n outcome: [\"Outcome\", pitchInfo.details.call.description],\n pitchType: [\"Pitch Type\", pitchInfo.details.type.code],\n };\n\n // Set Text\n if (tooltipModel.body) {\n const titleLines = tooltipModel.title || [];\n\n let innerHtml = \"\";\n\n titleLines.forEach(function (title) {\n innerHtml += \"\" + title + \"\";\n });\n innerHtml += \"\";\n\n Object.values(displayPitchConfig).forEach(function (\n lineOfInfo\n ) {\n const [label, value] = lineOfInfo;\n innerHtml += `${label}: ${value}`;\n });\n innerHtml += \"\";\n\n const tableRoot = tooltipEl.querySelector(\"table\");\n if (tableRoot) {\n tableRoot.innerHTML = innerHtml;\n }\n }\n\n const position = this.chartInstance.canvas.getBoundingClientRect();\n\n // Display, position, and set styles\n tooltipEl.style.backgroundColor = \"rgba(0, 0, 0, .7)\";\n tooltipEl.style.borderRadius = \"0.4rem\";\n tooltipEl.style.color = \"#fff\";\n tooltipEl.style.opacity = \"1\";\n tooltipEl.style.display = \"block\";\n tooltipEl.style.position = \"absolute\";\n tooltipEl.style.left =\n position.left +\n window.pageXOffset +\n tooltipModel.caretX +\n 5 +\n \"px\";\n tooltipEl.style.top =\n position.top +\n window.pageYOffset +\n tooltipModel.caretY +\n 5 +\n \"px\";\n tooltipEl.style.fontFamily = tooltipModel._bodyFontFamily;\n tooltipEl.style.fontSize = tooltipModel.bodyFontSize + \"px\";\n tooltipEl.style.fontStyle = tooltipModel._bodyFontStyle;\n tooltipEl.style.padding =\n tooltipModel.yPadding + \"px \" + tooltipModel.xPadding + \"px\";\n },\n },\n },\n });\n\n this.keepCanvasSizesInSync();\n } else {\n console.error(\"No canvas element reference!\");\n }\n }\n\n componentDidUpdate() {\n const { storeData } = this.props;\n //clears the old previous data and assigns it the new data rather than having to destroy/recreate chart instance\n this.chartInstance.data.datasets = [];\n this.chartInstance.data.datasets = storeData;\n this.chartInstance.update();\n }\n\n componentWillUnmount() {\n window.addEventListener(\"resize\", debounce(this.keepCanvasSizesInSync, 10));\n }\n\n render() {\n const { updateSelectedPitches } = this.props;\n\n return (\n ) => {\n e.preventDefault();\n const selectedPoint = this.chartInstance.getElementAtEvent(e)[0];\n if (selectedPoint) {\n const selectedPointsChartDataSet =\n selectedPoint._chart.data.datasets[selectedPoint._datasetIndex];\n const value = selectedPointsChartDataSet.data[selectedPoint._index];\n const resarchToolLink = `https://research.mlb.com/games/${value.pitch.gamePk}/plays/${value.pitch.playId}`;\n window.open(resarchToolLink);\n }\n }}\n onMouseDown={(event: React.MouseEvent) => {\n const axisXY = this.getChartsXYAxisForMouseEvent(\n event,\n this.chartInstance\n );\n\n this.chartMouseDownX = axisXY.x;\n this.chartMouseDownY = axisXY.y;\n\n // Only capture selection coordinates if we're left-clicking\n if (event.button === 0 && !this.selecting) {\n this.selecting = true;\n this.rectangleMouseMoveStartX = event.nativeEvent.offsetX;\n this.rectangleMouseMoveStartY = event.nativeEvent.offsetY;\n }\n }}\n onMouseMove={(event: React.MouseEvent) => {\n if (this.selecting) {\n this.drawRect({\n startingPointX: this.rectangleMouseMoveStartX,\n startingPointY: this.rectangleMouseMoveStartY,\n width: event.nativeEvent.offsetX - this.rectangleMouseMoveStartX,\n height: event.nativeEvent.offsetY - this.rectangleMouseMoveStartY,\n });\n }\n }}\n onMouseUp={(event: React.MouseEvent) => {\n if (this.selecting) {\n this.numberOfSelections = 0;\n const chartInstance = this.chartInstance;\n const axisXY = this.getChartsXYAxisForMouseEvent(\n event,\n this.chartInstance\n );\n this.chartMouseUpX = axisXY.x;\n this.chartMouseUpY = axisXY.y;\n\n if (chartInstance?.data.datasets) {\n chartInstance?.data.datasets.forEach(\n (dataSet: ChartDataSets | undefined) => {\n if (this.selecting) {\n this.rectangleMouseMoveStartX = 0;\n this.rectangleMouseMoveStartY = 0;\n let [xMin, xMax] =\n this.chartMouseUpX > this.chartMouseDownX\n ? [this.chartMouseDownX, this.chartMouseUpX]\n : [this.chartMouseUpX, this.chartMouseDownX];\n let [yMin, yMax] =\n this.chartMouseUpY > this.chartMouseDownY\n ? [this.chartMouseDownY, this.chartMouseUpY]\n : [this.chartMouseUpY, this.chartMouseDownY];\n\n if (dataSet?.data) {\n const chartPoints: ChartPoint[] = dataSet.data as ChartPoint[];\n chartPoints.forEach(\n (point: ChartPoint, index: number) => {\n if (\n point.x &&\n point.x >= xMin &&\n point.x <= xMax &&\n point.y &&\n point.y >= yMin &&\n point.y <= yMax\n ) {\n this.numberOfSelections++;\n updateSelectedPitches(dataSet, index);\n }\n }\n );\n }\n }\n }\n );\n }\n this.selecting = false;\n this.clearRect();\n }\n }}\n onMouseOut={() => {\n // Left chart area? Reset it all.\n this.selecting = false;\n this.chartMouseDownX = 0;\n this.chartMouseDownY = 0;\n this.chartMouseUpX = 0;\n this.chartMouseUpY = 0;\n this.clearRect();\n }}\n >\n \n \n \n );\n }\n}\n\nexport default PitchingChart;\n","import React, { Component, ContextType } from \"react\";\nimport { observer } from \"mobx-react\";\nimport Chart from \"components/chart\";\nimport Spinner from \"components/spinner\";\nimport styles from \"./ChartingContainer.module.scss\";\nimport { rootStoreContext } from \"contexts\";\nimport { ChartDataSets } from \"chart.js\";\n\ninterface ChartProperties {\n title: string;\n xAxisTitle: string;\n yAxisTitle: string;\n storeData: ChartDataSets[];\n}\n\n@observer\nclass ChartingContainer extends Component {\n static contextType = rootStoreContext;\n context!: ContextType;\n\n //Either renders all charts, or renders a single chart based on chartingStore.selectedSingleChart value\n chartsToRender = (chartProperties: ChartProperties[]) => {\n const { chartingStore } = this.context;\n switch (chartingStore.selectedSingleChart) {\n case \"View All\":\n //render all charts\n return chartProperties.map((chart) => {\n return (\n \n );\n });\n default:\n //render a single chart\n const singleChart = chartProperties.find(\n (chart) => chart.title === chartingStore.selectedSingleChart\n );\n if (singleChart) {\n return (\n \n );\n }\n }\n };\n\n render() {\n const { chartingStore } = this.context;\n\n const chartGenerator: ChartProperties[] = [\n {\n title: \"H Movement x V Movement\",\n xAxisTitle: \"H Movement\",\n yAxisTitle: \"V Movement\",\n storeData: chartingStore.horizontalMovementByVerticalMovement,\n },\n {\n title: \"H Movement x Speed\",\n xAxisTitle: \"H Movement\",\n yAxisTitle: \"Speed\",\n storeData: chartingStore.horizontalMovementBySpeed,\n },\n {\n title: \"V Movement x Speed\",\n xAxisTitle: \"V Movement\",\n yAxisTitle: \"Speed\",\n storeData: chartingStore.verticalMovementBySpeed,\n },\n {\n title: \"Spin x Speed\",\n xAxisTitle: \"Spin\",\n yAxisTitle: \"Speed\",\n storeData: chartingStore.spinByReleaseSpeed,\n },\n {\n title: \"H Movement x Spin\",\n xAxisTitle: \"Spin\",\n yAxisTitle: \"H Movement\",\n storeData: chartingStore.horizontalMovementBySpin,\n },\n {\n title: \"V Movement x Spin\",\n xAxisTitle: \"Spin\",\n yAxisTitle: \"V Movement\",\n storeData: chartingStore.verticalMovementBySpin,\n },\n ];\n\n return (\n
    \n {chartingStore.loading ? (\n
    \n \n
    \n ) : null}\n\n {this.chartsToRender(chartGenerator)}\n
    \n );\n }\n}\n\nexport default ChartingContainer;\n","import React, { Component, ContextType } from \"react\";\nimport styles from \"./Footer.module.scss\";\nimport { observer } from \"mobx-react\";\nimport { rootStoreContext } from \"contexts\";\n\n@observer\nclass Footer extends Component {\n static contextType = rootStoreContext;\n context!: ContextType;\n\n render() {\n const { navigationStore } = this.context;\n const { selectedPitcherInfo } = navigationStore.dropdownSelectedOptions;\n const pitcherId = selectedPitcherInfo?.id;\n\n return (\n
    \n {pitcherId ? (\n <>\n \n Research Tool\n \n \n Savant Player Page\n \n \n Pitch Mix\n \n \n Pitch 3D\n \n \n Velocity Distribution\n \n \n Brooks Baseball\n \n \n ) : null}\n
    \n );\n }\n}\n\nexport default Footer;\n","import React, { Component, ContextType } from \"react\";\nimport { Button, Select, Modal } from \"antd\";\nimport styles from \"./Header.module.scss\";\nimport { RedoOutlined } from \"@ant-design/icons\";\nimport { observer } from \"mobx-react\";\nimport { rootStoreContext } from \"contexts\";\nimport { SelectValue } from \"antd/lib/select\";\nimport classNames from \"classnames\";\n\nconst { Option } = Select;\n\nconst differentChartLabels = [\n \"View All\",\n \"H Movement x V Movement\",\n \"H Movement x Speed\",\n \"V Movement x Speed\",\n \"Spin x Speed\",\n \"H Movement x Spin\",\n \"V Movement x Spin\",\n];\n\n@observer\nclass Header extends Component {\n static contextType = rootStoreContext;\n context!: ContextType;\n\n selectChart = (e: SelectValue) => {\n const { chartingStore } = this.context;\n chartingStore.selectedSingleChart = e.toString();\n };\n\n render() {\n const {\n navigationStore,\n chartingStore,\n pitchClassifierStore,\n pitchClassifierApi,\n } = this.context;\n const { dropdownSelectedOptions } = navigationStore;\n\n const chartLabelSelections = differentChartLabels.map((label) => {\n return (\n \n );\n });\n\n const pitcherIsSet =\n dropdownSelectedOptions.selectedPitcherInfo?.id !== undefined;\n const dataIsSet = chartingStore.pitchersDataByPitchType.size > 0;\n\n return (\n
    \n
    \n {\n chartingStore.fetchAndSortLiveGameData(\n navigationStore.dropdownSelectedOptions.selectedGamePks\n );\n pitchClassifierStore.fetchPitcherArsenal();\n }}\n className={styles.button}\n >\n \n Refresh Pitches\n \n \n Select all\n \n {\n if (dropdownSelectedOptions.selectedPitcherInfo?.id) {\n chartingStore.loading = true;\n pitchClassifierApi\n .classifyPitches(\n dropdownSelectedOptions.selectedPitcherInfo?.id,\n chartingStore.allSelectedPitches\n )\n .then(() => {\n chartingStore.loading = false;\n });\n }\n }}\n className={styles.button}\n >\n Classify Pitches\n \n {\n if (dropdownSelectedOptions.selectedPitcherInfo?.id) {\n pitchClassifierApi.deleteTrainingData(\n dropdownSelectedOptions.selectedPitcherInfo?.id\n );\n }\n }}\n className={styles.button}\n >\n Delete Training\n \n {\n if (dropdownSelectedOptions.selectedPitcherInfo?.id) {\n pitchClassifierApi.trainPitcher(\n dropdownSelectedOptions.selectedPitcherInfo?.id,\n chartingStore.allSelectedPitches\n );\n }\n }}\n className={styles.button}\n >\n Train Pitches\n \n {\n if (dropdownSelectedOptions.selectedPitcherInfo?.id) {\n chartingStore.loading = true;\n pitchClassifierApi\n .trainNeuralNet(\n dropdownSelectedOptions.selectedPitcherInfo?.id\n )\n .then((data) => {\n Modal.info({\n title: `${dropdownSelectedOptions.selectedPitcherInfo?.name} training results`,\n content: (\n
    \n ${data.response}\n
    \n ),\n width: 600,\n });\n chartingStore.loading = false;\n });\n }\n }}\n className={styles.button}\n >\n Train NN\n \n
    \n
    \n
    \n {dropdownSelectedOptions.selectedPitcherInfo?.name}\n
    \n
    \n
    \n
    \n \n {chartLabelSelections}\n \n
    \n
    \n
    \n );\n }\n}\n\nexport default Header;\n","import React, { Component } from \"react\";\nimport { Radio } from \"antd\";\nimport { RadioChangeEvent } from \"antd/lib/radio\";\nimport { HandednessFilters } from \"enums/handedFilters\";\n\ninterface HandednessFilterProps {\n handedFilterValue: HandednessFilters;\n setHandednessFilter(value: HandednessFilters): void;\n}\n\nclass HandednessFilter extends Component {\n render() {\n const { handedFilterValue, setHandednessFilter } = this.props;\n return (\n <>\n {\n setHandednessFilter(e.target.value);\n }}\n >\n LHH\n RHH\n ALL\n \n \n );\n }\n}\n\nexport default HandednessFilter;\n","import React, { Component, ContextType } from \"react\";\nimport styles from \"./PitchClassifierContainer.module.scss\";\nimport { pitchTypes } from \"constants/pitchTypes\";\nimport ClassifierButton from \"components/classifierButton/ClassifierButton\";\nimport HandednessFilter from \"components/handednessFilter/HandednessFilter\";\nimport { observer } from \"mobx-react\";\nimport { HandednessFilters } from \"enums/handedFilters\";\nimport { rootStoreContext } from \"contexts\";\nimport { PitcherArsenalValues } from \"components/classifierButton/ClassifierButton\";\n\n@observer\nclass PitchClassifierContainer extends Component {\n static contextType = rootStoreContext;\n context!: ContextType;\n\n generateClassifierButtons = () => {\n const { pitchClassifierStore } = this.context;\n const buttons = pitchTypes.map((pitchType) => {\n const value = pitchClassifierStore.knownPitchTypes.includes(\n pitchType.label\n )\n ? \"2\"\n : \"0\";\n return (\n \n );\n });\n return buttons;\n };\n\n updateKnownPitchTypes = (value: string, pitchType: string) => {\n const { pitchClassifierStore } = this.context;\n if (\n value === PitcherArsenalValues.Yes ||\n value === PitcherArsenalValues.Maybe\n ) {\n pitchClassifierStore.knownPitchTypes.push(pitchType);\n } else {\n pitchClassifierStore.knownPitchTypes.splice(\n pitchClassifierStore.knownPitchTypes.findIndex(\n (type) => pitchType === type\n ),\n 1\n );\n }\n };\n\n /*\n * Loop over all selecetd pitches and change their pitch types to the passed\n * in value as well as change which bucket they appear in.\n */\n changePitchType = (value: string) => {\n const { chartingStore } = this.context;\n chartingStore.allSelectedPitches.forEach((selectedPitch) => {\n if (selectedPitch.details.type) {\n const removedFromThisBucket = chartingStore.pitchersDataByPitchType\n .get(selectedPitch.details.type?.code)\n ?.filter((pitch) => pitch.playId !== selectedPitch.playId)\n ?.map((pitch) => pitch);\n if (removedFromThisBucket) {\n chartingStore.pitchersDataByPitchType.set(\n selectedPitch.details.type.code,\n removedFromThisBucket\n );\n }\n let addToThisPitchBucket = chartingStore.pitchersDataByPitchType.get(\n value\n );\n if (addToThisPitchBucket === undefined) {\n addToThisPitchBucket = [];\n }\n selectedPitch.details.type.code = value;\n addToThisPitchBucket.push(selectedPitch);\n chartingStore.pitchersDataByPitchType.set(value, addToThisPitchBucket);\n }\n });\n };\n\n render() {\n const buttons = this.generateClassifierButtons();\n const { chartingStore } = this.context;\n return (\n
    \n
    {buttons}
    \n
    \n {\n chartingStore.handednessFilter = filterValue;\n }}\n />\n
    \n
    \n );\n }\n}\n\nexport default PitchClassifierContainer;\n","import React from \"react\";\nimport { useOktaAuth } from \"@okta/okta-react\";\nimport { Layout } from \"antd\";\nimport { Redirect } from \"react-router-dom\";\n\nimport NavigationContainer from \"./containers/navigationContainer\";\nimport ChartingContainer from \"./containers/chartingContainer\";\nimport Footer from \"./containers/footer\";\nimport Header from \"./containers/header\";\nimport PitchClassifierContainer from \"./containers/pitchClasssifierContainer\";\nimport { Routes } from \"./enums/routes\";\n\nimport styles from \"./App.module.scss\";\nimport classNames from \"classnames\";\n\nconst Content = Layout.Content;\n\nfunction App() {\n const { authState } = useOktaAuth();\n return authState.isAuthenticated ? (\n \n \n
    \n
    \n \n
    \n
    \n
    \n
    \n
    \n
    \n \n
    \n
    \n \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n
    \n ) : (\n \n );\n}\n\nexport default App;\n","import React, { Component, ContextType } from \"react\";\nimport { BrowserRouter, Route, Switch } from \"react-router-dom\";\nimport { Security, LoginCallback } from \"@okta/okta-react\";\nimport \"antd/dist/antd.css\";\nimport Login from \"./containers/login\";\nimport App from \"./App\";\nimport { rootStoreContext } from \"./contexts\";\nimport { Routes } from \"./enums/routes\";\n\nclass Routing extends Component {\n static contextType = rootStoreContext;\n context!: ContextType;\n\n render() {\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n );\n }\n}\n\nexport default Routing;\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\ntype Config = {\n onSuccess?: (registration: ServiceWorkerRegistration) => void;\n onUpdate?: (registration: ServiceWorkerRegistration) => void;\n};\n\nexport function register(config?: Config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(\n process.env.PUBLIC_URL,\n window.location.href\n );\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl: string, config?: Config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl: string, config?: Config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' }\n })\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.'\n );\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready\n .then(registration => {\n registration.unregister();\n })\n .catch(error => {\n console.error(error.message);\n });\n }\n}\n","import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport \"./index.scss\";\nimport Routing from \"./Routing\";\nimport * as serviceWorker from \"./serviceWorker\";\n\nReactDOM.render(, document.getElementById(\"root\"));\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorker.unregister();\n","// extracted by mini-css-extract-plugin\nmodule.exports = {\"container\":\"Footer_container__2KZQ3\",\"link\":\"Footer_link__BSecf\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"outer-container\":\"NavigationContainer_outer-container__1YlOa\",\"inner-container\":\"NavigationContainer_inner-container__o3hC7\",\"buttons\":\"NavigationContainer_buttons__3wMEm\",\"button\":\"NavigationContainer_button__qZMYl\",\"loading-container\":\"NavigationContainer_loading-container__3q0vC\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"selection\":\"NavigateByDate_selection__NsE1h\"};"],"sourceRoot":""}