{"version":3,"sources":["ttt/tictactoe.js","chess.js","LastUpdated.js","serviceWorker.js","index.js"],"names":["TTTButton","props","gameover","owner","className","gamewinner","hilite","color","onClick","id","Form","Grid","Hilite","reset","bind","state","current_player","game_over","game_winner","width","resetState","this","setState","console","log","row","comp","column","push","Array","fill","Math","floor","winner","i","length","isAllSame","map","r","upperLeft","elem","index","kiara","array","first","style","borderCollapse","paddingBottom","fontSize","verticalAlign","indr","key","indc","handleClick","type","size","maxLength","min","max","defaultValue","textAlign","v","document","getElementById","value","Number","Component","IP","fetch","then","response","text","split","substr","trim","ip","Piece","name","side","meta","Cell","el","element","shade","eastMutator","prev","westMutator","northMutator","southMutator","seMutator","swMutator","neMutator","nwMutator","knightMutator","next","undefined","origin","nRow","nCol","funcurl","grid","col","resetHilite","turn","selected","gridlock","lobby","ijoin","statusmsg","polling","request","handleServerMsg","piece","limit","increment","hilitePosition","rowIncrement","pawnCaptureMutater","mutater","allowCapture","mustCapture","fulfillLimit","occupied","testPosition","obj","targetrow","targetcolumn","game","String","padStart","move","selectPiece","selectCapture","lobbyString","toString","dataset","url","poll","setTimeout","msg","startPoll","turnNumber","moveData","r0","c0","r1","c1","performCapture","toLock","noped","alert","background","padding","outline","random","tryLobby","minHeight","href","gameServerPanel","rowIndex","columnIndex","oCF","getOnClickFunc","hl","LastUpdated","json","author","commit","login","branch","date","sha","link","_links","html","catch","error","slice","time","Boolean","window","location","hostname","match","ReactDOM","render","exact","path","component","chess","tictactoe","pathname","substring","to","navigator","serviceWorker","ready","registration","unregister","message"],"mappings":"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","file":"static/js/main.60ec320a.chunk.js","sourcesContent":["import React, {Component} from 'react';\r\nimport './tictactoe.css';\r\n\r\nfunction TTTButton(props)\r\n{ \r\n\tif (props.gameover === true)\r\n\t{\r\n\t\tif (props.owner === 0)\r\n\t\t{ return (\r\n\t\t\t\r\n\t\t)}\r\n\t\telse if (props.owner !== props.gamewinner)\r\n\t\t{ return (\r\n\t\t\t\r\n\t\t)}\r\n\t\telse if (props.hilite === true)\r\n\t\t{ return (\r\n\t\t\t\r\n\t\t)}\r\n\t}\r\n\t//console.log(props.id + \" owned by \" + props.owner)\r\n\tif (props.owner !== 0)\r\n\t{\r\n\t\treturn (\r\n\t\t\t\r\n\t\t)\r\n\t}\r\n\telse // no owner, free to play\r\n\t{\r\n\t\treturn (\r\n\t\t\t\r\n\t\t);\r\n\t}\r\n}\r\n\r\nclass Form extends Component\r\n{\r\n\tGrid = []\r\n\tHilite = [] // used to select which positions won the game\r\n\tconstructor(props) // props may have size?\r\n\t{\r\n\t\tsuper(props)\r\n\t\tthis.reset = this.reset.bind(this);\r\n\t\tthis.state = {\r\n\t\t\tcurrent_player: 1,\r\n\t\t\tgame_over: false,\r\n\t\t\tgame_winner: 0,\r\n\t\t\twidth: 3,\r\n\t\t}\r\n\t\tthis.reset(false)\r\n\t}\r\n\r\n\treset(resetState = true)\r\n\t{\t\r\n\t\tif (resetState)\r\n\t\t{\r\n\t\t\tthis.setState({\r\n\t\t\tcurrent_player: 1,\r\n\t\t\tgame_over: false,\r\n\t\t\tgame_winner: 0,\r\n\t\t\t})\r\n\t\t}\r\n\t\t// initialize grid with raw data\r\n\t\tthis.Grid = [];\r\n\t\tthis.Hilite = [];\r\n\t\tconsole.log(\"initing new grid of width \" + this.state.width);\r\n\t\tfor (let row = 0; row < this.state.width; row++)\r\n\t\t{\r\n\t\t\tvar comp = [] // List of data, accessed via column\r\n\t\t\tfor (var column = 0; column < this.state.width; column++)\r\n\t\t\t{\r\n\t\t\t\tvar id = row * this.state.width + column\r\n\t\t\t\tcomp.push(\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tid : id,\r\n\t\t\t\t\t\towner : 0,\r\n\t\t\t\t\t}\r\n\t\t\t\t)\r\n\t\t\t}\r\n\t\t\t//console.log(\"comp\" + row)\r\n\t\t\t//console.log(comp)\r\n\t\t\tthis.Grid.push(comp);\r\n\t\t\tlet width = this.state.width;\r\n\t\t\tthis.Hilite.push(new Array(width).fill(false));\r\n\t\t}\r\n\t\t//console.log(\"this grid\")\r\n\t\t//console.log(this.Grid)\r\n\t\t//console.log(this.Hilite)\r\n\t}\r\n\r\n\thandleClick(id)\r\n\t{\r\n\t\t// check for game condition\r\n\t\tif (this.state.game_over === true){ return; }\r\n\t\t//console.log(\"CLICKED \" + id);\r\n\t\tlet column = id % this.state.width;\r\n\t\tlet row = Math.floor(id / this.state.width);\r\n\t\t//console.log(`COORD R${row} C${column}`)\r\n\t\tthis.Grid[row][column].owner = this.state.current_player\r\n\t\t//console.log(\"Set \" + this.Grid[row][column].id + \r\n\t\t//\t\" to owned by \" + this.state.current_player + \" : \" +\r\n\t\t//\tthis.Grid[row][column].owner)\r\n\t\tthis.setState({current_player: this.state.current_player * -1})\r\n\r\n\t\t// after a cell is selected, check for win conditions\r\n\t\t// check all possibilities, since each move can only result in\r\n\t\t// a single winner and never a tie, but a player may win in more than one way\r\n\t\t// horizontals, i.e. rows, i.e. first axis\r\n\t\tlet winner = 0; // if zero, no winner.\r\n\t\tfor (let i = 0; i < this.Grid.length; i++)\r\n\t\t{\r\n\t\t\tlet row = this.Grid[i];\r\n\t\t\tif (this.isAllSame(row))\r\n\t\t\t{\r\n\t\t\t\twinner = row[0].owner;\r\n\t\t\t\tthis.Hilite[i].fill(true);\r\n\t\t\t\tconsole.log(\"ROW WINNER is \" + winner + \" at row \" + i)\r\n\t\t\t}\r\n\t\t}\r\n\t\t// verticals, i.e. columns, i.e. second axis\r\n\t\tfor (let i = 0; i < this.Grid[0].length; i++)\r\n\t\t{\r\n\t\t\tlet column = this.Grid.map((row)=>{return row[i]})\r\n\t\t\tif (this.isAllSame(column))\r\n\t\t\t{\r\n\t\t\t\twinner = column[0].owner;\r\n\t\t\t\tthis.Hilite = this.Hilite.map((row)=>{let r = row; r[i] = true; return r;})\r\n\t\t\t\tconsole.log(\"COL WINNER is \" + winner + \" at col \" + i)\r\n\t\t\t}\r\n\t\t}\r\n\t\t// diagonals\r\n\t\tlet upperLeft = this.Grid.map((elem, index)=>{return elem[index]})\r\n\t\tif (this.isAllSame(upperLeft))\r\n\t\t{\r\n\t\t\twinner = upperLeft[0].owner;\r\n\t\t\tthis.Hilite = this.Hilite.map((row, index)=>{let r = row; r[index] = true; return r;})\r\n\t\t\tconsole.log(\"DIA WINNER is \" + winner + \" at upperLeft\")\r\n\t\t}\r\n\t\tlet kiara = this.Grid.map((elem, index)=>{return elem[this.Grid.length - 1 - index]})\r\n\t\tif (this.isAllSame(kiara))\r\n\t\t{\r\n\t\t\twinner = kiara[0].owner;\r\n\t\t\tthis.Hilite = this.Hilite.map((row, index)=>{let r = row; r[this.Grid.length - 1 -index] = true; return r;})\r\n\t\t\tconsole.log(\"DIA WINNER is \" + winner + \" at kiara\")\r\n\t\t}\r\n\t\t// set game state if we have a winner\r\n\t\tif (winner !== 0) \r\n\t\t{ \r\n\t\t\tthis.setState(\r\n\t\t\t\t{\r\n\t\t\t\t\tgame_over: true,\r\n\t\t\t\t\tgame_winner: winner\r\n\t\t\t\t}\r\n\t\t\t); \r\n\t\t\t//console.log(this.Grid);\r\n\t\t\t//console.log(this.Hilite);\r\n\t\t}\r\n\t}\r\n\r\n/** @param {Array} array \r\n * @description Returns true if all element.owner values are the same in an\r\n * array, and also non-zero.\r\n*/\r\n\tisAllSame(array)\r\n\t{\r\n\t\tlet first = array[0].owner;\r\n\t\tif (first === 0) { return false; }\r\n\t\tfor (let i = 1; i < array.length; i++)\r\n\t\t{\r\n\t\t\tif (array[i].owner !== first) { return false; }\r\n\t\t}\r\n\t\treturn true;\r\n\t}\r\n\r\n\trender() {\r\n\t\t//console.log(\"rendering...\")\r\n\t\treturn (\r\n\t\t
\r\n\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\tA simple tic-tac-toe game.\r\n\t\t\t\t\t
Connect all cells in a row, column, or diagonal.\r\n\t\t\t\t
\r\n\t\t\t
\r\n\t\t\t\r\n\t\t\t\r\n\t\t\t\t{\r\n\t\t\t\tthis.Grid.map((row, indr)=>{\r\n\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t{row.map((column, indc)=>{\r\n\t\t\t\t\t\t\t// column is of type dict\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t)\r\n\t\t\t\t\t\t})}\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t)\r\n\t\t\t\t})\r\n\t\t\t\t}\r\n\t\t\t\r\n\t\t\t
\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t
\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t
\r\n\t\t\t\t\t\tGrid width: \r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t
\r\n\t\t\t\t\t\t
\r\n\t\t\t\t\t
\r\n\t\t
\r\n\t\t)\r\n\t}\r\n}\r\n\r\nexport default Form;\r\n","import React, {Component} from 'react';\r\nimport './chess.css';\r\n\r\n\r\nlet IP = null\r\nfetch('https://www.cloudflare.com/cdn-cgi/trace').then(response => {\r\n\treturn response.text()\r\n}).then(text => {\r\n\tlet split = text.split('\\n')\r\n\t// find one with the 'ip' header\r\n\tfor (let i = 0; i < split.length; i++)\r\n\t{\r\n\t\tif (split[i].substr(0, 3) === \"ip=\")\r\n\t\t\treturn split[i].substr(3).trim()\r\n\t}\r\n\treturn null\r\n}).then(ip => {\r\n\tconsole.log(\"IP is: \" + ip)\r\n\tIP = ip\r\n})\r\n\r\nclass Piece extends Component\r\n{\r\n\tconstructor(props)\r\n\t{\r\n\t\tsuper(props)\r\n\t\tthis.state = {\r\n\t\t\tname: props.name, \r\n\t\t\tside: props.side,\r\n\t\t\tmeta: props.meta\r\n\t\t}\r\n\t}\r\n\trender()\r\n\t{\r\n\t\treturn
{`${this.state.side} ${this.state.name}`}
\r\n\t}\r\n}\r\n\r\nfunction Cell(props)\r\n{\r\n\t//console.log(\"cell render hilite \" + props.hilite)\r\n\tlet el = props.element\r\n\treturn \r\n\t\t\r\n}\r\n\r\n/* \r\nChessboard holds pieces, with lite at the top and dark at the bottom,\r\nand therefore A1 at the top left. The board may be rendered opposite;\r\nthe data will remain locked as such. \r\n*/\r\nclass Grid extends Component\r\n{\r\n\t// hold all game pieces as kv\r\n\tconstructor(props)\r\n\t{\r\n\t\tsuper(props);\r\n\t\t// generate and fill board; grid is row-first, column-second\r\n\t\tlet grid = [];\r\n\t\tfor (let row = 0; row < 8; row++)\r\n\t\t\tgrid.push(new Array(8).fill(null))\r\n\t\t// generate dark and lite pawns\r\n\t\tfor (let row = 1; row < 8; row += 5)\r\n\t\t\tfor (let col = 0; col < 8; col++)\r\n\t\t\t\tgrid[row][col] = new Piece({name:\"pawn\", side: row === 1 ? \"lite\" : \"dark\"})\r\n\t\t// generate baselines\r\n\t\tfor (let row = 0; row < 8; row += 7)\r\n\t\t{\r\n\t\t\t// castles\r\n\t\t\tgrid[row][0] = new Piece({name:\"castle\", side: row === 0 ? \"lite\" : \"dark\"})\r\n\t\t\tgrid[row][7] = new Piece({name:\"castle\", side: row === 0 ? \"lite\" : \"dark\"})\r\n\t\t\t// knights\r\n\t\t\tgrid[row][1] = new Piece({name:\"knight\", side: row === 0 ? \"lite\" : \"dark\"})\r\n\t\t\tgrid[row][6] = new Piece({name:\"knight\", side: row === 0 ? \"lite\" : \"dark\"})\r\n\t\t\t// bishops\r\n\t\t\tgrid[row][2] = new Piece({name:\"bishop\", side: row === 0 ? \"lite\" : \"dark\"})\r\n\t\t\tgrid[row][5] = new Piece({name:\"bishop\", side: row === 0 ? \"lite\" : \"dark\"})\r\n\t\t\t// queen\r\n\t\t\tgrid[row][3] = new Piece({name:\"queen\", side: row === 0 ? \"lite\" : \"dark\"})\r\n\t\t\t// king\r\n\t\t\tgrid[row][4] = new Piece({name:\"king\", side: row === 0 ? \"lite\" : \"dark\"})\r\n\t\t}\r\n\t\t// generate test pawn\r\n\t\t// grid[5][4] = new Piece({name:\"pawn\", side: \"lite\"})\r\n\t\t// generate hilite overlay grid\r\n\t\tlet hilite = this.resetHilite();\r\n\t\t// attach\r\n\t\tthis.state = {\r\n\t\t\tgrid: grid,\r\n\t\t\thilite: hilite,\r\n\t\t\tturn: 0,\r\n\t\t\tselected: null,\r\n\t\t\tgridlock: true, // prevents grid from being manipulated via click until p2 shows up\r\n\t\t\tlobby: null,\r\n\t\t\tijoin: false, // indicates if this client joined a lobby, or if it created one instead\r\n\t\t\tside: \"lite\",\r\n\t\t\tstatusmsg: \"\",\r\n\t\t\tpolling: null,\r\n\t\t}\r\n\t\t// some binding\r\n\t\tthis.request = this.request.bind(this)\r\n\t\tthis.handleServerMsg = this.handleServerMsg.bind(this)\r\n\t}\r\n\r\n\tresetHilite() // creates a full hilite grid populated with false\r\n\t{\r\n\t\tlet grid = []\r\n\t\tfor (let row = 0; row < 8; row++)\r\n\t\t\tgrid.push(new Array(8).fill(false))\r\n\t\treturn grid\r\n\t}\r\n\r\n\t/* \r\n\tWhen a piece is selected, show the valid spots for the piece to move to.\r\n\t*/\r\n\t// Some general mutators that can be used by multiple pieces\r\n\teastMutator = (prev)=>{return {row: prev.row, column: prev.column + 1}}\r\n\twestMutator = (prev)=>{return {row: prev.row, column: prev.column - 1}}\r\n\tnorthMutator = (prev)=>{return {row: prev.row - 1, column: prev.column}}\r\n\tsouthMutator = (prev)=>{return {row: prev.row + 1, column: prev.column}}\r\n\tseMutator = (prev)=>{return {row: prev.row + 1, column: prev.column + 1}}\r\n\tswMutator = (prev)=>{return {row: prev.row + 1, column: prev.column - 1}}\r\n\tneMutator = (prev)=>{return {row: prev.row - 1, column: prev.column + 1}}\r\n\tnwMutator = (prev)=>{return {row: prev.row - 1, column: prev.column - 1}}\r\n\tknightMutator = (prev)=>{\r\n\t\tlet next = {\r\n\t\t\trow: 0, \r\n\t\t\tcolumn: 0, \r\n\t\t\tindex: prev.index===undefined ? 1 : prev.index + 1,\r\n\t\t\torigin: prev.origin===undefined ? {row:prev.row, column:prev.column} : prev.origin,\r\n\t\t}\r\n\t\t// use index to determine which of the 8 positions to go to;\r\n\t\t// 1 5 7 3\r\n\t\t// 2 6 8 4\r\n\t\tlet nRow = 0, nCol = 0;\r\n\t\tswitch (next.index)\r\n\t\t{\r\n\t\t\tcase 1:\r\n\t\t\t\tnRow = -1; nCol = -2;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 2:\r\n\t\t\t\tnRow = 1; nCol = -2;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 3:\r\n\t\t\t\tnRow = -1; nCol = 2;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 4:\r\n\t\t\t\tnRow = 1; nCol = 2\r\n\t\t\t\tbreak;\r\n\t\t\tcase 5:\r\n\t\t\t\tnRow = -2; nCol = -1;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 6:\r\n\t\t\t\tnRow = 2; nCol = -1;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 7:\r\n\t\t\t\tnRow = -2; nCol = 1;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 8:\r\n\t\t\t\tnRow = 2; nCol = 1;\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\treturn null\r\n\t\t}\r\n\t\tnext.row = next.origin.row + nRow\r\n\t\tnext.column = next.origin.column + nCol\r\n\t\t//console.log(next)\r\n\t\treturn next\r\n\t}\r\n\tselectPiece(row, column)\r\n\t{\r\n\t\tlet piece = this.state.grid[row][column]\r\n\t\tif (piece === null) // reset hilite and deselect\r\n\t\t{\r\n\t\t\t//console.log(\"nulled\")\r\n\t\t\tthis.state.hilite = this.resetHilite();\r\n\t\t\tthis.setState({selected: null})\r\n\t\t\treturn; \r\n\t\t}\r\n\t\t// only allow pieces of currently playing side to be clicked\r\n\t\tlet side = this.state.turn % 2 === 0 ? \"lite\" : \"dark\"\r\n\t\tif (piece.state.side !== side)\r\n\t\t{\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconsole.log(\"piece clicked at \" + row + \", \" + column)\r\n\t\t// reset hilite\r\n\t\tthis.state.hilite = this.resetHilite() // mutate; 'state.selected' will be used to trigger render\r\n\t\tswitch (piece.state.name)\r\n\t\t{\r\n\t\t\tcase \"pawn\":\r\n\t\t\t\t// if at home pos, move up to two. test each fwd mov for blocking.\r\n\t\t\t\tlet homeRow = piece.state.side === \"lite\" ? 1 : 6\r\n\t\t\t\tlet limit = row === homeRow ? 2 : 1\r\n\t\t\t\tlet increment = piece.state.side === \"lite\" ? 1 : -1\r\n\t\t\t\tlet pawnMutater = (prev)=>{return {row: prev.row + increment, column: prev.column}}\r\n\t\t\t\tthis.hilitePosition(row, column, pawnMutater, limit, piece.state.side, false)\r\n\t\t\t\t// test diag capture too (both directions)\r\n\t\t\t\tlet rowIncrement = piece.state.side === \"lite\" ? 1 : -1\r\n\t\t\t\tlet pawnCaptureMutater = (prev)=>{return {row: prev.row + rowIncrement, column: prev.column + 1}}\r\n\t\t\t\tthis.hilitePosition(row, column, pawnCaptureMutater, 1, piece.state.side, true, true)\r\n\t\t\t\tpawnCaptureMutater = (prev)=>{return {row: prev.row + rowIncrement, column: prev.column - 1}}\r\n\t\t\t\tthis.hilitePosition(row, column, pawnCaptureMutater, 1, piece.state.side, true, true)\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"castle\":\r\n\t\t\t\t// general cases first\r\n\t\t\t\tthis.hilitePosition(row, column, this.northMutator, 8, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.southMutator, 8, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.eastMutator, 8, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.westMutator, 8, piece.state.side, true, false)\r\n\t\t\t\t// check if castling is allowed\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"queen\":\r\n\t\t\t\tthis.hilitePosition(row, column, this.northMutator, 8, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.southMutator, 8, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.eastMutator, 8, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.westMutator, 8, piece.state.side, true, false)\r\n\t\t\t\t// allow multiple-case into bishop's diagonal\r\n\t\t\tcase \"bishop\":\r\n\t\t\t\tthis.hilitePosition(row, column, this.neMutator, 8, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.nwMutator, 8, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.seMutator, 8, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.swMutator, 8, piece.state.side, true, false)\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"king\":\r\n\t\t\t\t// ugh, but it works\r\n\t\t\t\tthis.hilitePosition(row, column, this.northMutator, 1, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.southMutator, 1, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.eastMutator, 1, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.westMutator, 1, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.neMutator, 1, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.nwMutator, 1, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.seMutator, 1, piece.state.side, true, false)\r\n\t\t\t\tthis.hilitePosition(row, column, this.swMutator, 1, piece.state.side, true, false)\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"knight\":\r\n\t\t\t\t// gonna cheat and use a more complex mutator\r\n\t\t\t\tthis.hilitePosition(row, column, this.knightMutator, 8, piece.state.side, true, false, true)\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tconsole.log(\"unknown piece \" + piece.state.name)\r\n\t\t}\r\n\t\t// trigger render\r\n\t\t//console.log(\"trying to force render...\")\r\n\t\tthis.setState({selected: {row:row, column:column}})\r\n\t}\r\n\r\n\t/** \r\n\t@description Sets a series of positions in the hilite grid to be highlighted.\r\n\t@param mutater A function that accepts one property pair as coordinates and returns a new property pair as the\r\n\tnext coordinates to apply; returns null to terminate.\r\n\t@param limit The number of cells that may be hilited in one sweep.\r\n\t@param allowCapture Determines if the piece, using this mutater, may capture a piece.\r\n\t@param mustCapture Only hilites a cell if a capturable piece is in it.\r\n\t@param fulfillLimit Forces the\r\n\t*/\r\n\thilitePosition(row, column, mutater, limit, side, allowCapture=true, mustCapture=false, fulfillLimit=false)\r\n\t{\r\n\t\t//console.log(\"hling source at \" + row + \", \" + column)\r\n\t\t// assume initial row and column are the origin; don't hilite it.\r\n\t\tlet next = mutater({row: row, column: column})\r\n\t\t//console.log(\"initial next\")\r\n\t\t//console.log(next)\r\n\t\twhile (next !== null && limit > 0)\r\n\t\t{\r\n\t\t\tlet occupied = this.testPosition(next.row, next.column)\r\n\t\t\t//console.log(\"occupancy:\")\r\n\t\t\t//console.log(occupied)\r\n\t\t\tif (occupied === null && fulfillLimit !== true)\r\n\t\t\t{\r\n\t\t\t\t// space is invalid, stop looking\r\n\t\t\t\tnext = null;\r\n\t\t\t\t//console.log(\"aborting\")\r\n\t\t\t}\r\n\t\t\telse if (occupied === null && fulfillLimit === true) // invalid space but must get next\r\n\t\t\t{\r\n\t\t\t\tnext = mutater(next);\r\n\t\t\t}\r\n\t\t\telse if (occupied !== false) // the position is occupied, capture but go no further\r\n\t\t\t{\r\n\t\t\t\tif (allowCapture === true && side !== occupied.state.side) // hilite if opposite team\r\n\t\t\t\t{\r\n\t\t\t\t\t//console.log(\"setting true\")\r\n\t\t\t\t\tthis.state.hilite[next.row][next.column] = true;\r\n\t\t\t\t}\r\n\t\t\t\tif (fulfillLimit) // even being blocked, continue\r\n\t\t\t\t{\r\n\t\t\t\t\tnext = mutater(next)\r\n\t\t\t\t}\r\n\t\t\t\telse // blocked, don't continue\r\n\t\t\t\t{\r\n\t\t\t\t\tnext = null; // disable next evaluation\r\n\t\t\t\t\t//console.log(\"aborting\")\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse // no occupancy, hilite and mutate if not mustCapture\r\n\t\t\t{\r\n\t\t\t\tif (mustCapture !== true) // don't have to capture, so mark empty cell as ok\r\n\t\t\t\t{\r\n\t\t\t\t\tthis.state.hilite[next.row][next.column] = true;\r\n\t\t\t\t\tnext = mutater(next);\r\n\t\t\t\t\t//console.log(\"next mutater result\")\r\n\t\t\t\t\t//console.log(next)\r\n\t\t\t\t}\r\n\t\t\t\telse // must capture, but cell is empty\r\n\t\t\t\t{\r\n\t\t\t\t\t// can't capture, so halt\r\n\t\t\t\t\tnext = null;\r\n\t\t\t\t\t//console.log(\"aborting\")\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tlimit -= 1\r\n\t\t}\r\n\t}\r\n\r\n\t/** \r\n\t@description Tests if a position is occupied. Returns the object if one exists, otherwise returns false.\r\n\tReturns null if the position is invalid.\r\n\t*/\r\n\ttestPosition(row, column)\r\n\t{\r\n\t\t//console.log(\"testing position \" + row + \", \" + column)\r\n\t\tlet obj = this.state.grid[row]?.[column];\r\n\t\t//console.log(obj)\r\n\t\tif (obj === undefined)\r\n\t\t\treturn null;\r\n\t\tif (obj === null)\r\n\t\t{\r\n\t\t\treturn false;\r\n\t\t} else {\r\n\t\t\treturn obj\r\n\t\t}\r\n\t}\r\n\r\n\t/*\r\n\tIf a valid movement is selected, move the selected piece to that location.\r\n\tselectMotion(row, column, targetrow, targetcolumn)\r\n\t{\r\n\t\t//console.log(\"select motion\")\r\n\t\tlet piece = this.state.grid[row][column]\r\n\t\t//console.log(\"moving piece \" + piece.state.name) // if this throws error, it has failed\r\n\t\tthis.state.grid[row][column] = null;\r\n\t\tthis.state.grid[targetrow][targetcolumn] = piece\r\n\t\t// force redraw\r\n\t\tthis.state.hilite = this.resetHilite()\r\n\t\tthis.setState({selected: null})\r\n\t}\r\n\t*/\r\n\t\r\n\t/*\r\n\tIf a valid movement is selected, move the selected piece to that location and capture the piece on it.\r\n\tDoes not actually make the move anymore; waits for server response. Server response is piped into\r\n\tperformCapture.\r\n\t*/\r\n\tselectCapture(row, column, targetrow, targetcolumn)\r\n\t{\r\n\t\tthis.request({\r\n\t\t\tkey: \"submit\",\r\n\t\t\tgame: this.state.lobby,\r\n\t\t\tturn: String(this.state.turn).padStart(3, \"0\"),\r\n\t\t\tmove: String(row) + String(column) + String(targetrow) + String(targetcolumn)\r\n\t\t})\r\n\t}\r\n\r\n\tperformCapture(row, column, targetrow, targetcolumn)\r\n\t{\r\n\t\t// make sure the piece to move exists, or else we delete the piece by\r\n\t\t// overwriting the target position with a null\r\n\t\tif (this.testPosition(row, column) === false)\r\n\t\t\treturn\r\n\t\t//console.log(\"select capture\")\r\n\t\tlet piece = this.state.grid[row][column]\r\n\t\tthis.state.grid[row][column] = null;\r\n\t\tthis.state.grid[targetrow][targetcolumn] = null;\r\n\t\t// force redraw twice to guarantee the capturing piece is shown\r\n\t\tthis.state.hilite = this.resetHilite()\r\n\t\tthis.setState({selected: null}, ()=>{\r\n\t\t\tthis.state.grid[targetrow][targetcolumn] = piece\r\n\t\t\tthis.setState({selected: null})\r\n\t\t})\r\n\t}\r\n\r\n\tgetOnClickFunc(row, column)\r\n\t{\r\n\t\tif (this.state.gridlock===true)\r\n\t\t{\r\n\t\t\treturn ()=>{\r\n\t\t\t\t// purposefully empty\r\n\t\t\t}\r\n\t\t}\r\n\t\t// if the space contains a piece only, select piece.\r\n\t\tif (this.state.grid[row][column] !== null && \r\n\t\t\tthis.state.grid[row][column].name !== null && \r\n\t\t\tthis.state.hilite[row][column] === false)\r\n\t\t{\r\n\t\t\treturn ()=>{\r\n\t\t\t\tconsole.log(\"selecting piece\")\r\n\t\t\t\tthis.selectPiece(row, column)\r\n\t\t\t}\r\n\t\t}\r\n\t\t// if the space is hilited only, select motion.\r\n\t\telse if (this.state.grid[row][column] === null && \r\n\t\t\tthis.state.hilite[row][column] === true)\r\n\t\t{\r\n\t\t\treturn ()=>{\r\n\t\t\t\tconsole.log(\"selecting motion\")\r\n\t\t\t\tthis.selectCapture(this.state.selected.row, this.state.selected.column, row, column)\r\n\t\t\t\tthis.setState({turn: this.state.turn + 1})\r\n\t\t\t}\r\n\t\t}\r\n\t\t// if the space has both, capture piece and select motion.\r\n\t\telse if (this.state.grid[row][column] !== null && \r\n\t\t\tthis.state.grid[row][column].name !== null &&\r\n\t\t\tthis.state.hilite[row][column] === true)\r\n\t\t{\r\n\t\t\treturn ()=>{\r\n\t\t\t\tconsole.log(\"selecting capture\")\r\n\t\t\t\tthis.selectCapture(this.state.selected.row, this.state.selected.column, row, column)\r\n\t\t\t\tthis.setState({turn: this.state.turn + 1})\r\n\t\t\t}\r\n\t\t}\r\n\t\t// if neither, no action occurs\r\n\t\treturn ()=>{this.selectPiece(row, column)} // select piece has handler for nulls\r\n\t}\r\n\r\n\ttryLobby() // sends msg to server asking for a lobby\r\n\t{\r\n\t\tlet lobbyString = document.getElementById(\"lobbyJoinInput\")?.value.toString()\r\n\t\tconsole.log(\"attempting to join \" + lobbyString)\r\n\t\tthis.request({key:\"begin\", game:lobbyString})\r\n\t}\r\n\r\n\tfuncurl = \"https://g96b10-tinker-app-chessfunction.azurewebsites.net/api/chessFunction?code=/Kv1K73yEYcDjPadDMKTGpvaEyQAHvDt1qVk2Iv0Wjf9mvLxkGOIIg==\"\r\n\trequest(dataset) // sends a server request to the Azure Function\r\n\t{\r\n\t\tlet url = this.funcurl\r\n\t\tswitch (dataset.key)\r\n\t\t{\r\n\t\t\tcase \"begin\":\r\n\t\t\t\turl += \"&src=\" + IP\r\n\t\t\t\turl += \"&game=\" + dataset.game\r\n\t\t\t\turl += \"&task=\" + \"begin\"\r\n\t\t\t\tconsole.log(\"out url: \" + url)\r\n\t\t\t\tbreak\r\n\t\t\tcase \"poll\":\r\n\t\t\t\turl += \"&src=\" + IP\r\n\t\t\t\turl += \"&game=\" + dataset.game\r\n\t\t\t\turl += \"&task=\" + \"poll\"\r\n\t\t\t\tbreak\r\n\t\t\tcase \"submit\":\r\n\t\t\t\turl += \"&src=\" + IP\r\n\t\t\t\turl += \"&game=\" + dataset.game\r\n\t\t\t\turl += \"&task=\" + \"submit\" + dataset.turn + dataset.move\r\n\t\t\t\tconsole.log(\"out url: \" + url)\r\n\t\t\t\tbreak\r\n\t\t\tdefault:\r\n\t\t\t\tconsole.log(\"invalid request key \" + dataset.key)\r\n\t\t\t\treturn\r\n\t\t}\r\n\t\t// make the function call and process the response\r\n\t\tfetch(url).then(response => {\r\n\t\t\treturn response.text()\r\n\t\t}).then(text => {this.handleServerMsg(text, dataset)})\r\n\t}\r\n\r\n\tstartPoll()\r\n\t{\r\n\t\tif (this.state.polling !== null)\r\n\t\t\treturn\r\n\t\tconsole.log(\"starting poll\")\r\n\t\tthis.setState({polling: true})\r\n\t\tthis.poll()\r\n\t}\r\n\r\n\tpoll()\r\n\t{\r\n\t\tconsole.log(\"polling\")\r\n\t\tthis.request({key:\"poll\", game:this.state.lobby})\r\n\t\tthis.setState({polling: setTimeout(this.poll.bind(this), 2000)})\r\n\t}\r\n\r\n\t/** @param {string} msg */\r\n\thandleServerMsg(msg, origin)\r\n\t{\r\n\t\t//console.log(\"server says \" + msg)\r\n\t\tlet key = msg.substr(0, 4)\r\n\t\t// key can be wait, play, join, turn, load, nope\r\n\t\tswitch (key)\r\n\t\t{\r\n\t\t\tcase \"wait\": // created a game successfully, waiting for someone to join\r\n\t\t\t\tthis.setState({lobby: origin.game}) // ori.game is game to create\r\n\t\t\t\tthis.startPoll()\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"play\": // p2 has joined me\r\n\t\t\t\t// un-gridlock, allowing me, p1, to play\r\n\t\t\t\tif (this.state.side === \"lite\") this.setState({gridlock: false})\r\n\t\t\t\tthis.startPoll()\r\n\t\t\t\tbreak\r\n\t\t\tcase \"join\": // i am p2 and i joined ok \r\n\t\t\t\t// still should be gridlocked, but store game info\r\n\t\t\t\tthis.setState({\r\n\t\t\t\t\tlobby: origin.game,\r\n\t\t\t\t\tside: \"dark\",\r\n\t\t\t\t\tijoin: true,\r\n\t\t\t\t\tgridlock: true,\r\n\t\t\t\t}) // ori.game is game to join\r\n\t\t\t\tthis.startPoll()\r\n\t\t\t\tbreak\r\n\t\t\tcase \"turn\": // the next turn was received\r\n\t\t\t\t// extract turn data\r\n\t\t\t\tconsole.log(msg)\r\n\t\t\t\tlet turnNumber = Number(msg.substr(4, 3))\r\n\t\t\t\tlet moveData = {\r\n\t\t\t\t\tr0: Number(msg.substr(7, 1)),\r\n\t\t\t\t\tc0: Number(msg.substr(8, 1)),\r\n\t\t\t\t\tr1: Number(msg.substr(9, 1)),\r\n\t\t\t\t\tc1: Number(msg.substr(10, 1)),\r\n\t\t\t\t}\r\n\t\t\t\t// perform it, if it hasn't been already\r\n\t\t\t\tthis.performCapture(moveData.r0, moveData.c0, moveData.r1, moveData.c1)\r\n\t\t\t\t// based on next turn num, lock or unlock\r\n\t\t\t\t// +1 because sent turn num was what was just played\r\n\t\t\t\tlet toLock = (((turnNumber+1)%2===0) === (this.state.side===\"lite\")) ? false : true\r\n\t\t\t\t//console.log(\"i'm side \" + this.state.side)\r\n\t\t\t\t//console.log(\"is current play even \" + ((turnNumber+1)%2===0) )\r\n\t\t\t\t//console.log(\"turn \" + (turnNumber+1).toString() + \", i'm locked=\" + toLock)\r\n\t\t\t\tthis.setState({\r\n\t\t\t\t\tturn: turnNumber + 1,\r\n\t\t\t\t\t// if even turn and i'm lite, don't lock\r\n\t\t\t\t\tgridlock: toLock\r\n\t\t\t\t})\r\n\t\t\t\tbreak\r\n\t\t\tcase \"load\": // replay from beginning\r\n\t\t\tcase \"nope\":\r\n\t\t\t\tlet noped = msg.substr(4)\r\n\t\t\t\tthis.setState({statusmsg: noped})\r\n\t\t\t\talert(noped)\r\n\t\t\t\tbreak\r\n\t\t\tdefault:\r\n\t\t\t\tconsole.log(\"an unknown server response was received: \" + key)\r\n\t\t}\r\n\t}\r\n\r\n\tgameServerPanel()\r\n\t{\r\n\t\tif (this.state.lobby === null) // no game is connected, show login\r\n\t\t{\r\n\t\t\treturn
\r\n\t\t\t\t
\r\n\t\t\t\t\tCreate or join a lobby:

\r\n\t\t\t\t\t\r\n\t\t\t\t\t

\r\n\t\t\t\t\t\r\n\t\t\t\t\t

\r\n\t\t\t\t
\r\n\t\t\t
\r\n\t\t}\r\n\t\telse if (this.state.ijoin !== true && this.state.gridlock === true) // create a game but no p2\r\n\t\t{\r\n\t\t\treturn
\r\n\t\t\t\t
\r\n\t\t\t\t\tLobby created; ask someone else to join your lobby!\r\n\t\t\t\t\t
\r\n\t\t\t\t\tLobby code: {this.state.lobby}\r\n\t\t\t\t\t
\r\n\t\t\t\t\tYou'll play as lite.\r\n\t\t\t\t\t
\r\n\t\t\t\t\t
\r\n\t\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t
\r\n\t\t}\r\n\t\telse // game lobby registered and no more gridlock\r\n\t\t{\r\n\t\t\treturn
\r\n\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\tLobby: {this.state.lobby}\r\n\t\t\t\t
\r\n\t\t\t\tYou're playing as {this.state.side}.\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t
\r\n\t\t
\r\n\t\t}\r\n\t}\r\n\r\n\t/**It's {this.state.turn % 2 === 0 ? \"lite\" : \"dark\"}'s turn. */\r\n\r\n\trender()\r\n\t{\r\n\t\t//console.log(\"rendering\")\r\n\t\treturn (\r\n\t\t\t
\r\n\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\tA chessboard, work in progress. Try tic tac toe!\r\n\t\t\t\t
\r\n\t\t\t
\r\n\t\t\t{\r\n\t\t\t\t// show either a join/create game panel or the current game status panel\r\n\t\t\t\tthis.gameServerPanel()\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tthis.state.grid.map((row, rowIndex)=>{\r\n\t\t\t\t\t\t\treturn \r\n\t\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\t\trow.map((element, columnIndex)=>\r\n\t\t\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\t\t\tlet shade = (rowIndex + columnIndex) % 2 === 0 ? \"dark\" : \"lite\"\r\n\t\t\t\t\t\t\t\t\t\tlet oCF = this.getOnClickFunc(rowIndex, columnIndex)\r\n\t\t\t\t\t\t\t\t\t\tlet hl = this.state.hilite[rowIndex][columnIndex]\r\n\t\t\t\t\t\t\t\t\t\t//if (hl === true){console.log(\"hiliting \" + rowIndex + \", \" + columnIndex + \": \" + hl)}\r\n\t\t\t\t\t\t\t\t\t\t// Cell onClick should be decided by content of cell or hilite.\r\n\t\t\t\t\t\t\t\t\t\treturn \r\n\t\t\t\t\t\t\t\t\t})\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t})\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t
\r\n\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\tTurn {this.state.turn}\r\n\t\t\t\t
\r\n\t\t\t
\r\n\t\t\t
)\r\n\t}\r\n}\r\n\r\nexport default Grid","import React, {Component} from 'react';\r\nimport './LastUpdated.css'\r\n\r\nclass LastUpdated extends Component\r\n{\r\n\tcomponentDidMount()\r\n\t{\r\n\t\tfetch(\r\n\t\t\t\"https://api.github.com/repos/geek96boolean10/reactjs_tictactoe/branches/master\"\r\n\t\t).then(response => {\r\n\t\t\tresponse.json().then(json => {\r\n\t\t\t\tconsole.log(\"Got commit data.\");\r\n\t\t\t\tthis.setState({\r\n\t\t\t\tauthor: json.commit.author.login,\r\n\t\t\t\tbranch: json.name,\r\n\t\t\t\tdate: json.commit.commit.author.date,\r\n\t\t\t\tsha: json.commit.sha,\r\n\t\t\t\tlink: json._links.html\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t\t})\r\n\t\t\t.catch(error => {\r\n\t\t\tconsole.log(error);\r\n\t\t\t});\r\n\t}\r\n\r\n\trender()\r\n\t{\r\n\t\tlet date = this.state?.date.slice(0,10);\r\n\t\tlet time = this.state?.date.slice(11,19)\r\n\t\treturn \r\n\t\t\t
\r\n\t\t\t\tThe latest commit for this page occurred at
\r\n\t\t\t\t{date} {time} UTC.
\r\n\t\t\t
\r\n\t\t
\r\n\t}\r\n}\r\n\r\nexport default LastUpdated\r\n","// This optional code is used to register a service worker.\r\n// register() is not called by default.\r\n\r\n// This lets the app load faster on subsequent visits in production, and gives\r\n// it offline capabilities. However, it also means that developers (and users)\r\n// will only see deployed updates on subsequent visits to a page, after all the\r\n// existing tabs open on the page have been closed, since previously cached\r\n// resources are updated in the background.\r\n\r\n// To learn more about the benefits of this model and instructions on how to\r\n// opt-in, read https://bit.ly/CRA-PWA\r\n\r\nconst isLocalhost = Boolean(\r\n window.location.hostname === 'localhost' ||\r\n // [::1] is the IPv6 localhost address.\r\n window.location.hostname === '[::1]' ||\r\n // 127.0.0.0/8 are considered localhost for IPv4.\r\n window.location.hostname.match(\r\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\r\n )\r\n);\r\n\r\nexport function register(config) {\r\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\r\n // The URL constructor is available in all browsers that support SW.\r\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\r\n if (publicUrl.origin !== window.location.origin) {\r\n // Our service worker won't work if PUBLIC_URL is on a different origin\r\n // from what our page is served on. This might happen if a CDN is used to\r\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\r\n return;\r\n }\r\n\r\n window.addEventListener('load', () => {\r\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\r\n\r\n if (isLocalhost) {\r\n // This is running on localhost. Let's check if a service worker still exists or not.\r\n checkValidServiceWorker(swUrl, config);\r\n\r\n // Add some additional logging to localhost, pointing developers to the\r\n // service worker/PWA documentation.\r\n navigator.serviceWorker.ready.then(() => {\r\n console.log(\r\n 'This web app is being served cache-first by a service ' +\r\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\r\n );\r\n });\r\n } else {\r\n // Is not localhost. Just register service worker\r\n registerValidSW(swUrl, config);\r\n }\r\n });\r\n }\r\n}\r\n\r\nfunction registerValidSW(swUrl, config) {\r\n navigator.serviceWorker\r\n .register(swUrl)\r\n .then(registration => {\r\n registration.onupdatefound = () => {\r\n const installingWorker = registration.installing;\r\n if (installingWorker == null) {\r\n return;\r\n }\r\n installingWorker.onstatechange = () => {\r\n if (installingWorker.state === 'installed') {\r\n if (navigator.serviceWorker.controller) {\r\n // At this point, the updated precached content has been fetched,\r\n // but the previous service worker will still serve the older\r\n // content until all client tabs are closed.\r\n console.log(\r\n 'New content is available and will be used when all ' +\r\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\r\n );\r\n\r\n // Execute callback\r\n if (config && config.onUpdate) {\r\n config.onUpdate(registration);\r\n }\r\n } else {\r\n // At this point, everything has been precached.\r\n // It's the perfect time to display a\r\n // \"Content is cached for offline use.\" message.\r\n console.log('Content is cached for offline use.');\r\n\r\n // Execute callback\r\n if (config && config.onSuccess) {\r\n config.onSuccess(registration);\r\n }\r\n }\r\n }\r\n };\r\n };\r\n })\r\n .catch(error => {\r\n console.error('Error during service worker registration:', error);\r\n });\r\n}\r\n\r\nfunction checkValidServiceWorker(swUrl, config) {\r\n // Check if the service worker can be found. If it can't reload the page.\r\n fetch(swUrl, {\r\n headers: { 'Service-Worker': 'script' },\r\n })\r\n .then(response => {\r\n // Ensure service worker exists, and that we really are getting a JS file.\r\n const contentType = response.headers.get('content-type');\r\n if (\r\n response.status === 404 ||\r\n (contentType != null && contentType.indexOf('javascript') === -1)\r\n ) {\r\n // No service worker found. Probably a different app. Reload the page.\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister().then(() => {\r\n window.location.reload();\r\n });\r\n });\r\n } else {\r\n // Service worker found. Proceed as normal.\r\n registerValidSW(swUrl, config);\r\n }\r\n })\r\n .catch(() => {\r\n console.log(\r\n 'No internet connection found. App is running in offline mode.'\r\n );\r\n });\r\n}\r\n\r\nexport function unregister() {\r\n if ('serviceWorker' in navigator) {\r\n navigator.serviceWorker.ready\r\n .then(registration => {\r\n registration.unregister();\r\n })\r\n .catch(error => {\r\n console.error(error.message);\r\n });\r\n }\r\n}\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport './index.css';\r\nimport tictactoe from './ttt/tictactoe';\r\nimport chess from './chess';\r\nimport LastUpdated from './LastUpdated';\r\nimport * as serviceWorker from './serviceWorker';\r\nimport { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';\r\n\r\nReactDOM.render(\r\n\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\r\n\r\n\t\t\t{\r\n\t\t\t\t//console.log(props)\r\n\t\t\t\treturn
\r\n\t\t\t\t\t

\r\n\t\t\t\t\t\tThe page '{props.location.pathname.substring(1)}' does not exist yet.\r\n\t\t\t\t\t

\r\n\t\t\t\t\t

\r\n\t\t\t\t\t\tReturn to Home\r\n\t\t\t\t\t

\r\n\t\t\t\t
\r\n\t\t\t\t}}>\r\n\t\t\t
\r\n\t\t
\r\n\t
,\r\n document.getElementById('root')\r\n);\r\n\r\nReactDOM.render(\r\n\t,\r\n\tdocument.getElementById('last-updated')\r\n);\r\n\r\n// If you want your app to work offline and load faster, you can change\r\n// unregister() to register() below. Note this comes with some pitfalls.\r\n// Learn more about service workers: https://bit.ly/CRA-PWA\r\nserviceWorker.unregister();\r\n"],"sourceRoot":""}