{"version":3,"sources":["css/App.module.css","css/Tile.module.css","actions/types.ts","actions/game.ts","actions/index.ts","css/LoseOverlay.module.css","css/Header.module.css","css/Board.module.css","css/Input.module.css","reducers/game.ts","components/Tile.tsx","utils/useDelayedValue.ts","components/LoseOverlay.tsx","components/Board.tsx","components/Input.tsx","components/Header.tsx","components/App.tsx","reducers/index.ts","store.ts","index.tsx"],"names":["module","exports","root","info","expanded","text","c2","c4","c8","c16","c32","c64","c128","c256","c512","c1024","c2048","c4096","c8192","c16384","c32768","c65536","Type","Direction","start","type","START","moveUp","MOVE","dir","UP","moveDown","DOWN","moveLeft","LEFT","moveRight","RIGHT","spawnNewTile","SPAWN_TILE","__webpack_require__","d","__webpack_exports__","lose","scoreGained","moveUpAndFade","touchDiv","reduce","state","action","newState","board","removedTiles","score","turns","highScore","highestTile","highestTileThisGame","GET_SAVE_FILE","Object","_opt_buildhome_repo_node_modules_babel_runtime_helpers_esm_objectSpread__WEBPACK_IMPORTED_MODULE_0__","find","x","y","map","concat","randomInt","id","Math","random","toString","substr","value","chance","getTileValue","i","j","tile","some","row","loseCheck","boardMerge","flipX","rotate90","boardMoved","targetJ","targetTile","replaceTile","push","removed","max","Tile","_ref","_useState","useState","_useState2","slicedToArray","tileValue","setTileValue","_useState3","_useState4","bounce","setBounce","useEffect","setInterval","clearInterval","fontSize","react_default","a","createElement","framer_motion_es","svg","width","height","viewBox","fill","className","clsx","styles","animate","initial","transition","damping","stiffness","style","zIndex","g","scale","stroke","strokeOpacity","strokeWidth","textAnchor","useDelayedValue","delay","current","setCurrent","timer","setTimeout","clearTimeout","connect","game","visible","props","objectWithoutProperties","share","useCallback","window","open","encodeURIComponent","assign","xmlns","fill-opacity","alignmentBaseline","onClick","whileHover","whileTap","transform","flatMap","objectSpread","filter","sort","tile1","tile2","components_Tile","key","components_LoseOverlay","swipeConfig","defineSwipe","swipeDistance","assignNoTouchMove","elem","addEventListener","e","preventDefault","reset","disabled","children","activateKey","useMemo","throttle","onKeyPress","ev","toLowerCase","removeEventListener","activateKeyUp","activateKeyDown","activateKeyLeft","activateKeyRight","lib","onSwipeUp","onSwipeDown","onSwipeLeft","onSwipeRight","config","ref","useRef","scoreGainedPopups","setScoreGainedPopups","array","turn","item","fontWeight","textContent","length","easeInOutQuint","DuplicateMagic","Fragment","position","visibility","overflow","aria-hidden","rootReducer","combineReducers","require","default","reduxDevTools","__REDUX_DEVTOOLS_EXTENSION__","store","createStore","undefined","localStorage","JSON","parse","stringify","ReactDOM","render","es","setExpanded","toggleExpanded","href","div","overflowY","ease","duration","span","opacity","components_Header","components_Input","components_Board","document","getElementById"],"mappings":"6EACAA,EAAAC,QAAA,CAAkBC,KAAA,kBAAAC,KAAA,kBAAAC,SAAA,4CCAlBJ,EAAAC,QAAA,CAAkBC,KAAA,mBAAAG,KAAA,mBAAAC,GAAA,iBAAAC,GAAA,iBAAAC,GAAA,iBAAAC,IAAA,kBAAAC,IAAA,kBAAAC,IAAA,kBAAAC,KAAA,mBAAAC,KAAA,mBAAAC,KAAA,mBAAAC,MAAA,oBAAAC,MAAA,oBAAAC,MAAA,oBAAAC,MAAA,oBAAAC,OAAA,qBAAAC,OAAA,qBAAAC,OAAA,uDCDX,IAAKC,EAMAC,ECJL,SAASC,IACd,MAAO,CAAEC,KAAMH,EAAKI,OAEf,SAASC,IACd,MAAO,CAAEF,KAAMH,EAAKM,KAAMC,IAAKN,EAAUO,IAEpC,SAASC,IACd,MAAO,CAAEN,KAAMH,EAAKM,KAAMC,IAAKN,EAAUS,MAEpC,SAASC,IACd,MAAO,CAAER,KAAMH,EAAKM,KAAMC,IAAKN,EAAUW,MAEpC,SAASC,IACd,MAAO,CAAEV,KAAMH,EAAKM,KAAMC,IAAKN,EAAUa,OAEpC,SAASC,IACd,MAAO,CAAEZ,KAAMH,EAAKgB,sBDlBVhB,oIAMAC,qEENZgB,EAAAC,EAAAC,EAAA,sBAAAjB,IAAAe,EAAAC,EAAAC,EAAA,sBAAAd,IAAAY,EAAAC,EAAAC,EAAA,sBAAAV,IAAAQ,EAAAC,EAAAC,EAAA,sBAAAR,IAAAM,EAAAC,EAAAC,EAAA,sBAAAN,IAAAI,EAAAC,EAAAC,EAAA,sBAAAJ,IAAAE,EAAAC,EAAAC,EAAA,sBAAAnB,IAAAiB,EAAAC,EAAAC,EAAA,sBAAAlB,yBCCAvB,EAAAC,QAAA,CAAkBC,KAAA,0BAAAwC,KAAA,gDCAlB1C,EAAAC,QAAA,CAAkBC,KAAA,qBAAAyC,YAAA,4BAAAC,cAAA,oDCAlB5C,EAAAC,QAAA,CAAkBC,KAAA,0CCAlBF,EAAAC,QAAA,CAAkB4C,SAAA,2KCyCH,SAASC,EAAOC,EAAcC,GAC3C,OAAQA,EAAOvB,MACb,KAAc,MAATsB,EAAgBC,EAAOvB,KAAO,KACnC,KAAKH,IAAKI,MACR,IAAIuB,EAAkB,CACpBC,MAAO,CACL,CAAC,KAAM,KAAM,KAAM,MACnB,CAAC,KAAM,KAAM,KAAM,MACnB,CAAC,KAAM,KAAM,KAAM,MACnB,CAAC,KAAM,KAAM,KAAM,OAErBC,aAAc,GACdC,MAAO,EACPT,YAAa,KACbU,MAAO,EACPX,MAAM,EACNY,UAAWP,EAAQA,EAAMO,UAAY,EACrCC,YAAaR,EAAQA,EAAMQ,YAAc,EACzCC,oBAAqB,GAOvB,OAHAP,EAAWH,EAAOG,EAAUZ,eAC5BY,EAAWH,EAAOG,EAAUZ,eAI9B,KAAKf,IAAKmC,cACR,OAAGV,EAAML,KACA,KAEAgB,OAAAC,EAAA,EAAAD,CAAA,GACFX,EADL,CAEEJ,YAAa,IAInB,KAAKrB,IAAKgB,WACR,IAAKS,EAAMG,MAAMU,KAAK,SAAAC,GAAC,OAAIA,EAAED,KAAK,SAAAC,GAAC,OAAU,OAANA,MAAc,CACnD,IACIA,EAAGC,EADHZ,EAAQH,EAAMG,MAAMa,IAAI,SAAAF,GAAC,OAAIA,EAAEG,WAAUA,SAG7C,GACEH,EAAII,oBAAU,EAAG,GACjBH,EAAIG,oBAAU,EAAG,SACM,OAAhBf,EAAMW,GAAGC,IAElBZ,EAAMW,GAAGC,GAAK,CAAEI,GAnEfC,KAAKC,SAASC,WAAWC,OAAO,GAmEPC,MAAOC,iBAAO,IAAM,EAAI,GAGlD,IAAM9B,EAnEd,SAAmBQ,GACjB,SAASuB,EAAaC,EAAWC,GAC/B,IAAMC,EAAO1B,EAAMwB,IAAMxB,EAAMwB,GAAGC,GAClC,OAAIC,EAAaA,EAAKL,MACf,EAGT,OAAQrB,EAAM2B,KAAK,SAACC,EAAKJ,GAAN,OAAYI,EAAID,KAAK,SAACD,EAAMD,GAC7C,OAAKC,GACDA,EAAKL,QAAUE,EAAaC,EAAI,EAAGC,IACnCC,EAAKL,QAAUE,EAAaC,EAAI,EAAGC,IACnCC,EAAKL,QAAUE,EAAaC,EAAGC,EAAI,IACnCC,EAAKL,QAAUE,EAAaC,EAAGC,EAAI,OAuDtBI,CAAU7B,GAEvB,OAAOQ,OAAAC,EAAA,EAAAD,CAAA,GACFX,EADL,CAEEG,QACAR,SAGJ,OAAOK,EAET,KAAKzB,IAAKM,KAaR,IAZA,IAAIsB,EAAQH,EAAMG,MAAMa,IAAI,SAAAF,GAAC,OAAIA,EAAEG,WAAUA,SACzCgB,EAA0B9B,EAAMa,IAAI,SAAAF,GAAC,OAAIA,EAAEE,IAAI,SAAAF,GAAC,OAAI,MAClDV,EAA2B,GAE3B8B,EAAQjC,EAAOnB,MAAQN,IAAUa,OAASY,EAAOnB,MAAQN,IAAUS,KACnEkD,EAAWlC,EAAOnB,MAAQN,IAAUS,MAAQgB,EAAOnB,MAAQN,IAAUO,GAEvEqD,GAAa,EACb5B,EAAcR,EAAMQ,YACpBC,EAAsBT,EAAMS,oBAC5Bb,EAAc,EAET+B,EAAI,EAAGA,EAAI,EAAGA,IACrB,IAAK,IAAIC,EAAIM,EAAQ,EAAI,EAAGA,EAAQN,GAAK,EAAIA,EAAI,EAAGA,GAAKM,GAAS,EAAI,EAAG,CACvE,IAAIL,EAAOM,EAAWhC,EAAMyB,GAAGD,GAAKxB,EAAMwB,GAAGC,GAC7C,GAAIC,EAAM,CAGR,IAFA,IAAIL,EAAQK,EAAKL,MACba,EAAUT,IAEVO,EACEhC,EAAM+B,EAAQG,EAAU,EAAIA,EAAU,IACnClC,EAAM+B,EAAQG,EAAU,EAAIA,EAAU,GAAGV,GAC5CxB,EAAMwB,GAAGO,EAAQG,EAAU,EAAIA,EAAU,MACvCH,EAAoB,IAAZG,EAA4B,IAAZA,IAE9BA,GAAWH,EAAQ,GAAK,EAE1B,GAAIC,EAAU,CACZ,IAAMG,EAAaL,EAAWC,EAAQG,EAAU,EAAIA,EAAU,KAA2D,IAArDJ,EAAWC,EAAQG,EAAU,EAAIA,EAAU,GAAGV,IAAgBxB,EAAM+B,EAAQG,EAAU,EAAIA,EAAU,GAAGV,GAM3K,GALIW,GAAcA,EAAWd,QAAUA,IAErCa,GAAWH,EAAQ,GAAK,EACxBtC,GAFA4B,GAAS,GAIPI,IAAMS,EAAS,CACjBlC,EAAMyB,GAAGD,GAAK,KACd,IAAMY,EAAcpC,EAAMkC,GAASV,GACf,OAAhBY,IACFnC,EAAaoC,KAAK,CAAErB,GAAIoB,EAAYpB,GAAIK,MAAOe,EAAYf,MAAOT,EAAGsB,EAASvB,EAAGa,EAAGc,SAAS,IAC7FR,EAAWI,GAASV,IAAK,EACzBlB,EAAsBW,KAAKsB,IAAIjC,EAAqBe,IAEtDrB,EAAMkC,GAASV,GAAK,CAAER,GAAIU,EAAKV,GAAIK,SACnCY,GAAa,OAEV,CACL,IAAME,GAAcL,EAAWN,GAAGO,EAAQG,EAAU,EAAIA,EAAU,IAAMlC,EAAMwB,GAAGO,EAAQG,EAAU,EAAIA,EAAU,GAMjH,GALIC,GAAcA,EAAWd,QAAUK,EAAKL,QAE1Ca,GAAWH,EAAQ,GAAK,EACxBtC,GAFA4B,GAAS,GAIPI,IAAMS,EAAS,CACjBlC,EAAMwB,GAAGC,GAAK,KACd,IAAMW,EAAcpC,EAAMwB,GAAGU,GACT,OAAhBE,IACFnC,EAAaoC,KAAK,CAAErB,GAAIoB,EAAYpB,GAAIK,MAAOe,EAAYf,MAAOT,EAAGY,EAAGb,EAAGuB,EAASI,SAAS,IAC7FR,EAAWN,GAAGU,IAAW,EACzB5B,EAAsBW,KAAKsB,IAAIjC,EAAqBe,IAEtDrB,EAAMwB,GAAGU,GAAW,CAAElB,GAAIU,EAAKV,GAAIK,SACnCY,GAAa,KASvB,GAFA5B,EAAcR,EAAMO,YAAcP,EAAMK,MAAQI,EAAsBD,EAElE4B,EAAY,CACd,IAAM/B,EAAQL,EAAMK,MAAQT,EAExBM,EAAeS,OAAAC,EAAA,EAAAD,CAAA,GACdX,EADc,CAEjBK,MAAOA,EACPE,UAAWa,KAAKsB,IAAIrC,EAAOL,EAAMO,WACjCD,MAAON,EAAMM,MAAQ,EACrBH,QACAP,cACAQ,eACAI,cACAC,wBAKF,OAFAP,EAAWH,EAAOG,EAAUZ,eAK9B,OAAOU,EAET,QACE,OAAOA,wpECxGE2C,MAtFf,SAAAC,GAA4C,IAA5Bf,EAA4Be,EAA5Bf,KAA4BgB,EACRC,mBAASjB,EAAKL,OADNuB,EAAApC,OAAAqC,EAAA,EAAArC,CAAAkC,EAAA,GACnCI,EADmCF,EAAA,GACxBG,EADwBH,EAAA,GAAAI,EAEdL,oBAAS,GAFKM,EAAAzC,OAAAqC,EAAA,EAAArC,CAAAwC,EAAA,GAEnCE,EAFmCD,EAAA,GAE3BE,EAF2BF,EAAA,GAI1CG,oBAAU,WACR,GAAIN,IAAcpB,EAAKL,MAAO,CAC5B,IAAMV,EAAI0C,YAAY,WACpBN,EAAarB,EAAKL,OAClB8B,GAAU,IACT,KACH,OAAO,kBAAMG,cAAc3C,MAE5B,CAACe,EAAKL,MAAOyB,IAChBM,oBAAU,WACR,GAAIF,EAAQ,CACV,IAAMvC,EAAI0C,YAAY,WACpBF,GAAU,IACT,IACH,OAAO,kBAAMG,cAAc3C,MAE5B,CAACuC,IAEJ,IAAIK,EAAW,GAUf,OATIT,GAAa,MACfS,EAAW,IAETT,GAAa,MACfS,EAAW,IAETT,GAAa,MACfS,EAAW,IAGXC,EAAAC,EAAAC,cAACC,EAAA,EAAOC,IAAR,CACEC,MAAM,MACNC,OAAO,MACPC,QAAQ,cACRC,KAAK,OACLC,UAAWC,YAAKC,IAAOnH,KAAMmH,IAAM,IAAArD,OAAKgC,KACxCsB,QAAS,CACPzD,EAAY,IAATe,EAAKf,EAAU,GAClBC,EAAY,IAATc,EAAKd,EAAU,IAEpByD,QAAS,CACP1D,EAAY,IAATe,EAAKf,EAAU,GAClBC,EAAY,IAATc,EAAKd,EAAU,IAEpB0D,WAAY,CAAE/F,KAAM,SAAUgG,QAAS,GAAIC,UAAW,KACtDC,MAAO,CACLC,OAAQhD,EAAKY,QAAU,EAAI,IAG7BkB,EAAAC,EAAAC,cAACC,EAAA,EAAOgB,EAAR,CACEP,QAAS,CACPQ,MAAO1B,EAAS,KAAO,GAEzBmB,QAAS,CACPO,MAAO,GAETN,WAAY,CAAE/F,KAAM,SAAUgG,QAAS,GAAIC,UAAW,MAEtDhB,EAAAC,EAAAC,cAAA,QACEpE,EAAE,4CACF0E,KAAK,4BAEPR,EAAAC,EAAAC,cAAA,QACEpE,EAAE,8FACFuF,OAAsB,QAAd/B,EAAsB,QAAU,QACxCgC,cAAc,OACdC,YAAY,MAEdvB,EAAAC,EAAAC,cAAA,QACE/C,EAAG,GAAIC,EAAG,GAAK2C,EAAW,EAAI,EAC9ByB,WAAW,SACXzB,SAAUA,EACVS,KAAK,QACLC,UAAWE,IAAOhH,KAClB0H,OAAsB,QAAd/B,EAAsB,QAAU,SAEvCA,yCClFI,SAASmC,EAAmB5D,EAAU6D,GAAkB,IAAAxC,EACvCC,mBAAYtB,GAD2BuB,EAAApC,OAAAqC,EAAA,EAAArC,CAAAkC,EAAA,GAC9DyC,EAD8DvC,EAAA,GACrDwC,EADqDxC,EAAA,GAerE,OAZAQ,oBAAU,WACR,GAAG+B,IAAY9D,EAAO,CACpB,IAAMgE,EAAQC,WAAW,WACvBF,EAAW/D,IACV6D,GAEH,OAAO,WACLK,aAAaF,MAGhB,CAACF,EAASD,EAAO7D,IAEb8D,ECqDMK,kBACb,SAAC3F,GAAD,MAAoB,CAClBK,MAAOL,EAAM4F,KAAKvF,MAClBI,oBAAqBT,EAAM4F,KAAKnF,sBAElC,CAAEhC,WALWkH,CA9Df,SAAA/C,GAaE,IAZEvC,EAYFuC,EAZEvC,MACAI,EAWFmC,EAXEnC,oBACAoF,EAUFjD,EAVEiD,QACAzB,EASFxB,EATEwB,UACA3F,EAQFmE,EAREnE,MACGqH,EAOLnF,OAAAoF,EAAA,EAAApF,CAAAiC,EAAA,+DACMoD,EAAQC,sBAAY,WACxBC,OAAOC,KAAK,yCAA2CC,mBAAkB,YAAAnF,OAAaZ,EAAb,iBAAAY,OAAkCR,EAAlC,iEACxE,CAACJ,EAAOI,IAEX,OACEkD,EAAAC,EAAAC,cAAA,MAAAlD,OAAA0F,OAAA,CACErC,MAAM,MACNC,OAAO,MACPC,QAAQ,cACRC,KAAK,OACLmC,MAAM,6BACNlC,UAAWC,YAAKC,IAAOnH,KAAM0I,GAAWvB,IAAO3E,KAAMyE,IACjD0B,GAEJnC,EAAAC,EAAAC,cAAA,QAAMG,MAAM,MAAMC,OAAO,MAAME,KAAK,UAAUoC,eAAa,SAC3D5C,EAAAC,EAAAC,cAAA,QAAMpE,EAAE,66KAA66K0E,KAAK,UAC17KR,EAAAC,EAAAC,cAAA,QACE/C,EAAE,QAAQC,EAAE,QAAQ2C,SAAS,OAAOS,KAAK,QACzCgB,WAAW,SAASqB,kBAAkB,UAFxC,UAIUpB,EAAgB/E,EAAO,MAEjCsD,EAAAC,EAAAC,cAAA,QACE/C,EAAE,QAAQC,EAAE,QAAQ2C,SAAS,OAAOS,KAAK,QACzCgB,WAAW,SAASqB,kBAAkB,UAFxC,iBAIiBpB,EAAgB3E,EAAqB,MAEtDkD,EAAAC,EAAAC,cAACC,EAAA,EAAOgB,EAAR,CACE2B,QAAShI,EACTiI,WAAY,CAAE3B,MAAO,MACrB4B,SAAU,CAAE5B,MAAO,MAEnBpB,EAAAC,EAAAC,cAAA,QAAMpE,EAAE,wDAAwD0E,KAAK,UACrER,EAAAC,EAAAC,cAAA,QAAMpE,EAAE,4pEAA4pE0E,KAAK,WAE3qER,EAAAC,EAAAC,cAACC,EAAA,EAAOgB,EAAR,CACE2B,QAAST,EACTU,WAAY,CAAE3B,MAAO,MACrB4B,SAAU,CAAE5B,MAAO,MAEnBpB,EAAAC,EAAAC,cAAA,QAAMpE,EAAE,4DAA4D0E,KAAK,UACzER,EAAAC,EAAAC,cAAA,QAAMpE,EAAE,wlEAAwlE0E,KAAK,cCb9lEwB,kBACb,SAAC3F,GAAD,MAAoB,CAClBG,MAAOH,EAAM4F,KAAKzF,MAClBC,aAAcJ,EAAM4F,KAAKxF,aACzBT,KAAMK,EAAM4F,KAAKjG,OAEnB,GANagG,CA5Cf,SAAA/C,GAA0G,IAAzFzC,EAAyFyC,EAAzFzC,MAAOC,EAAkFwC,EAAlFxC,aAAcT,EAAoEiD,EAApEjD,KACpC,OACEgE,EAAAC,EAAAC,cAAA,OACEO,UAAWE,IAAOnH,MAGlBwG,EAAAC,EAAAC,cAAA,OAAKG,MAAM,MAAMC,OAAO,MAAMC,QAAQ,cAAcC,KAAK,OAAOmC,MAAM,8BACpE3C,EAAAC,EAAAC,cAAA,QAAMpE,EAAE,iDAAiD0E,KAAK,YAC9DR,EAAAC,EAAAC,cAAA,QAAM/C,EAAE,KAAKC,EAAE,KAAKiD,MAAM,MAAMC,OAAO,MAAME,KAAK,YAClDR,EAAAC,EAAAC,cAAA,QAAM/C,EAAE,MAAMC,EAAE,MAAMiD,MAAM,KAAKC,OAAO,KAAKE,KAAK,YAClDR,EAAAC,EAAAC,cAAA,QAAM/C,EAAE,MAAMC,EAAE,KAAKiD,MAAM,KAAKC,OAAO,KAAKE,KAAK,YACjDR,EAAAC,EAAAC,cAAA,QAAM/C,EAAE,KAAKC,EAAE,MAAMiD,MAAM,KAAKC,OAAO,KAAKE,KAAK,YACjDR,EAAAC,EAAAC,cAAA,QAAM/C,EAAE,KAAKC,EAAE,KAAKiD,MAAM,KAAKC,OAAO,KAAKE,KAAK,YAChDR,EAAAC,EAAAC,cAAA,QAAM/C,EAAE,MAAMC,EAAE,KAAKiD,MAAM,IAAIC,OAAO,MAAME,KAAK,YACjDR,EAAAC,EAAAC,cAAA,QAAM/C,EAAE,MAAMC,EAAE,KAAKiD,MAAM,IAAIC,OAAO,MAAME,KAAK,YACjDR,EAAAC,EAAAC,cAAA,QAAM/C,EAAE,MAAMC,EAAE,KAAKiD,MAAM,IAAIC,OAAO,MAAME,KAAK,YACjDR,EAAAC,EAAAC,cAAA,QAAM/C,EAAE,MAAMC,EAAE,MAAMiD,MAAM,IAAIC,OAAO,MAAM2C,UAAU,qBAAqBzC,KAAK,YACjFR,EAAAC,EAAAC,cAAA,QAAM/C,EAAE,MAAMC,EAAE,MAAMiD,MAAM,IAAIC,OAAO,MAAM2C,UAAU,qBAAqBzC,KAAK,YACjFR,EAAAC,EAAAC,cAAA,QAAM/C,EAAE,MAAMC,EAAE,MAAMiD,MAAM,IAAIC,OAAO,MAAM2C,UAAU,qBAAqBzC,KAAK,YAE/E/D,EAAaa,OAAQd,EAClB0G,QAAQ,SAAC9E,EAAKhB,GAAN,OAAYgB,EAAIf,IAAI,SAACa,EAAMf,GAAP,OAAce,GAAIlB,OAAAmG,EAAA,EAAAnG,CAAA,GAASkB,EAAT,CAAef,IAAGC,UAChEgG,OAAQ,SAAClF,GAAD,OAAmB,OAATA,IAClBmF,KAAK,SAACC,EAAOC,GAAR,OAAmBD,EAAM9F,GAAK+F,EAAM/F,MACzCH,IAAI,SAACa,GACJ,OAAIA,EAGG8B,EAAAC,EAAAC,cAACsD,EAAD,CACLC,IAAKvF,EAAKV,GACVU,KAAMA,IAJC,OAQf8B,EAAAC,EAAAC,cAACwD,EAAD,CACEvG,EAAE,OACFC,EAAE,OACF8E,QAASlG,4CCtCb2H,EAAcC,sBAAY,CAAEC,cAAe,KAEjD,SAASC,EAAkBC,GACrBA,GACFA,EAAKC,iBAAiB,YAAa,SAACC,GAAD,OAAOA,EAAEC,mBA0FjClC,kBACb,SAAA3F,GAAK,MAAK,IACV,CACEpB,WACAI,aACAE,aACAE,cACA0I,MAAOrJ,KAPIkH,CAtFf,SAAA/C,GAgBG,IAfDhE,EAeCgE,EAfDhE,OACAI,EAcC4D,EAdD5D,SACAE,EAaC0D,EAbD1D,SACAE,EAYCwD,EAZDxD,UACA0I,EAWClF,EAXDkF,MACAC,EAUCnF,EAVDmF,SACAC,EASCpF,EATDoF,SAUMC,EAAcC,kBAAQ,kBAAMC,mBAAS,SAAUf,GACnD,OAAQA,GACN,IAAK,QAAWU,IAAS,MACzB,IAAK,KAAQlJ,IAAU,MACvB,IAAK,OAAUI,IAAY,MAC3B,IAAK,OAAUE,IAAY,MAC3B,IAAK,QAAWE,MAIjB,MAAM,CAACR,EAAQI,EAAUE,EAAUE,EAAW0I,IAE3CM,EAAanC,sBAAY,SAACoC,GAE9B,OADAA,EAAGR,iBACKQ,EAAGjB,IAAIkB,eACb,IAAK,SACL,IAAK,IACHL,EAAY,SAAU,MACxB,IAAK,IACL,IAAK,IACH,IAAK,UACHA,EAAY,MAAO,MACvB,IAAK,IACL,IAAK,IACL,IAAK,YACHA,EAAY,QAAS,MACvB,IAAK,IACL,IAAK,IACL,IAAK,YACHA,EAAY,QAAS,MACvB,IAAK,IACL,IAAK,IACL,IAAK,aACHA,EAAY,WAGf,CAACA,IAEJ1E,oBAAU,WACR,IAAKwE,EAEH,OADA7B,OAAOyB,iBAAiB,UAAWS,GAC5B,WACLlC,OAAOqC,oBAAoB,UAAWH,KAGzC,CAACL,EAAUK,IAGd,IAAMI,EAAgBvC,sBAAY,kBAAMgC,EAAY,OAAO,CAACA,IACtDQ,EAAkBxC,sBAAY,kBAAMgC,EAAY,SAAS,CAACA,IAC1DS,EAAkBzC,sBAAY,kBAAMgC,EAAY,SAAS,CAACA,IAC1DU,EAAmB1C,sBAAY,kBAAMgC,EAAY,UAAU,CAACA,IAElE,OAAOtE,EAAAC,EAAAC,cAAC+E,EAAA,UAAD,CACLC,UAAWL,EACXM,YAAaL,EACbM,YAAaL,EACbM,aAAcL,EACdM,OAAQ3B,GAER3D,EAAAC,EAAAC,cAAA,OACEO,UAAWE,IAAOxE,SAClBoJ,IAAKzB,GAEJO,wBCXQrC,kBACb,SAAC3F,GAAD,MAAoB,CAClBK,MAAOL,EAAM4F,KAAKvF,MAClBE,UAAWP,EAAM4F,KAAKrF,UACtBC,YAAaR,EAAM4F,KAAKpF,YACxBZ,YAAaI,EAAM4F,KAAKhG,YACxBU,MAAON,EAAM4F,KAAKtF,QAEpB,CAAE7B,WARWkH,CA1Ef,SAAA/C,GAA2M,IAAzLtC,EAAyLsC,EAAzLtC,MAAOD,EAAkLuC,EAAlLvC,MAAO5B,EAA2KmE,EAA3KnE,MAAOmB,EAAoKgD,EAApKhD,YAAaW,EAAuJqC,EAAvJrC,UAAWC,EAA4IoC,EAA5IpC,YACvD0I,EAAMC,mBACNzB,EAAOwB,EAAI5D,QAFwLzC,EAIvJC,mBAA4B,IAJ2HC,EAAApC,OAAAqC,EAAA,EAAArC,CAAAkC,EAAA,GAIlMuG,EAJkMrG,EAAA,GAI/KsG,EAJ+KtG,EAAA,GAczM,OATAQ,oBAAU,WACJ3D,IACFyJ,EAAqB,SAACC,GAAD,OAAWA,EAAMrI,OAAO,CAAEZ,MAAOT,EAAa2J,KAAMjJ,MACzEmF,WAAW,WACX4D,EAAqB,SAACC,GAAD,OAAWA,EAAMvC,OAAO,SAACyC,GAAD,OAAUA,EAAKD,OAASjJ,OAClE,OAEJ,CAACA,EAAOV,IAGT+D,EAAAC,EAAAC,cAAA,OAAKO,UAAWE,IAAOnH,KAAM6G,MAAM,MAAMC,OAAO,KAAKC,QAAQ,aAAaC,KAAK,OAAOmC,MAAM,8BAC1F3C,EAAAC,EAAAC,cAAA,QAAMpE,EAAE,iCAAiC0E,KAAK,YAC9CR,EAAAC,EAAAC,cAAA,SACEF,EAAAC,EAAAC,cAAA,QAAMpE,EAAE,qDAAqD0E,KAAK,YAClER,EAAAC,EAAAC,cAAA,QACE/C,EAAE,QACFC,EAAE,OACFoD,KAAK,QACLT,SAAS,OACTyB,WAAW,SACXqB,kBAAkB,SAClBiD,WAAW,OACXP,IAAKA,GARP,UASS7I,GACTsD,EAAAC,EAAAC,cAAA,QACE/C,EAAE,QACFC,EAAE,OACFoD,KAAK,UACLT,SAAS,OACTyB,WAAW,SACXqB,kBAAkB,SAClBiD,WAAW,QAPb,WAQUlJ,EARV,KAQwBC,EARxB,UAUE4I,EAAkBpI,IAAI,SAACwI,GACrB,OAAO7F,EAAAC,EAAAC,cAAA,QACLuD,IAAKoC,EAAKD,KACVzI,EAAG,KAAO4G,EAA0C,EAAlCA,EAAKgC,YAAoBC,OAAa,GAAK,KAC7D5I,EAAE,OACFqD,UAAWE,IAAO1E,YAClBuE,KAAK,iBACLT,SAAS,OACTyB,WAAW,OACXqB,kBAAkB,SAClBiD,WAAW,QATN,IAUJD,EAAKnJ,UAIdsD,EAAAC,EAAAC,cAACC,EAAA,EAAOgB,EAAR,CACE2B,QAAShI,EACTiI,WAAY,CAAE3B,MAAO,MACrB4B,SAAU,CAAE5B,MAAO,MAEnBpB,EAAAC,EAAAC,cAAA,QAAMpE,EAAE,iDAAiD0E,KAAK,YAC9DR,EAAAC,EAAAC,cAAA,QACE/C,EAAE,OACFC,EAAE,OACFoD,KAAK,QACLT,SAAS,OACTyB,WAAW,SACXqB,kBAAkB,SAClBiD,WAAW,QAPb,eC/DFG,EAAiB,CAAC,IAAM,EAAG,GAAK,GAEtC,SAASC,EAATjH,GAAgF,IAAtDoF,EAAsDpF,EAAtDoF,SACxB,OAAOrE,EAAAC,EAAAC,cAAAF,EAAAC,EAAAkG,SAAA,KACLnG,EAAAC,EAAAC,cAAA,OAAKe,MAAO,CAAEmF,SAAU,aACrB/B,GAEHrE,EAAAC,EAAAC,cAAA,OAAKe,MAAO,CAAElB,SAAS,UAAWsG,WAAY,SAAUC,SAAU,WAAaC,eAAA,GAC5ElC,gBCZDmC,EAAcC,YAAgB,CAClCxE,KAAMyE,EAAQ,KAAUC,UCApBC,EAAkBrE,OAAesE,6BAOxBC,EALDC,YDCC,SAAU1K,EAAeC,GACtC,QAAc0K,IAAV3K,GACE4K,aAAa,kBACf,OAAOT,EAAYU,KAAKC,MAAMF,aAAa,mBAAoB3K,GAGnE,IAAMC,EAAWiK,EAAYnK,EAAOC,GAEpC,OADA2K,aAAa,kBAAoBC,KAAKE,UAAUZ,EAAYnK,EAAO,CAAEtB,KAAMH,IAAKmC,iBACzER,GCPPqK,EAAgBA,SAAkBI,UCApCK,IAASC,OACPtH,EAAAC,EAAAC,cAACqH,EAAA,EAAD,CAAUT,MAAOA,GAAO9G,EAAAC,EAAAC,cHWX,WAAe,IAAAhB,EACIC,oBAAS,GADbC,EAAApC,OAAAqC,EAAA,EAAArC,CAAAkC,EAAA,GACrBxF,EADqB0F,EAAA,GACXoI,EADWpI,EAAA,GAGtBqI,EAAiBnF,sBAAY,SAACoC,GAClCA,EAAGR,iBACHsD,EAAY,SAAArK,GAAC,OAAKA,KACjB,IAEH,OACI6C,EAAAC,EAAAC,cAAA,OAAKO,UAAWC,YAAKC,IAAOnH,KAAME,GAAYiH,IAAOjH,WACnDsG,EAAAC,EAAAC,cAAA,kBACAF,EAAAC,EAAAC,cAAA,SACEF,EAAAC,EAAAC,cAAA,uDADF,mCAEQF,EAAAC,EAAAC,cAAA,KAAGwH,KAAK,yBAAR,SAFR,sCAMA1H,EAAAC,EAAAC,cAACC,EAAA,EAAOwH,IAAR,CACElH,UAAWE,IAAOlH,KAClBmH,QAAS,CAAEN,OAAQ5G,EAAW,OAAS,KACvCmH,QAAS,CAAEP,OAAQ,KACnBW,MAAO,CAAE2G,UAAW,UACpB9G,WAAY,CAAE+G,KAAM5B,EAAgB6B,SAAUpO,EAAW,IAAO,KAEhEsG,EAAAC,EAAAC,cAACgG,EAAD,KACElG,EAAAC,EAAAC,cAAA,2HAEwBF,EAAAC,EAAAC,cAAA,KAAGwH,KAAK,wBAAR,QAFxB,8FAKA1H,EAAAC,EAAAC,cAAA,2DACiDF,EAAAC,EAAAC,cAAA,KAAGwH,KAAK,qBAAR,SADjD,8EAGO1H,EAAAC,EAAAC,cAAA,KAAGwH,KAAK,8BAAR,iBAHP,uEAMA1H,EAAAC,EAAAC,cAAA,wBACcF,EAAAC,EAAAC,cAAA,KAAGwH,KAAK,qCAAR,0BADd,0FAIA1H,EAAAC,EAAAC,cAAA,OAAKe,MAAO,CAAEX,OAAQ,cAI1BN,EAAAC,EAAAC,cAAA,SACEF,EAAAC,EAAAC,cAAA,KAAGwH,KAAK,SAAS5E,QAAS2E,GACvB/N,EAAW,gBAAkB,aAG9BsG,EAAAC,EAAAC,cAACC,EAAA,EAAO4H,KAAR,CACEnH,QAAS,CAAEoH,QAAStO,EAAW,EAAI,GACnCmH,QAAS,CAAEmH,QAAS,IAEnB,MACDhI,EAAAC,EAAAC,cAAA,KAAGwH,KAAK,wBAAR,kBAON1H,EAAAC,EAAAC,cAACC,EAAA,EAAOwH,IAAR,CACE/G,QAAS,CAAEN,OAAQ5G,EAAW,IAAM,QACpCmH,QAAS,CAAEP,OAAQ,QACnBQ,WAAY,CAAE+G,KAAM5B,EAAgB6B,SAAUpO,EAAW,IAAO,IAChEuH,MAAO,CAAE2G,UAAW,WAEpB5H,EAAAC,EAAAC,cAAC+H,EAAD,MACAjI,EAAAC,EAAAC,cAACgI,EAAD,CAAO9D,SAAU1K,GACfsG,EAAAC,EAAAC,cAACiI,EAAD,UGhFc,OACxBC,SAASC,eAAe","file":"static/js/main.f2f9ee68.chunk.js","sourcesContent":["// extracted by mini-css-extract-plugin\nmodule.exports = {\"root\":\"App_root__26snQ\",\"info\":\"App_info__3Et8L\",\"expanded\":\"App_expanded__1ZUu0\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"root\":\"Tile_root__1Dzhz\",\"text\":\"Tile_text__37dg4\",\"c2\":\"Tile_c2__YetAB\",\"c4\":\"Tile_c4__rKdyw\",\"c8\":\"Tile_c8__2W1FY\",\"c16\":\"Tile_c16__2wovm\",\"c32\":\"Tile_c32__1wxYp\",\"c64\":\"Tile_c64__2Q75Y\",\"c128\":\"Tile_c128__30k-L\",\"c256\":\"Tile_c256__1krD_\",\"c512\":\"Tile_c512__1Kc37\",\"c1024\":\"Tile_c1024__2k2td\",\"c2048\":\"Tile_c2048__3zG15\",\"c4096\":\"Tile_c4096__3SxGT\",\"c8192\":\"Tile_c8192__1YKDh\",\"c16384\":\"Tile_c16384__3FoiX\",\"c32768\":\"Tile_c32768__1z8Pz\",\"c65536\":\"Tile_c65536__26TXJ\"};","export enum Type {\n START,\n MOVE,\n SPAWN_TILE,\n GET_SAVE_FILE,\n};\nexport enum Direction {\n UP = 'UP',\n DOWN = 'DOWN',\n LEFT = 'LEFT',\n RIGHT = 'RIGHT',\n};\n\nexport type StartAction = { type: Type.START };\nexport type MoveAction = { type: Type.MOVE, dir: Direction };\nexport type SpawnTileAction = { type: Type.SPAWN_TILE };\nexport type ActionObject\n = StartAction\n | MoveAction\n | SpawnTileAction\n | { type: string };\n","import { Type, Direction, StartAction, MoveAction, SpawnTileAction } from \"./types\";\n\nexport function start(): StartAction {\n return { type: Type.START };\n}\nexport function moveUp(): MoveAction {\n return { type: Type.MOVE, dir: Direction.UP };\n}\nexport function moveDown(): MoveAction {\n return { type: Type.MOVE, dir: Direction.DOWN };\n}\nexport function moveLeft(): MoveAction {\n return { type: Type.MOVE, dir: Direction.LEFT };\n}\nexport function moveRight(): MoveAction {\n return { type: Type.MOVE, dir: Direction.RIGHT };\n}\nexport function spawnNewTile(): SpawnTileAction {\n return { type: Type.SPAWN_TILE };\n}\n","export * from './game';\nexport * from './types';\n","// extracted by mini-css-extract-plugin\nmodule.exports = {\"root\":\"LoseOverlay_root__3kbA-\",\"lose\":\"LoseOverlay_lose__27SxD\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"root\":\"Header_root__3PTx9\",\"scoreGained\":\"Header_scoreGained__kGeFx\",\"moveUpAndFade\":\"Header_moveUpAndFade__1S0dI\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"root\":\"Board_root__1bVhV\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"touchDiv\":\"Input_touchDiv__U4wUA\"};","import { spawnNewTile, ActionObject, Type, Direction } from '../actions';\nimport { randomInt, chance } from '@reverse/random';\n\nexport type ITile = { value: number, id: string, removed?: boolean } | null;\nexport type ITileExt = ITile & { x: number, y: number };\n\nexport type IBoard = ITile[][];\n\nexport interface IGame {\n board: IBoard,\n score: number,\n highScore: number,\n highestTile: number,\n highestTileThisGame: number,\n scoreGained: number | null,\n turns: number,\n removedTiles: ITileExt[],\n lose: boolean,\n}\n\n/** Generates an Identifier */\nfunction id() {\n return Math.random().toString().substr(2);\n}\n\nfunction loseCheck(board: IBoard) {\n function getTileValue(i: number, j: number) {\n const tile = board[i] && board[i][j];\n if (tile) return tile.value;\n return 0;\n }\n\n return !board.some((row, i) => row.some((tile, j) => {\n if (!tile) return true;\n if (tile.value === getTileValue(i + 1, j)) return true;\n if (tile.value === getTileValue(i - 1, j)) return true;\n if (tile.value === getTileValue(i, j + 1)) return true;\n if (tile.value === getTileValue(i, j - 1)) return true;\n return false;\n }));\n}\n\nexport default function reduce(state: IGame, action: ActionObject): IGame {\n switch (action.type) {\n case state == null ? action.type : null:\n case Type.START: {\n let newState: IGame = {\n board: [\n [null, null, null, null],\n [null, null, null, null],\n [null, null, null, null],\n [null, null, null, null],\n ],\n removedTiles: [],\n score: 0,\n scoreGained: null,\n turns: 0,\n lose: false,\n highScore: state ? state.highScore : 0,\n highestTile: state ? state.highestTile : 2,\n highestTileThisGame: 2,\n };\n\n // Spawn Two Tiles\n newState = reduce(newState, spawnNewTile());\n newState = reduce(newState, spawnNewTile());\n\n return newState;\n }\n case Type.GET_SAVE_FILE: {\n if(state.lose) {\n return null as any;\n } else {\n return {\n ...state,\n scoreGained: 0,\n }\n }\n }\n case Type.SPAWN_TILE: {\n if (!state.board.find(x => x.find(x => x === null))) {\n let board = state.board.map(x => x.concat()).concat();\n let x, y;\n\n do {\n x = randomInt(0, 3);\n y = randomInt(0, 3);\n } while (board[x][y] !== null);\n\n board[x][y] = { id: id(), value: chance(90) ? 2 : 4 };\n\n // Lose check (by checking if we can still play)\n const lose = loseCheck(board);\n\n return {\n ...state,\n board,\n lose,\n };\n }\n return state;\n }\n case Type.MOVE: {\n let board = state.board.map(x => x.concat()).concat();\n let boardMerge: boolean[][] = board.map(x => x.map(x => false));\n const removedTiles: ITileExt[] = [];\n\n const flipX = action.dir === Direction.RIGHT || action.dir === Direction.DOWN;\n const rotate90 = action.dir === Direction.DOWN || action.dir === Direction.UP;\n\n let boardMoved = false;\n let highestTile = state.highestTile;\n let highestTileThisGame = state.highestTileThisGame;\n let scoreGained = 0;\n\n for (let i = 0; i < 4; i++) {\n for (let j = flipX ? 3 : 0; flipX ? j >= 0 : j < 4; j += flipX ? -1 : 1) {\n let tile = rotate90 ? board[j][i] : board[i][j];\n if (tile) {\n let value = tile.value;\n let targetJ = j;\n while (\n !(rotate90\n ? board[flipX ? targetJ + 1 : targetJ - 1]\n && board[flipX ? targetJ + 1 : targetJ - 1][i]\n : board[i][flipX ? targetJ + 1 : targetJ - 1]\n ) && (flipX ? targetJ !== 3 : targetJ !== 0)\n ) {\n targetJ += flipX ? 1 : -1;\n }\n if (rotate90) {\n const targetTile = boardMerge[flipX ? targetJ + 1 : targetJ - 1] && boardMerge[flipX ? targetJ + 1 : targetJ - 1][i] === false && board[flipX ? targetJ + 1 : targetJ - 1][i];\n if (targetTile && targetTile.value === value) {\n value *= 2;\n targetJ += flipX ? 1 : -1;\n scoreGained += value;\n }\n if (j !== targetJ) {\n board[j][i] = null;\n const replaceTile = board[targetJ][i];\n if (replaceTile !== null) {\n removedTiles.push({ id: replaceTile.id, value: replaceTile.value, y: targetJ, x: i, removed: true });\n boardMerge[targetJ][i] = true;\n highestTileThisGame = Math.max(highestTileThisGame, value);\n }\n board[targetJ][i] = { id: tile.id, value };;\n boardMoved = true;\n }\n } else {\n const targetTile = !boardMerge[i][flipX ? targetJ + 1 : targetJ - 1] && board[i][flipX ? targetJ + 1 : targetJ - 1];\n if (targetTile && targetTile.value === tile.value) {\n value *= 2;\n targetJ += flipX ? 1 : -1;\n scoreGained += value;\n }\n if (j !== targetJ) {\n board[i][j] = null;\n const replaceTile = board[i][targetJ];\n if (replaceTile !== null) {\n removedTiles.push({ id: replaceTile.id, value: replaceTile.value, y: i, x: targetJ, removed: true });\n boardMerge[i][targetJ] = true;\n highestTileThisGame = Math.max(highestTileThisGame, value);\n }\n board[i][targetJ] = { id: tile.id, value };\n boardMoved = true;\n }\n }\n }\n }\n }\n\n highestTile = state.highScore === state.score ? highestTileThisGame : highestTile;\n\n if (boardMoved) {\n const score = state.score + scoreGained;\n\n let newState: IGame = {\n ...state,\n score: score,\n highScore: Math.max(score, state.highScore),\n turns: state.turns + 1,\n board,\n scoreGained,\n removedTiles,\n highestTile,\n highestTileThisGame,\n };\n\n newState = reduce(newState, spawnNewTile());\n\n return newState;\n }\n\n return state;\n }\n default: {\n return state;\n }\n }\n}\n","import React, { useState, useEffect } from 'react'\nimport styles from '../css/Tile.module.css';\nimport { ITileExt } from '../reducers/game';\nimport { motion } from 'framer-motion';\nimport clsx from 'clsx';\n\nfunction Tile({ tile }: { tile: ITileExt }) {\n const [tileValue, setTileValue] = useState(tile.value);\n const [bounce, setBounce] = useState(false);\n\n useEffect(() => {\n if (tileValue !== tile.value) {\n const x = setInterval(() => {\n setTileValue(tile.value);\n setBounce(true);\n }, 100);\n return () => clearInterval(x);\n }\n }, [tile.value, tileValue]);\n useEffect(() => {\n if (bounce) {\n const x = setInterval(() => {\n setBounce(false);\n }, 50);\n return () => clearInterval(x);\n }\n }, [bounce]);\n\n let fontSize = 48;\n if (tileValue >= 100) {\n fontSize = 40;\n }\n if (tileValue >= 1000) {\n fontSize = 36;\n }\n if (tileValue >= 10000) {\n fontSize = 30;\n }\n return (\n \n \n \n \n \n {tileValue}\n \n \n \n )\n}\n\nexport default Tile\n","import { useEffect, useState } from \"react\";\n\n/** Returns the value passed, but changes are delayed by the time given */\nexport default function useDelayedValue(value: T, delay: number): T {\n const [current, setCurrent] = useState(value);\n\n useEffect(() => {\n if(current !== value) {\n const timer = setTimeout(() => {\n setCurrent(value);\n }, delay);\n\n return () => {\n clearTimeout(timer)\n };\n }\n }, [current, delay, value]);\n\n return current;\n}\n","import React, { SVGProps, useCallback } from 'react'\nimport styles from '../css/LoseOverlay.module.css';\nimport clsx from 'clsx';\nimport { connect } from 'react-redux';\nimport { IStore } from '../store';\nimport { motion } from 'framer-motion';\nimport { start } from '../actions';\nimport useDelayedValue from '../utils/useDelayedValue';\n\nfunction LoseOverlay({\n score,\n highestTileThisGame,\n visible,\n className,\n start,\n ...props\n }: (SVGProps & {\n highestTileThisGame: number,\n score: number,\n visible: boolean,\n start: VoidFunction,\n })\n) {\n const share = useCallback(() => {\n window.open('https://twitter.com/intent/tweet?text=' + encodeURIComponent(`I scored ${score} and got the ${highestTileThisGame} Tile on @imdaveead's 2048 clone! https://davecode.me/2048`));\n }, [score, highestTileThisGame]);\n\n return (\n \n \n \n \n Score: {useDelayedValue(score, 500)}\n \n \n Highest Tile: {useDelayedValue(highestTileThisGame, 500)}\n \n \n \n \n \n \n \n \n \n \n )\n}\n\nexport default connect(\n (state: IStore) => ({\n score: state.game.score,\n highestTileThisGame: state.game.highestTileThisGame,\n }),\n { start },\n)(LoseOverlay);\n","import React from 'react'\nimport styles from '../css/Board.module.css';\nimport { connect } from 'react-redux';\nimport { IBoard, ITileExt } from '../reducers/game';\nimport { IStore } from '../store';\nimport Tile from './Tile';\nimport LoseOverlay from './LoseOverlay';\n\nfunction Board({ board, removedTiles, lose }: { board: IBoard, removedTiles: ITileExt[], lose: boolean }) {\n return (\n \n {/* The Board */}\n \n \n \n \n \n \n \n \n \n \n \n \n \n {\n removedTiles.concat((board\n .flatMap((row, y) => row.map((tile, x) => (tile && { ...tile, x, y })))\n .filter(((tile) => tile !== null)) as ITileExt[])\n .sort((tile1, tile2) => (tile1.id > tile2.id) as any))\n .map((tile) => {\n if(!tile) {\n return null;\n }\n return ;\n })\n }\n \n \n \n )\n}\n\nexport default connect(\n (state: IStore) => ({\n board: state.game.board,\n removedTiles: state.game.removedTiles,\n lose: state.game.lose,\n }),\n { },\n)(Board);\n","import React, { useEffect, useMemo, useCallback } from 'react'\nimport { connect } from 'react-redux';\nimport { moveUp, moveDown, moveRight, moveLeft, start } from '../actions';\nimport { throttle } from '@reverse/debounce';\nimport { Swipeable, defineSwipe } from 'react-touch';\nimport styles from '../css/Input.module.css';\n\nconst swipeConfig = defineSwipe({ swipeDistance: 30 });\n\nfunction assignNoTouchMove(elem: HTMLElement | null) {\n if (elem) {\n elem.addEventListener('touchmove', (e) => e.preventDefault());\n }\n}\n\nfunction Input({\n moveUp,\n moveDown,\n moveLeft,\n moveRight,\n reset,\n disabled,\n children,\n}: {\n moveUp: Function,\n moveDown: Function,\n moveLeft: Function,\n moveRight: Function,\n reset: Function,\n disabled: boolean,\n children: JSX.Element | JSX.Element[],\n}) {\n const activateKey = useMemo(() => throttle(function (key: 'Up' | 'Left' | 'Down' | 'Right' | 'Reset') {\n switch (key) {\n case 'Reset': { reset(); break; }\n case 'Up': { moveUp(); break; }\n case 'Down': { moveDown(); break; }\n case 'Left': { moveLeft(); break; }\n case 'Right': { moveRight(); break; }\n default:\n break;\n }\n }, 125), [moveUp, moveDown, moveLeft, moveRight, reset]);\n\n const onKeyPress = useCallback((ev: KeyboardEvent) => {\n ev.preventDefault();\n switch (ev.key.toLowerCase()) {\n case 'escape':\n case 'r':\n activateKey('Reset'); break;\n case 'w':\n case 'k':\n case 'arrowup':\n activateKey('Up'); break;\n case 's':\n case 'j':\n case 'arrowdown':\n activateKey('Down'); break;\n case 'a':\n case 'h':\n case 'arrowleft':\n activateKey('Left'); break;\n case 'd':\n case 'l':\n case 'arrowright':\n activateKey('Right'); break;\n default:\n }\n }, [activateKey]);\n\n useEffect(() => {\n if (!disabled) {\n window.addEventListener('keydown', onKeyPress);\n return () => {\n window.removeEventListener('keydown', onKeyPress);\n };\n }\n }, [disabled, onKeyPress]);\n\n // const activateKeyReset = useCallback(() => activateKey('Reset'), [activateKey])\n const activateKeyUp = useCallback(() => activateKey('Up'), [activateKey])\n const activateKeyDown = useCallback(() => activateKey('Down'), [activateKey])\n const activateKeyLeft = useCallback(() => activateKey('Left'), [activateKey])\n const activateKeyRight = useCallback(() => activateKey('Right'), [activateKey])\n\n return \n \n {children}\n \n ;\n}\n\nexport default connect(\n state => ({}),\n {\n moveUp,\n moveDown,\n moveLeft,\n moveRight,\n reset: start,\n }\n)(Input);\n","import React, { useRef, useEffect, useState } from 'react'\nimport { connect } from 'react-redux';\nimport { IStore } from '../store';\nimport { start } from '../actions';\nimport styles from '../css/Header.module.css';\nimport { motion } from 'framer-motion';\n\ntype EventHandler = () => void;\n\ntype ScoreGainedInfo = { turn: number, score: number };\n\nfunction Header({ turns, score, start, scoreGained, highScore, highestTile }: ({ score: number, highScore: number, highestTile: number, scoreGained: number | null, turns: number, start: EventHandler })) {\n const ref = useRef();\n const elem = ref.current as any as SVGTextElement;\n\n const [scoreGainedPopups, setScoreGainedPopups] = useState([]);\n useEffect(() => {\n if (scoreGained) {\n setScoreGainedPopups((array) => array.concat({ score: scoreGained, turn: turns } as ScoreGainedInfo));\n setTimeout(() => {\n setScoreGainedPopups((array) => array.filter((item) => item.turn !== turns));\n }, 1000);\n }\n }, [turns, scoreGained]);\n\n return (\n \n \n \n \n Score: {score}\n Record: {highScore} ({ highestTile } Tile)\n {\n scoreGainedPopups.map((item) => {\n return +{item.score}\n })\n }\n \n \n \n RESTART\n \n \n )\n}\n\nexport default connect(\n (state: IStore) => ({\n score: state.game.score,\n highScore: state.game.highScore,\n highestTile: state.game.highestTile,\n scoreGained: state.game.scoreGained,\n turns: state.game.turns,\n }),\n { start }\n)(Header);\n","import React, { useState, useCallback } from 'react'\nimport styles from '../css/App.module.css';\nimport Board from './Board';\nimport Input from './Input';\nimport Header from './Header';\nimport { motion } from 'framer-motion';\nimport clsx from 'clsx';\n\nconst easeInOutQuint = [0.86, 0, 0.1, 1];\n\nfunction DuplicateMagic({ children }: { children: JSX.Element[] | JSX.Element}) {\n return <>\n
\n {children}\n
\n
\n {children}\n
\n \n}\n\nexport default function App() {\n const [expanded, setExpanded] = useState(false);\n\n const toggleExpanded = useCallback((ev) => {\n ev.preventDefault();\n setExpanded(x => !x);\n }, []);\n\n return (\n
\n

2048

\n

\n Join the numbers and get to the 2048 tile! This is an experiment to\n learn Redux and some better coding\n practices.\n

\n\n \n \n

\n Previously, I have never used Redux, but I somehow learned the basics somewhat well, and\n implemented a copy of 2048 in about no time. Once I had all the game mechanics done, I\n started building the game UI.\n

\n

\n For the Game UI, I designed it all myself with Figma,\n exported it into a couple of React Components, and then animated it\n with Framer Motion. A couple more reducer tweaks\n later, and then you got a full game.\n

\n

\n The game is open sourced on GitHub, so you can see how I programmed it. And it's not that\n bad of code, I'd say at least.\n

\n
\n
\n \n\n

\n \n {expanded ? 'Play the Game' : 'Read More'}\n \n {\n \n {' | '}\n \n More Content\n \n \n }\n

\n\n \n
\n \n \n \n \n
\n )\n}\n","import { combineReducers } from 'redux';\nimport { ActionObject, Type } from '../actions';\nimport { IStore } from '../store';\n\nconst rootReducer = combineReducers({\n game: require('./game').default,\n});\n\nexport default function (state: IStore, action: ActionObject) {\n if (state === undefined) {\n if (localStorage['2048_save_file']) {\n return rootReducer(JSON.parse(localStorage['2048_save_file']), action);\n }\n }\n const newState = rootReducer(state, action);\n localStorage['2048_save_file'] = JSON.stringify(rootReducer(state, { type: Type.GET_SAVE_FILE }));\n return newState;\n}\n","import { createStore, Reducer } from 'redux';\nimport { IGame } from './reducers/game';\nimport rootReducer from './reducers';\nimport { ActionObject } from './actions';\n\nconst reduxDevTools = ((window as any).__REDUX_DEVTOOLS_EXTENSION__) as (Function | undefined);\n\nconst store = createStore(\n rootReducer as Reducer,\n reduxDevTools ? reduxDevTools() : undefined,\n);\n\nexport default store;\n\nexport interface IStore {\n game: IGame,\n}\n","import 'array-flat-polyfill';\nimport 'core-js';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './components/App';\nimport { Provider } from 'react-redux';\nimport store from './store';\nimport './css/index.css';\n\nReactDOM.render(\n ,\n document.getElementById('root')\n);\n"],"sourceRoot":""}