U)a*OD(eYgSi^cdTn}pqcPM(;S)2%1By^Wh%-CaC%>d9hi`7J zaxL7@;nhA>PE%s99&;z{8>VFgf{u!(-B-x7Of6ueme+ScryL`h(^qKE)DtieWY>-7 zgB)VJESQS4*1LU(2&@pgLvSt{(((C?K_V(rQk``i&5}ZPG;G^FiPlZ$7|-vEmMWlU z5lQ%iK2nu=h2wd_7>gK@vX=*AG+u~rQP$NwPC`ZA?4nh{3tui1x@bT6-;Rk3yDQ>d z?3qRD#+PeV7#FAa>s`Xwxsx_oRFcN$StW2=CW`=qObsT?SD^#^jM1Yk}PSPxJ zG@-_mnNU_)vM|iLRSI>UMp|hatyS}17R{10IuL0TLlupt>9dR s_SPQbv7BLYyC#qv16E-y@XZ= z-!p7I%#r-BVi$nQq3&ssRc_IC%R6$tA&^s_l46880~Wst3@>(|EO<}T4~ci~#!=e; zD)B>o%1+$ksURD1p7I-<3ehlFyVkqrySf&gg>Bp
0Z9?JaG|gyTZ{Cb8SdvAWVmFX7v2ohs!OCc!Udk zUITUpmZ33rKLI#(&lDj}c KA#dpL4Fil=$5pu_wi1XJR !llw` zSItPBDEdMHk2>c7#%lBxZ HHvtVUOZ$}v?=?AT~9!Jcqa@IJGuMg(s^7r>pcTrd)pS`{5Cu8WPey` z9)!!OUUY@L%9Q+bZa*S5`3f_|lFCPN6kdp_M2>{le8;cn^XUsPa+TUk47qd6)IBR% zk*&Ip?!Ge_gmmdj)BX}P_5o@VI2*wbZ^>UhFju}0gQZh!pP%4XT9{@w;G#b3XK8sN zF(7i$Jv(IM$8Akys9dhP^^~H2(7BfJp}yDW1#@!CL-!mGcSCnJ599WK9MV@yo_u$v MDeX2GIKR{Qf5okjU;qFB literal 0 HcmV?d00001 diff --git a/game-of-life/public/index.html b/game-of-life/public/index.html new file mode 100644 index 000000000..aa069f27c --- /dev/null +++ b/game-of-life/public/index.html @@ -0,0 +1,43 @@ + + + + + + + + + + + + + React App + + + + + + + diff --git a/game-of-life/public/logo192.png b/game-of-life/public/logo192.png new file mode 100644 index 0000000000000000000000000000000000000000..fc44b0a3796c0e0a64c3d858ca038bd4570465d9 GIT binary patch literal 5347 zcmZWtbyO6NvR-oO24RV%BvuJ&=?+<7=`LvyB&A_#M7mSDYw1v6DJkiYl9XjT!%$dLEBTQ8R9|wd3008in6lFF3GV-6mLi?MoP_y~}QUnaDCHI#t z7w^m$@6DI)|C8_jrT?q=f8D?0AM?L)Z}xAo^e^W>t$*Y0KlT5=@bBjT9kxb%-KNdk zeOS1tKO#ChhG7%{ApNBzE2ZVNcxbrin#E1TiAw#BlUhXllzhN$qWez5l;h +t^q#Eav8PhR2|T}y5kkflaK`ba-eoE+Z2q@o6P$)=&` z+(8}+-McnNO>e#$Rr{32ngsZIAX>GH??tqgwUuUz6kjns|LjsB37zUEWd|(&O!)DY zQLrq%Y>)Y8G`yYbYCx&aVHi@-vZ3|ebG!f$sTQqMgi0hWRJ^Wc+Ibv!udh_r%2|U) zPi|E^PK?UE!>_4`f`1k4hqqj_$+d!EB_#IYt;f9)fBOumGNyglU(ofY`yHq4Y?B%- zp&G!MRY<~ajTgIHErMe(Z8JG*;D-PJhd@RX@QatggM7+G(Lz8eZ;73)72Hfx5KDOE zkT(m}i2;@X2AT5fW?qVp?@WgN$aT+f_6eo?IsLh;jscNRp|8H}Z9p_UBO^SJXpZew zEK8fz|0Th%(Wr|KZBGTM4yxkA5CFdAj8=QSrT$fKW#tweUFqr0TZ9D ~a5lF{)%-tTGMK^2tz(y2v$i%V8XAxIywrZCp=)83p(zIk6@S5AWl|Oa2hF`~~^W zI;KeOSkw1O#TiQ8;U7OPXjZM|KrnN}9arP)m0v$c|L)lF`j_rpG(zW1Qjv$=^|p*f z>)Na{D&>n`jOWMwB^TM}slgTEcjxTlUby89j1)|6ydRfWERn3|7Zd2&e7?!K&5G$x z`5U3uFtn4~SZq|LjFVrz$3iln-+ucY4q$BC{CSm7Xe5c1J<=%Oagztj{ifpaZk_bQ z9Sb-LaQMKp-qJA*bP6DzgE3`}*i1o3GKmo2pn@dj0;He}F=BgINo};6gQF8!n0ULZ zL>kC0nPSFzlcB7p4 1doao2F7%6IUTi_+!L`MM4o*#Y#0v~WiO8 uSeAUNp=vA2KaR&=jNR2iVwG>7t%sG2x_~yXzY)7K& zk3p+O0AFZ1eu^T3s};B %6TpJ6h-Y%B^*zT&SN7C=N;g|#dGIVMSOru3iv^SvO>h4 M=t-N1GSLLDqVTcgurco6)3&XpU!FP6Hlrmj}f$ zp95;b)>M~`kxuZF3r~a!rMf4|&1=uMG$;h^g=Kl;H&Np-(pFT9FF@++MMEx3R BsK?AU0fPk-#mdR)Wdkj)`>ZMl#^<80kM87VvsI3r_c@_vX=fdQ`_9-d(xiI z4K;1y1TiPj_RPh*SpDI7U~^QQ?%0&!$Sh#?x_@;ag)P}ZkAik{_WPB4rHyW#%>|Gs zdbhyt=qQPA7`?h2_8T;-E6HI#im9K>au*(j4;kzwMSLgo6u*}-K`$_Gzgu&XE)udQ zmQ72^eZd|vzI)~!20JV-v-T|<4@7ruqrj|o4=JJPlybwMg;M$Ud7>h6g()CT@wXm` zbq=A(t;RJ^{Xxi*Ff~!|3!-l_PS{AyNAU~t{h;(N(PXMEf^R(B+ZVX3 z8y0;0A8hJYp@g+c*`>eTA|3Tgv9U8#BDTO9@a@gVMDxr(fVaEqL1tl?md{v^j8aUv zm&%PX4^| rX|?E4^CkplWWNv*OKM>DxPa z!RJ)U^0-WJMi)Ksc!^ixOtw^egoAZZ2Cg;X7(5xZG7yL_;UJ#yp*ZD-;I^Z9qkP`} zwCTs0*%rIVF1sgLervtnUo&brwz?6?PXRuOCS*JI-WL6GKy7-~yi0giTEMmDs_-UX zo=+nFrW_EfTg>oY72_4Z0*uG>MnXP=c0VpT&*|rvv1i StW;*^={rP 1y?Hv+6R6bxFMkxpWkJ>m7Ba{>zc_q zEefC3jsXdyS5??Mz7IET$Kft|EMNJIv7Ny8ZOcKnzf`K5Cd)&`-fTY#W&jnV0l2vt z?Gqhic}l}mCv1yUEy$%DP}4AN;36$=7aNI^*AzV(eYGeJ(Px-j<^gSDp5dBAv2#?; zcM Xv#aj>%;MiG^q^$0MSg-(uTl!xm49dH!{X0){Ew7ThWV~Gtj7h%ZD zVN-R-^7Cf0VH!8O)uUHPL2mO2tmE*cecwQv_5CzWeh)ykX8r5Hi`ehYo)d{Jnh&3p z9ndXT$OW51#H5cFKa76c<%nNkP~ FU93b5h-|Cb}ScHs@4Q#|}byWg;KDMJ#|l zE=MKD0c>*F@HDBcX@~QJH%56eh~jfPO-uKm}~t7Vk HxHT;)4sd+?Wc4* z>CyR*{w@4(gnYRdFq=^(#-ytb^5ESD?x<0Skhb%Pt?npNW1m+Nv`tr9+qN<3H1f<% zZvNEqyK5F gPsQ`QIu9P0x_}wJR~^CotL|n zk?dn;tLRw9jJTur4uWoX6iMm914f0AJfB@C74a;_qRrAP4E7l890P&{v<}>_&GLrW z)klculcg`?zJO~4;BBAa=POU%aN|pmZJn2{hA!d!*lwO%YSIzv8bTJ}=nhC^n }g(ld^rn#kq9Z3)z`k9lvV>y#!F4e{5c$tnr9M{V)0m(Z< z#88vX6-AW7T2UUwW`g<;8I$Jb!R%z@rCcGT)-2k7&x9kZZT66}Ztid~6t0jKb&9mm zpa}LCb`bz`{MzpZR#E*QuBiZXI#<`5qxx=&LMr-UUf~@dRk}YI2hbMsAMWOmDzYtm zjof16D=mc`^B$+_bCG$$@R0t;e?~UkF?7<(vkb70*EQB1rfUWXh$j)R2)+dNAH5%R zEBs^?N;UMdy}V};59Gu#0$q53$}|+q7CIGg_w_WlvE}AdqoS<7DY1LWS9?TrfmcvT zaypmplwn=P4;a8-%l^e?f`OpGb}%(_mFsL&GywhyN(-VROj`4~V~9bGv%UhcA|YW% zs{;nh@aDX11y^HOF XB$a7#Sr3cEtNd4eLm@Y#fc&j)TGvbbMwze zXtekX_wJqxe4NhuW$r}cNy|L{V=t#$%SuWEW)YZTH|!iT79k#?632OFse{+BT_gau zJwQcbH{b}dzKO?^dV&3nTILYlGw{27UJ72ZN){BILd_HV_s$WfI2DC<9LIHFmtyw? zQ;?MuK7g%Ym+4e^W#5}WDLpko%jPOC=aN)3!=8)s#Rnercak&b3ESRX3z{xfKBF8L z5%CGkFmGO@x?_mPGlpEej!3!AMddChabyf~nJNZxx!D&{@xEb!TDyvqSj%Y5@A{}9 zRzoBn0?x}=krh{ok3Nn%e)#~uh;6jpezhA)ySb^b#E>73e*frBFu6IZ^D7Ii&rsiU z%jzygxT-n*joJpY4o&8UXr2s%j^Q{?e- voloX`4DQyEK+DmrZh8A$) iWL#NO9+Y@!sO2f@rI!@jN@>HOA< z?q2l{^%mY*PNx2FoX+A7X3N}(RV$B`g&N=e0uvAvEN1W^{*W?zT1i#fxuw10%~))J zjx#gxoVlXREWZf4hRkgdHx5V_S*;p-y%JtGgQ4}lnA~MBz-AFdxUxU1RIT$`sal|X zPB6sEVRjGbXIP0U+?rT|y5+ev&OMX*5C$n2SBPZr`jqzrmpVrNciR0e*Wm?fK6DY& zl(XQZ60yWXV-|Ps!A {EF;=_z(YAF=T(-MkJXUoX zI{UMQDAV2}Ya?EisdEW;@pE6dt;j0fg5oT2dxCi{wqWJ<)|SR6fxX~5CzblPGr8cb zUBVJ2CQd~3L?7yfTpLNbt)He1D>*KXI^GK%<`bq^cUq$Q@uJifG>p3LU(!H=C)aEL zenk7pVg}0{dKU}&l)Y2Y2eFMdS( JS0}oZUuVaf2+K*YFNGHB`^YGcIpnBlMhO7d4@vV zv(@N}(k#REdul8~fP+^F@ky*wt@~&|(&&meNO>rKDEnB{ykAZ}k>e@lad7to>Ao$B zz<1(L=#J*u4_LB=8w+*{KFK^u00NAmeNN7pr+Pf+N*Zl^dO{LM-hMHyP6N!~`24jd zXYP|Ze;dRXKdF2iJG$U{k=S86l@pytLx}$JFFs8e)*Vi?aVBtGJ3JZUj!~c{ (rw5>vuRF$`^p!P8w1B=O!skwkO5yd4_XuG^QVF z`-r5K7(IPSiKQ2|U9+`@Js! g6sfJwAHVd|s?|mnC*q zp|B|z)(8+mxXyxQ{8Pg3F4|tdpgZZSoU4P&9I8)nHo1@)9_9u&NcT^FI)6|hsAZFk zZ+arl&@*>RXBf-OZxhZerOr&dN5LW9@gV=oGFbK*J+m#R-|e6(Loz(;g@T^*oO)0R zN`N=X46b{7yk5FZGr#5&n1!-@j@g02g|X>MOpF3#IjZ_4wg{dX+G9eqS+Es9@6nC7 zD9$NuVJI}6ZlwtUm5cCAiYv0(Yi{%eH+}t)!E^>^KxB5^L~a`4%1~5q6h>d;paC9c zTj0wTCKrhWf+F#5>EgX `sl%POl?oyCq0(w0xoL?L%)|Q7d|Hl92rUYAU#lc**I&^6p=4lNQPa0 znQ|A~i0ip@`B=FW-Q;zh?-wF;Wl5!+q3GXDu-x&}$gUO)NoO7^$BeEIrd~1Dh{Tr` z8s<(Bn@gZ(mkIGnmYh_ehXnq78QL$pNDi)|QcT*|GtS%nz1uKE+E{7jdEBp%h0}%r zD2|KmYGiPa4;md-t_m5YDz#c*oV_FqXd85d@eub?9N61QuYcb3CnVWpM(D-^|CmkL z(F}L&N7qhL2PCq)fRh}XO@U`Yn< ?TNGR4L(mF7#4u29{i~@k;pLsgl({YW5`Mo+p=zZn3L*4{JU;++dG9 X@eDJUQo;Ye2mwlRs ?y0|+_a0zY+Zo%Dkae}+MySoIppb75o?vUW_?)>@g{U2`ERQIXV zeY$JrWnMZ$QC<=ii4X|@0H8`si75jB(ElJb00H AB%>SlLR{!zO|C9P3zxw_U8?1d8uRZ=({Ga4shyN}3 zAK}WA(ds|``G4jA)9}Bt2Hy0+f3rV1E6b|@?hpGA=PI&r8)ah|)I2s(P5Ic*Ndhn^ z*T&j@gbCTv7+8rpYbR^Ty}1AY)YH;p!m948r#%7x^Z@_-w{pDl|1S4`EM3n_PaXvK z1JF)E3qy$qTj5Xs{jU9k=y%SQ0>8E$;x?p9ayU0bZZeo{5Z@&FKX>}s!0+^>C^D#z z>xsCPvxD3Z=dP}TTOSJhNTPyVt14VCQ9MQFN`rn!c&_p?&4<5_PGm4a;WS&1(!qKE z_H$;dDdiPQ!F_gsN`2>`X}$I=B;={R8%L~`>RyKcS$72ai$!2>d(YkciA^J0@X%G4 z4cu!%Ps~2JuJ8ex`&;Fa0NQOq_nDZ&X;^A=oc1&f#3P1(!5il>6?uK4QpEG8z0Rhu zvBJ+A9RV?z%v?!$=(vcH?*;vRs*+PPbOQ3cdPr5=tOc Lqmfx@#hOqX0iN)wTTO21jH<>jpmwRIAGw7`a|sl?9y9zRBh>(_%| zF?h|P7}~RKj?HR+q|4U`CjRmV-$mLW>MScKnNXiv{vD3&2@*u)-6P@h0A`eeZ7}71 zK(w%@R<4lLt`O7fs1E)$5iGb~fPfJ?WxhY7c3Q>T-w#wT&zW522pH-B%r5v#5y^CF zcC30Se|`D2mY$hAlIULL%-PNXgbbpRHgn<&X3N9W!@BUk@9g*P5mz-YnZBb*-$zMM z7Qq}ic0mR8n{^L|=+diODdV}Q!gwr?y+2m=3HWwMq4z)DqYVg0J~^}-%7rMR@S1;9 z7GFj6K}i32X;3*$SmzB&HW{PJ55kT+EI#SsZf} bD7nW^Haf}_gXciYKX{QBxIPSx2 Ma? zHQqgzZq!_{&zg{yxqv3xq8YV+`S}F6A>Gtl39_m;K4dA{pP$BW0oIXJ>jEQ!2V3A2 zdpoTxG&V=(?^q?ZTj2ZUpDUdMb)T?E$}CI>r@}PFPWD9@*%V6;4Ag>D#h>!s)=$0R zRXvdkZ%|c}ubej`jl?cS$onl9Tw52rBKT)kgyw~Xy%z62Lr%V6Y=f?2)J|bZJ5(Wx zmji`O;_B+*X@qe-#~`HFP<{8$w@z4@&`q^Q-Zk8JG3>WalhnW1cvnoVw>*R@c&|o8 zZ%w!{Z+M HeZ*OE4v *otkZqz11*s!#s^Gq>+o`8Z5 z^i-qzJLJh9!W- ;SmFkR 8HEZ JWiXk$40i6)7 zZpr=k2lp}SasbM*Nbn3j$sn0;rUI;%EDbi7T1ZI4qL6PNNM2Y%6{LMIKW+FY_yF3) zSKQ2 QSujzNMSL2r&bYs`|i2Dnn z=>}c0>a}>|uT!IiMOA~pVT~R@bGlm}Edf}Kq0?*Af6#mW9f9!}RjW7om0c9Qlp;yK z)=XQs(| 6GCadQbWIhYF=rf{Y)sj%^Id-ARO0=O^Ad;Ph+ z0?$eE1xhH?{T$QI>0JP75`r)U_$#%K1^BQ8z#uciKf(C701&RyLQWBUp*Q7eyn76} z6JHpC9}R$J#(R0cDCkXoFSp;j6{x{b&0yE@P7{;pCEpKjS(+1RQy38`=&Yxo%F=3y zCPeefABp34U-s?WmU#JJw2 3dcC{sPPFc2#J$ZgEN%zod}J~8dLm*fx9f6SpO zn^Ww3bt9-r0XaT2a@Wpw;C23XM}7_14#%QpubrIw5aZtP+CqIFmsG4`Cm6rfxl9n5 z7=r2C-+lM2AB9X0T_`?EW&Byv &K?HS4QLoylJ|OAF z`8atBNTzJ&AQ !>sOo$?^0xj~D(;kS$`9zbEGd>f6r`NC3X`tX)sWgWUUOQ7w=$TO &*j;=u%25ay-%>3@81tGe^_z*C7pb9y*Ed^H3t$BIKH2o+olp#$q;)_ zfpjCb_^VFg5fU~K)nf*d*r@BCC>UZ!0&b?AGk_jTPXaSnCuW110wjHPPe^9R^;jo3 zwvzTl)C`Zl5}O2}3lec=hZ*$JnkW#7enKKc)(pM${_$9Hc=Sr_A9Biwe*Y=T?~1CK z6eZ9uPICjy-sMGbZl$yQmpB&`ouS8v{58__t0$JP%i3R&%QR3ianbZqDs<2#5FdN@n5bCn^ZtH992~5k(eA|8|@G9u`wdn7bnpg|@{m z^d6Y`*$Zf2Xr&|g%sai#5}Syvv(>Jnx&EM7-|Jr7!M~zdAyjt*xl;OLhvW-a%H1m0 z*x5*nb=R5u><7lyVpN AR?q@1U59 zO+)QW wL8t zyip?u_nI+K$uh{ y)~}qj?(w0&=SE^8`_WMM zTybjG=999h38Yes7}-4*LJ7H)UE8{mE(6;8voE+TYY%33A>S6`G_95^5QHNTo_;Ao ztIQIZ_}49%{8|=O;isBZ?=7kfdF8_@azfoTd+hEJKWE!)$)N%HIe2cplaK`ry#=pV z0q{9w-`i0h@!R8K3GC{ivt{70IWG`EP |(1g7i_Q<>aEAT{5( yD z=!O?kq61VegV+st@XCw475j6vS)_z@efuqQgHQR1T4;|-#OLZNQJPV4k$AX1Uk8Lm z{N*b*ia=I+MB}kWpupJ~>!C@xEN#Wa7V+7{m4j8c?)ChV=D?o~sjT?0C_AQ 7B-vxqX30s0I_`2$in86#`mAsT-w?j{&AL@B3$;P z31G4(lV|b}uSD CIrjk+M1R!X7s 4Aabn<)zpgT}#gE|mIvV38^ODy@<&yflpCwS#fRf9ZX3lPV_?8@C5)A;T zqmouFLFk;qIs4rA=hh=GL~sCFsXHsqO6_y~*AFt93 9UYVBSx1s(=Kb&5;j7cSowdE;7()CC2|-i9Zz+_BIw8#ll~-tyH?F3{%`QCsYa*b#s*9iCc`1P1oC26?`g<9))EJ3%xz+O!B3 zZ7$j~To)C@PquR>a1+Dh>-a%IvH_Y7^ys|4o?E%3`I&ADXfC8++hAdZfzIT#%C+Jz z1lU~K_vAm0m8Qk}K$F>| >RPK%<1SI0(G+8q~H zAsjezyP+u!Se4q3GW)`h`NPSRlMoBjCzNPesWJwVTY!o@G8=(6I%4XHGaSiS3MEBK zhgGFv6Jc>L$4jVE!I?TQuwvz_%CyO!bLh94nqK11C2W$*aa2ueGopG8DnBICVUORP zgytv#)49fVXDaR$SukloYC3u7#5H)}1K21=?DKj^U)8G;MS)&Op)g^zR2($<>C*zW z;X7`hLxiIO#J`ANdyAOJle4V%ppa*(+0i3w;8i*BA_;u8gOO6)MY`ueq7stBMJTB; z-a0R>hT*}>z|Gg}@^zDL1MrH+2hsR8 zHc}*9IvuQC^Ju)^#Y{fOr(96rQNPNhxc;mH@W*m206>Lo<*SaaH?~8zg&f&%YiOEG zGiz?*CP>Bci}!WiS=zj#K5I}>DtpregpP_tfZtPa(N<%vo^#WCQ5BTv0vr%Z{)0q+ z)RbfHktUm|lg&U3YM%lMUM(f u}i#kjX9h>GYctkx9Mt_8{@s%!K_EI zScgwy6%_fR?CG JQtmgNAj^h9B#zma MDWgH55pGuY1Gv7D z;8Psm(vEPiwn#MgJYu4Ty9D|h!?Rj0ddE|&L3S{IP%H4^N!m`60ZwZw^;eg4sk6K{ ziA^`Sbl_4~f&Oo%n;8Ye(tiAdlZKI!Z=|j$5hS|D$bDJ}p{gh$KN&JZYLUjv4h{NY zBJ>X9z !xfDGY z+oh_Z&_e#Q(-}>ssZfm=j$D&4W4FNy&-kAO1~#3Im;F)Nwe{(*75(p=P^VI?X 0GFakfh+X-px4a%Uw@fSbmp9hM1_~R>?Z8+ ziy|e9>8V*`OP}4x5JjdWp}7eX;lVxp5qS} 0YZek;SNmm7tEeSF*-dI)6U-A%m6YvCgM(}_=k#a6o^%-K4{`B1+}O4x zztDT%hVb;v#?j`lTvlFQ3aV#zkX=7 ;YFLS$uIzb0E3lozs5`Xy zi~vF+%{z9uLjKvKPhP%x5f ~7-Gj+%5N`%^=yk*Qn{`> z;xj&ROY6g`iy2a@{O)V(jk&8#hHACVDXey5a+KDod_Z&}kHM}xt7}Md@pil{2x7E~ zL$k^d2@Ec2XskjrN+IILw;#7((abu;OJii&v3?60x>d_Ma(onIPtcVnX@ELF0aL?T zSmWiL3(dOFkt!x=1O!_0n(cAzZW+3nHJ{2S>tgSK?~cF ha^y(l@-Mr2W$%MN{#af8J;V*>hdq!gx=d0h$T7l}>91Wh07)9CTX zh2_ZdQCyFOQ)l(}gft0UZ G`Sh2`x-w`5vC2UD}lZs*5 zG76$akzn}Xi))L3oGJ75#pcN=cX3!=57$Ha=hQ2^lwdyU#a}4JJOz6ddR%zae%#4& za)bFj)z=YQela(F#Y|Q#dp}PJghITwXouVaMq$BM?K%cXn9^Y@g43$=O)F&ZlOUom zJiad#dea;-eywBA@e&D6Pdso1?2^(pXiN91?jvcaUyYoKUmvl5G9e$W!okWe*@a<^ z8cQQ6cNSf+UPDx%?_G4a IiybZHHagF{ ;IcD(dPO!#=u zWfqLcPc^+7Uu#l(B pxft{*4lv#*u7X9AOzDO z1D9?^jIo}?%iz(_dwLa{ex#T}76ZfN_Z-hwpus9y+4xaUu9cX}&P{XrZVWE{1^0yw zO;YhLEW!pJcbCt3L8~a7>jsaN{V3>tz6_7`&pi%GxZ=V3?3K^ U+*ryLSb)8^IblJ0 zSRLNDvIxt)S}g30?s_3NX>F?NKIGrG_zB9@Z>uSW3k2es_H2kU;Rnn%j5qP)!XHKE zPB2mHP~tLCg4K_vH$xv`HbRsJwbZMUV(t=ez;Ec(vyHH)FbfLg`c61I$W_uBB>i^r z&{_P;369-&>23R%qNIULe=1~T$(DA`ev*EWZ6j(B$(te}x1WvmIll21zvygkS%vwG zzkR6Z#RKA2!z!C%M!O>!=Gr0(J0FP=-MN=5t-Ir)of50y10W}j`GtRCsXBakrKtG& zazmITDJMA0C51&BnLY)SY9r)NVTMs);1<=oosS9g31l{4ztjD3#+2H7u_|66b|_*O z;Qk6nalpqdHOjx|K&vUS_6ITgGll;TdaN*ta=M_YtyC)I9Tmr~VaPrH2q b6sd~=AcIxV+%z{E&0@y=DPArw zdV7z(G1hBx7hd{>(cr43^WF%4Y@PXZ?wPpj{OQ#tvc$pABJbvPGvdR`cAtHn)cSEV zrpu}1tJwQ3y!mSmH*uz*x0o|CS<^w%&KJzsj~DU0cLQUxk5B!hWE>aBkjJle8z~;s z-!A=($+}Jq_BTK5^B!`R>!MulZN)F=iXXeUd0w5lUsE5VP*H*oCy( ;?S$p*TVvTxwAeWFB$jHyb0593)$zqalVlDX=GcCN1gU0 zlgU)I$LcXZ8Oyc2TZYTPu@-;7<4YYB-``Qa;IDcvydIA$%kHhJKV^m*- zxcvU4viy &Kr5GVM{IT>WRywKQ9;>SEiQD*NqplK-KK4YR`p0@JW)n_{TU3bt0 zim%;(m1=#v2}zTps=?fU5w^(*y)xT%1vtQH&}50ZF!9YxW=&7*W($2kgKyz1mUgfs zfV<*XVVIFnohW=|j+@Kfo!#liQR^x>2yQdrG;2o8WZR+XzU_nG=Ed2rK?ntA;K5B{ z>M8+*A4 !Jm^Bg}aW?R?6;@QG@uQ8&oJ{hFixcfEnJ4QH?A4>P=q29oDGW;L;= z9-a0;g%c`C+Ai!UmK$NC*4#;Jp<1=TioL=t^YM)<<%u#hnnfSS`nq63QKGO1L8RzX z@MFDq s1z ztYmxDl@LU)5acvHk)~Z`RW7=aJ_nGD!mOSYD>5Odjn@TK#LY{jf?+piB5AM-CAoT_ z?S-*q7}wyLJzK>N%eMPuFgN)Q_otKP;aqy=D5f! 7<=n(lNkYRXVpkB{TAYLYg{|(jtRqYmg$xH zjmq ?B(RE4 zQx^~Pt}gxC2~l=K$$-sYy_r$CO(d=+b3H1MB*y_5g6WLaWTXn+TKQ|hNY^>Mp6k*$ zwkovomhu776vQATqT4blf~g;TY(MWCrf^^yfWJvSAB$p5l;jm@o#=!lqw+Lqfq>X= z$6~kxfm7`3q4zUEB;u4qa#BdJxO!;xGm)wwuisj{0y2x{R(IGMrsIzDY9LW>m!Y`= z04sx3IjnYvL<4JqxQ8f7qYd0s2Ig%`ytYPEMKI)s(LD}D@EY>x`VFtqvnADNBdeao zC96X+MxnwKmjpg{U&gP3HE}1=s!lv&D{6(g_lzyF3A`7Jn*&d_kL<;dAFx!UZ>hB8 z5A*%LsAn;VLp>3${0>M?PSQ)9s3}|h2e?TG4_F{}{Cs>#3Q*t$(CUc}M)I}8cPF6% z=+h(Kh^8)}gj(0}#e7O^FQ6`~fd1#8#!}LMuo3A0bN`o}PYsm!Y}sdOz$+Tegc=qT z8x`PH$7lvnhJp{kHWb22l;@7B7|4yL4UOOVM0MP_>P%S1Lnid)+k9{+3D+JFa#Pyf zhVc#&df87APl4W9X)F3pGS>@etfl=_E5tBcVoOfrD4hmVeTY-cj((pkn%n@EgN{0f zwb_^Rk0I#i ZuHK!l*lN`ceJn(sI{$Fq6nN& zE<-=0_2WN}m+*ivmIOxB@#~Q-cZ>l136w{#TIJe478`KE7@=a{>SzPHsKLzYAyBQO zAtuuF$-JSDy_S@6GW0MOE~R)b;+0f%_NMrW(+V#c_d&U8Z9+ec4=HmOHw?gdjF(Lu zzra 83M_BoO-1b3;9`%&DHfuUY)6YDV21P$C!Rc?mv&{lx#f8oc6?0?x zK08{WP65?#>(vPfA-c=MCY| %*1_<3D4NX zeVTi-JGl2uP_2@0F{G({pxQOXt_d{g_CV6b?jNpfUG9;8yle-^4KHRvZs-_2siata zt+d_T@U$&t*xaD22(fH(W1r$Mo?3dc%Tncm=C6{V9y{v&VT#^1L04vDrLM9qBoZ4@ z6DBN#m57hX7$C(=#$Y5$bJmwA$T8jKD8+6A!-IJwA{WOfs%s}yxUw^?MRZjF$n_KN z6`_bGXcmE#5e4Ym)aQJ)xg3Pg0@k`iGuHe?f(5LtuzSq=nS^5z>vqU0EuZ&75V%Z{ zYyhRLN^)$c6Ds{f7*FBpE;n5iglx5PkHfWrj3`x^j^t z7ntuV`g!9Xg#^3!x)l*}IW=(Tz3>Y5l4uGaB&lz{GDjm2D5S$CExLT`I1#n^lBH7Y zDgpMag@`iETKAI=p<5E#LTkw zVR@=yY|uBVI1HG|8h+d;G-qfuj}-ZR6fN>EfCCW z9~wRQoAPEa#aO?3h?x{YvV*d+NtPkf&4V0k4|L=uj!U{L+oLa(z#&iuhJr3-PjO3R z5s?=nn_5^*^Rawr>>Nr@K(jwkB#JK-=+HqwfdO<+P5byeim)wvqGlP-P|~Nse8=XF zz`?RYB|D6SwS}C+YQv+;}k6$-%D(@+t14BL@vM z2q%q?f6D-A5s$_WY3{^G0F131bbh|g!}#BKw=HQ7mx;Dzg4Z*bTLQSfo{ed{4}NZW zfrRm^Ca$rlE{Ue~uYv>R9{3s mwATcdM_6+yWIO z*ZRH~uXE@#p$XTbCt5j7j2=86e{9>HIB6xDzV+vAo&B?KUiMP|ttOElepnl%|DPqL b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN literal 0 HcmV?d00001 diff --git a/game-of-life/public/manifest.json b/game-of-life/public/manifest.json new file mode 100644 index 000000000..080d6c77a --- /dev/null +++ b/game-of-life/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/game-of-life/public/robots.txt b/game-of-life/public/robots.txt new file mode 100644 index 000000000..e9e57dc4d --- /dev/null +++ b/game-of-life/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/game-of-life/src/App.css b/game-of-life/src/App.css new file mode 100644 index 000000000..74b5e0534 --- /dev/null +++ b/game-of-life/src/App.css @@ -0,0 +1,38 @@ +.App { + text-align: center; +} + +.App-logo { + height: 40vmin; + pointer-events: none; +} + +@media (prefers-reduced-motion: no-preference) { + .App-logo { + animation: App-logo-spin infinite 20s linear; + } +} + +.App-header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; +} + +.App-link { + color: #61dafb; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/game-of-life/src/App.test.tsx b/game-of-life/src/App.test.tsx new file mode 100644 index 000000000..4db7ebc25 --- /dev/null +++ b/game-of-life/src/App.test.tsx @@ -0,0 +1,9 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import App from './App'; + +test('renders learn react link', () => { + const { getByText } = render( ); + const linkElement = getByText(/learn react/i); + expect(linkElement).toBeInTheDocument(); +}); diff --git a/game-of-life/src/App.tsx b/game-of-life/src/App.tsx new file mode 100644 index 000000000..b7d43553e --- /dev/null +++ b/game-of-life/src/App.tsx @@ -0,0 +1,116 @@ +import React, { useState, useCallback, useRef } from 'react'; +import produce, { current } from 'immer'; +const numRows = 50; +const numCols = 50; + +const operations = [ + [0,1], + [0, -1], + [1,-1], + [-1, 1], + [1, 1], + [-1,-1], + [1,0], + [-1,0] +]; +const generateEmptyGrid = () => { + const rows = []; + for (let i = 0; i < numRows; i++) { + rows.push(Array.from(Array(numCols), () => 0)); + } + return rows; +} +const App: React.FC = () => { + const [grid, setGrid] = useState(() => { + return generateEmptyGrid(); + }); + +const [running, setRunning] = useState(false); + +const runningRef = useRef(running); +runningRef.current = running + +const runSimulation = useCallback(() => { +if (!runningRef.current) { + return; +} +setGrid((g) => { +return produce(g, gridCopy => { + for (let i = 0; i < numRows; i++) { + for (let k = 0; k < numCols; k++) { + let neighbors = 0; + operations.forEach(([x, y]) => { + const newI = i + x; + const newK = k + y; + if (newI >= 0 && newI < numRows && newK >= 0 && newK < numCols) { + neighbors += g[newI][newK] + } + }) + + if (neighbors < 2 || neighbors > 3) { + gridCopy[i][k] = 0; + } else if (g[i][k] === 0 && neighbors === 3) { + gridCopy[i][k] = 1; + } + + + } + } +}) +}) + + // simulate + setTimeout(runSimulation, 100); +}, []) + return ( + <> + + + + + + + + + + {grid.map((rows, i) => rows.map((col, k) =>{ + const newGrid = produce(grid, gridCopy => { + gridCopy[i][k] = grid[i][k] ? 0 : 1; + }); + setGrid(newGrid); + }} + style={{width: 20, + height: 20, + backgroundColor: grid[i][k] ? 'black' : undefined, + border: "solid 1px black" + }} />) + )} ++ > + ); +} + +export default App; diff --git a/game-of-life/src/index.css b/game-of-life/src/index.css new file mode 100644 index 000000000..ec2585e8c --- /dev/null +++ b/game-of-life/src/index.css @@ -0,0 +1,13 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; +} diff --git a/game-of-life/src/index.tsx b/game-of-life/src/index.tsx new file mode 100644 index 000000000..f5185c1ec --- /dev/null +++ b/game-of-life/src/index.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import './index.css'; +import App from './App'; +import * as serviceWorker from './serviceWorker'; + +ReactDOM.render( ++ , + document.getElementById('root') +); + +// If you want your app to work offline and load faster, you can change +// unregister() to register() below. Note this comes with some pitfalls. +// Learn more about service workers: https://bit.ly/CRA-PWA +serviceWorker.unregister(); diff --git a/game-of-life/src/logo.svg b/game-of-life/src/logo.svg new file mode 100644 index 000000000..6b60c1042 --- /dev/null +++ b/game-of-life/src/logo.svg @@ -0,0 +1,7 @@ + diff --git a/game-of-life/src/react-app-env.d.ts b/game-of-life/src/react-app-env.d.ts new file mode 100644 index 000000000..6431bc5fc --- /dev/null +++ b/game-of-life/src/react-app-env.d.ts @@ -0,0 +1 @@ +///+ diff --git a/game-of-life/src/serviceWorker.ts b/game-of-life/src/serviceWorker.ts new file mode 100644 index 000000000..b09523f15 --- /dev/null +++ b/game-of-life/src/serviceWorker.ts @@ -0,0 +1,149 @@ +// This optional code is used to register a service worker. +// register() is not called by default. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on subsequent visits to a page, after all the +// existing tabs open on the page have been closed, since previously cached +// resources are updated in the background. + +// To learn more about the benefits of this model and instructions on how to +// opt-in, read https://bit.ly/CRA-PWA + +const isLocalhost = Boolean( + window.location.hostname === 'localhost' || + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.0/8 are considered localhost for IPv4. + window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ + ) +); + +type Config = { + onSuccess?: (registration: ServiceWorkerRegistration) => void; + onUpdate?: (registration: ServiceWorkerRegistration) => void; +}; + +export function register(config?: Config) { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL( + process.env.PUBLIC_URL, + window.location.href + ); + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebook/create-react-app/issues/2374 + return; + } + + window.addEventListener('load', () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + + if (isLocalhost) { + // This is running on localhost. Let's check if a service worker still exists or not. + checkValidServiceWorker(swUrl, config); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log( + 'This web app is being served cache-first by a service ' + + 'worker. To learn more, visit https://bit.ly/CRA-PWA' + ); + }); + } else { + // Is not localhost. Just register service worker + registerValidSW(swUrl, config); + } + }); + } +} + +function registerValidSW(swUrl: string, config?: Config) { + navigator.serviceWorker + .register(swUrl) + .then(registration => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + if (installingWorker == null) { + return; + } + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the updated precached content has been fetched, + // but the previous service worker will still serve the older + // content until all client tabs are closed. + console.log( + 'New content is available and will be used when all ' + + 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' + ); + + // Execute callback + if (config && config.onUpdate) { + config.onUpdate(registration); + } + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.'); + + // Execute callback + if (config && config.onSuccess) { + config.onSuccess(registration); + } + } + } + }; + }; + }) + .catch(error => { + console.error('Error during service worker registration:', error); + }); +} + +function checkValidServiceWorker(swUrl: string, config?: Config) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl, { + headers: { 'Service-Worker': 'script' } + }) + .then(response => { + // Ensure service worker exists, and that we really are getting a JS file. + const contentType = response.headers.get('content-type'); + if ( + response.status === 404 || + (contentType != null && contentType.indexOf('javascript') === -1) + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then(registration => { + registration.unregister().then(() => { + window.location.reload(); + }); + }); + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl, config); + } + }) + .catch(() => { + console.log( + 'No internet connection found. App is running in offline mode.' + ); + }); +} + +export function unregister() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready + .then(registration => { + registration.unregister(); + }) + .catch(error => { + console.error(error.message); + }); + } +} diff --git a/game-of-life/src/setupTests.ts b/game-of-life/src/setupTests.ts new file mode 100644 index 000000000..74b1a275a --- /dev/null +++ b/game-of-life/src/setupTests.ts @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom/extend-expect'; diff --git a/game-of-life/tsconfig.json b/game-of-life/tsconfig.json new file mode 100644 index 000000000..f2850b716 --- /dev/null +++ b/game-of-life/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react" + }, + "include": [ + "src" + ] +} From f5c130169b3dd48715e3126313df1166b6b4a04e Mon Sep 17 00:00:00 2001 From: Devin Cooper <37602228+DevinDCooper@users.noreply.github.com> Date: Wed, 26 Aug 2020 20:17:58 -0700 Subject: [PATCH 2/6] CSS_done_build_done --- game-of-life/README.md | 24 ++ game-of-life/package-lock.json | 54 ++--- game-of-life/package.json | 8 +- game-of-life/src/App.css | 50 ++--- game-of-life/src/App.js | 18 ++ .../src/{App.test.tsx => App.test.js} | 0 game-of-life/src/App.tsx | 116 ---------- game-of-life/src/Game.css | 50 +++++ game-of-life/src/Game.js | 206 ++++++++++++++++++ game-of-life/src/Space-Invaders.jpg | Bin 0 -> 33095 bytes game-of-life/src/index.css | 15 +- game-of-life/src/index.js | 8 + game-of-life/src/index.tsx | 17 -- game-of-life/src/react-app-env.d.ts | 1 - game-of-life/src/registerServiceWorker.js | 117 ++++++++++ .../{serviceWorker.ts => serviceWorker.js} | 18 +- .../src/{setupTests.ts => setupTests.js} | 0 game-of-life/tsconfig.json | 25 --- 18 files changed, 467 insertions(+), 260 deletions(-) create mode 100644 game-of-life/src/App.js rename game-of-life/src/{App.test.tsx => App.test.js} (100%) delete mode 100644 game-of-life/src/App.tsx create mode 100644 game-of-life/src/Game.css create mode 100644 game-of-life/src/Game.js create mode 100644 game-of-life/src/Space-Invaders.jpg create mode 100644 game-of-life/src/index.js delete mode 100644 game-of-life/src/index.tsx delete mode 100644 game-of-life/src/react-app-env.d.ts create mode 100644 game-of-life/src/registerServiceWorker.js rename game-of-life/src/{serviceWorker.ts => serviceWorker.js} (91%) rename game-of-life/src/{setupTests.ts => setupTests.js} (100%) delete mode 100644 game-of-life/tsconfig.json diff --git a/game-of-life/README.md b/game-of-life/README.md index 64e343e18..9c40dcdc3 100644 --- a/game-of-life/README.md +++ b/game-of-life/README.md @@ -42,3 +42,27 @@ You don’t have to ever use `eject`. The curated feature set is suitable for sm You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). To learn React, check out the [React documentation](https://reactjs.org/). + +### Code Splitting + +This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting + +### Analyzing the Bundle Size + +This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size + +### Making a Progressive Web App + +This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app + +### Advanced Configuration + +This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration + +### Deployment + +This section has moved here: https://facebook.github.io/create-react-app/docs/deployment + +### `yarn build` fails to minify + +This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify diff --git a/game-of-life/package-lock.json b/game-of-life/package-lock.json index fc2bedc60..f0aa6092c 100644 --- a/game-of-life/package-lock.json +++ b/game-of-life/package-lock.json @@ -1711,14 +1711,6 @@ "@types/istanbul-lib-report": "*" } }, - "@types/jest": { - "version": "24.9.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.9.1.tgz", - "integrity": "sha512-Fb38HkXSVA4L8fGKEZ6le5bB8r6MRWlOCZbVuWZcmOMSCd2wCYOwN1ibj8daIoV9naq7aaOZjrLCoCMptKU/4Q==", - "requires": { - "jest-diff": "^24.3.0" - } - }, "@types/json-schema": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", @@ -1730,9 +1722,9 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "12.12.54", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.54.tgz", - "integrity": "sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w==" + "version": "14.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.0.tgz", + "integrity": "sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA==" }, "@types/parse-json": { "version": "4.0.0", @@ -1750,9 +1742,9 @@ "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" }, "@types/react": { - "version": "16.9.46", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.46.tgz", - "integrity": "sha512-dbHzO3aAq1lB3jRQuNpuZ/mnu+CdD3H0WVaaBQA8LTT3S33xhVBUj232T8M3tAhSWJs/D/UqORYUlJNl/8VQZg==", + "version": "16.9.47", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.47.tgz", + "integrity": "sha512-dAJO4VbrjYqTUwFiQqAKjLyHHl4RSTNnRyPdX3p16MPbDKvow51wxATUPxoe2QsiXNMEYrOjc2S6s92VjG+1VQ==", "requires": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -4191,9 +4183,9 @@ } }, "csstype": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.2.tgz", - "integrity": "sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.3.tgz", + "integrity": "sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag==" }, "cyclist": { "version": "1.0.1", @@ -4649,9 +4641,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.544", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.544.tgz", - "integrity": "sha512-jx6H7M1db76Q/dI3MadZC4qwNTvpiq8tdYEJswxexrIm5bH+LKRdg+VAteMF1tJJbBLrcuogE9N3nxT3Dp1gag==" + "version": "1.3.547", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.547.tgz", + "integrity": "sha512-iIgTRpp3EZ6YE31zxBYHlWjODIF7RY4FaRuGpk2dnpwQL5wAL8iAGRPXkFgtK2mNQn1tEV6EFnSsk2DZVf2xuw==" }, "elliptic": { "version": "6.5.3", @@ -5330,9 +5322,9 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, "eventemitter3": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.5.tgz", - "integrity": "sha512-QR0rh0YiPuxuDQ6+T9GAO/xWTExXpxIes1Nl9RykNGTnE1HJmkuEfxJH9cubjIOQZ/GH4qNBR4u8VSHaKiWs4g==" + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.6.tgz", + "integrity": "sha512-s3GJL04SQoM+gn2c14oyqxvZ3Pcq7cduSDqy3sBFXx6UPSUmgVYwQM9zwkTn9je0lrfg0gHEwR42pF3Q2dCQkQ==" }, "events": { "version": "3.2.0", @@ -6539,9 +6531,9 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" }, "immer": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/immer/-/immer-7.0.7.tgz", - "integrity": "sha512-Q8yYwVADJXrNfp1ZUAh4XDHkcoE3wpdpb4mC5abDSajs2EbW8+cGdPyAnglMyLnm7EF6ojD2xBFX7L5i4TIytw==" + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/immer/-/immer-1.10.0.tgz", + "integrity": "sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg==" }, "import-cwd": { "version": "2.1.0", @@ -10399,11 +10391,6 @@ "path-exists": "^4.0.0" } }, - "immer": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/immer/-/immer-1.10.0.tgz", - "integrity": "sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg==" - }, "inquirer": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.4.tgz", @@ -12478,11 +12465,6 @@ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, - "typescript": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", - "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==" - }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", diff --git a/game-of-life/package.json b/game-of-life/package.json index 6f8ad1aa8..f7eb2ffc6 100644 --- a/game-of-life/package.json +++ b/game-of-life/package.json @@ -6,15 +6,9 @@ "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.3.2", "@testing-library/user-event": "^7.1.2", - "@types/jest": "^24.0.0", - "@types/node": "^12.0.0", - "@types/react": "^16.9.0", - "@types/react-dom": "^16.9.0", - "immer": "^7.0.7", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-scripts": "3.4.3", - "typescript": "~3.7.2" + "react-scripts": "3.4.3" }, "scripts": { "start": "react-scripts start", diff --git a/game-of-life/src/App.css b/game-of-life/src/App.css index 74b5e0534..1b590ce35 100644 --- a/game-of-life/src/App.css +++ b/game-of-life/src/App.css @@ -1,38 +1,18 @@ .App { + margin-left: 35%; + margin-top:150px; text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } + box-shadow: 3px 4px 0px 0px #101111; + background:linear-gradient(to bottom, #7892c2 5%, #476e9e 100%); + background-color:#7892c2; + border-radius:15px; + border:1px solid #4e6096; + display:inline-block; + cursor:pointer; + color:#ffffff; + font-family:Arial; + font-size:10px; + padding:7px 25px; + text-decoration:none; + text-shadow:0px 1px 0px #283966; } diff --git a/game-of-life/src/App.js b/game-of-life/src/App.js new file mode 100644 index 000000000..753636301 --- /dev/null +++ b/game-of-life/src/App.js @@ -0,0 +1,18 @@ +import React, { Component } from 'react'; +import './App.css'; +import Game from './Game'; + +class App extends Component { + + render() { + + return ( + ++ ); + } +} + +export default App; \ No newline at end of file diff --git a/game-of-life/src/App.test.tsx b/game-of-life/src/App.test.js similarity index 100% rename from game-of-life/src/App.test.tsx rename to game-of-life/src/App.test.js diff --git a/game-of-life/src/App.tsx b/game-of-life/src/App.tsx deleted file mode 100644 index b7d43553e..000000000 --- a/game-of-life/src/App.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import React, { useState, useCallback, useRef } from 'react'; -import produce, { current } from 'immer'; -const numRows = 50; -const numCols = 50; - -const operations = [ - [0,1], - [0, -1], - [1,-1], - [-1, 1], - [1, 1], - [-1,-1], - [1,0], - [-1,0] -]; -const generateEmptyGrid = () => { - const rows = []; - for (let i = 0; i < numRows; i++) { - rows.push(Array.from(Array(numCols), () => 0)); - } - return rows; -} -const App: React.FC = () => { - const [grid, setGrid] = useState(() => { - return generateEmptyGrid(); - }); - -const [running, setRunning] = useState(false); - -const runningRef = useRef(running); -runningRef.current = running - -const runSimulation = useCallback(() => { -if (!runningRef.current) { - return; -} -setGrid((g) => { -return produce(g, gridCopy => { - for (let i = 0; i < numRows; i++) { - for (let k = 0; k < numCols; k++) { - let neighbors = 0; - operations.forEach(([x, y]) => { - const newI = i + x; - const newK = k + y; - if (newI >= 0 && newI < numRows && newK >= 0 && newK < numCols) { - neighbors += g[newI][newK] - } - }) - - if (neighbors < 2 || neighbors > 3) { - gridCopy[i][k] = 0; - } else if (g[i][k] === 0 && neighbors === 3) { - gridCopy[i][k] = 1; - } - - - } - } -}) -}) - - // simulate - setTimeout(runSimulation, 100); -}, []) - return ( - <> - - - - - - - - -Dev's Game of Life
++ - {grid.map((rows, i) => rows.map((col, k) =>{ - const newGrid = produce(grid, gridCopy => { - gridCopy[i][k] = grid[i][k] ? 0 : 1; - }); - setGrid(newGrid); - }} - style={{width: 20, - height: 20, - backgroundColor: grid[i][k] ? 'black' : undefined, - border: "solid 1px black" - }} />) - )} -- > - ); -} - -export default App; diff --git a/game-of-life/src/Game.css b/game-of-life/src/Game.css new file mode 100644 index 000000000..1f541f1f1 --- /dev/null +++ b/game-of-life/src/Game.css @@ -0,0 +1,50 @@ +.Board { + position: relative; + margin: 0 auto; + background-color: #000; + background-image: + linear-gradient(#333 1px, transparent 1px), + linear-gradient(90deg, #333 1px, transparent 1px); +} + +.Cell { + background: #ccc; + position: absolute; +} + +.controls { + margin-top: 20px; + padding-left:20px ; + font-family: 'Arial'; + font-size: 17px; +} + +.button { + box-shadow: 3px 4px 0px 0px #101111; + background:linear-gradient(to bottom, #7892c2 5%, #476e9e 100%); + background-color:#7892c2; + border-radius:15px; + border:1px solid #4e6096; + display:inline-block; + cursor:pointer; + color:#ffffff; + font-family:Arial; + font-size:10px; + padding:7px 25px; + text-decoration:none; + text-shadow:0px 1px 0px #283966; + margin-left: 12px ; +} + +.button:hover { + background:linear-gradient(to bottom, #476e9e 5%, #7892c2 100%); + background-color:#476e9e; +} +.button:active { + position:relative; + top:1px; +} + +.gen { + font-size: 20px; +} \ No newline at end of file diff --git a/game-of-life/src/Game.js b/game-of-life/src/Game.js new file mode 100644 index 000000000..c18a859c0 --- /dev/null +++ b/game-of-life/src/Game.js @@ -0,0 +1,206 @@ +import React from 'react'; +import './Game.css'; + + +const CELL_SIZE = 20; +const WIDTH = 800; +const HEIGHT = 600; + + +class Cell extends React.Component { + + render() { + const { x, y } = this.props; + return ( + + ); + } +} + + +class Game extends React.Component { + + constructor() { + super(); + this.rows = HEIGHT / CELL_SIZE; + this.cols = WIDTH / CELL_SIZE; + + this.board = this.makeEmptyBoard(); + } + + state = { + cells: [], + generation: 0, + isRunning: false, + interval: 100, + } + + makeEmptyBoard() { + let board = []; + for (let y = 0; y < this.rows; y++) { + board[y] = []; + for (let x = 0; x < this.cols; x++) { + board[y][x] = false; + } + } + + return board; + } + + getElementOffset() { + const rect = this.boardRef.getBoundingClientRect(); + const doc = document.documentElement; + + return { + x: (rect.left + window.pageXOffset) - doc.clientLeft, + y: (rect.top + window.pageYOffset) - doc.clientTop, + }; + } + + makeCells() { + let cells = []; + for (let y = 0; y < this.rows; y++) { + for (let x = 0; x < this.cols; x++) { + if (this.board[y][x]) { + cells.push({ x, y }); + } + } + } + + return cells; + } + + handleClick = (event) => { + + const elemOffset = this.getElementOffset(); + const offsetX = event.clientX - elemOffset.x; + const offsetY = event.clientY - elemOffset.y; + + const x = Math.floor(offsetX / CELL_SIZE); + const y = Math.floor(offsetY / CELL_SIZE); + + if (x >= 0 && x <= this.cols && y >= 0 && y <= this.rows) { + this.board[y][x] = !this.board[y][x]; + } + + this.setState({ cells: this.makeCells() }); + } + + runGame = () => { + this.setState({ isRunning: true}); + this.runIteration(); + } + + stopGame = () => { + this.setState({ isRunning: false }); + if (this.timeoutHandler) { + window.clearTimeout(this.timeoutHandler); + this.timeoutHandler = null; + } + } + + runIteration() { + let newBoard = this.makeEmptyBoard(); + + for (let y = 0; y < this.rows; y++) { + for (let x = 0; x < this.cols; x++) { + let neighbors = this.calculateNeighbors(this.board, x, y); + if (this.board[y][x]) { + if (neighbors === 2 || neighbors === 3) { + newBoard[y][x] = true; + } else { + newBoard[y][x] = false; + } + } else { + if (!this.board[y][x] && neighbors === 3) { + newBoard[y][x] = true; + } + } + } + } + + this.board = newBoard; + this.setState({ cells: this.makeCells() }); + + this.timeoutHandler = window.setTimeout(() => { + this.runIteration(); + }, this.state.interval); + } + + /** + * Calculate the number of neighbors at point (x, y) + * @param {Array} board + * @param {int} x + * @param {int} y + */ + calculateNeighbors(board, x, y) { + let neighbors = 0; + const dirs = [[-1, -1], [-1, 0], [-1, 1], [0, 1], [1, 1], [1, 0], [1, -1], [0, -1]]; + for (let i = 0; i < dirs.length; i++) { + const dir = dirs[i]; + let y1 = y + dir[0]; + let x1 = x + dir[1]; + + if (x1 >= 0 && x1 < this.cols && y1 >= 0 && y1 < this.rows && board[y1][x1]) { + neighbors++; + } + } + + return neighbors; + } + + handleIntervalChange = (event) => { + this.setState({ interval: event.target.value }); + } + + handleClear = () => { + this.board = this.makeEmptyBoard(); + this.setState({ cells: this.makeCells() }); + } + + handleRandom = () => { + for (let y = 0; y < this.rows; y++) { + for (let x = 0; x < this.cols; x++) { + this.board[y][x] = (Math.random() >= 0.5); + } + } + + this.setState({ cells: this.makeCells() }); + } + + render() { + const { cells, interval, isRunning } = this.state; + return ( +++ ); + } +} + + +export default Game; \ No newline at end of file diff --git a/game-of-life/src/Space-Invaders.jpg b/game-of-life/src/Space-Invaders.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dd56d83fc4b620045a99128e801bf0104126383f GIT binary patch literal 33095 zcmeHw1z1#DyYL=H8A2ICLZm|w5m7;q9FcNB$pHZoR8T-Er6dO>L^>6uLt!YTrBew> z=?;}H>Has0cGen:{this.generation}+{ this.boardRef = n; }}> + + {cells.map(cell => ( ++ ++ ))} + | + Update every msec + {isRunning ? + : + + } + + ++*N?Zw3-*aO1{pMihBK@32EJp@n~9EMA{7q$lq01zDL-aWV^ P8+V ~EdCIW#XQdrOb$=<7>&Q;t j?GC@oQg|g5=2`4B9RKn` t+96bP{rEY_Hz!>)vrI@{>xA}*%N;focd^)RrhK6i?`(qZHynn83z5@yC4 zdJ x`o9;!}94}`A_kB4otFGL1t0VD~=;+?{4HsUuqpVgsyyh(`TEP;m9SU?3 z@=o`Fw{?FZ7FpuEQu)-|+0yte->14`X5- !q!;*pBl$+#0&_Hx{YO!EEkf&=i$7A|fg*v7)v(I$Pty@rM|RpmHWQ!c;V zQ+D~)6a3ZZ4h)|m_>JFApU#SVKM3J& 6}+v@CB;F#0ousPgoCSn-9%#SMiNd%r`sZ%>N#7bNKV&q*?v z#(o(XESLA##k#CqMvX`Of@E7jVLa`loBswhakd8n+rJX_v9&or6mgjP!`tG|1Bt*` zeu8Wd1nRP0H+Re6%0&jU{dYcUe}<525nKU2LzLOyyqB4IoQ)XY<<(v8&k&!f{TX7Q z=v01Z=VSkeU#R^V;`io*)*`b_!&rTT{W!~01;<>S1rAtj@z xYLSz;ZT P&H}d9NcRH=pZ1PWzy*n$%`Srz+TJ!Omz&Z0IoRjyP)HJDG_#8{0j>WHwhd^ z<#&iINH})4H$8efU0&1#ZpZ)EaiFme89c#%9LwcnxySl^W3`a?H%T7S7=7s)GG!=h zGm#;+SkkdH=GZR(9eVx?Jg|}eyP)RNZE}UF=liryZvlG|^YJ^hpmkn2Gp*KW*%42l z11k*u;hFhYtO9nf!u(Uuk?GbZ)wmJ|ymF$GJAE&4Jv(}PTsN9GC+0!=EP-Rkz8_~v zu=j(Nd%+HBUeRV;ScBBk)98oAB6cvEut`w0HhLsdQ(RCi9FK()!rm5G`^OI*Xll@? zoPCyG0T NcNURrIV%7=7zi=-0{Z`fuA@pu!0g53XI3+3Ewgc zjge5qR63lVWF=)=#yF00e?bxu+&5-{sW!-tUQk7`Bbl0sl-X7Rn}HubOTlJ-{0xG< znQYP2yq*_vVZT|!d-sM)TMZ8r6+CCL{ dnogKDU3x#~K(PeWk;%j2jwJ`9 zCi^S3UT8$_X;_@mIo_V!fTL$)b&_&IWdy<_oPUsT@u(RPLf5;`d5t_5xBxfC729~! z0~~hEe!ys7VT2Zy?e>0FORiJVxL?z}$%zB=!n`Tqxf^Yy$iu1I250CyMoGG!*B-5C zS8{6_SpQH3aXl%+E_?bw0Nd5VQX7L)ikh*kCs}nSsyYK1>@MRx^&){Oa0jXy)hfr_ z%n0=H;y!AAnR2D(_;@5txnv6nJ++w&R87BC>Na@3-~(GLI=KZ@D6LlFq&ue{Fc(i& z-jw^~`vE6wvuq1EC^yakU)cZTd4>zdK@HIT8Rh`%WCP@(G90POhOBs-$1Pj;8fJ Vsd*T z7JP6~_+piv;DX?9fYnSk6-Y8CX?t
zv`>8Ru>hIckv#Ii2MC5wn@SRGNS2`U7O1JDU}7go`(d^U*W1WPDGwuuZ@$F2i+ED} zgz3B}W5`1k{zBF9r2Th)lru&DoM;c9)kSG4V{+rw@F!XE#p9(9whaY0Jez$n=9tLU zoW_kJT@pegL&EI$-(MrQ1} &28S$; X^n+Rn5>VBL59?OZk_B;q=7cKIKBD|@x;R#MAS;n665f0nGeX *?b||H((<}cWTIZI!Ep`boolt8;|9#wJEY$^d@D-%OR1| zn`=(%+71}~2Qs%?#U|$C4h5 N-EmO+#E2;w76najpzV$QDq3qY6Lp z(4ayWvMNaYeCMR&r_9kLu5c~+)>O*y5av9qbGm+MHLP0zff%bCDRC~b(>-D*1~}QW z$vZjE<;g7|p3&hWut~%7ZpdEHVGK`e1ug2jpJ%zxt8eu_<)$`$;C$ON6+hz;4X<10 zy8|}} o|bTLTi=Ig#blL!xZ>FTAXr{dM`&YLFa ztY~ouYyqvX%mte^OSzCeUN2ztxT1v-T)G u<5T`X;~q)-vB zcCtiFP?8MYeI{Do#%W=inl)`-OjXwZ>6vnr E>3D(&Gs#G~=5M@^SBz%fGg+$yWWAr8G kT1Gpu6pO$R-#Urg(41EB7hTe0D>L@%(&*(H_uR-GB2kU^0-AIw7$CBr? zl&P+oMO=s3*~a5{7l6m>)OtfBdo(th%LX8SC_~$)-pC}>>{Y=Twm8c`tZQTN^1%s| z-@}bZ7?AdyKOr-Kr`?Y$ps<2MQ&UEjR6Nb!HW4l7s9Fg{9SAmT=UIg%mm zckfmo=%q|3^ayg|RWnOBWAsaqdy7d-a$;^q3y=M{P=Sr9hiPs! ={@#&BueTi5 FHl1XlBOdYM4 z>8&_ OGl6wIa~*Bd_n)K{`&+^8^W^_DbB|poLXXQQkvBaw9eZLe4l$&?LnL~; z1<3Td#-bL7g(TSFAJ>Cm)le C|gxcFOZlrANwEb%T9o8QfR Ss{$==`zc<5uSNQ`r`n%?<@!?##zTj9< a#zeGoHDlz8F@EWzA;#A zGx~d67*U>0WY~(e^6Cez932>4@eU~_G~$i#Ej}uYy1C@;I3@MN_7UuwH^6sW@Bg>E z=6{}LfF5Eg_0(K4Cl_Iuo}Nu`Etqx60bGzgI~0Pn)8FkFZw?99>+n`GtQ<$`cKXk| z-vi#O{_nAU*z#@xTDEP6kjGg3^{1knOl4p?FnYw-HNYF6IAqmACXoc1KdzS7l1`pK z{vq`}w0Hei%vb-u+26JtK^T79e6f52v>`aq+cA3gaKH}j&cAqu_Ax;czhr&ILnKD2?=q1%7E{k3n)t2; z32YSWF^P3QhnHDQFue8aB<*;5*kDOjQ-=d1tPia=m1HmUiVs|!7SH2}6DpKHYW{{Y zUubF=X@(y6I&O8Zr!HU=%GL&TEi)my^IV!JheqTO`fi{AB5BY=!H!np=t8fXg+B70 zZKTRK_;vM@6&3P VZhp0R{Y( z_b9wTQ2||PD(xM@ij+@X8Rv^>n{o>4r1l^Q!kO??&`ng~)P9jQmL_|WAZ=7LWFpI- zsf+z$btUNLpup+J3f%3fpo(54!2?G>IZ?IJ6t2ZizB=UIOJ{jEP5`k>2uJ^M$FhMO z*cqi**kvO6{l#ah!x&Wl3Bp0zXs*o6<%Jz-!j(&b!Cm@kK3w#nHQ~4A1BN-w9M!hb z6^K?HFCd+03iz~wNZy5qrtlXG3|k5)#qNvP#ZjQ&WZ4K(r#y<2{^*3nyt#O4n>A}k z+>sBT95r^~VV6y9%Ic=fo=YDT*_~YT;(?iNXlO#y-kS%mxsQywX{F4|q$8DTKHy~U z!V~2TF1dzvk6!c jqtOXtsCLdYMVDhiQlJpV5qHGbEJl}oDh_|j^_{eL zEW7JL+VO(RB#o6bj@e>~r;Kr3)AXW8CKnq5IB}o;w~qf5x9Za@>Rh$raAG~NO7R4g zKS~uzGA2zY{p0WFPx4!~H+!sG>CP0)cfJwxk}lhiu4vDMT Z0LWCS|A3``D4Yh{COMl*{uvB$fTn_wSe8b7v(ryI;Vb76W~RBorqM@&Lr@5~Ya z!0u+Dg<^%nF;RHu>L{F;bDU0V#KIS?Y^)S1CtF7$zu7&`|Eh*&yTlHas`fGN@8s2b zm62PeCX@i3*(DWyqtjusy=q5GqV^x;3~y459z`8_4_&MOnd$f|Jsgu7U4k<_quEEs zy-#rQ3Ps8<=`c!;i21}d#OR`A6K*uB>8PQ6IY^yihM{R!JYqr*N#_c>n@-_5G5W8x z!Ca#VmWYEq8q(yw+XG_Z!avN7g5$! _^oW}12EQzc__ha9C}Ie2 zmpngTfVB51EGA~PkclU&a|R@3s5l})#S8*&_~VQ}ApLLiY7xOP^3ERfygTpHb^WFR z<=#md&WMl`P)~-RC&X?I*tKKQT7s|RR}Wur&eI^dg6n3HSLDA2EIIr;c-o)l+u--R zqI*`TCFbLg4^TP2?%y5P&ljLC?Bj$-bC0Z@f-WK6ll`!I0PN| uwF`%aj=55o+eOV>nB|;?P&;*6;2KU;{rcRsSd8yT|Px^a=c1 zp$gi6cx25!zD@M}{;bm$Q6^WK)2dcti20j#C*c pi}e zw<7uiZaMSMI1&7<3ih)m67(7VaUTGzj$pq)2C#}CY)q;5X>>$7v8Wl*+23|tgAWk8 z7Hdv4w9@apimPzMm+-WnGjYHy(nsj|0X=t)1c5rTfO4mS2EPPhBT0!oY(sf4SEC$$LaNB_+ 8p6Km|(6xnp5T`@Gj}x5`2ZRV6hr0UW@Qhh%7izy++<6C`NQYgV?5;P%%;4fa z!W8^GN8_G%QKc-o%bN-I6EADMFOKrj)$MHv3VUrx>_(2Hm}JWcV9RxaHR46lUlSbM z*F-Vq#U-slfr(FZf9aa02D;==E(SrR+Bh$NT@N*sB45_SNjsAqA^vGlGDMF%mkhjd z00mTnI`%h|fn%P}=U#2EkuO3bmb$07Z>D3Y-`#V}?@#VL&sB4{Iw@H68YwIQyOZdD ziCWm**ok;=4dp^8%~2LihbvAKTekZ2%JRJ?mS_!hf92O#VbptZOldt( @;Q8t;z>sR*HCC#oiL}Ek$wl8OsrCVjZFPK=auiD5Ymfy&m6D^iNn>?45M2AE z;FJxOg{C$^Qz*9pS2~&x_Mkjmw9Y>>d~_Zh^%gMj#`TOAD3>4K0*HjpRBtc{3^**C z4%DfRLT6g$myIyWMvE>yDB;*Bi}5)6P9LGKs#gG5EqXHC2U5Qsmo?#gHs9cSd&PIA<_%Kum^{MP8&GjlBdrCYoW5M7Jp^PqUJY$MhZ$ z*qU@{m4E!>?Nz`$kwU~vVCAU@n%C}T#qsDmuWK~}kXBp8RnC!*oQ1?JMN9!GrG!PM znmEuv>$j(t<_d!KTP4wo!2pzAv|5HcS6rYPDXVgEa2&oA1C2;q+ubWnqfAE%c%q{4 z^7fj%k-APkVAwOmN?f;Z@dk!8FtE3Ag@f0Z-Y-DfsnUrB?q2&O^Fh`Xq8>jmx *th|W}ARS ze9CQcr C_| zgGWaxgGm6RV3!1?7;%7fhF?rh0Mf~^?Ice{o0Eb^y&h&!=?3+%OE$WcWX{;*G1C3~ z`#|}_U*BJ7<$a-WuK74_Jln(jGkbc~lVbDTpw;8yCpQ@H&1Ho#2n>4^Nnf#@1hrwW zhK@H;MhNPI>(i=c-g&sL6MPr{7I5#wm^e+Q@=I?3Ptz-Bg!|>#ZkaRgqfXeTzpksq zL7c|wtE h|FaK}nh78&sj*Z6x5-VB@nuPwKw} z-$0kkuHxS>?kWvL;mc6SWQdW?RXW8IWrtkzZhU~GR`4WQJXNMHb_M=8l!>@exApN= z<&*&SXi*eO-dWy@g<+q`SIX?(Cm3H9L9XI7*GL^IeW;3IIHr-xR+m=$I8d}5#-N2I z&S%^|bq~tCy!O`olfgSB%~x@5Y#6n;vyw0+HRM_}IaxRP2vhI2{^x=PS@-)#M)7e8 zb>3=u3}dG>N1+CvoKr9?eHt0J^Ap)>(lGI$k#QJ{WkX=_RwnQukN0Jh2LVC!fg7<` zomlat#--C7GLJx;5P#|k(!Qh^=vSCP&4jeqi=32V-iug_!Aj;|lNE*dY92`moe@^+ ze!#maHTJw3cIjr@zH=L_sfB;smv*p%w6opq0j(0DBURo?la*s?CnwLZ>aL^jF#nQy zd3-#Vpv|ETdj1$_tnW>b^;;5U1x)+@M1pTWC-~yah7uN}8z0a;>+HD0;bsy0cw=l6 zAw2m@VIAf}ZDEE5Mj5gBeuko*&twQ3M `IokBnA2*%o 4#j8mPag!*8M_b^{>^Dpc|(rfW79e_5XcWZtrK-zC9 z)h!s3+4)-7l}6h1V6*Omkh?J>UkwS410p%p^drf3<&G^S3uVMx!1-I#vG9F=Y90XW zR+`BQppp*C&!<(P{zO;|)VBC-ONHaoed=sI2pXHeH1PF-;9i4sy%8~@38=M-;`f4B z1a4Y;-uKg4O|EUV!WF>0_ScGE?-ta}a|IgWeL9*ECh>Gj*kW0*2Ul8od*QiSpVBgC zFb}meDHm;0UmJy%eQkF4PV2%au=Y0N`ht3&Z4TWEmcT`5D#eJgy@ql zu!M_(RsJd_3rW4%bFScEYOaq!ok-3#`q5){^Ns`PKQ~WQb|}p5qxy-}WaGlia9b?R zL)zTU_=@PyM`$EZMG^`8xq;o^wC?6a(`Oqkn;)*VqHTP!=mv>i Kq3OFDsrIs2Zz#e=zlvC`v?LpzQBx zQX&{WeI>SeSW?zH!bnQ7>al^`yW{VnzP}dAr={7TlDC;deI7I|XDuLg9=}>)hkE~c z^t-=dR|_QRY2`4I9#jjbTWfrkWinZcrd2;drj7nZu;AY-22$zr#|_8L<5=JO>u v2dd@Ki&IQ!D4YSb_1snAzb@QJNa%D3Iv-WRtU5ep4%W# z&G8Y)`I||A7YW?AjMS?i3)mRzzjGDKW(Ic@*j(z-KQu1B77z8-{_~)|{)TBMOWVAg zzq!CsWR*kXie;~WroPS(TkMoyU3s1pN$2sk;@3M-nR>WoqTbU9_w*@pXfL*n833Tm z=dKXLZn5xLl|{~|=*vFTOh+lJTsflXBbx5TUqLPqW5DyOk?XBrS@1oFO9VaE;?r?n zM)oy>kha*1tCv0wPZTno46~Gwi=7I$t_Po*DX(4}9ZuS0;K&*BP*4JedYLfNi7L)B zj~_3flfPABeeKC8&UX8<^*P4ImhuvJszbVMnwIVd81cm10!3d#lde~#`8@XEAg(=$ zX-ON$L@=o!5wpc#2lw?3>lUu ?CKpa0U5Ir z^^%_HH&0b&Bn=f-^saM0GQ6kg#3=GYSnumt|8lpB>7HuMJ2&f%n7u9u*Xy3TBN?BH zdj*Q;D0B!@hB+WM&Y7qp!x_MlmVnY>WDimXEyG4!l2#c#lH)HuxL!YcuFH;mk) L)>Y_H;WPQia2Cfv%i33pV212-nn5xA?cVKKWt0OI zJq3T2*7qq@^HuN(k;Dp59_*3lKgFt;JE>82Fdh>xWqt&y2)ojwH _mL0gLdG-$};UHLF`Gluns0Qtt-dY&_Qnbg P*?E@P-80wy_C!+c zV1*7_UN@2gdbUkSeN}AYvqq|(qR=Pr45*PhiDgU#Ui?**%443{bFb9EHE %y*;Ow;ypwuaE2zapWmn)BqGzM$R>r}dr||IQ(4dU!^5(v9HxzJnUCJ(=DN zCzcYom MjrDh#tjdOFDfc@ifEW{9vu-8e$e%<^D08FzJ6cX ztI`byw&7uytK9?kK4f!qW!zIHMbh{yD+5m~`L$yAtgp|!6%0Mz1RF^28OOU3B<~t} z4CBruj>*#v60 #j+JiFKMx@WkZAi)n#D(txkKcu?W2Dhd_RWytg)Ztsf8kf- zpi$rAb!u$Ak@Y)J>-REo^i)@P#weuiw!y0G;&3wPd+=RAIsFsC p}qG0~R{ z_N$YgTIa*N7eMhg@49N!&1~Uq@wUBXK6n!B4?Uj6Yj@b@ZY%f#{4Jp4`c(zT4I*$C z815D!t`%;fE>+c3UiI@4+C^oz0IhjY(ECC{K9*#d@ES(&;f)Smc`tFt_vVcU3w?!F zx iCApYi{$AjS$)_xy~J; 2b>gBY;7fa_E;;A0`5!)#&rgim4r!HgSe6ex2=H~BQu?c5Hw{pP8y4zk7@f}?e( z^$%_V_y$EPWt}e_PiX2Z;5w$OalF*Qi0CjXGih ?@JNr`gDq6{aMkF3Z gLe%xF+D-4K$xz^zT%&jMjT)o#bDj=JF8*U zGyd6!MfdsV(W+d*X6>{0gscY@xZ|PGd+}sx-PuK& 9hLcgIsl+aW0HA z%I4{6m_YE08)f3$l73O_NDVRdlz=L>x 2^Nl_FxIH!1NVhkL?XQp@*l zzW(^k{xEHCPii^z<*S4UH&@H-TeA@1@mKE>n#u0 hToW8*j2l8y#?nnMDC!{pxf8(5$K>kEawBa`}Mp< zA`(W;WdhmAPEq}WiSv{pF?pOtp&65ob6*AI?;TTfH2Eih`JgMSz(jF>KbvLri6vrK zC|2{K2$@lk<-i-ckz&wD7fEyFHz)xHm5uTB`bPJqPn>}IVvV9%Ig!Wr={d1| mJys8dOol1;3`ja{C7q} z>$q@eTDsA=W0A_S@;SEjJho4Io~|f86qV;)NA}xJ>~!`Mt6RLnds+Y82&c%T{1L~$ z7>B^{Z8%!v`Nryr@kPWIurHEE`FF-6NHzxRHIGh>rvgoKh$ST~3Q<5r#HedMS#N1# zNUl5s`tj?w_nm_p^6`w-HOMGu!91k%FsDP=#fY<4mkb Eo$4SxrPNb~^c h_&Of?AMLz(ZEXBVvjGa0#Z9B=eCLWDNI~RsKN3f`20s6yy zH#U_A;m!LUNOR}~zxMSLtGn^U^-XHCRYG{4GJ!U>IB{q{#po7b?_s^+BU;7|BmdgR zuiS~sR~?ta^b*H#MF)L^o3X`Z!@ZwoZ2?Esh1dAs%^m|*GQQH{J8bhGjtDn*`k8mn z8!p*(Mk;+v=eg?`v)_as$d+51zuq?CxOou4AOE$7mazK$bsKv|WzKqS93OSAB5=r$ zNbWj}zgPA|43!WyQFIr_rVLMvzHTg1F)+^mBh-J|uy*o7e_q{O)Cl$I50B@vMh7<> z*vZyt)g!E;9Os_(f$W*e^Imps+tKWDT-TS+6I|UY*@TQ|(G&V(R|oIl*B@HfzG!1) zY+$^%*D?%_Xw2p;3d;tW;}wuO9&28!*ar_g4YFqfnIg02pu-mm8F+*}g=K{ _t0JxHJ)7V9hrVn{Sb9W7FJL$e ziTXqTg4EVetU~YKeZ2)xk%f0X?R;8d88&>bfyWSh qU%q(d zo$ K{#Wj1SH6o9|+4FTBo zM5XBi+#+UOgV1w-K)`}$fqVAMo?*{TZZ_d;zD&OR(}H!bk$PQ0T6JB|-51s)<^F(x z;J4|bru)`E^xJefo|$}AkdRLave3d%kcHl~=n>LN{ea`}t$)ZLrmJD`TmQ7*rVGFR ze}1_L4R3yU{p@% 8;v3MIx(O8oHom&*r6XR3ReAudCz(g zedsZEsgDn%$}Z21N^TZQ?%+|pkhNcDk`>gwBPqm)ouY)xS%{A9yfXhk9>DbWe0(4~ zpYRrOy}8Tb>FMpn2!UW?gy8=*i4p!SA-*DZQ?+6p=jQPbbSCc=bARcfCzi;1G7eAe zQB%yT_Xv6#^v;@@I391)mcV `4U$L-$9xALdx%0_Ql~E0; zNxlL%ra5Ix-N$o5VJ}2Xcl!M2Pj|b~?ulu{Ly<>q(<;zFZ0;F<_5JvP)S_SAME)hH z39|*;djd|o7}Y6N=urO-iT?)#mtW-R*51A9=yfEvBTwy3f^pFNaN^A$kM+PF7Sb;{ zp;}3EX-zV)vwIXxE^s9mng_nrLvABl(AyN4sIGgX~H2)qb zWUj^{<~=U^Ml9$9ehKb@-l3EQTQfX=TtZ9!#1?SCaq2l1Z$7}*wkLZYtZb%dK9 ztTu9|>UWF?(6@JH%ArkaHY3ms*-Kl1OPI+0vZ)rFCx3OT0kfAc@6C1Si=ivhfzMP! zDiAwe2<|b`UkV=C0vfwEJ{8|##p3^h#Y^YEAsIS6{7~l6^O4e#sWdvEw=+nv;vJO! zM+lZ4d)aQ<^j>Ry0&9ok3-LUMcyERSH-9-7HT_<`3mWE +`JLmNM@WQ!R*e``p-e&1p)05A_%NWhwK2Px|W5u8P0rgH&(V@#eA0$Vs+@ z{ArsLZbvqG(zbwCpn}kAcd<}53xmF-ks~j`3>Q_D?awq5M9fxzrM6#=286y>nUp=1 zXqFta__Vj&_Z~(tt!Aa>Vmm$m*FJwjM0`s`gkx#VOm7O@E5??)8ai-#^rk(H*`^14 zW(-o%zq4LM=BF$yBgN?@ZY?E3s$H?^<-j+nKOM9E{#1A9fnF&Np>5ekD!Mh~7bH z0v_LIE$MDw|Dv2o0*kXK8v6eAL|=92*;U8XK~?Cm_D;S3s{C4$z6gs&dHcE?E9_4! ziJE#7dYBMjCyfP}d_XUa)O!Ld@}(NMu`Tv-?@`&_+0qH!lriruG2vqjNxmQ%Be4w} zI-oM@j+ P5(_z!8 =`}WfgI;gUrJQ&hk#IS|1qk{Ik5;ZJk^ZS5qpl-@IFm+et|9fGf!G$>|$` z)TcCQV?oD*$td E+JS!2@ZA>RR@t`}mt6|ocxtu<4Bp|}95tMAT-yR}7+$rNkviTzxk*evQJZw! zP4B~6SWzi#MoU##I9=A0hmQuekz%n0;L%q-OU*UYJ>2_{`97HIvFhpbO&?LwVv0~( z`8V+H7v5+h#8~~SxaS+ZudN96K9FB+ l$4hHz+U0!a74GstIZHk zj5PqB^YUIT8P9o=9@86p@f=@;5>YX;?>nd`W3G1UMy-U7WK#_*Uf@Y&!1^c>fnIO= z_=vLiG*8%pR(}IEdU>6y?hO+V4MKsVvyaI|ZA%KdMfIA3Jp8*PeXqTlwi11fo4Bmj zsO6E9u=a8PtmB$wK!#2L(vzveDN1xDpMD5OWA1$JX)UYvrhV$_7ZP-A&VrhZ{tJ>m zgE$Ht%x|@jWaV>LXCa&5$Q59t ikMgVM z3!uPt8ISU3$-bQ^ocXRBr5PKoyh02+m@R2;VRwr%(Z8hTfOeIWq;wv>!u;fenB|7p zbd(N{cIr51bQO}n70jDjybL8mmudREo*E7y$)F&|)k{D8_7MB_>!e&6sDcvCVBJnA z3tj&5Vmnyc;!rQRmh^ayoRSvjqG*xaN0qLE3gJ;>7sEu+3n&Ie0T!2ATA9Rnu1ChZ z5i=T0l+qYcv5;VjKBc(mbxI{1K>}^qatA;^N=~|X(#i3M5ochg?{l^8`{-0kD@WcU zp4XJ@gL$hWM@pKOOmh5=GR8X;?)&8h2hNaT4#%lqY)v_Rwj;Nv!S%A-gVQQz4p}+@ zCvMc@ug4u^6@KPP)&)jS>Z}y6O-64}R|pe}vvGMboy(La3x0#EvLANC$)eSNxh5$h zOg9Lrg0we_V=zE0;07#6wv=6fvxsDPN2?xc{IDKxKo#e~XlBZ}om*JPzBv}ICY;T` zzys>1UOPt;OoAFWpMcqW_3UJMw4LErA(nITQm>&edlH7-o;wIQ*=p <@C!M79i_Q+SY4 zK&w~MI%dll@;1O_Q$r;QjA!F?rqBzBJ1-wh#^UE#`2uSqP;3eR4-DlSnw3+9u6fnB z=5@WQ0E}jwlFMuT+%%0R5VRHxL9J!T&bLxIW;Z>3U8pNsinv@gg57lk9w4+oZ6Y5k z;QJmue;E9J%n{j0>zfY7TYyK=f* JP1n zqsNvl=U#6%GB~9BSI}14GIu67;oPy>0z{qGP`QW=#<6)RefWR<920C5{y3L}iS9)? zcy#rGnN&t+2lQ@cYsJDB;BPufnCOY$JFJ7=hg-nSw!R&=!|~}Ix5I^{9k;{PwJ&am zICl0{H)!i9N1=VW$+t?LX{s}u5l})rykX@iy&kp3vVBgRE$%nY%YERi*FVzR$w-^Q z>BjHh34L(@=~;Ja;{eUeUanI4p4JWYORKZg%qy}X@y>yAOo&ZvUmmb+=%MVPZz6Ir zd( (4S=BdVRU3<0w zPI#M6j3zy;{M1d*D~S_cx)y6a!XumT?s^4% _9S^`kE^<8Ftmk}l^ zS?(Z772trT6IfliWt~gvG>%V8a-6I-`UJGx=~ilT=+T=Ft)xQ9>D^mE7Ih4 h~3Pt9A66OoqF@u$#iVm$K9LN`PTJ55{WJVW-lfrol zyTC`R3(2i&+mAYhScUZM_?FS@$C5?Tjz&w&f1nML3jEYJ2wmO+GJ0QZ3dB5~cIhLg zcL}MvwWsyMoa}6czMx-0mn{O}A)wNvW9WQ#;AOa|Xs>6#o7g2DXCdkgH9z@aT@~fU zJZ+1UE#Z7+F&|SqMLp|JC-S-og%V48c5((Q=83aAtEe4WX$nZ>aL_wwc*?*xF(@c} zVrY+T<59Q%1w*b4B9zyso+Q8XS$RB|zyf_}>xS2)oX`cqm1gE4Nc&XtT=~1AFfkEs z9!*a>8Qb&4XC~Ozi)sH*29@4Fv#Hn|lIrv{NQ_>t-|Kba)VVq<=0TjSZVJ+tV~m8{ zS|2sVdDL_`(nNHkNFAq5uzocSdNh_jlXB>RXRNyC#Y=}enrCk0Q7IE`$LeaZ2eXP* zCwEHI+|{}}uC(Z$lxxN@BBmmn#?g{SGA2ej3E8v|UJ#k(99yg{ {dJqHUuBsDbZOnkKDFz1;;;W~q6tJUy}N^m1{F z;F911uSMCxb5Hb+y>7HP%BYJnN>@p0ir{ch3RLuFl7|(Ada-e;TX5g07?vgJoW757 zrYh0)K qzIk~#w;@c)EUQ8V|3+Z6d(Ee;{OVqWz}T0Q z_YeOQm3F#{be?J DBsfJND;YJa%Is}tedJVtzYM@*DC1tn3@~!nAtBX0-az^=S zNlU7^!8(#Nb>ep*Z@&5w>|!t>m2edN Vu4u$8iKSpUDv-7sLr_~miMemYnr$AI}{RlK`myJWUAtq|5u3Hvn+Ht 5Ozc>_a )ko?Z+7_(fu|9pK z@n*AZ!3Xrxbu3; zCnqP*&poe%6 !NAlv8Plga2e&VlXJ%6rhiyYtx@HgY9VD}zZf-SR<)%N$zE;y)1#fN2X$ z*fjB6T_B{Nm8S8+7B$&VQCP4PBD>n5_38#J68)zZpf6nF3dTB5tvWx>e?jAjrGX#c zs(rWH{yin)P+gWmQejevqJlE(5n1JXjCkPaqqGI4{){&Ox^H=%?K+!@Y`o*y5hoGk zK4bAv%-&o@Oc7(J2gW`!VM|fJygzk sS4})hUX> z^e_8`Ailws=xT%17+w`|w 1 z30wExd`PaSLbMx7bP%RtC^~Xlz+f(RxX?2uu^^qIfnt1tg;kf-#iX4lp||UloGH5+ zsSKOx$w>I+KT#Fh)A`IGlaBXUlNtE+p=Ck~E`C8>>LR)>{N6};eTSo;^4#>&Sj8|) zy0Qi3koF)BiO1ry?p*P){SS`9EM7(4*5;N(MvJpof!`lezQYLEV+#&namcMmP}cDx zp1*Z8dPz{#g9E-t5q>ai=7zpn+S}l0Ns~-+DMQ0R2UauYY$nX}kJ9w4O-`5qOd6Q) z5=^r6aeI~h;o2*mNTGG2?xY}7s3tnoMW}b?nF;? Wql|5~RAL(LD zG>5GkT LPCEw}Ic-VD8MN!g-Ua6whNFGghPw{n0hkFt9 zW5pI+ykxTnH$K`rB;wray9-yy0sYDJ&fNrExTcQ|oLu4`K*&wpG>{rpTB}^z0+gYD zK#!WM;&rq=vuJ+3_ky Y^=t?Cy$YuJX>jv$rhV)wISRkm*d6ev_6GLaEqOo2&0d{7=nn-LYii6L28 zYGb+C;O~}RO_5epdZ r79h0k21ic q@_kmV|YvK~0o&@xzuFVd7kxX=id|(m)N5F~RLBd~vtlR-@ce zMP&=WKpkjz@$a#UDd4v%KZ% KEjhpp , document.getElementById('root')); + registerServiceWorker(); \ No newline at end of file diff --git a/game-of-life/src/index.tsx b/game-of-life/src/index.tsx deleted file mode 100644 index f5185c1ec..000000000 --- a/game-of-life/src/index.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import './index.css'; -import App from './App'; -import * as serviceWorker from './serviceWorker'; - -ReactDOM.render( - - , - document.getElementById('root') -); - -// If you want your app to work offline and load faster, you can change -// unregister() to register() below. Note this comes with some pitfalls. -// Learn more about service workers: https://bit.ly/CRA-PWA -serviceWorker.unregister(); diff --git a/game-of-life/src/react-app-env.d.ts b/game-of-life/src/react-app-env.d.ts deleted file mode 100644 index 6431bc5fc..000000000 --- a/game-of-life/src/react-app-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -///- diff --git a/game-of-life/src/registerServiceWorker.js b/game-of-life/src/registerServiceWorker.js new file mode 100644 index 000000000..9979c1f0c --- /dev/null +++ b/game-of-life/src/registerServiceWorker.js @@ -0,0 +1,117 @@ +// In production, we register a service worker to serve assets from local cache. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on the "N+1" visit to a page, since previously +// cached resources are updated in the background. + +// To learn more about the benefits of this model, read https://goo.gl/KwvDNy. +// This link also includes instructions on opting out of this behavior. + +const isLocalhost = Boolean( + window.location.hostname === 'localhost' || + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.1/8 is considered localhost for IPv4. + window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ + ) + ); + + export default function register() { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL(process.env.PUBLIC_URL, window.location); + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 + return; + } + + window.addEventListener('load', () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + + if (isLocalhost) { + // This is running on localhost. Lets check if a service worker still exists or not. + checkValidServiceWorker(swUrl); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log( + 'This web app is being served cache-first by a service ' + + 'worker. To learn more, visit https://goo.gl/SC7cgQ' + ); + }); + } else { + // Is not local host. Just register service worker + registerValidSW(swUrl); + } + }); + } + } + + function registerValidSW(swUrl) { + navigator.serviceWorker + .register(swUrl) + .then(registration => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the old content will have been purged and + // the fresh content will have been added to the cache. + // It's the perfect time to display a "New content is + // available; please refresh." message in your web app. + console.log('New content is available; please refresh.'); + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.'); + } + } + }; + }; + }) + .catch(error => { + console.error('Error during service worker registration:', error); + }); + } + + function checkValidServiceWorker(swUrl) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl) + .then(response => { + // Ensure service worker exists, and that we really are getting a JS file. + if ( + response.status === 404 || + response.headers.get('content-type').indexOf('javascript') === -1 + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then(registration => { + registration.unregister().then(() => { + window.location.reload(); + }); + }); + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl); + } + }) + .catch(() => { + console.log( + 'No internet connection found. App is running in offline mode.' + ); + }); + } + + export function unregister() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready.then(registration => { + registration.unregister(); + }); + } + } \ No newline at end of file diff --git a/game-of-life/src/serviceWorker.ts b/game-of-life/src/serviceWorker.js similarity index 91% rename from game-of-life/src/serviceWorker.ts rename to game-of-life/src/serviceWorker.js index b09523f15..b04b771a8 100644 --- a/game-of-life/src/serviceWorker.ts +++ b/game-of-life/src/serviceWorker.js @@ -20,18 +20,10 @@ const isLocalhost = Boolean( ) ); -type Config = { - onSuccess?: (registration: ServiceWorkerRegistration) => void; - onUpdate?: (registration: ServiceWorkerRegistration) => void; -}; - -export function register(config?: Config) { +export function register(config) { if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { // The URL constructor is available in all browsers that support SW. - const publicUrl = new URL( - process.env.PUBLIC_URL, - window.location.href - ); + const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); if (publicUrl.origin !== window.location.origin) { // Our service worker won't work if PUBLIC_URL is on a different origin // from what our page is served on. This might happen if a CDN is used to @@ -62,7 +54,7 @@ export function register(config?: Config) { } } -function registerValidSW(swUrl: string, config?: Config) { +function registerValidSW(swUrl, config) { navigator.serviceWorker .register(swUrl) .then(registration => { @@ -106,10 +98,10 @@ function registerValidSW(swUrl: string, config?: Config) { }); } -function checkValidServiceWorker(swUrl: string, config?: Config) { +function checkValidServiceWorker(swUrl, config) { // Check if the service worker can be found. If it can't reload the page. fetch(swUrl, { - headers: { 'Service-Worker': 'script' } + headers: { 'Service-Worker': 'script' }, }) .then(response => { // Ensure service worker exists, and that we really are getting a JS file. diff --git a/game-of-life/src/setupTests.ts b/game-of-life/src/setupTests.js similarity index 100% rename from game-of-life/src/setupTests.ts rename to game-of-life/src/setupTests.js diff --git a/game-of-life/tsconfig.json b/game-of-life/tsconfig.json deleted file mode 100644 index f2850b716..000000000 --- a/game-of-life/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "lib": [ - "dom", - "dom.iterable", - "esnext" - ], - "allowJs": true, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react" - }, - "include": [ - "src" - ] -} From 7545992a68f5dbd3a91d2988fb797b7cbaa1c792 Mon Sep 17 00:00:00 2001 From: Devin Cooper <37602228+DevinDCooper@users.noreply.github.com> Date: Wed, 26 Aug 2020 20:29:25 -0700 Subject: [PATCH 3/6] Rules --- game-of-life/src/Game.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/game-of-life/src/Game.js b/game-of-life/src/Game.js index c18a859c0..5a0f3fc83 100644 --- a/game-of-life/src/Game.js +++ b/game-of-life/src/Game.js @@ -196,6 +196,12 @@ class Game extends React.Component { } + + Rules:
+1. Any live cell with fewer than two live neighbours dies, as if by underpopulation.
+2. Any live cell with two or three live neighbours lives on to the next generation.
+3. Any live cell with more than three live neighbours dies, as if by overpopulation.
+4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
); From e5552a521c78dea519fb37ead306a1c3eee05fab Mon Sep 17 00:00:00 2001 From: Devin Cooper <37602228+DevinDCooper@users.noreply.github.com> Date: Thu, 27 Aug 2020 20:43:00 -0700 Subject: [PATCH 4/6] Gen bug fixed --- game-of-life/src/Game.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/game-of-life/src/Game.js b/game-of-life/src/Game.js index 5a0f3fc83..5c32c35c7 100644 --- a/game-of-life/src/Game.js +++ b/game-of-life/src/Game.js @@ -80,7 +80,7 @@ class Game extends React.Component { const elemOffset = this.getElementOffset(); const offsetX = event.clientX - elemOffset.x; const offsetY = event.clientY - elemOffset.y; - + const x = Math.floor(offsetX / CELL_SIZE); const y = Math.floor(offsetY / CELL_SIZE); @@ -106,6 +106,7 @@ class Game extends React.Component { runIteration() { let newBoard = this.makeEmptyBoard(); + for (let y = 0; y < this.rows; y++) { for (let x = 0; x < this.cols; x++) { @@ -122,6 +123,10 @@ class Game extends React.Component { } } } + this.setState({ + generation: this.state.generation + 1 + }); + } this.board = newBoard; @@ -160,7 +165,7 @@ class Game extends React.Component { handleClear = () => { this.board = this.makeEmptyBoard(); - this.setState({ cells: this.makeCells() }); + this.setState({ cells: this.makeCells() , generation: this.state.generation = 0 }); } handleRandom = () => { @@ -177,7 +182,7 @@ class Game extends React.Component { const { cells, interval, isRunning } = this.state; return (-Gen:{this.generation}+Gen:{this.state.generation}Date: Thu, 27 Aug 2020 20:46:02 -0700 Subject: [PATCH 5/6] Gen bug fixed_2 --- game-of-life/src/Game.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game-of-life/src/Game.js b/game-of-life/src/Game.js index 5c32c35c7..1a19344cc 100644 --- a/game-of-life/src/Game.js +++ b/game-of-life/src/Game.js @@ -175,7 +175,7 @@ class Game extends React.Component { } } - this.setState({ cells: this.makeCells() }); + this.setState({ cells: this.makeCells(), generation: this.state.generation = 0 }); } render() { From 5365b4403a28979bb3ba4a1f523b62370ae6bef1 Mon Sep 17 00:00:00 2001 From: Devin Cooper <37602228+DevinDCooper@users.noreply.github.com> Date: Thu, 27 Aug 2020 20:56:17 -0700 Subject: [PATCH 6/6] Gen bug fixed_3 --- game-of-life/src/Game.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/game-of-life/src/Game.js b/game-of-life/src/Game.js index 1a19344cc..a11acbe83 100644 --- a/game-of-life/src/Game.js +++ b/game-of-life/src/Game.js @@ -124,7 +124,7 @@ class Game extends React.Component { } } this.setState({ - generation: this.state.generation + 1 + generation: this.state.generation += 1 }); } @@ -182,7 +182,7 @@ class Game extends React.Component { const { cells, interval, isRunning } = this.state; return (-Gen:{this.state.generation}+Generation:{this.state.generation}