From cd9718ad9299786de5973656290e2ccb5fa10011 Mon Sep 17 00:00:00 2001 From: Maryam Shafiq <108004519+daisy21000@users.noreply.github.com> Date: Thu, 4 Aug 2022 19:27:56 +0100 Subject: [PATCH 01/55] Add option of new neon theme --- index.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/index.html b/index.html index 5e955524..166431ec 100755 --- a/index.html +++ b/index.html @@ -60,6 +60,9 @@ case 6: changeTheme('css/head-snake.css?' + Math.random()); break; + case 7: + changeTheme('css/neon-snake.css?' + Math.random()); + break; default: changeTheme('css/main-snake.css?' + Math.random()); break; @@ -94,6 +97,7 @@ +
From 9a9e0a224f6e5e2ea15901ba4ad10905c62a7481 Mon Sep 17 00:00:00 2001 From: Maryam Shafiq <108004519+daisy21000@users.noreply.github.com> Date: Thu, 4 Aug 2022 19:28:57 +0100 Subject: [PATCH 02/55] Add new neon theme stylesheets --- css/neon-snake.css | 139 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 css/neon-snake.css diff --git a/css/neon-snake.css b/css/neon-snake.css new file mode 100644 index 00000000..1be055f0 --- /dev/null +++ b/css/neon-snake.css @@ -0,0 +1,139 @@ +/* +JavaScript Snake +By Patrick Gillespie +http://patorjk.com/games/snake +*/ +body { + margin:0px; + padding:0px; + background-color: #000000; +} + +.snake-toolbar { + color: #ffffff; +} + +#game-area { + margin:10px; + padding:0px; +} + +#mode-wrapper { + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + +} + +#game-area:focus { outline: none; } + +a.snake-link, a.snake-link:link, a.snake-link:visited { + color: #00FFE0; +} + +a.snake-link:hover { + color: #0FFF00; +} + +.snake-pause-screen { + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position:absolute; + width:300px; + height:80px; + text-align:center; + top:50%; + left:50%; + margin-top:-40px; + margin-left:-150px; + display:none; + background-color:#0FFF00; + color:#000000; +} + +.snake-panel-component { + position: absolute; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + color: #ffffff; + text-align: center; + padding: 8px; + margin: 0px; +} + +.snake-snakebody-block { + margin: 0px; + padding: 0px; + background-color: #FF0000; + position: absolute; + border: 0px solid #000080; + background-repeat: no-repeat; +} + +.snake-snakebody-alive { + background-image: url('./images/neon-body-snakeblock.png'), url('./css/images/neon-body-snakeblock.png'); +} +.snake-snakebody-dead { + background-image: url('./images/neon-dead-snakeblock.png'), url('./css/images/neon-dead-snakeblock.png'); +} + +.snake-food-block { + margin: 0px; + padding: 0px; + background-color: #FF0000; + border: 0px solid #000080; + position: absolute; +} + +.snake-playing-field { + margin: 0px; + padding: 0px; + position: absolute; + background-color: #00FFD4; + border: 0px solid #0000A8; +} + +.snake-game-container { + margin: 0px; + padding: 0px; + border-width: 0px; + border-style: none; + zoom: 1; + position: relative; +} + +.snake-welcome-dialog { + padding: 8px; + margin: 0px; + background-color: #0FFF00; + color: #000000; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + /*height: 150px;*/ + margin-top: -100px; + margin-left: -158px; + text-align: center; + display: block; +} + +.snake-try-again-dialog, .snake-win-dialog { + padding: 8px; + margin: 0px; + background-color: #0FFF00; + color: #000000; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + height: 100px; + margin-top: -75px; + margin-left: -158px; + text-align: center; + display: none; +} From 8bd63208d1629c0b1775df2029b4f4b725b5e166 Mon Sep 17 00:00:00 2001 From: Maryam Shafiq <108004519+daisy21000@users.noreply.github.com> Date: Thu, 4 Aug 2022 19:29:48 +0100 Subject: [PATCH 03/55] Add new neon theme snakeblocks --- css/images/neon-body-snakeblock.png | Bin 0 -> 5213 bytes css/images/neon-dead-snakeblock.png | Bin 0 -> 5198 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 css/images/neon-body-snakeblock.png create mode 100644 css/images/neon-dead-snakeblock.png diff --git a/css/images/neon-body-snakeblock.png b/css/images/neon-body-snakeblock.png new file mode 100644 index 0000000000000000000000000000000000000000..1a7107d36117193e69c9a0e6b0b0d308ab1d4bff GIT binary patch literal 5213 zcmeHKc~n#95)Xoa5vUfbpg}{VAY%4}kO*Q;Sn?$72#P2-H#Z@W%_JBWE6Acy6xk}3 zihwLdrHDmE1YAG`MT%k-MFBPElHrC8eF(&EFBZWdgYSu(eE3IxLFg8I<<(bi}o0x@%Dv|pgo2T;8$5?UE0gV0c< zkdHt_b`AuJGoLRtnrO3msjqJ_r|AKiD{aDcWzWQ*VZJJ-?&*=|hU22NRW+rq>XCs?YcO#GNF&JukLS7HDk} zRF}0?o^=pZ(sV{-`dKNCgWDf!#SJV(1^9*bC@OOcen+WV8cp@1E@n+8Ug`3$2^-~% zb4)y3YnhGYef`Teoy@w|>6sw$oe=T|JFa>TKnJ`dmfSfLZWs~X+E}~5cq!)>-}x)n zoNalB z3aE6}GA-TTMMTD5i@uN{ieKFE20Y#AVevCRDdA>yBg>cpw)7@fU)!}k{zYJTc9Rfc z0!Xw>xl8XG$LD|j8nxPL#vbJN%M5JhaYEDMSPh6PbM_fuxE`W-nCBiNN|#Z zDdb|C4Tb&}F6|h*>^+z1A9yg?^728SVk-|K`(HNJcPGLgqpBWdD{gI&``;=%$gVnk z^^&K4BM&zu9ZsU191KK6`hNsNJW96C^ybWNY;EcHg$(V0?WVAu=T2 zRQRZ{Xct3>$>#4T-MH#2*cV~($GoGbcqKpPRQ&d|WI+w{7QUm+zi4L|U<+xFlq}fT z`WlEAt(bem;D;nPFNdFJ=syX`jVdusAoshIH_cd^q*GvGEJ(M}o%ygBor)V+nH|&K zdT}i1bka`w@5STBSLj)T3;WJIeYyGsa5wnX^OLJj8tnFK3*1I1poRvogcy=;NzzOK3*HOP3Zs0d2`@)Fd^g#YHfZ^`MNAFGB=@2 zW}<(pwkvvckv?%k>zHSs_uRVv#_iJKD%-|?`Wns4`YQutUOB zsh%&c=(<*)`1bM%!C-7&w5oBE{M7N5S%X1=PiAt@x^n8-hs*mcZpT-;H@dqWO2oX4 zexrXQW5LfraB{_g05chhYIA>CM|#(zo7T&ABdu=9%d5I;d#nym0{s(vHhBe&XB9TQ zC|HF|P!hH~FgxNcT2pOLnQH|>jr@a6M-17$tyS~4ZFe3KopyR;ws!Jp1f8Fy+T1Rw z*^)`l+1>KCs>;VnE=Ij*wwg_yk4hCR=3Rd2dUOfO#D%Wt->!{G?Q8ktn|{LAn~OVZ z?~;bQcC%`e^4tPY%YCc1?wg(V%xqC$ZhZ{au;)#5{EEVLXBI2;oBOiPum%UOMYveL z$j`V-1XLr2ca4=Q;OvG}mGZ06w)@g+T{DNM|5^BK{%QRE{0-ygon5NtSeM#7$(5C? zTFcA<6Y=CPTUj}7>51A#9JA5hxRJxkv$4ICuFSxJaFbU~j^~Kmo9-P6f!}7PLUV%90fe^t<@PG7jfGyhJh0 z0?Y?K5|H7EI09ZQ#(!*~P&#jcL8b%xTMLCB{9eKPKniJu9E6;=KoaGWk0E&AdwW@g zT%<{d2jU?SB!*QLuvg+IE?wCiulE*e3Isy2Ok)L;{fVYh$p1jrC$Xs|nsh!61U7$< z`-%3u+%?Lu7Kg)NNx=wpcx;vrH35`_|wfRGvr2FD3u90Hw22KhV?%LD0jEX9sT!~zte9hOhBr;s3f zE(w6BA3=D^g>Y8_qK~6eL-AlJJ1&(75=k^HK;V;LC^{9(rP6p<0-X#}2sD~KodRi~ zcp$??Di;HAIfY_C0O4g4fkvPvobjC(+Yv*;5k9PVi2x-ZHh}klP{Na{6dy!>LNVm4 z1k`*I?I=X5ogINfCKD($%2d=E#I=xI0r#RBl}NymC>nEhVHj{aFtvcXQ(*wjI-CuI zDTe^1RPHC0iX1U&2(;Q#)8J@_sj|2U6|hE>y6306-WS?D^)$5!L_&=Sjn*_S0|2L- zD1a>xPvZ!-n-YPcfJ6YnJAAsO-mMG&rd%|83IsuX3Kk%7K`ezpCt>YrkR6r_5~wu3 zogEjVaz8~^Ncr#>lSAJL;7s9c;1<$kgI+pKrp>4Ns!&MH6an7f1R|C|^CMCjWD0{o z#^9%u#jE%9yKEis|HFraM&Y9&0NYKi!NUcfRrvSAYML)Kh5z7hx(@%K2N?Q`lh5M! z3teC6`YZ-MOZiK8eWB~K82BvZFWvQjqYL@ra|e>Z|A18R$4rIc*RJq~ke-swan^gR zrDufE{wXM`6kejSS>O5DdxE^N$w?>eZ?ufFOBck|{^^v?o`qPTQ+jBy!CTu#uSnO& m$i=W2Ww1?KFD9k+90K8%Iomu$i4egM2)45at73IX{C@#am;HqR literal 0 HcmV?d00001 diff --git a/css/images/neon-dead-snakeblock.png b/css/images/neon-dead-snakeblock.png new file mode 100644 index 0000000000000000000000000000000000000000..55da41ab4a51d49002cbc6f44f3a182b0eceb161 GIT binary patch literal 5198 zcmeHKc~n#95)ZP75l{DL)db%>1D2Y_e6NEts#PYVE(ikpv zo<>O?K1FE1nWSB|+!FWsEJu^?esnDN>_q-X|M}eToNThW6*ff~T3efY`Dj9NMVUdF z5;dy%_}SCKXXx*`vy3(-A~#2#+c(rryRTS^y4m7ZS#5#nl9Y1Y_7m^=Sq=Y)So3VB zt}AeQp$De;`ib)ceKxlOGx?9=ZvEO5rlV#4n8w>^@Ji>^)nZWEZ8?8~*Y#a(yBjbe zsiSExj<$&p&R#Ox&gW!%Qxqr7f5piYomWbO`|5Ah&tp@UZ)qGY-P--QH0xODUCTJY zmS0+U#ywPvu+l6=%eua1nl8}r{hF+23b@cn_Zln|-fiC-OA5 z@GDE&$}iaQ%c)vJ65Wj5jDh$k8r%C9o2>T@ejqE)&ilhe(Nbru8+AEjBC)y4uPS7i zJ;pY2cdlmEkq-2&*m64Key2x*$Y)%@8|b*|(GMN+3SV~je5ihSXlq^dBE#kEUwsy= zT335fr#b4vehCz-{nxqU%C)AweW|gd1B=VtlV)%?7zsR!9A#NKbkr5Rrui(h;fvL5 zGp|`WH3{z5u^Y`~k7|*GRZl5Bmy(i3&Osg>u7p>pJ$hQ8ym9IKtAG8Le`@8^-RCxM z(pX>as9{`uu#13HUW=|z3sWxbcn6;CbT|8jmy~d;vW{g)2U{NRs=T%*UisQTG_yf~ zFaksx#+>C34VAgyyfs;4F=HR{hZTBO^Vz|v+gXaXk=ZStDO^z%Qw%e?8ZccFzl!S!EOmiNX(dQB>xX3B1FlKR~)IqX_- z^v2;+iI?t}6cwf?@AnS5T=?yN>+UjR&(PU>1H#(9Ti5}DQ_EtbU$*6gK^YZkX(|UV-+x)lT^C-cA_MDTIE4JN# ze?;zJIvToT$4vb^>S?`VaA&E6h@G2iVSA)KKzMb#eR~MGQ+ljUoXWJ`+7f!#CU-%J zzZVV%$g0ojLwp3fTL6y|?FPO(WWWvfdrK6NnFbX0k4~s&qpJ2brBv zA~DiEQ{5FkyhN8Uu5rSn$7|lXzPfnvs|xG7f8$1TuRG+&Xg|0w>wS>)ey}`F+P_1@ zR4869E$g~gllZ>r6n`KtCt6WAL3+-(z3`G=o_G4L2OCN$7oM!_F}tHIcdK)AIg*He zAN@}EM%toZfWTd4ht@BY5GhsJ&(f^G4RLt$qfo-SNBaXhj&_lLUU z^>WGJ#Gn1Ybq1WO3=!YzK3d}!b8KW?{}!LtKWLC;o-M#zyPEIzzR|&I{`!F0S&FUg zqN<2=Qr6y<_Z1c14pO1X>qd*&lm#Zq{H5Hc5$EH}OpKgpvc7mtbaGG2&2Rhg-)t@H ztiDHl)wP#Zos{FU-ejduMeKpuDK8c-@z1V_!RSAD7p+{Czv28+nQmiG#(CDjz_oBE z^Vhj)_XvPuNdKOpTmf9zl&p}?8E$(hzSgBZNcqp=7Yokf9_DTuGwtkBG{!kq=ZKo^ zS=Hw0{YJuxUt?KWE~$x{2JD5ykGBsUm0yT^JmJjr?+-P46(p=!%Eu9CG#U<1 z#1V-YSOX)A63Kx`j7YXj1u==if@GjnAdw5iB9saf;E2QJ3^W>+qdvqZl(5+!;YG43 z7GOSbk$?n8z~XU2A#S>bOzs!~gG>eVw-z#A_`QPjhGgP!DF``6KqC3F=@4A-qrD_t z8m3N%3*w+KNC>OSV6TMFTsph5JwIBgDBuf(615df_Gg-M0q+x8pT(w3>T!)Fk~Ap0RxZ;HW(h!mP~|f zIYa=WOoQ-{3gE5;!lp;1g5ttZHXI58BoL_>0M8@BP&5jLL!ojpcp3>LJDIQ@H1R|cAh#eZ7y3u@%7 zrW69?VyUlK9L7MaAW$kxb%UeqCd=X?kii;Js-BRzC zL{SO~@YK3V-0JfW4gNF+|t8gEO)f8VU3je{+R2}|74>0ssCtt+x zSGvB^^+gPPk@DB>`byUqG4MsoU%Tu7Mi=taaR(B?|9}+mVWv#~8)x_+G*j-%cAVL( zG1CC8`Ex*2F}$?gmG!-^tp~^*os;OR<>r|k5_EHQb8Sg{W`dWd)yx7NZv&m`cs)JD XV(l3gF?AuDssoj)qdTi?O_1`xXa4u? literal 0 HcmV?d00001 From 12b320ed373ae18db238d02fc47b8e9a35d4c83f Mon Sep 17 00:00:00 2001 From: Maryam Shafiq <108004519+daisy21000@users.noreply.github.com> Date: Thu, 4 Aug 2022 20:30:27 +0100 Subject: [PATCH 04/55] Delete neon snake-alive body for changes --- css/images/neon-body-snakeblock.png | Bin 5213 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 css/images/neon-body-snakeblock.png diff --git a/css/images/neon-body-snakeblock.png b/css/images/neon-body-snakeblock.png deleted file mode 100644 index 1a7107d36117193e69c9a0e6b0b0d308ab1d4bff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5213 zcmeHKc~n#95)Xoa5vUfbpg}{VAY%4}kO*Q;Sn?$72#P2-H#Z@W%_JBWE6Acy6xk}3 zihwLdrHDmE1YAG`MT%k-MFBPElHrC8eF(&EFBZWdgYSu(eE3IxLFg8I<<(bi}o0x@%Dv|pgo2T;8$5?UE0gV0c< zkdHt_b`AuJGoLRtnrO3msjqJ_r|AKiD{aDcWzWQ*VZJJ-?&*=|hU22NRW+rq>XCs?YcO#GNF&JukLS7HDk} zRF}0?o^=pZ(sV{-`dKNCgWDf!#SJV(1^9*bC@OOcen+WV8cp@1E@n+8Ug`3$2^-~% zb4)y3YnhGYef`Teoy@w|>6sw$oe=T|JFa>TKnJ`dmfSfLZWs~X+E}~5cq!)>-}x)n zoNalB z3aE6}GA-TTMMTD5i@uN{ieKFE20Y#AVevCRDdA>yBg>cpw)7@fU)!}k{zYJTc9Rfc z0!Xw>xl8XG$LD|j8nxPL#vbJN%M5JhaYEDMSPh6PbM_fuxE`W-nCBiNN|#Z zDdb|C4Tb&}F6|h*>^+z1A9yg?^728SVk-|K`(HNJcPGLgqpBWdD{gI&``;=%$gVnk z^^&K4BM&zu9ZsU191KK6`hNsNJW96C^ybWNY;EcHg$(V0?WVAu=T2 zRQRZ{Xct3>$>#4T-MH#2*cV~($GoGbcqKpPRQ&d|WI+w{7QUm+zi4L|U<+xFlq}fT z`WlEAt(bem;D;nPFNdFJ=syX`jVdusAoshIH_cd^q*GvGEJ(M}o%ygBor)V+nH|&K zdT}i1bka`w@5STBSLj)T3;WJIeYyGsa5wnX^OLJj8tnFK3*1I1poRvogcy=;NzzOK3*HOP3Zs0d2`@)Fd^g#YHfZ^`MNAFGB=@2 zW}<(pwkvvckv?%k>zHSs_uRVv#_iJKD%-|?`Wns4`YQutUOB zsh%&c=(<*)`1bM%!C-7&w5oBE{M7N5S%X1=PiAt@x^n8-hs*mcZpT-;H@dqWO2oX4 zexrXQW5LfraB{_g05chhYIA>CM|#(zo7T&ABdu=9%d5I;d#nym0{s(vHhBe&XB9TQ zC|HF|P!hH~FgxNcT2pOLnQH|>jr@a6M-17$tyS~4ZFe3KopyR;ws!Jp1f8Fy+T1Rw z*^)`l+1>KCs>;VnE=Ij*wwg_yk4hCR=3Rd2dUOfO#D%Wt->!{G?Q8ktn|{LAn~OVZ z?~;bQcC%`e^4tPY%YCc1?wg(V%xqC$ZhZ{au;)#5{EEVLXBI2;oBOiPum%UOMYveL z$j`V-1XLr2ca4=Q;OvG}mGZ06w)@g+T{DNM|5^BK{%QRE{0-ygon5NtSeM#7$(5C? zTFcA<6Y=CPTUj}7>51A#9JA5hxRJxkv$4ICuFSxJaFbU~j^~Kmo9-P6f!}7PLUV%90fe^t<@PG7jfGyhJh0 z0?Y?K5|H7EI09ZQ#(!*~P&#jcL8b%xTMLCB{9eKPKniJu9E6;=KoaGWk0E&AdwW@g zT%<{d2jU?SB!*QLuvg+IE?wCiulE*e3Isy2Ok)L;{fVYh$p1jrC$Xs|nsh!61U7$< z`-%3u+%?Lu7Kg)NNx=wpcx;vrH35`_|wfRGvr2FD3u90Hw22KhV?%LD0jEX9sT!~zte9hOhBr;s3f zE(w6BA3=D^g>Y8_qK~6eL-AlJJ1&(75=k^HK;V;LC^{9(rP6p<0-X#}2sD~KodRi~ zcp$??Di;HAIfY_C0O4g4fkvPvobjC(+Yv*;5k9PVi2x-ZHh}klP{Na{6dy!>LNVm4 z1k`*I?I=X5ogINfCKD($%2d=E#I=xI0r#RBl}NymC>nEhVHj{aFtvcXQ(*wjI-CuI zDTe^1RPHC0iX1U&2(;Q#)8J@_sj|2U6|hE>y6306-WS?D^)$5!L_&=Sjn*_S0|2L- zD1a>xPvZ!-n-YPcfJ6YnJAAsO-mMG&rd%|83IsuX3Kk%7K`ezpCt>YrkR6r_5~wu3 zogEjVaz8~^Ncr#>lSAJL;7s9c;1<$kgI+pKrp>4Ns!&MH6an7f1R|C|^CMCjWD0{o z#^9%u#jE%9yKEis|HFraM&Y9&0NYKi!NUcfRrvSAYML)Kh5z7hx(@%K2N?Q`lh5M! z3teC6`YZ-MOZiK8eWB~K82BvZFWvQjqYL@ra|e>Z|A18R$4rIc*RJq~ke-swan^gR zrDufE{wXM`6kejSS>O5DdxE^N$w?>eZ?ufFOBck|{^^v?o`qPTQ+jBy!CTu#uSnO& m$i=W2Ww1?KFD9k+90K8%Iomu$i4egM2)45at73IX{C@#am;HqR From b1fa26bcdaa9fe5c6ec4d3d7fc081429608bbfb0 Mon Sep 17 00:00:00 2001 From: Maryam Shafiq <108004519+daisy21000@users.noreply.github.com> Date: Thu, 4 Aug 2022 20:31:20 +0100 Subject: [PATCH 05/55] Add new edited neon snake-alive body --- css/images/neon-body-snakeblock.png | Bin 0 -> 5200 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 css/images/neon-body-snakeblock.png diff --git a/css/images/neon-body-snakeblock.png b/css/images/neon-body-snakeblock.png new file mode 100644 index 0000000000000000000000000000000000000000..d66f77173bc74d9377bc9adda5259ff59cd8b421 GIT binary patch literal 5200 zcmeHKc~n#95)YeV6sm2m_WI(;NOZR$uzl;P2f#%?uC-twbS%;mKk!P*RzMFARqeh~+Imr8~IQ zdKxEr_!OZ1rjwHGctxDKOlQ-jKRTCswj+O||6DclO%B<@3Y)45tEtJoax5XGti-TH zg&Ng){In8^8E6h`MEsBZ`ClXDWLaN)z^n7_mLfqZqW%UIa$8}v&^?dUfL*ozQ{){=Z zWou}w2eN6^>y+nPcWECA%JY(U41#T<{fHXD!^V&|HW9(EGDp_0Nio&ZxqtCW#2TO1 z+nUURpEmfexRR+ll^DAy(&>n#Q9Gf0)nJZO`4bvv@iuaE=$mPFcDh%QS=F77Ivo1t zW5cObr+O#Xm$JP@%A8ENEHk8T>*NT8;brxu^^=X^LIgrjFWNUi;SDI?7YU_^l0qmb zQpiUjBHQ}|L>VuZ8;-YFz0%h=pI!He#FgOdx{S9}R6e*(svfLPe&f@NP0&j5EzDz9 zzG;ig9{a}e#Sx{~?}Zr|b<6e!taf&OJ9Ko6V=(D{(H^%QJ+3tB6JCUcg zNl;$YQhLE&P)gMumg;BjbQp;5*4oy;(A3{Iq)T3!llOZYKk7>6L}FuyUq$E$ zdyH+&ajj(3lJ@mkZ#t9tpxq-u>@zOp542tL=!Xt^MJ%~@KFlB@thu&wfzfjIuRilu zuC2K^tugAtUMUo-_gB>k)f%%WeQB|y0}D$yN!q-1#zM~mXLR;o${tGZrKF@+Rggy;i!g-RHA@#%)GvN_?XTYsonFzivufi8 zE&ozyEtA6i9R#H6di3S=aMj|rx8S*Uj`=VAq=eh$wM-*A*z`EL{Q9nV)ysgetU4jW z7!YfjaF;(cQssX8#&or%_8#O9*0ZeUvP06gF)tw+XYVt*d?Q%ieZV~?JWWalTU4_z z?Ih(}Z8+q2`Rex32Cq2`zktKZ77d5J^DQ|9*1xQl-5(EqVp`UdCBL&l=69#)Fstm? z&BLb?FWogQ$j?aG>m7O}|GT|5oh2roVKa9JhPQe*u>*ytm&8WDX!U6c3c^*V;v<7| zO@uv%j_jff(OLZc#GBWA1p6Y)Z_Pb%mRImocFFJ03Kmo_?%>*5{EqAh1#BRl;erJl zo8JJc@Rf6J&iXOQ&C~uDZT+XgIZ*{B38X%E(kAV-NxFH)MuIe}X?orHs1$6!V^&OS z^Oe!Sb4fd7f8>uDHPSK%7WSTh_G!e4o*PN=p+IY!OnN97#aih66oDRk4bv=+j=}LMxSQ;nm-!5h- zl`j^TbX>1aeAjSVFc5bjT3I_mdggFv{-s%Y-WkbV>xwBCx>xj?-&K{m*SfnMO+>$o zeye{oeZen4P;$vZ|M^lP#p+)@G7nvP znYRj=puor5Gul+<%_%l#&9nlcTK?g>;|8q9&1Lhp#yby(pL6P&zjoq8~-8VD!`TRuzIn^;3gRZyHs+EVaW0hy#Ep*3 zN{ftsW6{K~vCM3@v_u_4_WY5@+lG%RF2p^aaAgGahZ(sD5)l^QNw^R;QY3}PCjw#b6e$J3Fi3&oLIR=K0X-?PxofJOhLd;4(JetLQ2Qslu9L5Ny18G0vv%xqv7yG z9Fd5DH8Aohu>y$1h~-Pv5R({8NDj(`QiV_=MyW9Yt|UU?fJVb|)cg2EQa1YoyjVWP z0?Y?45|H8uSUgT7!hLEXS2%BhL8b!wTMM}_{9eI%Lvl%k41}DwKw`y`Pa$~V2YYFR zEL@Wg55z&?kO)?l!(IuWxpZZ*JwI5eDG&%nQjHZ%_Gg+3A^#&;pT(w@XwvyK5ZL?! z?q}NXbJr-tT5L9*DFGwY;jx$wXtjSjPXY>gbj>Z*mTODp5&0Mb70<KYVaT>T0tO%xY%zSI9hnH( zaftv#`2@m4CWN~Z2>&!HH53nqvgJ|;Ac0850C+wThN4k0Tnd$k!P7_}8Be9!(a4Yn ziU-nNBr*{Ims2PL1Q1Rt7H9-&!s*|8vK-JvEdJw)XE>nX!v^pk5Q=#crTnAFS15vf z6o8sff-RXqv9-mMNhCa(N}h~bgSZxw$>Cm9qZ05~B3WauE({$`2c{NKcPb2^S%P*|`hB+cxc}k9UZe2I5P--!TRR}LxvzXue+IfKE6S2I!kdgyR_9uDwZ>cS+Y7<^ Date: Mon, 18 Sep 2023 20:01:30 -0400 Subject: [PATCH 06/55] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 7942c5ff..e2df65d7 100755 --- a/README.md +++ b/README.md @@ -26,3 +26,16 @@ The index.html file should give an idea of how to use this code. However, below }); The comments within the source code are formatted a little strange because at the time I was playing around with YUI Doc which generates documentation from code. Kind of sucks that there's so much churn in the JavaScript world. However, I'm glad the rest of the code doesn't use any external libraries, as this game still works the same after over a decade. + +## Contributors + +Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/emoji-key)) + + + + + + + + + From 59caa54317dcd8aa5bf3324fae3a6d4bd8a8d04f Mon Sep 17 00:00:00 2001 From: patorjk Date: Mon, 18 Sep 2023 20:02:18 -0400 Subject: [PATCH 07/55] Create .all-contributorsrc --- .all-contributorsrc | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .all-contributorsrc diff --git a/.all-contributorsrc b/.all-contributorsrc new file mode 100644 index 00000000..d6c56871 --- /dev/null +++ b/.all-contributorsrc @@ -0,0 +1,4 @@ +{ + "projectName": "", + "projectOwner": "" +} From f6c25767a05ef453fd0ed15fe76d8429350dd375 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 00:07:59 +0000 Subject: [PATCH 08/55] docs: update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index e2df65d7..b62fde92 100755 --- a/README.md +++ b/README.md @@ -34,6 +34,13 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em + + + + + + +
patorjk
patorjk

💻 📖 🎨 💡
From e2251a840459c7edefc0e3250a2e02418aef6e61 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 00:08:00 +0000 Subject: [PATCH 09/55] docs: update .all-contributorsrc --- .all-contributorsrc | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index d6c56871..fa768f9f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1,4 +1,24 @@ { - "projectName": "", - "projectOwner": "" + "projectName": "JavaScript-Snake", + "projectOwner": "patorjk", + "files": [ + "README.md" + ], + "commitType": "docs", + "commitConvention": "angular", + "contributorsPerLine": 7, + "contributors": [ + { + "login": "patorjk", + "name": "patorjk", + "avatar_url": "https://avatars.githubusercontent.com/u/521224?v=4", + "profile": "http://patorjk.com/", + "contributions": [ + "code", + "doc", + "design", + "example" + ] + } + ] } From 0167015c8b2e613862c771905805aefe701e23f4 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 00:08:04 +0000 Subject: [PATCH 10/55] docs: update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index e2df65d7..5dbe39b5 100755 --- a/README.md +++ b/README.md @@ -34,6 +34,13 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em + + + + + + +
ultra17
ultra17

💻 📖 🎨 🐛
From 6139163a735316307f049a34b0cb8818ef9b3038 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 00:08:38 +0000 Subject: [PATCH 11/55] docs: update .all-contributorsrc --- .all-contributorsrc | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index d6c56871..0234577b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1,4 +1,24 @@ { - "projectName": "", - "projectOwner": "" + "projectName": "JavaScript-Snake", + "projectOwner": "patorjk", + "files": [ + "README.md" + ], + "commitType": "docs", + "commitConvention": "angular", + "contributorsPerLine": 7, + "contributors": [ + { + "login": "ultra17", + "name": "ultra17", + "avatar_url": "https://avatars.githubusercontent.com/u/27869698?v=4", + "profile": "https://github.com/ultra17", + "contributions": [ + "code", + "doc", + "design", + "bug" + ] + } + ] } From 8a8e8388bdc486a69d89fd8a19ec402df3c8fe72 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 00:17:42 +0000 Subject: [PATCH 12/55] docs: update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 642a207e..eef438e5 100755 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em patorjk
patorjk

💻 📖 🎨 💡 - ultra17
ultra17

💻 📖 🎨 🐛 + Rb64
Rb64

💻 🐛 From 1d0d0553f72f62d67f00eff379da9a67f020f8ee Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:16:36 +0000 Subject: [PATCH 13/55] docs: update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index eef438e5..21daa05e 100755 --- a/README.md +++ b/README.md @@ -37,7 +37,8 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em - + + From 13723d4e1d50748e28f3f5fe8b77c00950ee1ddf Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:16:37 +0000 Subject: [PATCH 14/55] docs: update .all-contributorsrc --- .all-contributorsrc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 063ca88b..e1f55e83 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -32,6 +32,16 @@ "design", "bug" ] + }, + { + "login": "Rb64", + "name": "Rb64", + "avatar_url": "https://avatars.githubusercontent.com/u/91498309?v=4", + "profile": "https://github.com/Rb64", + "contributions": [ + "code", + "bug" + ] } ] } From 9aee661527c5149ff0b53422744bb4c1a962953a Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:18:11 +0000 Subject: [PATCH 15/55] docs: update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 21daa05e..f75c5102 100755 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em +
patorjk
patorjk

💻 📖 🎨 💡
patorjk
patorjk

💻 📖 🎨 🐛 💡
ultra17
ultra17

💻 📖 🎨 🐛
Rb64
Rb64

💻 🐛
patorjk
patorjk

💻 📖 🎨 🐛 💡
ultra17
ultra17

💻 📖 🎨 🐛
Rb64
Rb64

💻 🐛
Wyatt Nulton
Wyatt Nulton

💻 🐛
From 2ea5c6296c16b23a7268b75cde3a18a200e79a06 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:18:12 +0000 Subject: [PATCH 16/55] docs: update .all-contributorsrc --- .all-contributorsrc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index e1f55e83..09f1d649 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -42,6 +42,16 @@ "code", "bug" ] + }, + { + "login": "legoman8304", + "name": "Wyatt Nulton", + "avatar_url": "https://avatars.githubusercontent.com/u/43346988?v=4", + "profile": "https://github.com/legoman8304", + "contributions": [ + "code", + "bug" + ] } ] } From a00780a2a92cadd9454cd44f83249b1e0de1af60 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:19:43 +0000 Subject: [PATCH 17/55] docs: update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f75c5102..d2b08713 100755 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em ultra17
ultra17

💻 📖 🎨 🐛 Rb64
Rb64

💻 🐛 Wyatt Nulton
Wyatt Nulton

💻 🐛 + Ashish Bhoir
Ashish Bhoir

📖 From 429405857f02fe0d28535e8301a4727c7c98a1b4 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:19:44 +0000 Subject: [PATCH 18/55] docs: update .all-contributorsrc --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 09f1d649..80193ed4 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -52,6 +52,15 @@ "code", "bug" ] + }, + { + "login": "ashishsiot", + "name": "Ashish Bhoir", + "avatar_url": "https://avatars.githubusercontent.com/u/63919950?v=4", + "profile": "https://github.com/ashishsiot", + "contributions": [ + "doc" + ] } ] } From cc430833e6fbbd996dd34bde2eac11f064ed2ad4 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:20:49 +0000 Subject: [PATCH 19/55] docs: update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d2b08713..6bd14bd2 100755 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em Rb64
Rb64

💻 🐛 Wyatt Nulton
Wyatt Nulton

💻 🐛 Ashish Bhoir
Ashish Bhoir

📖 + Dan G
Dan G

💻 🐛 From 34d720dc2c983d06d2947e18587b576d64b6056f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:20:50 +0000 Subject: [PATCH 20/55] docs: update .all-contributorsrc --- .all-contributorsrc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 80193ed4..248d4f8b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -61,6 +61,16 @@ "contributions": [ "doc" ] + }, + { + "login": "dginovker", + "name": "Dan G", + "avatar_url": "https://avatars.githubusercontent.com/u/32943174?v=4", + "profile": "http://dginovker.github.io", + "contributions": [ + "code", + "bug" + ] } ] } From 7a8b9431ef8966abe8d24e732320ae2b2bbd7ddb Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:21:47 +0000 Subject: [PATCH 21/55] docs: update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6bd14bd2..00fe66e7 100755 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em Wyatt Nulton
Wyatt Nulton

💻 🐛 Ashish Bhoir
Ashish Bhoir

📖 Dan G
Dan G

💻 🐛 + Megas4ever
Megas4ever

💻 🎨 From cb7085d22565f323405b3a9557014ec0c89139c6 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:21:48 +0000 Subject: [PATCH 22/55] docs: update .all-contributorsrc --- .all-contributorsrc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 248d4f8b..f0dc5b57 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -71,6 +71,16 @@ "code", "bug" ] + }, + { + "login": "Megas4ever", + "name": "Megas4ever", + "avatar_url": "https://avatars.githubusercontent.com/u/28103886?v=4", + "profile": "https://github.com/Megas4ever", + "contributions": [ + "code", + "design" + ] } ] } From b436b28eeaf60e7e199ea3e2da379f2b7c18714d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:22:35 +0000 Subject: [PATCH 23/55] docs: update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 00fe66e7..b2fc1a9f 100755 --- a/README.md +++ b/README.md @@ -45,6 +45,9 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em Dan G
Dan G

💻 🐛 Megas4ever
Megas4ever

💻 🎨 + + Bugs Bunny
Bugs Bunny

💻 🐛 + From 19b41a7851cccf58e5350701f77c06c3115e6efe Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:22:36 +0000 Subject: [PATCH 24/55] docs: update .all-contributorsrc --- .all-contributorsrc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index f0dc5b57..efa4d624 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -81,6 +81,16 @@ "code", "design" ] + }, + { + "login": "mamamia5x", + "name": "Bugs Bunny", + "avatar_url": "https://avatars.githubusercontent.com/u/57536929?v=4", + "profile": "https://github.com/mamamia5x", + "contributions": [ + "code", + "bug" + ] } ] } From 1c6c0b3c99429c9fbfb181664e2dca4ce4de71b4 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:23:15 +0000 Subject: [PATCH 25/55] docs: update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b2fc1a9f..9513509b 100755 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em Bugs Bunny
Bugs Bunny

💻 🐛 + James Cote
James Cote

💻 🐛 📖 From a4ddbf179706a9648eccf6e5e21bd42f2e4ae1ad Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:23:16 +0000 Subject: [PATCH 26/55] docs: update .all-contributorsrc --- .all-contributorsrc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index efa4d624..6cc579c1 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -91,6 +91,17 @@ "code", "bug" ] + }, + { + "login": "Coteh", + "name": "James Cote", + "avatar_url": "https://avatars.githubusercontent.com/u/3276350?v=4", + "profile": "https://www.jamescote.ca", + "contributions": [ + "code", + "bug", + "doc" + ] } ] } From 99b4cda6525d9696f8aa337f3ec6030d5e3255eb Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:24:06 +0000 Subject: [PATCH 27/55] docs: update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9513509b..946e9f90 100755 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em Bugs Bunny
Bugs Bunny

💻 🐛 James Cote
James Cote

💻 🐛 📖 + Arun Yokesh
Arun Yokesh

💻 🎨 From 31942ef017e733b3edc41adeb2b0263d29b9d373 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:24:07 +0000 Subject: [PATCH 28/55] docs: update .all-contributorsrc --- .all-contributorsrc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 6cc579c1..34575b56 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -102,6 +102,16 @@ "bug", "doc" ] + }, + { + "login": "yokesharun", + "name": "Arun Yokesh", + "avatar_url": "https://avatars.githubusercontent.com/u/12830078?v=4", + "profile": "http://yokesharun.github.io/", + "contributions": [ + "code", + "design" + ] } ] } From ea91bd281bc5f02344581d930d36bdbc0a5a42ba Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:24:43 +0000 Subject: [PATCH 29/55] docs: update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 946e9f90..947bfc44 100755 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em Bugs Bunny
Bugs Bunny

💻 🐛 James Cote
James Cote

💻 🐛 📖 Arun Yokesh
Arun Yokesh

💻 🎨 + Greg French
Greg French

💻 From 76069473a70a936a307d1720c3390b96cb2e9e94 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:24:44 +0000 Subject: [PATCH 30/55] docs: update .all-contributorsrc --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 34575b56..f0a6f388 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -112,6 +112,15 @@ "code", "design" ] + }, + { + "login": "GregFrench", + "name": "Greg French", + "avatar_url": "https://avatars.githubusercontent.com/u/17938510?v=4", + "profile": "https://github.com/GregFrench", + "contributions": [ + "code" + ] } ] } From 621530900b08f3f42b211beec61d2508b8a2d3b9 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:25:25 +0000 Subject: [PATCH 31/55] docs: update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 947bfc44..7cfb95e3 100755 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em James Cote
James Cote

💻 🐛 📖 Arun Yokesh
Arun Yokesh

💻 🎨 Greg French
Greg French

💻 + KT360
KT360

💻 🎨 From 5651abbca54c99b1ed297653a8d8cdc1ef52406c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:25:26 +0000 Subject: [PATCH 32/55] docs: update .all-contributorsrc --- .all-contributorsrc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index f0a6f388..1894c2f2 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -121,6 +121,16 @@ "contributions": [ "code" ] + }, + { + "login": "KT360", + "name": "KT360", + "avatar_url": "https://avatars.githubusercontent.com/u/31077743?v=4", + "profile": "https://github.com/KT360", + "contributions": [ + "code", + "design" + ] } ] } From 07d6c685794c6507e137c35977ae7a5b08e60b7c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:26:09 +0000 Subject: [PATCH 33/55] docs: update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7cfb95e3..d6e1c56a 100755 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em Arun Yokesh
Arun Yokesh

💻 🎨 Greg French
Greg French

💻 KT360
KT360

💻 🎨 + Thusal Ranawaka
Thusal Ranawaka

💻 🎨 From c5245ec69a6e6ffefaf63ca31aa2e035f6693029 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:26:10 +0000 Subject: [PATCH 34/55] docs: update .all-contributorsrc --- .all-contributorsrc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 1894c2f2..2ba3e062 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -131,6 +131,16 @@ "code", "design" ] + }, + { + "login": "Thusal06", + "name": "Thusal Ranawaka", + "avatar_url": "https://avatars.githubusercontent.com/u/66709891?v=4", + "profile": "https://thusal06.github.io/", + "contributions": [ + "code", + "design" + ] } ] } From ab4dcf3ee33bee3e5b80ff116ad48be88c10f769 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:26:52 +0000 Subject: [PATCH 35/55] docs: update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d6e1c56a..f87b3ade 100755 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em Greg French
Greg French

💻 KT360
KT360

💻 🎨 Thusal Ranawaka
Thusal Ranawaka

💻 🎨 + Akhil Manohar
Akhil Manohar

💻 From 18f5ef31969cf5656fa6df12d2fe21832f784172 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:26:53 +0000 Subject: [PATCH 36/55] docs: update .all-contributorsrc --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 2ba3e062..94e1b2e4 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -141,6 +141,15 @@ "code", "design" ] + }, + { + "login": "akhill2606", + "name": "Akhil Manohar", + "avatar_url": "https://avatars.githubusercontent.com/u/56164681?v=4", + "profile": "https://github.com/akhill2606", + "contributions": [ + "code" + ] } ] } From eee96d3f047e14cb4585e6151858d9fb88186e86 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:27:16 +0000 Subject: [PATCH 37/55] docs: update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d6e1c56a..21adcaf6 100755 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em Greg French
Greg French

💻 KT360
KT360

💻 🎨 Thusal Ranawaka
Thusal Ranawaka

💻 🎨 + C. S.
C. S.

💻 🎨 From badb9b8faf3cd4b3773f91d53eb4809dc96b5166 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:27:17 +0000 Subject: [PATCH 38/55] docs: update .all-contributorsrc --- .all-contributorsrc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 2ba3e062..c98f0441 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -141,6 +141,16 @@ "code", "design" ] + }, + { + "login": "Furtano", + "name": "C. S.", + "avatar_url": "https://avatars.githubusercontent.com/u/4115133?v=4", + "profile": "https://github.com/Furtano", + "contributions": [ + "code", + "design" + ] } ] } From af972f0b596647832d0b39e9f5871946c6ca45b7 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:27:50 +0000 Subject: [PATCH 39/55] docs: update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 21adcaf6..797de829 100755 --- a/README.md +++ b/README.md @@ -54,6 +54,9 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em Thusal Ranawaka
Thusal Ranawaka

💻 🎨 C. S.
C. S.

💻 🎨 + + Thunderforge
Thunderforge

📖 + From c6b75c5e9c42ef80b126d653a3f875bf68b1188c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 03:27:51 +0000 Subject: [PATCH 40/55] docs: update .all-contributorsrc --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index c98f0441..e31ca5bf 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -151,6 +151,15 @@ "code", "design" ] + }, + { + "login": "Thunderforge", + "name": "Thunderforge", + "avatar_url": "https://avatars.githubusercontent.com/u/6200170?v=4", + "profile": "https://github.com/Thunderforge", + "contributions": [ + "doc" + ] } ] } From 95587abd03efb50622916e739bc80725bb6753d2 Mon Sep 17 00:00:00 2001 From: patorjk Date: Tue, 19 Sep 2023 00:06:18 -0400 Subject: [PATCH 41/55] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 797de829..21adcaf6 100755 --- a/README.md +++ b/README.md @@ -54,9 +54,6 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em Thusal Ranawaka
Thusal Ranawaka

💻 🎨 C. S.
C. S.

💻 🎨 - - Thunderforge
Thunderforge

📖 - From acee3b89cc5ff2f75ec6b4ae9321ceb2102ca1eb Mon Sep 17 00:00:00 2001 From: patorjk Date: Tue, 19 Sep 2023 00:06:43 -0400 Subject: [PATCH 42/55] Update .all-contributorsrc --- .all-contributorsrc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index e31ca5bf..c98f0441 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -151,15 +151,6 @@ "code", "design" ] - }, - { - "login": "Thunderforge", - "name": "Thunderforge", - "avatar_url": "https://avatars.githubusercontent.com/u/6200170?v=4", - "profile": "https://github.com/Thunderforge", - "contributions": [ - "doc" - ] } ] } From 489deafdcec5f2d93f589dc215fd6af09376955e Mon Sep 17 00:00:00 2001 From: LucassSantoss Date: Thu, 18 Jan 2024 13:51:13 -0300 Subject: [PATCH 43/55] new style added --- css/black-snake.css | 136 ++++++++++++++++++++++++++++++++++++++++++++ index.html | 6 +- 2 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 css/black-snake.css diff --git a/css/black-snake.css b/css/black-snake.css new file mode 100644 index 00000000..0c460b7c --- /dev/null +++ b/css/black-snake.css @@ -0,0 +1,136 @@ +/* +JavaScript Snake +By Patrick Gillespie +http://patorjk.com/games/snake +*/ +body { + margin:0px; + padding:0px; + background-color: black; + color: white; +} + +#game-area { + margin:10px; + padding:0px; +} + +#mode-wrapper { + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + +} + +#game-area:focus { outline: none; } + +a.snake-link, a.snake-link:link, a.snake-link:visited { + color: #FCFC54; +} + +a.snake-link:hover { + color: #FfFf54; +} + +.snake-pause-screen { + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position:absolute; + width:300px; + height:80px; + text-align:center; + top:50%; + left:50%; + margin-top:-40px; + margin-left:-150px; + display:none; + background-color:black; + color:white; +} + +.snake-panel-component { + position: absolute; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + color: #ffffff; + text-align: center; + padding: 8px; + margin: 0px; +} + +.snake-snakebody-block { + margin: 0px; + padding: 0px; + background-color: #FF0000; + position: absolute; + border: 0px solid #000080; + background-repeat: no-repeat; +} + +.snake-snakebody-alive { + background-image: url('./css/images/snakeblock.png'), url('./images/snakeblock.png'); +} +.snake-snakebody-dead { + background-image: url('./css/images/deadblock.png'), url('./images/deadblock.png'); +} + +.snake-food-block { + margin: 0px; + padding: 0px; + background-color: aqua; + border: 0px solid #000080; + position: absolute; +} + +.snake-playing-field { + margin: 0px; + padding: 0px; + position: absolute; + background-color: purple; + border: 0px solid purple; +} + +.snake-game-container { + margin: 0px; + padding: 0px; + border-width: 0px; + border-style: none; + zoom: 1; + position: relative; +} + +.snake-welcome-dialog { + padding: 8px; + margin: 0px; + background-color: #000000; + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + /*height: 150px;*/ + margin-top: -100px; + margin-left: -158px; + text-align: center; + display: block; +} + +.snake-try-again-dialog, .snake-win-dialog { + padding: 8px; + margin: 0px; + background-color: #000000; + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + height: 100px; + margin-top: -75px; + margin-left: -158px; + text-align: center; + display: none; +} diff --git a/index.html b/index.html index 5e955524..77442c73 100755 --- a/index.html +++ b/index.html @@ -57,9 +57,12 @@ case 5: changeTheme('css/Senura-snake.css?' + Math.random()); break; - case 6: + case 6: changeTheme('css/head-snake.css?' + Math.random()); break; + case 7: + changeTheme("css/black-snake.css?" + Math.random()); + break; default: changeTheme('css/main-snake.css?' + Math.random()); break; @@ -94,6 +97,7 @@ +
From 3de7b6ae0d44bceeea94a188f879a46fd31eee19 Mon Sep 17 00:00:00 2001 From: mmpalasc <114777311+mmpalasc@users.noreply.github.com> Date: Mon, 19 Feb 2024 01:33:30 +0200 Subject: [PATCH 44/55] Pause and info Added pause when window minimized or user changes tab. Added game info button in welcome screen. --- js/snake.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/js/snake.js b/js/snake.js index 556637f7..91ccf984 100644 --- a/js/snake.js +++ b/js/snake.js @@ -669,6 +669,7 @@ SNAKE.Board = SNAKE.Board || (function() { mySnake, boardState = 1, // 0: in active; 1: awaiting game start; 2: playing game myKeyListener, + myWindowListener, isPaused = false,//note: both the board and the snake can be paused // Board components elmContainer, elmPlayingField, elmAboutPanel, elmLengthPanel, elmHighscorePanel, elmWelcome, elmTryAgain, elmWin, elmPauseScreen; @@ -754,6 +755,13 @@ SNAKE.Board = SNAKE.Board || (function() { welcomeTxt.innerHTML = "JavaScript Snake

Use the arrow keys on your keyboard to play the game. " + fullScreenText + "

"; var welcomeStart = document.createElement("button"); welcomeStart.appendChild(document.createTextNode("Play Game")); + + //Game info + var gameinfo = document.createElement("button"); + gameinfo.appendChild(document.createTextNode("Info")); + var gameInfo = function() { + alert("Welcome to Snake! The goal of the game is to eat the food. Each time you eat food, you grow longer. You die if you run into the wall or yourself. Good luck!"); + } var loadGame = function() { SNAKE.removeEventListener(window, "keyup", kbShortcut, false); tmpElm.style.display = "none"; @@ -768,11 +776,14 @@ SNAKE.Board = SNAKE.Board || (function() { loadGame(); } }; + SNAKE.addEventListener(window, "keyup", kbShortcut, false); SNAKE.addEventListener(welcomeStart, "click", loadGame, false); + SNAKE.addEventListener(gameinfo, "click", gameInfo, false); tmpElm.appendChild(welcomeTxt); tmpElm.appendChild(welcomeStart); + tmpElm.appendChild(gameinfo); return tmpElm; } @@ -849,6 +860,7 @@ SNAKE.Board = SNAKE.Board || (function() { */ me.resetBoard = function() { SNAKE.removeEventListener(elmContainer, "keydown", myKeyListener, false); + SNAKE.removeEventListener(elmContainer, "visibilitychange", myWindowListener, false); mySnake.reset(); elmLengthPanel.innerHTML = "Length: 1"; me.setupPlayingField(); @@ -1005,6 +1017,7 @@ SNAKE.Board = SNAKE.Board || (function() { // This removes the listener added at the #listenerX line SNAKE.removeEventListener(elmContainer, "keydown", myKeyListener, false); + SNAKE.removeEventListener(elmContainer, "visibilitychange", myWindowListener, false); myKeyListener = function(evt) { if (!evt) var evt = window.event; @@ -1023,7 +1036,17 @@ SNAKE.Board = SNAKE.Board || (function() { if (evt.preventDefault) {evt.preventDefault();} return false; }; + + //listener for pausing the game if user change tab or minimize the browser window + document.addEventListener("visibilitychange", () => { + if (document.visibilityState === 'hidden') { + if(me.getBoardState()!=0 && !me.getPaused()) + me.setPaused(true); + } + }); + SNAKE.addEventListener( elmContainer, "keydown", myKeyListener, false); + SNAKE.addEventListener( elmContainer, "visibilitychange", myWindowListener, false); mySnake.rebirth(); mySnake.handleArrowKeys(keyNum); @@ -1039,6 +1062,7 @@ SNAKE.Board = SNAKE.Board || (function() { // Search for #listenerX to see where this is removed SNAKE.addEventListener( elmContainer, "keydown", myKeyListener, false); + SNAKE.addEventListener( elmContainer, "visibilitychange", myWindowListener, false); }; /** From b735d5bc9e2daa647a1d8f28276aeb8bac48bc55 Mon Sep 17 00:00:00 2001 From: David Cote Date: Fri, 20 Sep 2024 12:47:14 -0400 Subject: [PATCH 45/55] Fix issue #116: Refactor var to let and const --- README.md | 2 +- index.html | 16 ++--- js/init.js | 4 +- js/snake.js | 202 ++++++++++++++++++++++++++++------------------------ 4 files changed, 119 insertions(+), 105 deletions(-) diff --git a/README.md b/README.md index 1a7d7e9b..7f373fc1 100755 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ http://patorjk.com/games/snake ## How to use The index.html file should give an idea of how to use this code. However, below you can see how to initialize it into any div within a webpage. - var mySnakeBoard = new SNAKE.Board( { + const mySnakeBoard = new SNAKE.Board( { boardContainer: "game-area", fullScreen: false, width: 580, diff --git a/index.html b/index.html index 5e955524..a0e6b1be 100755 --- a/index.html +++ b/index.html @@ -27,17 +27,17 @@ function getTheme () { function changeTheme(themeUrl) { - var elm = document.getElementById("style"); + const elm = document.getElementById("style"); elm && elm.remove(); - var newCss = document.createElement("link"); + const newCss = document.createElement("link"); newCss.id = "style"; newCss.rel = "stylesheet"; newCss.type = "text/css"; newCss.href = themeUrl; document.head.appendChild(newCss); } - var index = document.getElementById("select").selectedIndex; + const index = document.getElementById("select").selectedIndex; switch (index) { case 0: changeTheme('css/light-snake.css?' + Math.random()); @@ -70,14 +70,14 @@ } if (navigator.onLine && window.location.hostname === 'patorjk.com') { - var _gaq = _gaq || []; + const _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-3312460-1']); _gaq.push(['_trackPageview']); (function() { - var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; + const ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; - var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); + const s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); } @@ -126,7 +126,7 @@

Select which mode you would like to play in.

- + \ No newline at end of file diff --git a/js/init.js b/js/init.js index 93de8de3..045d093f 100644 --- a/js/init.js +++ b/js/init.js @@ -1,5 +1,5 @@ -var mySnakeBoard = new SNAKE.Board({ +const mySnakeBoard = new SNAKE.Board({ boardContainer: "game-area", fullScreen: true, premoveOnPause: false -}); +}); \ No newline at end of file diff --git a/js/snake.js b/js/snake.js index 556637f7..40e31690 100644 --- a/js/snake.js +++ b/js/snake.js @@ -9,8 +9,10 @@ http://patorjk.com/games/snake * @class SNAKE */ -var SNAKE = SNAKE || {}; -window.SNAKE = SNAKE; // this will allow us to access the game in other JS files when the app is loaded up in a codesandbox.com sandbox, that's the only reason it's here +// this will allow us to access the game in other JS files when the app is loaded up in a codesandbox.com sandbox, that's the only reason it's here +if (!window.SNAKE) { + window.SNAKE = {}; +} /** * @method addEventListener @@ -64,10 +66,10 @@ SNAKE.Snake = SNAKE.Snake || (function() { // Private static variables and methods // ------------------------------------------------------------------------- - var instanceNumber = 0; - var blockPool = []; + let instanceNumber = 0; + const blockPool = []; - var SnakeBlock = function() { + const SnakeBlock = function() { this.elm = null; this.elmStyle = null; this.row = -1; @@ -80,7 +82,7 @@ SNAKE.Snake = SNAKE.Snake || (function() { // this function is adapted from the example at http://greengeckodesign.com/blog/2007/07/get-highest-z-index-in-javascript.html function getNextHighestZIndex(myObj) { - var highestIndex = 0, + let highestIndex = 0, currentIndex = 0, ii; for (ii in myObj) { @@ -113,19 +115,20 @@ SNAKE.Snake = SNAKE.Snake || (function() { // ----- private variables ----- - var me = this, - playingBoard = config.playingBoard, - myId = instanceNumber++, - growthIncr = 5, - lastMove = 1, + const me = this; + const playingBoard = config.playingBoard; + const myId = instanceNumber++; + const growthIncr = 5; + const columnShift = [0, 1, 0, -1]; + const rowShift = [-1, 0, 1, 0]; + const xPosShift = []; + const yPosShift = []; + + let lastMove = 1, preMove = -1, isFirstMove = true, isFirstGameMove = true, currentDirection = -1, // 0: up, 1: left, 2: down, 3: right - columnShift = [0, 1, 0, -1], - rowShift = [-1, 0, 1, 0], - xPosShift = [], - yPosShift = [], snakeSpeed = 80, isDead = false, isPaused = false; @@ -134,11 +137,11 @@ SNAKE.Snake = SNAKE.Snake || (function() { document.getElementById(mode).addEventListener('click', function () { snakeSpeed = speed; }); } - var modeDropdown = document.getElementById('selectMode'); + const modeDropdown = document.getElementById('selectMode'); if ( modeDropdown ) { modeDropdown.addEventListener('change', function(evt) { evt = evt || {}; - var val = evt.target ? parseInt(evt.target.value) : 75; + const val = evt.target ? parseInt(evt.target.value) : 75; if (isNaN(val)) { val = 75; @@ -183,7 +186,7 @@ SNAKE.Snake = SNAKE.Snake || (function() { // ----- private methods ----- function createSnakeElement() { - var tempNode = document.createElement("div"); + const tempNode = document.createElement("div"); tempNode.className = "snake-snakebody-block"; tempNode.style.left = "-1000px"; tempNode.style.top = "-1000px"; @@ -193,10 +196,10 @@ SNAKE.Snake = SNAKE.Snake || (function() { } function createBlocks(num) { - var tempBlock; - var tempNode = createSnakeElement(); + let tempBlock; + const tempNode = createSnakeElement(); - for (var ii = 1; ii < num; ii++){ + for (let ii = 1; ii < num; ii++){ tempBlock = new SnakeBlock(); tempBlock.elm = tempNode.cloneNode(true); tempBlock.elmStyle = tempBlock.elm.style; @@ -211,7 +214,7 @@ SNAKE.Snake = SNAKE.Snake || (function() { } function recordScore() { - var highScore = localStorage.jsSnakeHighScore; + const highScore = localStorage.jsSnakeHighScore; if (me.snakeLength > highScore) { alert('Congratulations! You have beaten your previous high score, which was ' + highScore + '.'); localStorage.setItem('jsSnakeHighScore', me.snakeLength); @@ -252,7 +255,7 @@ SNAKE.Snake = SNAKE.Snake || (function() { me.handleArrowKeys = function(keyNum) { if (isDead || (isPaused && !config.premoveOnPause)) {return;} - var snakeLength = me.snakeLength; + const snakeLength = me.snakeLength; //console.log("lastmove="+lastMove); //console.log("dir="+keyNum); @@ -295,7 +298,7 @@ SNAKE.Snake = SNAKE.Snake || (function() { */ me.go = function() { - var oldHead = me.snakeHead, + const oldHead = me.snakeHead, newHead = me.snakeTail, grid = playingBoard.grid; // cache grid for quicker lookup @@ -367,10 +370,10 @@ SNAKE.Snake = SNAKE.Snake || (function() { if (blockPool.length <= growthIncr) { createBlocks(growthIncr*2); } - var blocks = blockPool.splice(0, growthIncr); + const blocks = blockPool.splice(0, growthIncr); - var ii = blocks.length, - index, + let ii = blocks.length, + index; prevNode = me.snakeTail; while (ii--) { index = "b" + me.snakeLength++; @@ -391,8 +394,8 @@ SNAKE.Snake = SNAKE.Snake || (function() { //Checks if the current selected option is that of "Rush" //If so, "increase" the snake speed - var selectDropDown = document.getElementById("selectMode"); - var selectedOption = selectDropDown.options[selectDropDown.selectedIndex]; + const selectDropDown = document.getElementById("selectMode"); + const selectedOption = selectDropDown.options[selectDropDown.selectedIndex]; if(selectedOption.text.localeCompare("Rush") == 0) { @@ -408,7 +411,7 @@ SNAKE.Snake = SNAKE.Snake || (function() { */ me.handleDeath = function() { //Reset speed - var selectedSpeed = document.getElementById("selectMode").value; + const selectedSpeed = document.getElementById("selectMode").value; snakeSpeed = parseInt(selectedSpeed); handleEndCondition(playingBoard.handleDeath); @@ -440,9 +443,10 @@ SNAKE.Snake = SNAKE.Snake || (function() { me.reset = function() { if (isDead === false) {return;} - var blocks = [], - curNode = me.snakeHead.next, - nextNode; + const blocks = []; + let curNode = me.snakeHead.next; + let nextNode; + while (curNode !== me.snakeHead) { nextNode = curNode.next; curNode.prev = null; @@ -455,7 +459,7 @@ SNAKE.Snake = SNAKE.Snake || (function() { me.snakeTail = me.snakeHead; me.snakeLength = 1; - for (var ii = 0; ii < blocks.length; ii++) { + for (let ii = 0; ii < blocks.length; ii++) { blocks[ii].elm.style.left = "-1000px"; blocks[ii].elm.style.top = "-1000px"; blocks[ii].elm.className = me.snakeHead.elm.className.replace(/\bsnake-snakebody-dead\b/,'') @@ -504,7 +508,7 @@ SNAKE.Food = SNAKE.Food || (function() { // Private static variables and methods // ------------------------------------------------------------------------- - var instanceNumber = 0; + let instanceNumber = 0; function getRandomPosition(x, y){ return Math.floor(Math.random()*(y+1-x)) + x; @@ -524,12 +528,12 @@ SNAKE.Food = SNAKE.Food || (function() { // ----- private variables ----- - var me = this; - var playingBoard = config.playingBoard; - var fRow, fColumn; - var myId = instanceNumber++; + const me = this; + const playingBoard = config.playingBoard; + let fRow, fColumn; + const myId = instanceNumber++; - var elmFood = document.createElement("div"); + const elmFood = document.createElement("div"); elmFood.setAttribute("id", "snake-food-"+myId); elmFood.className = "snake-food-block"; elmFood.style.width = playingBoard.getBlockWidth() + "px"; @@ -559,10 +563,10 @@ SNAKE.Food = SNAKE.Food || (function() { playingBoard.grid[fRow][fColumn] = 0; } - var row = 0, col = 0, numTries = 0; + let row = 0, col = 0, numTries = 0; - var maxRows = playingBoard.grid.length-1; - var maxCols = playingBoard.grid[0].length-1; + const maxRows = playingBoard.grid.length-1; + const maxCols = playingBoard.grid[0].length-1; while (playingBoard.grid[row][col] !== 0){ row = getRandomPosition(1, maxRows); @@ -601,11 +605,11 @@ SNAKE.Board = SNAKE.Board || (function() { // Private static variables and methods // ------------------------------------------------------------------------- - var instanceNumber = 0; + let instanceNumber = 0; // this function is adapted from the example at http://greengeckodesign.com/blog/2007/07/get-highest-z-index-in-javascript.html function getNextHighestZIndex(myObj) { - var highestIndex = 0, + let highestIndex = 0, currentIndex = 0, ii; for (ii in myObj) { @@ -625,7 +629,7 @@ SNAKE.Board = SNAKE.Board || (function() { This function returns the width of the available screen real estate that we have */ function getClientWidth(){ - var myWidth = 0; + let myWidth = 0; if( typeof window.innerWidth === "number" ) { myWidth = window.innerWidth;//Non-IE } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { @@ -639,7 +643,7 @@ SNAKE.Board = SNAKE.Board || (function() { This function returns the height of the available screen real estate that we have */ function getClientHeight(){ - var myHeight = 0; + let myHeight = 0; if( typeof window.innerHeight === "number" ) { myHeight = window.innerHeight;//Non-IE } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { @@ -657,21 +661,31 @@ SNAKE.Board = SNAKE.Board || (function() { return function(inputConfig) { // --- private variables --- - var me = this, - myId = instanceNumber++, - config = inputConfig || {}, - MAX_BOARD_COLS = 250, - MAX_BOARD_ROWS = 250, - blockWidth = 20, - blockHeight = 20, - GRID_FOOD_VALUE = -1, // the value of a spot on the board that represents snake food, MUST BE NEGATIVE - myFood, + const me = this; + const myId = instanceNumber++; + const config = inputConfig || {}; + const MAX_BOARD_COLS = 250; + const MAX_BOARD_ROWS = 250; + const blockWidth = 20; + const blockHeight = 20; + const GRID_FOOD_VALUE = -1; // the value of a spot on the board that represents snake food; MUST BE NEGATIVE + + let myFood, mySnake, - boardState = 1, // 0: in active; 1: awaiting game start; 2: playing game + boardState = 1, // 0: in active, 1: awaiting game start, 2: playing game myKeyListener, - isPaused = false,//note: both the board and the snake can be paused - // Board components - elmContainer, elmPlayingField, elmAboutPanel, elmLengthPanel, elmHighscorePanel, elmWelcome, elmTryAgain, elmWin, elmPauseScreen; + isPaused = false;//note: both the board and the snake can be paused + + // Board components + let elmContainer, + elmPlayingField, + elmAboutPanel, + elmLengthPanel, + elmHighscorePanel, + elmWelcome, + elmTryAgain, + elmWin, + elmPauseScreen; // --- public variables --- me.grid = []; @@ -710,7 +724,7 @@ SNAKE.Board = SNAKE.Board || (function() { elmWin = createWinElement(); SNAKE.addEventListener( elmContainer, "keyup", function(evt) { - if (!evt) var evt = window.event; + if (!evt) evt = window.event; evt.cancelBubble = true; if (evt.stopPropagation) {evt.stopPropagation();} if (evt.preventDefault) {evt.preventDefault();} @@ -742,28 +756,28 @@ SNAKE.Board = SNAKE.Board || (function() { } function createWelcomeElement() { - var tmpElm = document.createElement("div"); + const tmpElm = document.createElement("div"); tmpElm.id = "sbWelcome" + myId; tmpElm.className = "snake-welcome-dialog"; - var welcomeTxt = document.createElement("div"); - var fullScreenText = ""; + const welcomeTxt = document.createElement("div"); + let fullScreenText = ""; if (config.fullScreen) { fullScreenText = "On Windows, press F11 to play in Full Screen mode."; } welcomeTxt.innerHTML = "JavaScript Snake

Use the arrow keys on your keyboard to play the game. " + fullScreenText + "

"; - var welcomeStart = document.createElement("button"); + const welcomeStart = document.createElement("button"); welcomeStart.appendChild(document.createTextNode("Play Game")); - var loadGame = function() { + const loadGame = function() { SNAKE.removeEventListener(window, "keyup", kbShortcut, false); tmpElm.style.display = "none"; me.setBoardState(1); me.getBoardContainer().focus(); }; - var kbShortcut = function(evt) { - if (!evt) var evt = window.event; - var keyNum = (evt.which) ? evt.which : evt.keyCode; + const kbShortcut = function(evt) { + if (!evt) evt = window.event; + const keyNum = (evt.which) ? evt.which : evt.keyCode; if (keyNum === 32 || keyNum === 13) { loadGame(); } @@ -777,26 +791,26 @@ SNAKE.Board = SNAKE.Board || (function() { } function createGameEndElement(message, elmId, elmClassName) { - var tmpElm = document.createElement("div"); + const tmpElm = document.createElement("div"); tmpElm.id = elmId + myId; tmpElm.className = elmClassName; - var gameEndTxt = document.createElement("div"); + const gameEndTxt = document.createElement("div"); gameEndTxt.innerHTML = "JavaScript Snake

" + message + "

"; - var gameEndStart = document.createElement("button"); + const gameEndStart = document.createElement("button"); gameEndStart.appendChild(document.createTextNode("Play Again?")); - var reloadGame = function () { + const reloadGame = function () { tmpElm.style.display = "none"; me.resetBoard(); me.setBoardState(1); me.getBoardContainer().focus(); }; - var kbGameEndShortcut = function (evt) { + const kbGameEndShortcut = function (evt) { if (boardState !== 0 || tmpElm.style.display !== "block") { return; } - if (!evt) var evt = window.event; - var keyNum = (evt.which) ? evt.which : evt.keyCode; + if (!evt) evt = window.event; + const keyNum = (evt.which) ? evt.which : evt.keyCode; if (keyNum === 32 || keyNum === 13) { reloadGame(); } @@ -818,7 +832,7 @@ SNAKE.Board = SNAKE.Board || (function() { } function handleEndCondition(elmDialog) { - var index = Math.max(getNextHighestZIndex(mySnake.snakeBody), getNextHighestZIndex({ tmp: { elm: myFood.getFoodElement() } })); + const index = Math.max(getNextHighestZIndex(mySnake.snakeBody), getNextHighestZIndex({ tmp: { elm: myFood.getFoodElement() } })); elmContainer.removeChild(elmDialog); elmContainer.appendChild(elmDialog); elmDialog.style.zIndex = index; @@ -927,8 +941,8 @@ SNAKE.Board = SNAKE.Board || (function() { if (!elmPlayingField) {createBoardElements();} // create playing field // calculate width of our game container - var cWidth, cHeight; - var cTop, cLeft; + let cWidth, cHeight; + let cTop, cLeft; if (config.fullScreen === true) { cTop = 0; cLeft = 0; @@ -943,10 +957,10 @@ SNAKE.Board = SNAKE.Board || (function() { } // define the dimensions of the board and playing field - var wEdgeSpace = me.getBlockWidth()*2 + (cWidth % me.getBlockWidth()); - var fWidth = Math.min(maxBoardWidth()-wEdgeSpace,cWidth-wEdgeSpace); - var hEdgeSpace = me.getBlockHeight()*3 + (cHeight % me.getBlockHeight()); - var fHeight = Math.min(maxBoardHeight()-hEdgeSpace,cHeight-hEdgeSpace); + const wEdgeSpace = me.getBlockWidth()*2 + (cWidth % me.getBlockWidth()); + const fWidth = Math.min(maxBoardWidth()-wEdgeSpace,cWidth-wEdgeSpace); + const hEdgeSpace = me.getBlockHeight()*3 + (cHeight % me.getBlockHeight()); + const fHeight = Math.min(maxBoardHeight()-hEdgeSpace,cHeight-hEdgeSpace); elmContainer.style.left = cLeft + "px"; elmContainer.style.top = cTop + "px"; @@ -959,8 +973,8 @@ SNAKE.Board = SNAKE.Board || (function() { // the math for this will need to change depending on font size, padding, etc // assuming height of 14 (font size) + 8 (padding) - var bottomPanelHeight = hEdgeSpace - me.getBlockHeight(); - var pLabelTop = me.getBlockHeight() + fHeight + Math.round((bottomPanelHeight - 30)/2) + "px"; + const bottomPanelHeight = hEdgeSpace - me.getBlockHeight(); + const pLabelTop = me.getBlockHeight() + fHeight + Math.round((bottomPanelHeight - 30)/2) + "px"; elmAboutPanel.style.top = pLabelTop; elmAboutPanel.style.width = "450px"; @@ -980,12 +994,12 @@ SNAKE.Board = SNAKE.Board || (function() { } me.grid = []; - var numBoardCols = fWidth / me.getBlockWidth() + 2; - var numBoardRows = fHeight / me.getBlockHeight() + 2; + const numBoardCols = fWidth / me.getBlockWidth() + 2; + const numBoardRows = fHeight / me.getBlockHeight() + 2; - for (var row = 0; row < numBoardRows; row++) { + for (let row = 0; row < numBoardRows; row++) { me.grid[row] = []; - for (var col = 0; col < numBoardCols; col++) { + for (let col = 0; col < numBoardCols; col++) { if (col === 0 || row === 0 || col === (numBoardCols-1) || row === (numBoardRows-1)) { me.grid[row][col] = 1; // an edge } else { @@ -997,8 +1011,8 @@ SNAKE.Board = SNAKE.Board || (function() { myFood.randomlyPlaceFood(); myKeyListener = function(evt) { - if (!evt) var evt = window.event; - var keyNum = (evt.which) ? evt.which : evt.keyCode; + if (!evt) evt = window.event; + const keyNum = (evt.which) ? evt.which : evt.keyCode; if (me.getBoardState() === 1) { if ( !(keyNum >= 37 && keyNum <= 40) && !(keyNum === 87 || keyNum === 65 || keyNum === 83 || keyNum === 68)) {return;} // if not an arrow key, leave @@ -1007,8 +1021,8 @@ SNAKE.Board = SNAKE.Board || (function() { SNAKE.removeEventListener(elmContainer, "keydown", myKeyListener, false); myKeyListener = function(evt) { - if (!evt) var evt = window.event; - var keyNum = (evt.which) ? evt.which : evt.keyCode; + if (!evt) evt = window.event; + const keyNum = (evt.which) ? evt.which : evt.keyCode; //console.log(keyNum); if (keyNum === 32) { @@ -1100,4 +1114,4 @@ SNAKE.Board = SNAKE.Board || (function() { } }; // end return function -})(); +})(); \ No newline at end of file From b15c66d442d12606cd411857ea0da3488e4c1dcc Mon Sep 17 00:00:00 2001 From: patorjk Date: Wed, 29 Jan 2025 22:36:25 -0500 Subject: [PATCH 46/55] Updated to work with Parcel 2 --- .gitignore | 1 + .parcelrc | 4 + README.md | 10 + package-lock.json | 3389 +++++++++++++++++ package.json | 13 +- {css => src/css}/Senura-snake.css | 4 +- {css => src/css}/black-snake.css | 4 +- {css => src/css}/dark-snake.css | 4 +- {css => src/css}/green-snake.css | 4 +- {css => src/css}/head-snake.css | 6 +- {css => src/css}/images/Thumbs.db | Bin {css => src/css}/images/dark-snakeblock.png | Bin .../css}/images/dead-dark-snakeblock.png | Bin {css => src/css}/images/deadblock.png | Bin {css => src/css}/images/deadblock_border.png | Bin {css => src/css}/images/favicon.png | Bin .../css}/images/green-body-snakeblock.png | Bin .../css}/images/green-head-snakeblock.png | Bin {css => src/css}/images/matrix-food-block.png | Bin .../css}/images/matrix-snake-block.png | Bin .../css}/images/neon-body-snakeblock.png | Bin .../css}/images/neon-dead-snakeblock.png | Bin {css => src/css}/images/snakeblock.png | Bin {css => src/css}/light-snake.css | 4 +- {css => src/css}/main-snake.css | 4 +- {css => src/css}/matrix-snake.css | 8 +- {css => src/css}/neon-snake.css | 4 +- {css => src/css}/teal-snake.css | 4 +- index.html => src/index.html | 30 +- {js => src/js}/init.js | 0 {js => src/js}/snake.js | 41 +- 31 files changed, 3466 insertions(+), 68 deletions(-) create mode 100644 .gitignore create mode 100644 .parcelrc create mode 100644 package-lock.json rename {css => src/css}/Senura-snake.css (94%) rename {css => src/css}/black-snake.css (92%) rename {css => src/css}/dark-snake.css (94%) rename {css => src/css}/green-snake.css (95%) rename {css => src/css}/head-snake.css (90%) rename {css => src/css}/images/Thumbs.db (100%) rename {css => src/css}/images/dark-snakeblock.png (100%) rename {css => src/css}/images/dead-dark-snakeblock.png (100%) rename {css => src/css}/images/deadblock.png (100%) rename {css => src/css}/images/deadblock_border.png (100%) rename {css => src/css}/images/favicon.png (100%) rename {css => src/css}/images/green-body-snakeblock.png (100%) rename {css => src/css}/images/green-head-snakeblock.png (100%) rename {css => src/css}/images/matrix-food-block.png (100%) rename {css => src/css}/images/matrix-snake-block.png (100%) rename {css => src/css}/images/neon-body-snakeblock.png (100%) rename {css => src/css}/images/neon-dead-snakeblock.png (100%) rename {css => src/css}/images/snakeblock.png (100%) rename {css => src/css}/light-snake.css (95%) rename {css => src/css}/main-snake.css (93%) rename {css => src/css}/matrix-snake.css (92%) rename {css => src/css}/neon-snake.css (86%) rename {css => src/css}/teal-snake.css (95%) rename index.html => src/index.html (89%) rename {js => src/js}/init.js (100%) rename {js => src/js}/snake.js (98%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f78ec928 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.parcel-cache diff --git a/.parcelrc b/.parcelrc new file mode 100644 index 00000000..1f3df894 --- /dev/null +++ b/.parcelrc @@ -0,0 +1,4 @@ +{ + "extends": ["@parcel/config-default"], + "reporters": ["...", "parcel-reporter-static-files-copy"] +} diff --git a/README.md b/README.md index 7f373fc1..fff1ef7a 100755 --- a/README.md +++ b/README.md @@ -27,6 +27,16 @@ The index.html file should give an idea of how to use this code. However, below The comments within the source code are formatted a little strange because at the time I was playing around with YUI Doc which generates documentation from code. Kind of sucks that there's so much churn in the JavaScript world. However, I'm glad the rest of the code doesn't use any external libraries, as this game still works the same after over a decade. +## Running + +Clone project, then at command line: + +``` +npx parcel src/index.html +``` + +Runs on http://localhost:1234 + ## Contributors Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/emoji-key)) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..d7f43490 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3389 @@ +{ + "name": "javascript-snake", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "javascript-snake", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "parcel": "^2.13.3", + "parcel-reporter-static-files-copy": "^1.5.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@lezer/common": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz", + "integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@lezer/lr": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", + "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.8.5.tgz", + "integrity": "sha512-KPDeVScZgA1oq0CiPBcOa3kHIqU+pTOwRFDIhxvmf8CTNvqdZQYp5cCKW0bUk69VygB2PuTiINFWbY78aR2pQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.8.5.tgz", + "integrity": "sha512-w/sLhN4T7MW1nB3R/U8WK5BgQLz904wh+/SmA2jD8NnF7BLLoUgflCNxOeSPOWp8geP6nP/+VjWzZVip7rZ1ug==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.8.5.tgz", + "integrity": "sha512-c0TGMbm2M55pwTDIfkDLB6BpIsgxV4PjYck2HiOX+cy/JWiBXz32lYbarPqejKs9Flm7YVAKSILUducU9g2RVg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.8.5.tgz", + "integrity": "sha512-vtbZRHH5UDlL01TT5jB576Zox3+hdyogvpcbvVJlmU5PdL3c5V7cj1EODdh1CHPksRl+cws/58ugEHi8bcj4Ww==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.8.5.tgz", + "integrity": "sha512-Xkc8IUx9aEhP0zvgeKy7IQ3ReX2N8N1L0WPcQwnZweWmOuKfwpS3GRIYqLtK5za/w3E60zhFfNdS+3pBZPytqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.8.5.tgz", + "integrity": "sha512-4wvrf5BgnR8RpogHhtpCPJMKBmvyZPhhUtEwMJbXh0ni2BucpfF07jlmyM11zRqQ2XIq6PbC2j7W7UCCcm1rRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@mischnic/json-sourcemap": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.1.tgz", + "integrity": "sha512-iA7+tyVqfrATAIsIRWQG+a7ZLLD0VaOCKV2Wd/v4mqIU3J9c4jx9p7S0nw1XH3gJCKNBOOwACOPYYSUu9pgT+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0", + "@lezer/lr": "^1.0.0", + "json5": "^2.2.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@parcel/bundler-default": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/bundler-default/-/bundler-default-2.13.3.tgz", + "integrity": "sha512-mOuWeth0bZzRv1b9Lrvydis/hAzJyePy0gwa0tix3/zyYBvw0JY+xkXVR4qKyD/blc1Ra2qOlfI2uD3ucnsdXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/graph": "3.3.3", + "@parcel/plugin": "2.13.3", + "@parcel/rust": "2.13.3", + "@parcel/utils": "2.13.3", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/cache": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/cache/-/cache-2.13.3.tgz", + "integrity": "sha512-Vz5+K5uCt9mcuQAMDo0JdbPYDmVdB8Nvu/A2vTEK2rqZPxvoOTczKeMBA4JqzKqGURHPRLaJCvuR8nDG+jhK9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/fs": "2.13.3", + "@parcel/logger": "2.13.3", + "@parcel/utils": "2.13.3", + "lmdb": "2.8.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.13.3" + } + }, + "node_modules/@parcel/codeframe": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/codeframe/-/codeframe-2.13.3.tgz", + "integrity": "sha512-L/PQf+PT0xM8k9nc0B+PxxOYO2phQYnbuifu9o4pFRiqVmCtHztP+XMIvRJ2gOEXy3pgAImSPFVJ3xGxMFky4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/compressor-raw": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/compressor-raw/-/compressor-raw-2.13.3.tgz", + "integrity": "sha512-C6vjDlgTLjYc358i7LA/dqcL0XDQZ1IHXFw6hBaHHOfxPKW2T4bzUI6RURyToEK9Q1X7+ggDKqgdLxwp4veCFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/config-default": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/config-default/-/config-default-2.13.3.tgz", + "integrity": "sha512-WUsx83ic8DgLwwnL1Bua4lRgQqYjxiTT+DBxESGk1paNm1juWzyfPXEQDLXwiCTcWMQGiXQFQ8OuSISauVQ8dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/bundler-default": "2.13.3", + "@parcel/compressor-raw": "2.13.3", + "@parcel/namer-default": "2.13.3", + "@parcel/optimizer-css": "2.13.3", + "@parcel/optimizer-htmlnano": "2.13.3", + "@parcel/optimizer-image": "2.13.3", + "@parcel/optimizer-svgo": "2.13.3", + "@parcel/optimizer-swc": "2.13.3", + "@parcel/packager-css": "2.13.3", + "@parcel/packager-html": "2.13.3", + "@parcel/packager-js": "2.13.3", + "@parcel/packager-raw": "2.13.3", + "@parcel/packager-svg": "2.13.3", + "@parcel/packager-wasm": "2.13.3", + "@parcel/reporter-dev-server": "2.13.3", + "@parcel/resolver-default": "2.13.3", + "@parcel/runtime-browser-hmr": "2.13.3", + "@parcel/runtime-js": "2.13.3", + "@parcel/runtime-react-refresh": "2.13.3", + "@parcel/runtime-service-worker": "2.13.3", + "@parcel/transformer-babel": "2.13.3", + "@parcel/transformer-css": "2.13.3", + "@parcel/transformer-html": "2.13.3", + "@parcel/transformer-image": "2.13.3", + "@parcel/transformer-js": "2.13.3", + "@parcel/transformer-json": "2.13.3", + "@parcel/transformer-postcss": "2.13.3", + "@parcel/transformer-posthtml": "2.13.3", + "@parcel/transformer-raw": "2.13.3", + "@parcel/transformer-react-refresh-wrap": "2.13.3", + "@parcel/transformer-svg": "2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.13.3" + } + }, + "node_modules/@parcel/core": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/core/-/core-2.13.3.tgz", + "integrity": "sha512-SRZFtqGiaKHlZ2YAvf+NHvBFWS3GnkBvJMfOJM7kxJRK3M1bhbwJa/GgSdzqro5UVf9Bfj6E+pkdrRQIOZ7jMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mischnic/json-sourcemap": "^0.1.0", + "@parcel/cache": "2.13.3", + "@parcel/diagnostic": "2.13.3", + "@parcel/events": "2.13.3", + "@parcel/feature-flags": "2.13.3", + "@parcel/fs": "2.13.3", + "@parcel/graph": "3.3.3", + "@parcel/logger": "2.13.3", + "@parcel/package-manager": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/profiler": "2.13.3", + "@parcel/rust": "2.13.3", + "@parcel/source-map": "^2.1.1", + "@parcel/types": "2.13.3", + "@parcel/utils": "2.13.3", + "@parcel/workers": "2.13.3", + "base-x": "^3.0.8", + "browserslist": "^4.6.6", + "clone": "^2.1.1", + "dotenv": "^16.4.5", + "dotenv-expand": "^11.0.6", + "json5": "^2.2.0", + "msgpackr": "^1.9.9", + "nullthrows": "^1.1.1", + "semver": "^7.5.2" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/diagnostic": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/diagnostic/-/diagnostic-2.13.3.tgz", + "integrity": "sha512-C70KXLBaXLJvr7XCEVu8m6TqNdw1gQLxqg5BQ8roR62R4vWWDnOq8PEksxDi4Y8Z/FF4i3Sapv6tRx9iBNxDEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mischnic/json-sourcemap": "^0.1.0", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/events": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/events/-/events-2.13.3.tgz", + "integrity": "sha512-ZkSHTTbD/E+53AjUzhAWTnMLnxLEU5yRw0H614CaruGh+GjgOIKyukGeToF5Gf/lvZ159VrJCGE0Z5EpgHVkuQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/feature-flags": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/feature-flags/-/feature-flags-2.13.3.tgz", + "integrity": "sha512-UZm14QpamDFoUut9YtCZSpG1HxPs07lUwUCpsAYL0PpxASD3oWJQxIJGfDZPa2272DarXDG9adTKrNXvkHZblw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/fs": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-2.13.3.tgz", + "integrity": "sha512-+MPWAt0zr+TCDSlj1LvkORTjfB/BSffsE99A9AvScKytDSYYpY2s0t4vtV9unSh0FHMS2aBCZNJ4t7KL+DcPIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/feature-flags": "2.13.3", + "@parcel/rust": "2.13.3", + "@parcel/types-internal": "2.13.3", + "@parcel/utils": "2.13.3", + "@parcel/watcher": "^2.0.7", + "@parcel/workers": "2.13.3" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.13.3" + } + }, + "node_modules/@parcel/graph": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@parcel/graph/-/graph-3.3.3.tgz", + "integrity": "sha512-pxs4GauEdvCN8nRd6wG3st6LvpHske3GfqGwUSR0P0X0pBPI1/NicvXz6xzp3rgb9gPWfbKXeI/2IOTfIxxVfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/feature-flags": "2.13.3", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/logger": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-2.13.3.tgz", + "integrity": "sha512-8YF/ZhsQgd7ohQ2vEqcMD1Ag9JlJULROWRPGgGYLGD+twuxAiSdiFBpN3f+j4gQN4PYaLaIS/SwUFx11J243fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/events": "2.13.3" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/markdown-ansi": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/markdown-ansi/-/markdown-ansi-2.13.3.tgz", + "integrity": "sha512-B4rUdlNUulJs2xOQuDbN7Hq5a9roq8IZUcJ1vQ8PAv+zMGb7KCfqIIr/BSCDYGhayfAGBVWW8x55Kvrl1zrDYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/namer-default": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/namer-default/-/namer-default-2.13.3.tgz", + "integrity": "sha512-A2a5A5fuyNcjSGOS0hPcdQmOE2kszZnLIXof7UMGNkNkeC62KAG8WcFZH5RNOY3LT5H773hq51zmc2Y2gE5Rnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/node-resolver-core": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/@parcel/node-resolver-core/-/node-resolver-core-3.4.3.tgz", + "integrity": "sha512-IEnMks49egEic1ITBp59VQyHzkSQUXqpU9hOHwqN3KoSTdZ6rEgrXcS3pa6tdXay4NYGlcZ88kFCE8i/xYoVCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mischnic/json-sourcemap": "^0.1.0", + "@parcel/diagnostic": "2.13.3", + "@parcel/fs": "2.13.3", + "@parcel/rust": "2.13.3", + "@parcel/utils": "2.13.3", + "nullthrows": "^1.1.1", + "semver": "^7.5.2" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/optimizer-css": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-css/-/optimizer-css-2.13.3.tgz", + "integrity": "sha512-A8o9IVCv919vhv69SkLmyW2WjJR5WZgcMqV6L1uiGF8i8z18myrMhrp2JuSHx29PRT9uNyzNC4Xrd4StYjIhJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.13.3", + "browserslist": "^4.6.6", + "lightningcss": "^1.22.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/optimizer-htmlnano": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-htmlnano/-/optimizer-htmlnano-2.13.3.tgz", + "integrity": "sha512-K4Uvg0Sy2pECP7pdvvbud++F0pfcbNkq+IxTrgqBX5HJnLEmRZwgdvZEKF43oMEolclMnURMQRGjRplRaPdbXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/utils": "2.13.3", + "htmlnano": "^2.0.0", + "nullthrows": "^1.1.1", + "posthtml": "^0.16.5" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/optimizer-image": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-image/-/optimizer-image-2.13.3.tgz", + "integrity": "sha512-wlDUICA29J4UnqkKrWiyt68g1e85qfYhp4zJFcFJL0LX1qqh1QwsLUz3YJ+KlruoqPxJSFEC8ncBEKiVCsqhEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/rust": "2.13.3", + "@parcel/utils": "2.13.3", + "@parcel/workers": "2.13.3" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.13.3" + } + }, + "node_modules/@parcel/optimizer-svgo": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-svgo/-/optimizer-svgo-2.13.3.tgz", + "integrity": "sha512-piIKxQKzhZK54dJR6yqIcq+urZmpsfgUpLCZT3cnWlX4ux5+S2iN66qqZBs0zVn+a58LcWcoP4Z9ieiJmpiu2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/utils": "2.13.3" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/optimizer-swc": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-swc/-/optimizer-swc-2.13.3.tgz", + "integrity": "sha512-zNSq6oWqLlW8ksPIDjM0VgrK6ZAJbPQCDvs1V+p0oX3CzEe85lT5VkRpnfrN1+/vvEJNGL8e60efHKpI+rXGTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.13.3", + "@swc/core": "^1.7.26", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/package-manager": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/package-manager/-/package-manager-2.13.3.tgz", + "integrity": "sha512-FLNI5OrZxymGf/Yln0E/kjnGn5sdkQAxW7pQVdtuM+5VeN75yibJRjsSGv88PvJ+KvpD2ANgiIJo1RufmoPcww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/fs": "2.13.3", + "@parcel/logger": "2.13.3", + "@parcel/node-resolver-core": "3.4.3", + "@parcel/types": "2.13.3", + "@parcel/utils": "2.13.3", + "@parcel/workers": "2.13.3", + "@swc/core": "^1.7.26", + "semver": "^7.5.2" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.13.3" + } + }, + "node_modules/@parcel/packager-css": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/packager-css/-/packager-css-2.13.3.tgz", + "integrity": "sha512-ghDqRMtrUwaDERzFm9le0uz2PTeqqsjsW0ihQSZPSAptElRl9o5BR+XtMPv3r7Ui0evo+w35gD55oQCJ28vCig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.13.3", + "lightningcss": "^1.22.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-html": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/packager-html/-/packager-html-2.13.3.tgz", + "integrity": "sha512-jDLnKSA/EzVEZ3/aegXO3QJ/Ij732AgBBkIQfeC8tUoxwVz5b3HiPBAjVjcUSfZs7mdBSHO+ELWC3UD+HbsIrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3", + "@parcel/types": "2.13.3", + "@parcel/utils": "2.13.3", + "nullthrows": "^1.1.1", + "posthtml": "^0.16.5" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-js": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/packager-js/-/packager-js-2.13.3.tgz", + "integrity": "sha512-0pMHHf2zOn7EOJe88QJw5h/wcV1bFfj6cXVcE55Wa8GX3V+SdCgolnlvNuBcRQ1Tlx0Xkpo+9hMFVIQbNQY6zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/rust": "2.13.3", + "@parcel/source-map": "^2.1.1", + "@parcel/types": "2.13.3", + "@parcel/utils": "2.13.3", + "globals": "^13.2.0", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-raw": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/packager-raw/-/packager-raw-2.13.3.tgz", + "integrity": "sha512-AWu4UB+akBdskzvT3KGVHIdacU9f7cI678DQQ1jKQuc9yZz5D0VFt3ocFBOmvDfEQDF0uH3jjtJR7fnuvX7Biw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-svg": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/packager-svg/-/packager-svg-2.13.3.tgz", + "integrity": "sha512-tKGRiFq/4jh5u2xpTstNQ7gu+RuZWzlWqpw5NaFmcKe6VQe5CMcS499xTFoREAGnRvevSeIgC38X1a+VOo+/AA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3", + "@parcel/types": "2.13.3", + "@parcel/utils": "2.13.3", + "posthtml": "^0.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-wasm": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/packager-wasm/-/packager-wasm-2.13.3.tgz", + "integrity": "sha512-SZB56/b230vFrSehVXaUAWjJmWYc89gzb8OTLkBm7uvtFtov2J1R8Ig9TTJwinyXE3h84MCFP/YpQElSfoLkJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3" + }, + "engines": { + "node": ">=16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/plugin": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.13.3.tgz", + "integrity": "sha512-cterKHHcwg6q11Gpif/aqvHo056TR+yDVJ3fSdiG2xr5KD1VZ2B3hmofWERNNwjMcnR1h9Xq40B7jCKUhOyNFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/types": "2.13.3" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/profiler": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/profiler/-/profiler-2.13.3.tgz", + "integrity": "sha512-ok6BwWSLvyHe5TuSXjSacYnDStFgP5Y30tA9mbtWSm0INDsYf+m5DqzpYPx8U54OaywWMK8w3MXUClosJX3aPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/events": "2.13.3", + "@parcel/types-internal": "2.13.3", + "chrome-trace-event": "^1.0.2" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/reporter-cli": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/reporter-cli/-/reporter-cli-2.13.3.tgz", + "integrity": "sha512-EA5tKt/6bXYNMEavSs35qHlFdx6cZmRazlZxPBgxPePQYoouNAPMNLUOEQozaPhz9f5fvNDN7EHOFaAWcdO2LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3", + "@parcel/types": "2.13.3", + "@parcel/utils": "2.13.3", + "chalk": "^4.1.2", + "term-size": "^2.2.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/reporter-dev-server": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/reporter-dev-server/-/reporter-dev-server-2.13.3.tgz", + "integrity": "sha512-ZNeFp6AOIQFv7mZIv2P5O188dnZHNg0ymeDVcakfZomwhpSva2dFNS3AnvWo4eyWBlUxkmQO8BtaxeWTs7jAuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3", + "@parcel/utils": "2.13.3" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/reporter-tracer": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/reporter-tracer/-/reporter-tracer-2.13.3.tgz", + "integrity": "sha512-aBsVPI8jLZTDkFYrI69GxnsdvZKEYerkPsu935LcX9rfUYssOnmmUP+3oI+8fbg+qNjJuk9BgoQ4hCp9FOphMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3", + "@parcel/utils": "2.13.3", + "chrome-trace-event": "^1.0.3", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/resolver-default": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/resolver-default/-/resolver-default-2.13.3.tgz", + "integrity": "sha512-urBZuRALWT9pFMeWQ8JirchLmsQEyI9lrJptiwLbJWrwvmlwSUGkcstmPwoNRf/aAQjICB7ser/247Vny0pFxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/node-resolver-core": "3.4.3", + "@parcel/plugin": "2.13.3" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/runtime-browser-hmr": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.13.3.tgz", + "integrity": "sha512-EAcPojQFUNUGUrDk66cu3ySPO0NXRVS5CKPd4QrxPCVVbGzde4koKu8krC/TaGsoyUqhie8HMnS70qBP0GFfcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3", + "@parcel/utils": "2.13.3" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/runtime-js": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/runtime-js/-/runtime-js-2.13.3.tgz", + "integrity": "sha512-62OucNAnxb2Q0uyTFWW/0Hvv2DJ4b5H6neh/YFu2/wmxaZ37xTpEuEcG2do7KW54xE5DeLP+RliHLwi4NvR3ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/utils": "2.13.3", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/runtime-react-refresh": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/runtime-react-refresh/-/runtime-react-refresh-2.13.3.tgz", + "integrity": "sha512-PYZ1klpJVwqE3WuifILjtF1dugtesHEuJcXYZI85T6UoRSD5ctS1nAIpZzT14Ga1lRt/jd+eAmhWL1l3m/Vk1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3", + "@parcel/utils": "2.13.3", + "react-error-overlay": "6.0.9", + "react-refresh": ">=0.9 <=0.14" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/runtime-service-worker": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/runtime-service-worker/-/runtime-service-worker-2.13.3.tgz", + "integrity": "sha512-BjMhPuT7Us1+YIo31exPRwomPiL+jrZZS5UUAwlEW2XGHDceEotzRM94LwxeFliCScT4IOokGoxixm19qRuzWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3", + "@parcel/utils": "2.13.3", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/rust/-/rust-2.13.3.tgz", + "integrity": "sha512-dLq85xDAtzr3P5200cvxk+8WXSWauYbxuev9LCPdwfhlaWo/JEj6cu9seVdWlkagjGwkoV1kXC+GGntgUXOLAQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/source-map": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@parcel/source-map/-/source-map-2.1.1.tgz", + "integrity": "sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^1.0.3" + }, + "engines": { + "node": "^12.18.3 || >=14" + } + }, + "node_modules/@parcel/transformer-babel": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/transformer-babel/-/transformer-babel-2.13.3.tgz", + "integrity": "sha512-ikzK9f5WTFrdQsPitQgjCPH6HmVU8AQPRemIJ2BndYhtodn5PQut5cnSvTrqax8RjYvheEKCQk/Zb/uR7qgS3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.13.3", + "browserslist": "^4.6.6", + "json5": "^2.2.0", + "nullthrows": "^1.1.1", + "semver": "^7.5.2" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-css": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/transformer-css/-/transformer-css-2.13.3.tgz", + "integrity": "sha512-zbrNURGph6JeVADbGydyZ7lcu/izj41kDxQ9xw4RPRW/3rofQiTU0OTREi+uBWiMENQySXVivEdzHA9cA+aLAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.13.3", + "browserslist": "^4.6.6", + "lightningcss": "^1.22.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-html": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/transformer-html/-/transformer-html-2.13.3.tgz", + "integrity": "sha512-Yf74FkL9RCCB4+hxQRVMNQThH9+fZ5w0NLiQPpWUOcgDEEyxTi4FWPQgEBsKl/XK2ehdydbQB9fBgPQLuQxwPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/rust": "2.13.3", + "nullthrows": "^1.1.1", + "posthtml": "^0.16.5", + "posthtml-parser": "^0.12.1", + "posthtml-render": "^3.0.0", + "semver": "^7.5.2", + "srcset": "4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-html/node_modules/srcset": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", + "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@parcel/transformer-image": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/transformer-image/-/transformer-image-2.13.3.tgz", + "integrity": "sha512-wL1CXyeFAqbp2wcEq/JD3a/tbAyVIDMTC6laQxlIwnVV7dsENhK1qRuJZuoBdixESeUpFQSmmQvDIhcfT/cUUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3", + "@parcel/utils": "2.13.3", + "@parcel/workers": "2.13.3", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "peerDependencies": { + "@parcel/core": "^2.13.3" + } + }, + "node_modules/@parcel/transformer-js": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/transformer-js/-/transformer-js-2.13.3.tgz", + "integrity": "sha512-KqfNGn1IHzDoN2aPqt4nDksgb50Xzcny777C7A7hjlQ3cmkjyJrixYjzzsPaPSGJ+kJpknh3KE8unkQ9mhFvRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/rust": "2.13.3", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.13.3", + "@parcel/workers": "2.13.3", + "@swc/helpers": "^0.5.0", + "browserslist": "^4.6.6", + "nullthrows": "^1.1.1", + "regenerator-runtime": "^0.14.1", + "semver": "^7.5.2" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.13.3" + } + }, + "node_modules/@parcel/transformer-json": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/transformer-json/-/transformer-json-2.13.3.tgz", + "integrity": "sha512-rrq0ab6J0w9ePtsxi0kAvpCmrUYXXAx1Z5PATZakv89rSYbHBKEdXxyCoKFui/UPVCUEGVs5r0iOFepdHpIyeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3", + "json5": "^2.2.0" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-postcss": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/transformer-postcss/-/transformer-postcss-2.13.3.tgz", + "integrity": "sha512-AIiWpU0QSFBrPcYIqAnhqB8RGE6yHFznnxztfg1t2zMSOnK3xoU6xqYKv8H/MduShGGrC3qVOeDfM8MUwzL3cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/rust": "2.13.3", + "@parcel/utils": "2.13.3", + "clone": "^2.1.1", + "nullthrows": "^1.1.1", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.2" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-posthtml": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/transformer-posthtml/-/transformer-posthtml-2.13.3.tgz", + "integrity": "sha512-5GSLyccpHASwFAu3uJ83gDIBSvfsGdVmhJvy0Vxe+K1Fklk2ibhvvtUHMhB7mg6SPHC+R9jsNc3ZqY04ZLeGjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3", + "@parcel/utils": "2.13.3", + "nullthrows": "^1.1.1", + "posthtml": "^0.16.5", + "posthtml-parser": "^0.12.1", + "posthtml-render": "^3.0.0", + "semver": "^7.5.2" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-raw": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/transformer-raw/-/transformer-raw-2.13.3.tgz", + "integrity": "sha512-BFsAbdQF0l8/Pdb7dSLJeYcd8jgwvAUbHgMink2MNXJuRUvDl19Gns8jVokU+uraFHulJMBj40+K/RTd33in4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-react-refresh-wrap": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.13.3.tgz", + "integrity": "sha512-mOof4cRyxsZRdg8kkWaFtaX98mHpxUhcGPU+nF9RQVa9q737ItxrorsPNR9hpZAyE2TtFNflNW7RoYsgvlLw8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.13.3", + "@parcel/utils": "2.13.3", + "react-refresh": ">=0.9 <=0.14" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-svg": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/transformer-svg/-/transformer-svg-2.13.3.tgz", + "integrity": "sha512-9jm7ZF4KHIrGLWlw/SFUz5KKJ20nxHvjFAmzde34R9Wu+F1BOjLZxae7w4ZRwvIc+UVOUcBBQFmhSVwVDZg6Dw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/plugin": "2.13.3", + "@parcel/rust": "2.13.3", + "nullthrows": "^1.1.1", + "posthtml": "^0.16.5", + "posthtml-parser": "^0.12.1", + "posthtml-render": "^3.0.0", + "semver": "^7.5.2" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.13.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/types": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/types/-/types-2.13.3.tgz", + "integrity": "sha512-+RpFHxx8fy8/dpuehHUw/ja9PRExC3wJoIlIIF42E7SLu2SvlTHtKm6EfICZzxCXNEBzjoDbamCRcN0nmTPlhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/types-internal": "2.13.3", + "@parcel/workers": "2.13.3" + } + }, + "node_modules/@parcel/types-internal": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/types-internal/-/types-internal-2.13.3.tgz", + "integrity": "sha512-Lhx0n+9RCp+Ipktf/I+CLm3zE9Iq9NtDd8b2Vr5lVWyoT8AbzBKIHIpTbhLS4kjZ80L3I6o93OYjqAaIjsqoZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/feature-flags": "2.13.3", + "@parcel/source-map": "^2.1.1", + "utility-types": "^3.10.0" + } + }, + "node_modules/@parcel/utils": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/utils/-/utils-2.13.3.tgz", + "integrity": "sha512-yxY9xw2wOUlJaScOXYZmMGoZ4Ck4Kqj+p6Koe5kLkkWM1j98Q0Dj2tf/mNvZi4yrdnlm+dclCwNRnuE8Q9D+pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/codeframe": "2.13.3", + "@parcel/diagnostic": "2.13.3", + "@parcel/logger": "2.13.3", + "@parcel/markdown-ansi": "2.13.3", + "@parcel/rust": "2.13.3", + "@parcel/source-map": "^2.1.1", + "chalk": "^4.1.2", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/workers": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-2.13.3.tgz", + "integrity": "sha512-oAHmdniWTRwwwsKbcF4t3VjOtKN+/W17Wj5laiYB+HLkfsjGTfIQPj3sdXmrlBAGpI4omIcvR70PHHXnfdTfwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.13.3", + "@parcel/logger": "2.13.3", + "@parcel/profiler": "2.13.3", + "@parcel/types-internal": "2.13.3", + "@parcel/utils": "2.13.3", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.13.3" + } + }, + "node_modules/@swc/core": { + "version": "1.10.12", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.12.tgz", + "integrity": "sha512-+iUL0PYpPm6N9AdV1wvafakvCqFegQus1aoEDxgFsv3/uNVNIyRaupf/v/Zkp5hbep2EzhtoJR0aiJIzDbXWHg==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.17" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.10.12", + "@swc/core-darwin-x64": "1.10.12", + "@swc/core-linux-arm-gnueabihf": "1.10.12", + "@swc/core-linux-arm64-gnu": "1.10.12", + "@swc/core-linux-arm64-musl": "1.10.12", + "@swc/core-linux-x64-gnu": "1.10.12", + "@swc/core-linux-x64-musl": "1.10.12", + "@swc/core-win32-arm64-msvc": "1.10.12", + "@swc/core-win32-ia32-msvc": "1.10.12", + "@swc/core-win32-x64-msvc": "1.10.12" + }, + "peerDependencies": { + "@swc/helpers": "*" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.10.12", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.12.tgz", + "integrity": "sha512-pOANQegUTAriW7jq3SSMZGM5l89yLVMs48R0F2UG6UZsH04SiViCnDctOGlA/Sa++25C+rL9MGMYM1jDLylBbg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.10.12", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.12.tgz", + "integrity": "sha512-m4kbpIDDsN1FrwfNQMU+FTrss356xsXvatLbearwR+V0lqOkjLBP0VmRvQfHEg+uy13VPyrT9gj4HLoztlci7w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.10.12", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.12.tgz", + "integrity": "sha512-OY9LcupgqEu8zVK+rJPes6LDJJwPDmwaShU96beTaxX2K6VrXbpwm5WbPS/8FfQTsmpnuA7dCcMPUKhNgmzTrQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.10.12", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.12.tgz", + "integrity": "sha512-nJD587rO0N4y4VZszz3xzVr7JIiCzSMhEMWnPjuh+xmPxDBz0Qccpr8xCr1cSxpl1uY7ERkqAGlKr6CwoV5kVg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.10.12", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.12.tgz", + "integrity": "sha512-oqhSmV+XauSf0C//MoQnVErNUB/5OzmSiUzuazyLsD5pwqKNN+leC3JtRQ/QVzaCpr65jv9bKexT9+I2Tt3xDw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.10.12", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.12.tgz", + "integrity": "sha512-XldSIHyjD7m1Gh+/8rxV3Ok711ENLI420CU2EGEqSe3VSGZ7pHJvJn9ZFbYpWhsLxPqBYMFjp3Qw+J6OXCPXCA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.10.12", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.12.tgz", + "integrity": "sha512-wvPXzJxzPgTqhyp1UskOx1hRTtdWxlyFD1cGWOxgLsMik0V9xKRgqKnMPv16Nk7L9xl6quQ6DuUHj9ID7L3oVw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.10.12", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.12.tgz", + "integrity": "sha512-TUYzWuu1O7uyIcRfxdm6Wh1u+gNnrW5M1DUgDOGZLsyQzgc2Zjwfh2llLhuAIilvCVg5QiGbJlpibRYJ/8QGsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.10.12", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.12.tgz", + "integrity": "sha512-4Qrw+0Xt+Fe2rz4OJ/dEPMeUf/rtuFWWAj/e0vL7J5laUHirzxawLRE5DCJLQTarOiYR6mWnmadt9o3EKzV6Xg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.10.12", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.12.tgz", + "integrity": "sha512-YiloZXLW7rUxJpALwHXaGjVaAEn+ChoblG7/3esque+Y7QCyheoBUJp2DVM1EeVA43jBfZ8tvYF0liWd9Tpz1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@swc/types": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.17.tgz", + "integrity": "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/base-x": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001696", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001696.tgz", + "integrity": "sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dotenv": { + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "11.0.7", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz", + "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.90", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.90.tgz", + "integrity": "sha512-C3PN4aydfW91Natdyd449Kw+BzhLmof6tzy5W1pFC5SpQxVXT+oyiyOG9AgYYSN9OdA/ik3YkCrpwqI8ug5Tug==", + "dev": true, + "license": "ISC" + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/get-port": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz", + "integrity": "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/htmlnano": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-2.1.1.tgz", + "integrity": "sha512-kAERyg/LuNZYmdqgCdYvugyLWNFAm8MWXpQMz1pLpetmCbFwoMxvkSoaAMlFrOC4OKTWI4KlZGT/RsNxg4ghOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^9.0.0", + "posthtml": "^0.16.5", + "timsort": "^0.3.0" + }, + "peerDependencies": { + "cssnano": "^7.0.0", + "postcss": "^8.3.11", + "purgecss": "^6.0.0", + "relateurl": "^0.2.7", + "srcset": "5.0.1", + "svgo": "^3.0.2", + "terser": "^5.10.0", + "uncss": "^0.17.3" + }, + "peerDependenciesMeta": { + "cssnano": { + "optional": true + }, + "postcss": { + "optional": true + }, + "purgecss": { + "optional": true + }, + "relateurl": { + "optional": true + }, + "srcset": { + "optional": true + }, + "svgo": { + "optional": true + }, + "terser": { + "optional": true + }, + "uncss": { + "optional": true + } + } + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-json": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz", + "integrity": "sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lightningcss": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.1.tgz", + "integrity": "sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^1.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.29.1", + "lightningcss-darwin-x64": "1.29.1", + "lightningcss-freebsd-x64": "1.29.1", + "lightningcss-linux-arm-gnueabihf": "1.29.1", + "lightningcss-linux-arm64-gnu": "1.29.1", + "lightningcss-linux-arm64-musl": "1.29.1", + "lightningcss-linux-x64-gnu": "1.29.1", + "lightningcss-linux-x64-musl": "1.29.1", + "lightningcss-win32-arm64-msvc": "1.29.1", + "lightningcss-win32-x64-msvc": "1.29.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.1.tgz", + "integrity": "sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.1.tgz", + "integrity": "sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.1.tgz", + "integrity": "sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.1.tgz", + "integrity": "sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.1.tgz", + "integrity": "sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.1.tgz", + "integrity": "sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.1.tgz", + "integrity": "sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.1.tgz", + "integrity": "sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.1.tgz", + "integrity": "sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.1.tgz", + "integrity": "sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lmdb": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.8.5.tgz", + "integrity": "sha512-9bMdFfc80S+vSldBmG3HOuLVHnxRdNTlpzR6QDnzqCQtCzGUEAGTzBKYMeIM+I/sU4oZfgbcbS7X7F65/z/oxQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "msgpackr": "^1.9.5", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.1.1", + "ordered-binary": "^1.4.1", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "2.8.5", + "@lmdb/lmdb-darwin-x64": "2.8.5", + "@lmdb/lmdb-linux-arm": "2.8.5", + "@lmdb/lmdb-linux-arm64": "2.8.5", + "@lmdb/lmdb-linux-x64": "2.8.5", + "@lmdb/lmdb-win32-x64": "2.8.5" + } + }, + "node_modules/lmdb/node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true, + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/msgpackr": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz", + "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/msgpackr-extract/node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", + "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp-build-optional-packages/node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ordered-binary": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz", + "integrity": "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==", + "dev": true, + "license": "MIT" + }, + "node_modules/parcel": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/parcel/-/parcel-2.13.3.tgz", + "integrity": "sha512-8GrC8C7J8mwRpAlk7EJ7lwdFTbCN+dcXH2gy5AsEs9pLfzo9wvxOTx6W0fzSlvCOvZOita+8GdfYlGfEt0tRgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/config-default": "2.13.3", + "@parcel/core": "2.13.3", + "@parcel/diagnostic": "2.13.3", + "@parcel/events": "2.13.3", + "@parcel/feature-flags": "2.13.3", + "@parcel/fs": "2.13.3", + "@parcel/logger": "2.13.3", + "@parcel/package-manager": "2.13.3", + "@parcel/reporter-cli": "2.13.3", + "@parcel/reporter-dev-server": "2.13.3", + "@parcel/reporter-tracer": "2.13.3", + "@parcel/utils": "2.13.3", + "chalk": "^4.1.2", + "commander": "^12.1.0", + "get-port": "^4.2.0" + }, + "bin": { + "parcel": "lib/bin.js" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/parcel-reporter-static-files-copy": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/parcel-reporter-static-files-copy/-/parcel-reporter-static-files-copy-1.5.3.tgz", + "integrity": "sha512-Ukq2SyJYn3GFIPCLamXuQ+2t+0j54llujjOUoRjtmVvfsuGnJDEpMznADeIoKuQDvy0jpxtWzWkQvxqI/j+U4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "^2.0.0-beta.1" + }, + "engines": { + "parcel": "^2.0.0-beta.1" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/posthtml": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.16.6.tgz", + "integrity": "sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "posthtml-parser": "^0.11.0", + "posthtml-render": "^3.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/posthtml-parser": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.12.1.tgz", + "integrity": "sha512-rYFmsDLfYm+4Ts2Oh4DCDSZPtdC1BLnRXAobypVzX9alj28KGl65dIFtgDY9zB57D0TC4Qxqrawuq/2et1P0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "htmlparser2": "^9.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/posthtml-render": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-3.0.0.tgz", + "integrity": "sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-json": "^2.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/posthtml/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/posthtml/node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/posthtml/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/posthtml/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/posthtml/node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/posthtml/node_modules/htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, + "node_modules/posthtml/node_modules/posthtml-parser": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.11.0.tgz", + "integrity": "sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "htmlparser2": "^7.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/react-error-overlay": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", + "integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==", + "dev": true, + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", + "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/srcset": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-5.0.1.tgz", + "integrity": "sha512-/P1UYbGfJVlxZag7aABNRrulEXAwCSDo7fklafOQrantuPTDmYgijJMks2zusPCVzgW9+4P69mq7w6pYuZpgxw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", + "dev": true, + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/package.json b/package.json index a8e13a48..6ff84628 100644 --- a/package.json +++ b/package.json @@ -2,10 +2,9 @@ "name": "javascript-snake", "version": "1.0.0", "description": "JavaScript Snake
By Patrick Gillespie
License: MIT
http://patorjk.com/games/snake", - "main": "index.html", "scripts": { - "start": "parcel index.html --open", - "build": "parcel build index.html", + "start": "parcel src/index.html --open", + "build": "parcel build src/index.html", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { @@ -18,8 +17,12 @@ "url": "https://github.com/patorjk/JavaScript-Snake/issues" }, "homepage": "https://github.com/patorjk/JavaScript-Snake#readme", - "dependencies": {}, "devDependencies": { - "parcel-bundler": "^1.6.1" + "parcel": "^2.13.3", + "parcel-reporter-static-files-copy": "^1.5.3" + }, + "staticFiles": { + "staticPath": "src/css", + "staticOutPath": "css" } } diff --git a/css/Senura-snake.css b/src/css/Senura-snake.css similarity index 94% rename from css/Senura-snake.css rename to src/css/Senura-snake.css index 180ea4a3..15ac9b61 100644 --- a/css/Senura-snake.css +++ b/src/css/Senura-snake.css @@ -72,10 +72,10 @@ a.snake-link:hover { } .snake-snakebody-alive { - background-image: url('./images/dark-snakeblock.png'); + background-image: url('src/css/images/dark-snakeblock.png'); } .snake-snakebody-dead { - background-image: url('./images/dead-dark-snakeblock.png'); + background-image: url('src/css/images/dead-dark-snakeblock.png'); } .snake-food-block { diff --git a/css/black-snake.css b/src/css/black-snake.css similarity index 92% rename from css/black-snake.css rename to src/css/black-snake.css index 0c460b7c..90d22abf 100644 --- a/css/black-snake.css +++ b/src/css/black-snake.css @@ -68,10 +68,10 @@ a.snake-link:hover { } .snake-snakebody-alive { - background-image: url('./css/images/snakeblock.png'), url('./images/snakeblock.png'); + background-image: url('src/cssss/images/snakeblock.png'), url('src/css/images/snakeblock.png'); } .snake-snakebody-dead { - background-image: url('./css/images/deadblock.png'), url('./images/deadblock.png'); + background-image: url('src/cssss/images/deadblock.png'), url('src/css/images/deadblock.png'); } .snake-food-block { diff --git a/css/dark-snake.css b/src/css/dark-snake.css similarity index 94% rename from css/dark-snake.css rename to src/css/dark-snake.css index ab8728d4..8603a1cb 100644 --- a/css/dark-snake.css +++ b/src/css/dark-snake.css @@ -72,10 +72,10 @@ a.snake-link:hover { } .snake-snakebody-alive { - background-image: url('./images/dark-snakeblock.png'); + background-image: url('src/css/images/dark-snakeblock.png'); } .snake-snakebody-dead { - background-image: url('./images/dead-dark-snakeblock.png'); + background-image: url('src/css/images/dead-dark-snakeblock.png'); } .snake-food-block { diff --git a/css/green-snake.css b/src/css/green-snake.css similarity index 95% rename from css/green-snake.css rename to src/css/green-snake.css index 17a347a3..64cf1564 100644 --- a/css/green-snake.css +++ b/src/css/green-snake.css @@ -74,10 +74,10 @@ a.snake-link:hover { } .snake-snakebody-alive { - background-image: url('./images/snakeblock.png'); + background-image: url('src/css/images/snakeblock.png'); } .snake-snakebody-dead { - background-image: url('./images/deadblock.png'); + background-image: url('src/css/images/deadblock.png'); } .snake-food-block { diff --git a/css/head-snake.css b/src/css/head-snake.css similarity index 90% rename from css/head-snake.css rename to src/css/head-snake.css index dc05c8f2..e077a44a 100644 --- a/css/head-snake.css +++ b/src/css/head-snake.css @@ -53,7 +53,7 @@ a.snake-link:hover { } #snake-snakehead-alive { - background-image: url('./images/green-head-snakeblock.png'); + background-image: url('src/css/images/green-head-snakeblock.png'); margin: 0px; padding: 0px; background-color: rgb(10, 173, 10); @@ -73,10 +73,10 @@ a.snake-link:hover { } .snake-snakebody-alive { - background-image: url('./images/green-body-snakeblock.png'), url('./images/green-body-snakeblock.png'); + background-image: url('src/css/images/green-body-snakeblock.png'), url('src/css/images/green-body-snakeblock.png'); } .snake-snakebody-dead { - background-image: url('./images/deadblock.png'), url('./images/deadblock.png'); + background-image: url('src/css/images/deadblock.png'), url('src/css/images/deadblock.png'); } .snake-food-block { diff --git a/css/images/Thumbs.db b/src/css/images/Thumbs.db similarity index 100% rename from css/images/Thumbs.db rename to src/css/images/Thumbs.db diff --git a/css/images/dark-snakeblock.png b/src/css/images/dark-snakeblock.png similarity index 100% rename from css/images/dark-snakeblock.png rename to src/css/images/dark-snakeblock.png diff --git a/css/images/dead-dark-snakeblock.png b/src/css/images/dead-dark-snakeblock.png similarity index 100% rename from css/images/dead-dark-snakeblock.png rename to src/css/images/dead-dark-snakeblock.png diff --git a/css/images/deadblock.png b/src/css/images/deadblock.png similarity index 100% rename from css/images/deadblock.png rename to src/css/images/deadblock.png diff --git a/css/images/deadblock_border.png b/src/css/images/deadblock_border.png similarity index 100% rename from css/images/deadblock_border.png rename to src/css/images/deadblock_border.png diff --git a/css/images/favicon.png b/src/css/images/favicon.png similarity index 100% rename from css/images/favicon.png rename to src/css/images/favicon.png diff --git a/css/images/green-body-snakeblock.png b/src/css/images/green-body-snakeblock.png similarity index 100% rename from css/images/green-body-snakeblock.png rename to src/css/images/green-body-snakeblock.png diff --git a/css/images/green-head-snakeblock.png b/src/css/images/green-head-snakeblock.png similarity index 100% rename from css/images/green-head-snakeblock.png rename to src/css/images/green-head-snakeblock.png diff --git a/css/images/matrix-food-block.png b/src/css/images/matrix-food-block.png similarity index 100% rename from css/images/matrix-food-block.png rename to src/css/images/matrix-food-block.png diff --git a/css/images/matrix-snake-block.png b/src/css/images/matrix-snake-block.png similarity index 100% rename from css/images/matrix-snake-block.png rename to src/css/images/matrix-snake-block.png diff --git a/css/images/neon-body-snakeblock.png b/src/css/images/neon-body-snakeblock.png similarity index 100% rename from css/images/neon-body-snakeblock.png rename to src/css/images/neon-body-snakeblock.png diff --git a/css/images/neon-dead-snakeblock.png b/src/css/images/neon-dead-snakeblock.png similarity index 100% rename from css/images/neon-dead-snakeblock.png rename to src/css/images/neon-dead-snakeblock.png diff --git a/css/images/snakeblock.png b/src/css/images/snakeblock.png similarity index 100% rename from css/images/snakeblock.png rename to src/css/images/snakeblock.png diff --git a/css/light-snake.css b/src/css/light-snake.css similarity index 95% rename from css/light-snake.css rename to src/css/light-snake.css index 069cbd88..3829ee4e 100644 --- a/css/light-snake.css +++ b/src/css/light-snake.css @@ -61,10 +61,10 @@ a.snake-link:hover { background-repeat: no-repeat; } .snake-snakebody-alive { - background-image: url('./images/snakeblock.png'); + background-image: url('src/css/images/snakeblock.png'); } .snake-snakebody-dead { - background-image: url('./images/deadblock.png'); + background-image: url('src/css/images/deadblock.png'); } .snake-food-block { margin: 0px; diff --git a/css/main-snake.css b/src/css/main-snake.css similarity index 93% rename from css/main-snake.css rename to src/css/main-snake.css index 82a05adb..5623c07e 100755 --- a/css/main-snake.css +++ b/src/css/main-snake.css @@ -67,10 +67,10 @@ a.snake-link:hover { } .snake-snakebody-alive { - background-image: url('./css/images/snakeblock.png'), url('./images/snakeblock.png'); + background-image: url('./images/snakeblock.png'), url('./images/snakeblock.png'); } .snake-snakebody-dead { - background-image: url('./css/images/deadblock.png'), url('./images/deadblock.png'); + background-image: url('./images/deadblock.png'), url('./images/deadblock.png'); } .snake-food-block { diff --git a/css/matrix-snake.css b/src/css/matrix-snake.css similarity index 92% rename from css/matrix-snake.css rename to src/css/matrix-snake.css index 5c8c79ce..643d6960 100644 --- a/css/matrix-snake.css +++ b/src/css/matrix-snake.css @@ -64,10 +64,10 @@ background-repeat: no-repeat; } .snake-snakebody-alive { -background-image: url('./images/matrix-snake-block.png'); +background-image: url('src/css/images/matrix-snake-block.png'); } .snake-snakebody-dead { -background-image: url('./images/deadblock.png'); +background-image: url('src/css/images/deadblock.png'); } .snake-food-block { @@ -76,7 +76,7 @@ padding: 0px; background-color: #FF0000; border: 0px solid #000080; position: absolute; -background-image: url("./images/matrix-food-block.png") +background-image: url("src/css/images/matrix-food-block.png") } .snake-playing-field { @@ -131,4 +131,4 @@ margin-top: -75px; margin-left: -158px; text-align: center; display: none; -} \ No newline at end of file +} diff --git a/css/neon-snake.css b/src/css/neon-snake.css similarity index 86% rename from css/neon-snake.css rename to src/css/neon-snake.css index 1be055f0..31b3291f 100644 --- a/css/neon-snake.css +++ b/src/css/neon-snake.css @@ -71,10 +71,10 @@ a.snake-link:hover { } .snake-snakebody-alive { - background-image: url('./images/neon-body-snakeblock.png'), url('./css/images/neon-body-snakeblock.png'); + background-image: url('src/css/images/neon-body-snakeblock.png'), url('src/cssss/images/neon-body-snakeblock.png'); } .snake-snakebody-dead { - background-image: url('./images/neon-dead-snakeblock.png'), url('./css/images/neon-dead-snakeblock.png'); + background-image: url('src/css/images/neon-dead-snakeblock.png'), url('src/cssss/images/neon-dead-snakeblock.png'); } .snake-food-block { diff --git a/css/teal-snake.css b/src/css/teal-snake.css similarity index 95% rename from css/teal-snake.css rename to src/css/teal-snake.css index f3ad07d1..8fbe6ffa 100644 --- a/css/teal-snake.css +++ b/src/css/teal-snake.css @@ -75,10 +75,10 @@ a.snake-link:hover { } .snake-snakebody-alive { - background-image: url('./images/snakeblock.png'); + background-image: url('src/css/images/snakeblock.png'); } .snake-snakebody-dead { - background-image: url('./images/dead-dark-snakeblock.png'); + background-image: url('src/css/images/dead-dark-snakeblock.png'); } .snake-food-block { diff --git a/index.html b/src/index.html similarity index 89% rename from index.html rename to src/index.html index 172fd32b..360fe818 100755 --- a/index.html +++ b/src/index.html @@ -4,15 +4,14 @@ JavaScript Snake - + + + + + +
+
+ Theme: + +
+
+ Mode: + +
+ +
+
+ +
+ +
+ + + + + diff --git a/src/css/Senura-snake.css b/src/css/Senura-snake.css index 15ac9b61..2102a783 100644 --- a/src/css/Senura-snake.css +++ b/src/css/Senura-snake.css @@ -5,29 +5,33 @@ http://patorjk.com/games/snake */ body { - margin:0px; - padding:0px; - background-color:#000000; + margin: 0px; + padding: 0px; + background-color: #000000; } .snake-toolbar { - color: #847a87; + color: #847a87; } #game-area { - margin:10px; - padding:0px; + margin: 10px; + padding: 0px; } -#game-area:focus { outline: none; } +#game-area:focus { + outline: none; +} #mode-wrapper { - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - color: #f6f0f7; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + color: #f6f0f7; } -a.snake-link, a.snake-link:link, a.snake-link:visited { +a.snake-link, +a.snake-link:link, +a.snake-link:visited { color: #605d61; } @@ -36,106 +40,107 @@ a.snake-link:hover { } .snake-pause-screen { - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position:absolute; - width:300px; - height:80px; - text-align:center; - top:50%; - left:50%; - margin-top:-40px; - margin-left:-150px; - display:none; - background-color:#ffffff; - color: #938996; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + width: 300px; + height: 80px; + text-align: center; + top: 50%; + left: 50%; + margin-top: -40px; + margin-left: -150px; + display: none; + background-color: #ffffff; + color: #938996; } .snake-panel-component { - position: absolute; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - color: #cf6d6d; - text-align: center; - background-color: #550b70; - padding: 8px; - margin: 0px; + position: absolute; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + color: #cf6d6d; + text-align: center; + background-color: #550b70; + padding: 8px; + margin: 0px; } .snake-snakebody-block { - margin: 0px; - padding: 0px; - background-color: #eddff2; - position: absolute; - border: 0px solid black; - background-repeat: no-repeat; + margin: 0px; + padding: 0px; + background-color: #eddff2; + position: absolute; + border: 0px solid black; + background-repeat: no-repeat; } .snake-snakebody-alive { - background-image: url('src/css/images/dark-snakeblock.png'); + background-image: url("src/css/images/dark-snakeblock.png"); } .snake-snakebody-dead { - background-image: url('src/css/images/dead-dark-snakeblock.png'); + background-image: url("src/css/images/dead-dark-snakeblock.png"); } .snake-food-block { - margin: 0px; - padding: 0px; - background-color: black; - border: 2px solid #000000; - position: absolute; + margin: 0px; + padding: 0px; + background-color: black; + border: 2px solid #000000; + position: absolute; } .snake-playing-field { - margin: 0px; - padding: 0px; - position: absolute; - background-color: #fcfcfc; - border: 3px solid black; + margin: 0px; + padding: 0px; + position: absolute; + background-color: #fcfcfc; + border: 3px solid black; } .snake-game-container { - margin: 0px; - padding: 0px; - border-width: 0px; - border-style: none; - zoom: 1; - background-color: #3E2E44; - position: relative; + margin: 0px; + padding: 0px; + border-width: 0px; + border-style: none; + zoom: 1; + background-color: #3e2e44; + position: relative; } .snake-welcome-dialog { - padding: 8px; - margin: 0px; - background-color: black; - color: #ab00de; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - /*height: 150px;*/ - margin-top: -100px; - margin-left: -158px; - text-align: center; - display: block; -} - -.snake-try-again-dialog, .snake-win-dialog { - padding: 8px; - margin: 0px; - background-color: black; - color: #ab00de; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - height: 100px; - margin-top: -75px; - margin-left: -158px; - text-align: center; - display: none; + padding: 8px; + margin: 0px; + background-color: black; + color: #ab00de; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + /*height: 150px;*/ + margin-top: -100px; + margin-left: -158px; + text-align: center; + display: block; +} + +.snake-try-again-dialog, +.snake-win-dialog { + padding: 8px; + margin: 0px; + background-color: black; + color: #ab00de; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + height: 100px; + margin-top: -75px; + margin-left: -158px; + text-align: center; + display: none; } diff --git a/src/css/black-snake.css b/src/css/black-snake.css index 90d22abf..a92710b5 100644 --- a/src/css/black-snake.css +++ b/src/css/black-snake.css @@ -4,133 +4,139 @@ By Patrick Gillespie http://patorjk.com/games/snake */ body { - margin:0px; - padding:0px; - background-color: black; - color: white; + margin: 0px; + padding: 0px; + background-color: black; + color: white; } #game-area { - margin:10px; - padding:0px; + margin: 10px; + padding: 0px; } #mode-wrapper { - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; } -#game-area:focus { outline: none; } +#game-area:focus { + outline: none; +} -a.snake-link, a.snake-link:link, a.snake-link:visited { - color: #FCFC54; +a.snake-link, +a.snake-link:link, +a.snake-link:visited { + color: #fcfc54; } a.snake-link:hover { - color: #FfFf54; + color: #ffff54; } .snake-pause-screen { - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position:absolute; - width:300px; - height:80px; - text-align:center; - top:50%; - left:50%; - margin-top:-40px; - margin-left:-150px; - display:none; - background-color:black; - color:white; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + width: 300px; + height: 80px; + text-align: center; + top: 50%; + left: 50%; + margin-top: -40px; + margin-left: -150px; + display: none; + background-color: black; + color: white; } .snake-panel-component { - position: absolute; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - color: #ffffff; - text-align: center; - padding: 8px; - margin: 0px; + position: absolute; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + color: #ffffff; + text-align: center; + padding: 8px; + margin: 0px; } .snake-snakebody-block { - margin: 0px; - padding: 0px; - background-color: #FF0000; - position: absolute; - border: 0px solid #000080; - background-repeat: no-repeat; + margin: 0px; + padding: 0px; + background-color: #ff0000; + position: absolute; + border: 0px solid #000080; + background-repeat: no-repeat; } .snake-snakebody-alive { - background-image: url('src/cssss/images/snakeblock.png'), url('src/css/images/snakeblock.png'); + background-image: url("src/cssss/images/snakeblock.png"), + url("src/css/images/snakeblock.png"); } .snake-snakebody-dead { - background-image: url('src/cssss/images/deadblock.png'), url('src/css/images/deadblock.png'); + background-image: url("src/cssss/images/deadblock.png"), + url("src/css/images/deadblock.png"); } .snake-food-block { - margin: 0px; - padding: 0px; - background-color: aqua; - border: 0px solid #000080; - position: absolute; + margin: 0px; + padding: 0px; + background-color: aqua; + border: 0px solid #000080; + position: absolute; } .snake-playing-field { - margin: 0px; - padding: 0px; - position: absolute; - background-color: purple; - border: 0px solid purple; + margin: 0px; + padding: 0px; + position: absolute; + background-color: purple; + border: 0px solid purple; } .snake-game-container { - margin: 0px; - padding: 0px; - border-width: 0px; - border-style: none; - zoom: 1; - position: relative; + margin: 0px; + padding: 0px; + border-width: 0px; + border-style: none; + zoom: 1; + position: relative; } .snake-welcome-dialog { - padding: 8px; - margin: 0px; - background-color: #000000; - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - /*height: 150px;*/ - margin-top: -100px; - margin-left: -158px; - text-align: center; - display: block; + padding: 8px; + margin: 0px; + background-color: #000000; + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + /*height: 150px;*/ + margin-top: -100px; + margin-left: -158px; + text-align: center; + display: block; } -.snake-try-again-dialog, .snake-win-dialog { - padding: 8px; - margin: 0px; - background-color: #000000; - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - height: 100px; - margin-top: -75px; - margin-left: -158px; - text-align: center; - display: none; +.snake-try-again-dialog, +.snake-win-dialog { + padding: 8px; + margin: 0px; + background-color: #000000; + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + height: 100px; + margin-top: -75px; + margin-left: -158px; + text-align: center; + display: none; } diff --git a/src/css/dark-snake.css b/src/css/dark-snake.css index 8603a1cb..16388e41 100644 --- a/src/css/dark-snake.css +++ b/src/css/dark-snake.css @@ -5,29 +5,33 @@ http://patorjk.com/games/snake */ body { - margin:0px; - padding:0px; - background-color:#3E2E44; + margin: 0px; + padding: 0px; + background-color: #3e2e44; } .snake-toolbar { - color: #938996; + color: #938996; } #game-area { - margin:10px; - padding:0px; + margin: 10px; + padding: 0px; } -#game-area:focus { outline: none; } +#game-area:focus { + outline: none; +} #mode-wrapper { - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - color: #938996; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + color: #938996; } -a.snake-link, a.snake-link:link, a.snake-link:visited { +a.snake-link, +a.snake-link:link, +a.snake-link:visited { color: #938996; } @@ -36,106 +40,107 @@ a.snake-link:hover { } .snake-pause-screen { - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position:absolute; - width:300px; - height:80px; - text-align:center; - top:50%; - left:50%; - margin-top:-40px; - margin-left:-150px; - display:none; - background-color:#3E2E44; - color: #938996; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + width: 300px; + height: 80px; + text-align: center; + top: 50%; + left: 50%; + margin-top: -40px; + margin-left: -150px; + display: none; + background-color: #3e2e44; + color: #938996; } .snake-panel-component { - position: absolute; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - color: #938996; - text-align: center; - background-color: #3E2E44; - padding: 8px; - margin: 0px; + position: absolute; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + color: #938996; + text-align: center; + background-color: #3e2e44; + padding: 8px; + margin: 0px; } .snake-snakebody-block { - margin: 0px; - padding: 0px; - background-color: #3E2E44; - position: absolute; - border: 0px solid black; - background-repeat: no-repeat; + margin: 0px; + padding: 0px; + background-color: #3e2e44; + position: absolute; + border: 0px solid black; + background-repeat: no-repeat; } .snake-snakebody-alive { - background-image: url('src/css/images/dark-snakeblock.png'); + background-image: url("src/css/images/dark-snakeblock.png"); } .snake-snakebody-dead { - background-image: url('src/css/images/dead-dark-snakeblock.png'); + background-image: url("src/css/images/dead-dark-snakeblock.png"); } .snake-food-block { - margin: 0px; - padding: 0px; - background-color: black; - border: 2px solid #3E2E44; - position: absolute; + margin: 0px; + padding: 0px; + background-color: black; + border: 2px solid #3e2e44; + position: absolute; } .snake-playing-field { - margin: 0px; - padding: 0px; - position: absolute; - background-color: #312E44; - border: 3px solid black; + margin: 0px; + padding: 0px; + position: absolute; + background-color: #312e44; + border: 3px solid black; } .snake-game-container { - margin: 0px; - padding: 0px; - border-width: 0px; - border-style: none; - zoom: 1; - background-color: #3E2E44; - position: relative; + margin: 0px; + padding: 0px; + border-width: 0px; + border-style: none; + zoom: 1; + background-color: #3e2e44; + position: relative; } .snake-welcome-dialog { - padding: 8px; - margin: 0px; - background-color: black; - color: #938996; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - /*height: 150px;*/ - margin-top: -100px; - margin-left: -158px; - text-align: center; - display: block; -} - -.snake-try-again-dialog, .snake-win-dialog { - padding: 8px; - margin: 0px; - background-color: black; - color: #938996; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - height: 100px; - margin-top: -75px; - margin-left: -158px; - text-align: center; - display: none; + padding: 8px; + margin: 0px; + background-color: black; + color: #938996; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + /*height: 150px;*/ + margin-top: -100px; + margin-left: -158px; + text-align: center; + display: block; +} + +.snake-try-again-dialog, +.snake-win-dialog { + padding: 8px; + margin: 0px; + background-color: black; + color: #938996; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + height: 100px; + margin-top: -75px; + margin-left: -158px; + text-align: center; + display: none; } diff --git a/src/css/green-snake.css b/src/css/green-snake.css index 64cf1564..9cd114c5 100644 --- a/src/css/green-snake.css +++ b/src/css/green-snake.css @@ -4,140 +4,144 @@ By Patrick Gillespie http://patorjk.com/games/snake */ body { - margin:0px; - padding:0px; - background-color: darkgreen; + margin: 0px; + padding: 0px; + background-color: darkgreen; } .snake-toolbar { - background-color: rgba(255,255,255,0.4); - border-radius: 10px; + background-color: rgba(255, 255, 255, 0.4); + border-radius: 10px; } #game-area { - margin:10px; - padding:0px; - background-color: lightgreen; + margin: 10px; + padding: 0px; + background-color: lightgreen; } #mode-wrapper { - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; } -#game-area:focus { outline: none; } +#game-area:focus { + outline: none; +} -a.snake-link, a.snake-link:link, a.snake-link:visited { +a.snake-link, +a.snake-link:link, +a.snake-link:visited { color: black; } a.snake-link:hover { - color: #FfFf54; + color: #ffff54; } .snake-pause-screen { - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position:absolute; - width:300px; - height:80px; - text-align:center; - top:50%; - left:50%; - margin-top:-40px; - margin-left:-150px; - display:none; - background-color:black; - color:white; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + width: 300px; + height: 80px; + text-align: center; + top: 50%; + left: 50%; + margin-top: -40px; + margin-left: -150px; + display: none; + background-color: black; + color: white; } .snake-panel-component { - position: absolute; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - color: black; - text-align: center; - background-color: white; - padding: 8px; - margin: 0px; + position: absolute; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + color: black; + text-align: center; + background-color: white; + padding: 8px; + margin: 0px; } .snake-snakebody-block { - margin: 0px; - padding: 0px; - background-color: #FF0000; - position: absolute; - border: 0px solid #000080; - background-repeat: no-repeat; + margin: 0px; + padding: 0px; + background-color: #ff0000; + position: absolute; + border: 0px solid #000080; + background-repeat: no-repeat; } .snake-snakebody-alive { - background-image: url('src/css/images/snakeblock.png'); + background-image: url("src/css/images/snakeblock.png"); } .snake-snakebody-dead { - background-image: url('src/css/images/deadblock.png'); + background-image: url("src/css/images/deadblock.png"); } .snake-food-block { - margin: 0px; - padding: 0px; - background-color: black; - border: 0px solid #000080; - position: absolute; + margin: 0px; + padding: 0px; + background-color: black; + border: 0px solid #000080; + position: absolute; } .snake-playing-field { - margin: 0px; - padding: 0px; - position: absolute; - background-color: white; - border: 0px solid #0000A8; + margin: 0px; + padding: 0px; + position: absolute; + background-color: white; + border: 0px solid #0000a8; } .snake-game-container { - margin: 0px; - padding: 0px; - border-width: 0px; - border-style: none; - zoom: 1; - background-color: #FC5454; - position: relative; + margin: 0px; + padding: 0px; + border-width: 0px; + border-style: none; + zoom: 1; + background-color: #fc5454; + position: relative; } .snake-welcome-dialog { - padding: 8px; - margin: 0px; - background-color: #000000; - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - /*height: 150px;*/ - margin-top: -100px; - margin-left: -158px; - text-align: center; - display: block; -} - -.snake-try-again-dialog, .snake-win-dialog { - padding: 8px; - margin: 0px; - background-color: #000000; - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - height: 100px; - margin-top: -75px; - margin-left: -158px; - text-align: center; - display: none; + padding: 8px; + margin: 0px; + background-color: #000000; + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + /*height: 150px;*/ + margin-top: -100px; + margin-left: -158px; + text-align: center; + display: block; +} + +.snake-try-again-dialog, +.snake-win-dialog { + padding: 8px; + margin: 0px; + background-color: #000000; + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + height: 100px; + margin-top: -75px; + margin-left: -158px; + text-align: center; + display: none; } diff --git a/src/css/head-snake.css b/src/css/head-snake.css index e077a44a..0e7daf95 100644 --- a/src/css/head-snake.css +++ b/src/css/head-snake.css @@ -1,142 +1,148 @@ body { - margin:0px; - padding:0px; - background-color: rgb(0, 0, 0); + margin: 0px; + padding: 0px; + background-color: rgb(0, 0, 0); } #game-area { - margin:10px; - padding:0px; + margin: 10px; + padding: 0px; } #mode-wrapper { - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; } -#game-area:focus { outline: none; } +#game-area:focus { + outline: none; +} -a.snake-link, a.snake-link:link, a.snake-link:visited { - color: #FCFC54; +a.snake-link, +a.snake-link:link, +a.snake-link:visited { + color: #fcfc54; } a.snake-link:hover { - color: #FfFf54; + color: #ffff54; } .snake-pause-screen { - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position:absolute; - width:300px; - height:80px; - text-align:center; - top:50%; - left:50%; - margin-top:-40px; - margin-left:-150px; - display:none; - background-color:black; - color:white; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + width: 300px; + height: 80px; + text-align: center; + top: 50%; + left: 50%; + margin-top: -40px; + margin-left: -150px; + display: none; + background-color: black; + color: white; } .snake-panel-component { - position: absolute; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - color: #ffffff; - text-align: center; - padding: 8px; - margin: 0px; + position: absolute; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + color: #ffffff; + text-align: center; + padding: 8px; + margin: 0px; } #snake-snakehead-alive { - background-image: url('src/css/images/green-head-snakeblock.png'); - margin: 0px; - padding: 0px; - background-color: rgb(10, 173, 10); - position: absolute; - border: 0px solid #000080; - background-repeat: no-repeat; - border-radius: 4px; + background-image: url("src/css/images/green-head-snakeblock.png"); + margin: 0px; + padding: 0px; + background-color: rgb(10, 173, 10); + position: absolute; + border: 0px solid #000080; + background-repeat: no-repeat; + border-radius: 4px; } .snake-snakebody-block { - margin: 0px; - padding: 0px; - background-color: #FF0000; - position: absolute; - border: 0px solid #000080; - background-repeat: no-repeat; + margin: 0px; + padding: 0px; + background-color: #ff0000; + position: absolute; + border: 0px solid #000080; + background-repeat: no-repeat; } .snake-snakebody-alive { - background-image: url('src/css/images/green-body-snakeblock.png'), url('src/css/images/green-body-snakeblock.png'); + background-image: url("src/css/images/green-body-snakeblock.png"), + url("src/css/images/green-body-snakeblock.png"); } .snake-snakebody-dead { - background-image: url('src/css/images/deadblock.png'), url('src/css/images/deadblock.png'); + background-image: url("src/css/images/deadblock.png"), + url("src/css/images/deadblock.png"); } .snake-food-block { - margin: 0px; - padding: 0px; - background-color: rgb(182, 11, 11); - border: 0px solid #000080; - position: absolute; - border-radius: 6px; + margin: 0px; + padding: 0px; + background-color: rgb(182, 11, 11); + border: 0px solid #000080; + position: absolute; + border-radius: 6px; } .snake-playing-field { - margin: 0px; - padding: 0px; - position: absolute; - background-color: rgb(245, 245, 220); - border: 0px solid #0000A8; + margin: 0px; + padding: 0px; + position: absolute; + background-color: rgb(245, 245, 220); + border: 0px solid #0000a8; } .snake-game-container { - margin: 0px; - padding: 0px; - border-width: 0px; - border-style: none; - zoom: 1; - position: relative; + margin: 0px; + padding: 0px; + border-width: 0px; + border-style: none; + zoom: 1; + position: relative; } .snake-welcome-dialog { - padding: 8px; - margin: 0px; - background-color: #000000; - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - /*height: 150px;*/ - margin-top: -100px; - margin-left: -158px; - text-align: center; - display: block; -} - -.snake-try-again-dialog, .snake-win-dialog { - padding: 8px; - margin: 0px; - background-color: #000000; - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - height: 100px; - margin-top: -75px; - margin-left: -158px; - text-align: center; - display: none; + padding: 8px; + margin: 0px; + background-color: #000000; + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + /*height: 150px;*/ + margin-top: -100px; + margin-left: -158px; + text-align: center; + display: block; +} + +.snake-try-again-dialog, +.snake-win-dialog { + padding: 8px; + margin: 0px; + background-color: #000000; + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + height: 100px; + margin-top: -75px; + margin-left: -158px; + text-align: center; + display: none; } diff --git a/src/css/light-snake.css b/src/css/light-snake.css index 3829ee4e..db0be890 100644 --- a/src/css/light-snake.css +++ b/src/css/light-snake.css @@ -5,120 +5,123 @@ http://patorjk.com/games/snake */ body { - margin: 0px; - padding: 0px; - background-color: #f73378; + margin: 0px; + padding: 0px; + background-color: #f73378; } #game-area { - margin: 10px; - padding: 0px; + margin: 10px; + padding: 0px; } #mode-wrapper { - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; } #game-area:focus { - outline: none; + outline: none; } -a.snake-link, a.snake-link:link, a.snake-link:visited { - color: #FCFC54; +a.snake-link, +a.snake-link:link, +a.snake-link:visited { + color: #fcfc54; } a.snake-link:hover { - color: #FfFf54; + color: #ffff54; } .snake-pause-screen { - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - width: 300px; - height: 80px; - text-align: center; - top: 50%; - left: 50%; - margin-top: -40px; - margin-left: -150px; - display: none; - background-color: black; - color: white; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + width: 300px; + height: 80px; + text-align: center; + top: 50%; + left: 50%; + margin-top: -40px; + margin-left: -150px; + display: none; + background-color: black; + color: white; } .snake-panel-component { - position: absolute; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - color: #ffffff; - text-align: center; - padding: 8px; - margin: 0px; + position: absolute; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + color: #ffffff; + text-align: center; + padding: 8px; + margin: 0px; } .snake-snakebody-block { - margin: 0px; - padding: 0px; - background-color: #FF0000; - position: absolute; - border: 0px solid #000080; - background-repeat: no-repeat; + margin: 0px; + padding: 0px; + background-color: #ff0000; + position: absolute; + border: 0px solid #000080; + background-repeat: no-repeat; } .snake-snakebody-alive { - background-image: url('src/css/images/snakeblock.png'); + background-image: url("src/css/images/snakeblock.png"); } .snake-snakebody-dead { - background-image: url('src/css/images/deadblock.png'); + background-image: url("src/css/images/deadblock.png"); } .snake-food-block { - margin: 0px; - padding: 0px; - background-color: #6cfd6a; - border: 0px solid #000080; - position: absolute; + margin: 0px; + padding: 0px; + background-color: #6cfd6a; + border: 0px solid #000080; + position: absolute; } .snake-playing-field { - margin: 0px; - padding: 0px; - position: absolute; - background-color: #ab003c; - border: 0px solid #ab003c; + margin: 0px; + padding: 0px; + position: absolute; + background-color: #ab003c; + border: 0px solid #ab003c; } .snake-game-container { - margin: 0px; - padding: 0px; - border-width: 0px; - border-style: none; - zoom: 1; - position: relative; + margin: 0px; + padding: 0px; + border-width: 0px; + border-style: none; + zoom: 1; + position: relative; } .snake-welcome-dialog { - padding: 8px; - margin: 0px; - background-color: #000000; - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - /*height: 150px;*/ - margin-top: -100px; - margin-left: -158px; - text-align: center; - display: block; -} -.snake-try-again-dialog, .snake-win-dialog { - padding: 8px; - margin: 0px; - background-color: #000000; - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - height: 100px; - margin-top: -75px; - margin-left: -158px; - text-align: center; - display: none; + padding: 8px; + margin: 0px; + background-color: #000000; + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + /*height: 150px;*/ + margin-top: -100px; + margin-left: -158px; + text-align: center; + display: block; +} +.snake-try-again-dialog, +.snake-win-dialog { + padding: 8px; + margin: 0px; + background-color: #000000; + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + height: 100px; + margin-top: -75px; + margin-left: -158px; + text-align: center; + display: none; } diff --git a/src/css/main-snake.css b/src/css/main-snake.css index 5623c07e..7938bf34 100755 --- a/src/css/main-snake.css +++ b/src/css/main-snake.css @@ -4,132 +4,137 @@ By Patrick Gillespie http://patorjk.com/games/snake */ body { - margin:0px; - padding:0px; - background-color: #FC5454; + margin: 0px; + padding: 0px; + background-color: #fc5454; } #game-area { - margin:10px; - padding:0px; + margin: 10px; + padding: 0px; } #mode-wrapper { - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; } -#game-area:focus { outline: none; } +#game-area:focus { + outline: none; +} -a.snake-link, a.snake-link:link, a.snake-link:visited { - color: #FCFC54; +a.snake-link, +a.snake-link:link, +a.snake-link:visited { + color: #fcfc54; } a.snake-link:hover { - color: #FfFf54; + color: #ffff54; } .snake-pause-screen { - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position:absolute; - width:300px; - height:80px; - text-align:center; - top:50%; - left:50%; - margin-top:-40px; - margin-left:-150px; - display:none; - background-color:black; - color:white; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + width: 300px; + height: 80px; + text-align: center; + top: 50%; + left: 50%; + margin-top: -40px; + margin-left: -150px; + display: none; + background-color: black; + color: white; } .snake-panel-component { - position: absolute; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - color: #ffffff; - text-align: center; - padding: 8px; - margin: 0px; + position: absolute; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + color: #ffffff; + text-align: center; + padding: 8px; + margin: 0px; } .snake-snakebody-block { - margin: 0px; - padding: 0px; - background-color: #FF0000; - position: absolute; - border: 0px solid #000080; - background-repeat: no-repeat; + margin: 0px; + padding: 0px; + background-color: #ff0000; + position: absolute; + border: 0px solid #000080; + background-repeat: no-repeat; } .snake-snakebody-alive { - background-image: url('./images/snakeblock.png'), url('./images/snakeblock.png'); + background-image: url("./images/snakeblock.png"), + url("./images/snakeblock.png"); } .snake-snakebody-dead { - background-image: url('./images/deadblock.png'), url('./images/deadblock.png'); + background-image: url("./images/deadblock.png"), url("./images/deadblock.png"); } .snake-food-block { - margin: 0px; - padding: 0px; - background-color: #FF0000; - border: 0px solid #000080; - position: absolute; + margin: 0px; + padding: 0px; + background-color: #ff0000; + border: 0px solid #000080; + position: absolute; } .snake-playing-field { - margin: 0px; - padding: 0px; - position: absolute; - background-color: #0000A8; - border: 0px solid #0000A8; + margin: 0px; + padding: 0px; + position: absolute; + background-color: #0000a8; + border: 0px solid #0000a8; } .snake-game-container { - margin: 0px; - padding: 0px; - border-width: 0px; - border-style: none; - zoom: 1; - position: relative; + margin: 0px; + padding: 0px; + border-width: 0px; + border-style: none; + zoom: 1; + position: relative; } .snake-welcome-dialog { - padding: 8px; - margin: 0px; - background-color: #000000; - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - /*height: 150px;*/ - margin-top: -100px; - margin-left: -158px; - text-align: center; - display: block; + padding: 8px; + margin: 0px; + background-color: #000000; + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + /*height: 150px;*/ + margin-top: -100px; + margin-left: -158px; + text-align: center; + display: block; } -.snake-try-again-dialog, .snake-win-dialog { - padding: 8px; - margin: 0px; - background-color: #000000; - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - height: 100px; - margin-top: -75px; - margin-left: -158px; - text-align: center; - display: none; +.snake-try-again-dialog, +.snake-win-dialog { + padding: 8px; + margin: 0px; + background-color: #000000; + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + height: 100px; + margin-top: -75px; + margin-left: -158px; + text-align: center; + display: none; } diff --git a/src/css/neon-snake.css b/src/css/neon-snake.css index 31b3291f..49591510 100644 --- a/src/css/neon-snake.css +++ b/src/css/neon-snake.css @@ -1,139 +1,145 @@ -/* -JavaScript Snake -By Patrick Gillespie -http://patorjk.com/games/snake -*/ -body { - margin:0px; - padding:0px; - background-color: #000000; -} - -.snake-toolbar { - color: #ffffff; -} - -#game-area { - margin:10px; - padding:0px; -} - -#mode-wrapper { - color: #ffffff; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - -} - -#game-area:focus { outline: none; } - -a.snake-link, a.snake-link:link, a.snake-link:visited { - color: #00FFE0; -} - -a.snake-link:hover { - color: #0FFF00; -} - -.snake-pause-screen { - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position:absolute; - width:300px; - height:80px; - text-align:center; - top:50%; - left:50%; - margin-top:-40px; - margin-left:-150px; - display:none; - background-color:#0FFF00; - color:#000000; -} - -.snake-panel-component { - position: absolute; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - color: #ffffff; - text-align: center; - padding: 8px; - margin: 0px; -} - -.snake-snakebody-block { - margin: 0px; - padding: 0px; - background-color: #FF0000; - position: absolute; - border: 0px solid #000080; - background-repeat: no-repeat; -} - -.snake-snakebody-alive { - background-image: url('src/css/images/neon-body-snakeblock.png'), url('src/cssss/images/neon-body-snakeblock.png'); -} -.snake-snakebody-dead { - background-image: url('src/css/images/neon-dead-snakeblock.png'), url('src/cssss/images/neon-dead-snakeblock.png'); -} - -.snake-food-block { - margin: 0px; - padding: 0px; - background-color: #FF0000; - border: 0px solid #000080; - position: absolute; -} - -.snake-playing-field { - margin: 0px; - padding: 0px; - position: absolute; - background-color: #00FFD4; - border: 0px solid #0000A8; -} - -.snake-game-container { - margin: 0px; - padding: 0px; - border-width: 0px; - border-style: none; - zoom: 1; - position: relative; -} - -.snake-welcome-dialog { - padding: 8px; - margin: 0px; - background-color: #0FFF00; - color: #000000; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - /*height: 150px;*/ - margin-top: -100px; - margin-left: -158px; - text-align: center; - display: block; -} - -.snake-try-again-dialog, .snake-win-dialog { - padding: 8px; - margin: 0px; - background-color: #0FFF00; - color: #000000; - font-family: Verdana, arial, helvetica, sans-serif; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - height: 100px; - margin-top: -75px; - margin-left: -158px; - text-align: center; - display: none; -} +/* +JavaScript Snake +By Patrick Gillespie +http://patorjk.com/games/snake +*/ +body { + margin: 0px; + padding: 0px; + background-color: #000000; +} + +.snake-toolbar { + color: #ffffff; +} + +#game-area { + margin: 10px; + padding: 0px; +} + +#mode-wrapper { + color: #ffffff; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; +} + +#game-area:focus { + outline: none; +} + +a.snake-link, +a.snake-link:link, +a.snake-link:visited { + color: #00ffe0; +} + +a.snake-link:hover { + color: #0fff00; +} + +.snake-pause-screen { + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + width: 300px; + height: 80px; + text-align: center; + top: 50%; + left: 50%; + margin-top: -40px; + margin-left: -150px; + display: none; + background-color: #0fff00; + color: #000000; +} + +.snake-panel-component { + position: absolute; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + color: #ffffff; + text-align: center; + padding: 8px; + margin: 0px; +} + +.snake-snakebody-block { + margin: 0px; + padding: 0px; + background-color: #ff0000; + position: absolute; + border: 0px solid #000080; + background-repeat: no-repeat; +} + +.snake-snakebody-alive { + background-image: url("src/css/images/neon-body-snakeblock.png"), + url("src/cssss/images/neon-body-snakeblock.png"); +} +.snake-snakebody-dead { + background-image: url("src/css/images/neon-dead-snakeblock.png"), + url("src/cssss/images/neon-dead-snakeblock.png"); +} + +.snake-food-block { + margin: 0px; + padding: 0px; + background-color: #ff0000; + border: 0px solid #000080; + position: absolute; +} + +.snake-playing-field { + margin: 0px; + padding: 0px; + position: absolute; + background-color: #00ffd4; + border: 0px solid #0000a8; +} + +.snake-game-container { + margin: 0px; + padding: 0px; + border-width: 0px; + border-style: none; + zoom: 1; + position: relative; +} + +.snake-welcome-dialog { + padding: 8px; + margin: 0px; + background-color: #0fff00; + color: #000000; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + /*height: 150px;*/ + margin-top: -100px; + margin-left: -158px; + text-align: center; + display: block; +} + +.snake-try-again-dialog, +.snake-win-dialog { + padding: 8px; + margin: 0px; + background-color: #0fff00; + color: #000000; + font-family: Verdana, arial, helvetica, sans-serif; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + height: 100px; + margin-top: -75px; + margin-left: -158px; + text-align: center; + display: none; +} diff --git a/src/css/teal-snake.css b/src/css/teal-snake.css index 8fbe6ffa..ac06471a 100644 --- a/src/css/teal-snake.css +++ b/src/css/teal-snake.css @@ -3,34 +3,37 @@ JavaScript Snake By Patrick Gillespie http://patorjk.com/games/snake */ -@import url('https://fonts.googleapis.com/css2?family=Electrolize&display=swap'); - +@import url("https://fonts.googleapis.com/css2?family=Electrolize&display=swap"); body { - margin:0px; - padding:0px; - background-color:teal; + margin: 0px; + padding: 0px; + background-color: teal; } .snake-toolbar { - font-family: Electrolize; - color: white; + font-family: Electrolize; + color: white; } #game-area { - margin:10px; - padding:0px; + margin: 10px; + padding: 0px; } -#game-area:focus { outline: none; } +#game-area:focus { + outline: none; +} #mode-wrapper { - font-family: Electrolize; - font-size: 14px; - color: whitesmoke; + font-family: Electrolize; + font-size: 14px; + color: whitesmoke; } -a.snake-link, a.snake-link:link, a.snake-link:visited { +a.snake-link, +a.snake-link:link, +a.snake-link:visited { color: white; } @@ -39,106 +42,107 @@ a.snake-link:hover { } .snake-pause-screen { - font-family: Electrolize; - font-size: 16px; - position:absolute; - width:300px; - height:80px; - text-align:center; - top:50%; - left:50%; - margin-top:-40px; - margin-left:-150px; - display:none; - background-color:#3E2E44; - color: whitesmoke; + font-family: Electrolize; + font-size: 16px; + position: absolute; + width: 300px; + height: 80px; + text-align: center; + top: 50%; + left: 50%; + margin-top: -40px; + margin-left: -150px; + display: none; + background-color: #3e2e44; + color: whitesmoke; } .snake-panel-component { - position: absolute; - font-family: Electrolize; - font-size: 16px; - color: #938996; - text-align: center; - background-color: #3E2E44; - padding: 8px; - margin: 0px; + position: absolute; + font-family: Electrolize; + font-size: 16px; + color: #938996; + text-align: center; + background-color: #3e2e44; + padding: 8px; + margin: 0px; } .snake-snakebody-block { - margin: 0px; - padding: 0px; - background-color: orange; - position: absolute; - border: 0px solid black; - background-repeat: no-repeat; + margin: 0px; + padding: 0px; + background-color: orange; + position: absolute; + border: 0px solid black; + background-repeat: no-repeat; } .snake-snakebody-alive { - background-image: url('src/css/images/snakeblock.png'); + background-image: url("src/css/images/snakeblock.png"); } .snake-snakebody-dead { - background-image: url('src/css/images/dead-dark-snakeblock.png'); + background-image: url("src/css/images/dead-dark-snakeblock.png"); } .snake-food-block { - margin: 0px; - padding: 0px; - background-color: red; - border: 2px solid black; - position: absolute; + margin: 0px; + padding: 0px; + background-color: red; + border: 2px solid black; + position: absolute; } .snake-playing-field { - margin: 0px; - padding: 0px; - position: absolute; - background-color: rgb(0, 180, 180); - border: 3px solid black; + margin: 0px; + padding: 0px; + position: absolute; + background-color: rgb(0, 180, 180); + border: 3px solid black; } .snake-game-container { - margin: 0px; - padding: 0px; - border-width: 0px; - border-style: none; - zoom: 1; - background-color: #3E2E44; - position: relative; + margin: 0px; + padding: 0px; + border-width: 0px; + border-style: none; + zoom: 1; + background-color: #3e2e44; + position: relative; } .snake-welcome-dialog { - padding: 8px; - margin: 0px; - background-color: black; - color: whitesmoke; - font-family: Electrolize; - font-size: 14px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - /*height: 150px;*/ - margin-top: -100px; - margin-left: -158px; - text-align: center; - display: block; -} - -.snake-try-again-dialog, .snake-win-dialog { - padding: 8px; - margin: 0px; - background-color: black; - color: whitesmoke; - font-family: Electrolize; - font-size: 16px; - position: absolute; - top: 50%; - left: 50%; - width: 300px; - height: 100px; - margin-top: -75px; - margin-left: -158px; - text-align: center; - display: none; + padding: 8px; + margin: 0px; + background-color: black; + color: whitesmoke; + font-family: Electrolize; + font-size: 14px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + /*height: 150px;*/ + margin-top: -100px; + margin-left: -158px; + text-align: center; + display: block; +} + +.snake-try-again-dialog, +.snake-win-dialog { + padding: 8px; + margin: 0px; + background-color: black; + color: whitesmoke; + font-family: Electrolize; + font-size: 16px; + position: absolute; + top: 50%; + left: 50%; + width: 300px; + height: 100px; + margin-top: -75px; + margin-left: -158px; + text-align: center; + display: none; } diff --git a/src/index.html b/src/index.html index 360fe818..d29237b0 100755 --- a/src/index.html +++ b/src/index.html @@ -1,154 +1,147 @@ - + - - - + --> + JavaScript Snake - + - + +
-
+
Theme:
-
+
Mode:
-
+ +
- -
-
+
-
-
+
- + + diff --git a/src/js/ai-init.js b/src/js/ai-init.js new file mode 100644 index 00000000..daddd8b8 --- /dev/null +++ b/src/js/ai-init.js @@ -0,0 +1,21 @@ +const mySnakeBoard = new SNAKE.Board({ + boardContainer: "game-area", + fullScreen: true, + premoveOnPause: false, + onLengthUpdate: (length) => { + console.log(`Length: ${length}`); + }, + onPauseToggle: (isPaused) => { + console.log(`Is paused: ${isPaused}`); + }, + onInit: (params) => { + console.log("init!"); + console.log(params); + }, + onWin: () => { + console.log("wn!"); + }, + onDeath: () => { + console.log("dead!"); + }, +}); diff --git a/src/js/init.js b/src/js/init.js index 045d093f..daddd8b8 100644 --- a/src/js/init.js +++ b/src/js/init.js @@ -1,5 +1,21 @@ const mySnakeBoard = new SNAKE.Board({ boardContainer: "game-area", fullScreen: true, - premoveOnPause: false -}); \ No newline at end of file + premoveOnPause: false, + onLengthUpdate: (length) => { + console.log(`Length: ${length}`); + }, + onPauseToggle: (isPaused) => { + console.log(`Is paused: ${isPaused}`); + }, + onInit: (params) => { + console.log("init!"); + console.log(params); + }, + onWin: () => { + console.log("wn!"); + }, + onDeath: () => { + console.log("dead!"); + }, +}); diff --git a/src/js/snake.js b/src/js/snake.js index 103a5bdb..2bfe6a79 100644 --- a/src/js/snake.js +++ b/src/js/snake.js @@ -29,6 +29,14 @@ const MOVE_RIGHT = 1; const MIN_SNAKE_SPEED = 25; const RUSH_INCR = 5; +const DEFAULT_SNAKE_SPEED = 80; + +const BOARD_NOT_READY = 0; +const BOARD_READY = 1; +const BOARD_IN_PLAY = 2; + +const HIGH_SCORE_KEY = "jsSnakeHighScore"; + /** * @method addEventListener * @param {Object} obj The object to add an event listener to. @@ -75,426 +83,468 @@ SNAKE.removeEventListener = (function () { * @namespace SNAKE * @param {Object} config The configuration object for the class. Contains playingBoard (the SNAKE.Board that this snake resides in), startRow and startCol. */ -SNAKE.Snake = SNAKE.Snake || (function () { - - // ------------------------------------------------------------------------- - // Private static variables and methods - // ------------------------------------------------------------------------- - - const blockPool = []; - - const SnakeBlock = function () { - this.elm = null; - this.elmStyle = null; - this.row = -1; - this.col = -1; - this.next = null; - this.prev = null; - }; - - // this function is adapted from the example at http://greengeckodesign.com/blog/2007/07/get-highest-z-index-in-javascript.html - function getNextHighestZIndex(myObj) { - let highestIndex = 0, - currentIndex = 0, - ii; - for (ii in myObj) { - if (myObj[ii].elm.currentStyle) { - currentIndex = parseFloat(myObj[ii].elm.style["z-index"], 10); - } else if (window.getComputedStyle) { - currentIndex = parseFloat(document.defaultView.getComputedStyle(myObj[ii].elm, null).getPropertyValue("z-index"), 10); - } - if (!isNaN(currentIndex) && currentIndex > highestIndex) { - highestIndex = currentIndex; +SNAKE.Snake = + SNAKE.Snake || + (function () { + // ------------------------------------------------------------------------- + // Private static variables and methods + // ------------------------------------------------------------------------- + + const blockPool = []; + + const SnakeBlock = function () { + this.elm = null; + this.elmStyle = null; + this.row = -1; + this.col = -1; + this.next = null; + this.prev = null; + }; + + // this function is adapted from the example at http://greengeckodesign.com/blog/2007/07/get-highest-z-index-in-javascript.html + function getNextHighestZIndex(myObj) { + let highestIndex = 0, + currentIndex = 0, + ii; + for (ii in myObj) { + if (myObj[ii].elm.currentStyle) { + currentIndex = parseFloat(myObj[ii].elm.style["z-index"], 10); + } else if (window.getComputedStyle) { + currentIndex = parseFloat( + document.defaultView + .getComputedStyle(myObj[ii].elm, null) + .getPropertyValue("z-index"), + 10, + ); + } + if (!isNaN(currentIndex) && currentIndex > highestIndex) { + highestIndex = currentIndex; + } } + return highestIndex + 1; } - return (highestIndex + 1); - } - // ------------------------------------------------------------------------- - // Contructor + public and private definitions - // ------------------------------------------------------------------------- + // ------------------------------------------------------------------------- + // Contructor + public and private definitions + // ------------------------------------------------------------------------- - /* + /* config options: playingBoard - the SnakeBoard that this snake belongs too. startRow - The row the snake should start on. startCol - The column the snake should start on. + moveSnakeWithAI - function to move the snake with AI */ - return function (config) { + return function (config) { + if (!config || !config.playingBoard) { + return; + } + if (localStorage[HIGH_SCORE_KEY] === undefined) + localStorage.setItem(HIGH_SCORE_KEY, 0); + + // ----- private variables ----- + + const me = this; + const playingBoard = config.playingBoard; + const growthIncr = 5; + const columnShift = [0, 1, 0, -1]; + const rowShift = [-1, 0, 1, 0]; + + let lastMove = 1, + preMove = MOVE_NONE, + isFirstGameMove = true, + currentDirection = MOVE_NONE, // 0: up, 1: left, 2: down, 3: right + snakeSpeed = DEFAULT_SNAKE_SPEED, + isDead = false, + isPaused = false; + + const modeDropdown = document.getElementById("selectMode"); + if (modeDropdown) { + modeDropdown.addEventListener("change", function (evt) { + evt = evt || {}; + let val = evt.target + ? parseInt(evt.target.value) + : DEFAULT_SNAKE_SPEED; + + if (isNaN(val)) { + val = DEFAULT_SNAKE_SPEED; + } else if (val < MIN_SNAKE_SPEED) { + val = DEFAULT_SNAKE_SPEED; + } - if (!config || !config.playingBoard) { - return; - } - if (localStorage.jsSnakeHighScore === undefined) localStorage.setItem('jsSnakeHighScore', 0); - - // ----- private variables ----- - - const me = this; - const playingBoard = config.playingBoard; - const growthIncr = 5; - const columnShift = [0, 1, 0, -1]; - const rowShift = [-1, 0, 1, 0]; - - let lastMove = 1, - preMove = MOVE_NONE, - isFirstMove = true, - isFirstGameMove = true, - currentDirection = MOVE_NONE, // 0: up, 1: left, 2: down, 3: right - snakeSpeed = 80, - isDead = false, - isPaused = false; - - const modeDropdown = document.getElementById('selectMode'); - if (modeDropdown) { - modeDropdown.addEventListener('change', function (evt) { - evt = evt || {}; - let val = evt.target ? parseInt(evt.target.value) : 75; - - if (isNaN(val)) { - val = 75; - } else if (val < MIN_SNAKE_SPEED) { - val = 75 - } + snakeSpeed = val; - snakeSpeed = val; + setTimeout(function () { + document.getElementById("game-area").focus(); + }, 10); + }); + } - setTimeout(function () { - document.getElementById('game-area').focus(); - }, 10); - }); - } + // ----- public variables ----- + me.snakeBody = {}; + me.snakeBody["b0"] = new SnakeBlock(); // create snake head + me.snakeBody["b0"].row = config.startRow || 1; + me.snakeBody["b0"].col = config.startCol || 1; + me.snakeBody["b0"].elm = createSnakeElement(); + me.snakeBody["b0"].elmStyle = me.snakeBody["b0"].elm.style; + playingBoard.getBoardContainer().appendChild(me.snakeBody["b0"].elm); + me.snakeBody["b0"].elm.style.left = getLeftPosition(me.snakeBody["b0"]); + me.snakeBody["b0"].elm.style.top = getTopPosition(me.snakeBody["b0"]); + me.snakeBody["b0"].next = me.snakeBody["b0"]; + me.snakeBody["b0"].prev = me.snakeBody["b0"]; - // ----- public variables ----- - me.snakeBody = {}; - me.snakeBody["b0"] = new SnakeBlock(); // create snake head - me.snakeBody["b0"].row = config.startRow || 1; - me.snakeBody["b0"].col = config.startCol || 1; - me.snakeBody["b0"].elm = createSnakeElement(); - me.snakeBody["b0"].elmStyle = me.snakeBody["b0"].elm.style; - playingBoard.getBoardContainer().appendChild(me.snakeBody["b0"].elm); - me.snakeBody["b0"].elm.style.left = getLeftPosition(me.snakeBody["b0"]); - me.snakeBody["b0"].elm.style.top = getTopPosition(me.snakeBody["b0"]); - me.snakeBody["b0"].next = me.snakeBody["b0"]; - me.snakeBody["b0"].prev = me.snakeBody["b0"]; - - me.snakeLength = 1; - me.snakeHead = me.snakeBody["b0"]; - me.snakeTail = me.snakeBody["b0"]; - me.snakeHead.elm.className = me.snakeHead.elm.className.replace(/\bsnake-snakebody-dead\b/, ''); - me.snakeHead.elm.id = "snake-snakehead-alive"; - me.snakeHead.elm.className += " snake-snakebody-alive"; - - // ----- private methods ----- - - function getTopPosition(block) { - const num = block.row * playingBoard.getBlockHeight() - return `${num}px`; - } - function getLeftPosition(block) { - const num = block.col * playingBoard.getBlockWidth() - return `${num}px`; - } + me.snakeLength = 1; + me.snakeHead = me.snakeBody["b0"]; + me.snakeTail = me.snakeBody["b0"]; + me.snakeHead.elm.className = me.snakeHead.elm.className.replace( + /\bsnake-snakebody-dead\b/, + "", + ); + me.snakeHead.elm.id = "snake-snakehead-alive"; + me.snakeHead.elm.className += " snake-snakebody-alive"; - function createSnakeElement() { - const tempNode = document.createElement("div"); - tempNode.className = "snake-snakebody-block"; - tempNode.style.left = "-1000px"; - tempNode.style.top = "-1000px"; - tempNode.style.width = playingBoard.getBlockWidth() + "px"; - tempNode.style.height = playingBoard.getBlockHeight() + "px"; - return tempNode; - } + // ----- private methods ----- - function createBlocks(num) { - let tempBlock; - const tempNode = createSnakeElement(); + function getTopPosition(block) { + const num = block.row * playingBoard.getBlockHeight(); + return `${num}px`; + } + + function getLeftPosition(block) { + const num = block.col * playingBoard.getBlockWidth(); + return `${num}px`; + } + + function createSnakeElement() { + const tempNode = document.createElement("div"); + tempNode.className = "snake-snakebody-block"; + tempNode.style.left = "-1000px"; + tempNode.style.top = "-1000px"; + tempNode.style.width = playingBoard.getBlockWidth() + "px"; + tempNode.style.height = playingBoard.getBlockHeight() + "px"; + return tempNode; + } + + function createBlocks(num) { + let tempBlock; + const tempNode = createSnakeElement(); + + for (let ii = 1; ii < num; ii++) { + tempBlock = new SnakeBlock(); + tempBlock.elm = tempNode.cloneNode(true); + tempBlock.elmStyle = tempBlock.elm.style; + playingBoard.getBoardContainer().appendChild(tempBlock.elm); + blockPool[blockPool.length] = tempBlock; + } - for (let ii = 1; ii < num; ii++) { tempBlock = new SnakeBlock(); - tempBlock.elm = tempNode.cloneNode(true); - tempBlock.elmStyle = tempBlock.elm.style; + tempBlock.elm = tempNode; playingBoard.getBoardContainer().appendChild(tempBlock.elm); blockPool[blockPool.length] = tempBlock; } - tempBlock = new SnakeBlock(); - tempBlock.elm = tempNode; - playingBoard.getBoardContainer().appendChild(tempBlock.elm); - blockPool[blockPool.length] = tempBlock; - } - - function recordScore() { - const highScore = localStorage.jsSnakeHighScore; - if (me.snakeLength > highScore) { - alert('Congratulations! You have beaten your previous high score, which was ' + highScore + '.'); - localStorage.setItem('jsSnakeHighScore', me.snakeLength); + function recordScore() { + const highScore = localStorage[HIGH_SCORE_KEY]; + if (me.snakeLength > highScore) { + alert( + "Congratulations! You have beaten your previous high score, which was " + + highScore + + ".", + ); + localStorage.setItem(HIGH_SCORE_KEY, me.snakeLength); + } } - } - function handleEndCondition(handleFunc) { - recordScore(); - me.snakeHead.elm.style.zIndex = getNextHighestZIndex(me.snakeBody); - me.snakeHead.elm.className = me.snakeHead.elm.className.replace(/\bsnake-snakebody-alive\b/, '') - me.snakeHead.elm.className += " snake-snakebody-dead"; - - isDead = true; - handleFunc(); - } + function handleEndCondition(handleFunc) { + recordScore(); + me.snakeHead.elm.style.zIndex = getNextHighestZIndex(me.snakeBody); + me.snakeHead.elm.className = me.snakeHead.elm.className.replace( + /\bsnake-snakebody-alive\b/, + "", + ); + me.snakeHead.elm.className += " snake-snakebody-dead"; + + isDead = true; + handleFunc(); + } - // ----- public methods ----- + // ----- public methods ----- - me.setPaused = function (val) { - isPaused = val; - }; - me.getPaused = function () { - return isPaused; - }; + me.setPaused = function (val) { + isPaused = val; + }; + me.getPaused = function () { + return isPaused; + }; - /** - * This method is called when a user presses a key. It logs arrow key presses in "currentDirection", which is used when the snake needs to make its next move. - * @method handleArrowKeys - * @param {Number} keyNum A number representing the key that was pressed. - */ - /* + /** + * This method is called when a user presses a key. It logs arrow key presses in "currentDirection", which is used when the snake needs to make its next move. + * @method handleArrowKeys + * @param {Number} keyNum A number representing the key that was pressed. + */ + /* Handles what happens when an arrow key is pressed. Direction explained (0 = up, etc etc) 0 3 1 2 */ - me.handleArrowKeys = function (keyNum) { - if (isDead || (isPaused && !config.premoveOnPause)) { - return; - } - - let directionFound = MOVE_NONE; - - switch (keyNum) { - case 37: - case 65: - directionFound = MOVE_LEFT; - break; - case 38: - case 87: - directionFound = MOVE_UP; - break; - case 39: - case 68: - directionFound = MOVE_RIGHT; - break; - case 40: - case 83: - directionFound = MOVE_DOWN; - break; - } - if (currentDirection !== lastMove) // Allow a queue of 1 premove so you can turn again before the first turn registers - { - preMove = directionFound; - } - if (Math.abs(directionFound - lastMove) !== 2 && (isFirstMove || isPaused) || isFirstGameMove) // Prevent snake from turning 180 degrees - { - currentDirection = directionFound; - isFirstMove = false; - isFirstGameMove = false; - } - }; - - /** - * This method is executed for each move of the snake. It determines where the snake will go and what will happen to it. This method needs to run quickly. - * @method go - */ - me.go = function () { + me.handleArrowKeys = function (keyNum) { + if (isDead || (isPaused && !config.premoveOnPause)) { + return; + } - const oldHead = me.snakeHead, - newHead = me.snakeTail, - grid = playingBoard.grid; // cache grid for quicker lookup + let directionFound = MOVE_NONE; + + switch (keyNum) { + case 37: + case 65: + directionFound = MOVE_LEFT; + break; + case 38: + case 87: + directionFound = MOVE_UP; + break; + case 39: + case 68: + directionFound = MOVE_RIGHT; + break; + case 40: + case 83: + directionFound = MOVE_DOWN; + break; + } + if (currentDirection !== lastMove) { + // Allow a queue of 1 premove so you can turn again before the first turn registers + preMove = directionFound; + } + if (Math.abs(directionFound - lastMove) !== 2 || isFirstGameMove) { + // Prevent snake from turning 180 degrees + currentDirection = directionFound; + isFirstGameMove = false; + } + }; - if (isPaused === true) { - setTimeout(function () { - me.go(); - }, snakeSpeed); - return; - } + /** + * This method is executed for each move of the snake. It determines where the snake will go and what will happen to it. This method needs to run quickly. + * @method go + */ + me.go = function () { + const oldHead = me.snakeHead, + newHead = me.snakeTail, + grid = playingBoard.grid; // cache grid for quicker lookup + + if (isPaused === true) { + setTimeout(function () { + me.go(); + }, snakeSpeed); + return; + } - me.snakeTail = newHead.prev; - me.snakeHead = newHead; + // code to execute if snake is being moved by AI + if (config.moveSnakeWithAI) { + config.moveSnakeWithAI({ + grid, + snakeHead: me.snakeHead, + currentDirection, + isFirstGameMove, + setDirection: me.setDirection, + }); + } - // clear the old board position - if (grid[newHead.row] && grid[newHead.row][newHead.col]) { - grid[newHead.row][newHead.col] = 0; - } + me.snakeTail = newHead.prev; + me.snakeHead = newHead; - if (currentDirection !== MOVE_NONE) { - lastMove = currentDirection; - if (preMove !== MOVE_NONE) // If the user queued up another move after the current one - { - currentDirection = preMove; // Execute that move next time (unless overwritten) - preMove = MOVE_NONE; + // clear the old board position + if (grid[newHead.row] && grid[newHead.row][newHead.col]) { + grid[newHead.row][newHead.col] = 0; } - } - isFirstMove = true; - newHead.col = oldHead.col + columnShift[lastMove]; - newHead.row = oldHead.row + rowShift[lastMove]; - - if (!newHead.elmStyle) { - newHead.elmStyle = newHead.elm.style; - } + if (currentDirection !== MOVE_NONE) { + lastMove = currentDirection; + if (preMove !== MOVE_NONE) { + // If the user queued up another move after the current one + currentDirection = preMove; // Execute that move next time (unless overwritten) + preMove = MOVE_NONE; + } + } - newHead.elmStyle.left = getLeftPosition(newHead); - newHead.elmStyle.top = getTopPosition(newHead); - if (me.snakeLength > 1) { - newHead.elm.id = "snake-snakehead-alive"; - oldHead.elm.id = ""; - } + newHead.col = oldHead.col + columnShift[lastMove]; + newHead.row = oldHead.row + rowShift[lastMove]; + if (!newHead.elmStyle) { + newHead.elmStyle = newHead.elm.style; + } - // check the new spot the snake moved into + newHead.elmStyle.left = getLeftPosition(newHead); + newHead.elmStyle.top = getTopPosition(newHead); + if (me.snakeLength > 1) { + newHead.elm.id = "snake-snakehead-alive"; + oldHead.elm.id = ""; + } - if (grid[newHead.row][newHead.col] === 0) { - grid[newHead.row][newHead.col] = 1; - setTimeout(function () { - me.go(); - }, snakeSpeed); - } else if (grid[newHead.row][newHead.col] > 0) { - me.handleDeath(); - } else if (grid[newHead.row][newHead.col] === playingBoard.getGridFoodValue()) { - grid[newHead.row][newHead.col] = 1; - if (!me.eatFood()) { - me.handleWin(); - return; + // check the new spot the snake moved into + + if (grid[newHead.row][newHead.col] === 0) { + grid[newHead.row][newHead.col] = 1; + setTimeout(function () { + me.go(); + }, snakeSpeed); + } else if (grid[newHead.row][newHead.col] > 0) { + me.handleDeath(); + } else if ( + grid[newHead.row][newHead.col] === playingBoard.getGridFoodValue() + ) { + grid[newHead.row][newHead.col] = 1; + if (!me.eatFood()) { + me.handleWin(); + return; + } + setTimeout(function () { + me.go(); + }, snakeSpeed); } - setTimeout(function () { - me.go(); - }, snakeSpeed); - } - }; + }; - /** - * This method is called when it is determined that the snake has eaten some food. - * @method eatFood - * @return {bool} Whether a new food was able to spawn (true) - * or not (false) after the snake eats food. - */ - me.eatFood = function () { - if (blockPool.length <= growthIncr) { - createBlocks(growthIncr * 2); - } - const blocks = blockPool.splice(0, growthIncr); - - let ii = blocks.length, - index; - prevNode = me.snakeTail; - while (ii--) { - index = "b" + me.snakeLength++; - me.snakeBody[index] = blocks[ii]; - me.snakeBody[index].prev = prevNode; - me.snakeBody[index].elm.className = me.snakeHead.elm.className.replace(/\bsnake-snakebody-dead\b/, '') - me.snakeBody[index].elm.className += " snake-snakebody-alive"; - prevNode.next = me.snakeBody[index]; - prevNode = me.snakeBody[index]; - } - me.snakeTail = me.snakeBody[index]; - me.snakeTail.next = me.snakeHead; - me.snakeHead.prev = me.snakeTail; + /** + * This method is called when it is determined that the snake has eaten some food. + * @method eatFood + * @return {bool} Whether a new food was able to spawn (true) + * or not (false) after the snake eats food. + */ + me.eatFood = function () { + if (blockPool.length <= growthIncr) { + createBlocks(growthIncr * 2); + } + const blocks = blockPool.splice(0, growthIncr); + + let ii = blocks.length, + index; + prevNode = me.snakeTail; + while (ii--) { + index = "b" + me.snakeLength++; + me.snakeBody[index] = blocks[ii]; + me.snakeBody[index].prev = prevNode; + me.snakeBody[index].elm.className = + me.snakeHead.elm.className.replace(/\bsnake-snakebody-dead\b/, ""); + me.snakeBody[index].elm.className += " snake-snakebody-alive"; + prevNode.next = me.snakeBody[index]; + prevNode = me.snakeBody[index]; + } + me.snakeTail = me.snakeBody[index]; + me.snakeTail.next = me.snakeHead; + me.snakeHead.prev = me.snakeTail; - if (!playingBoard.foodEaten()) { - return false; - } + if (!playingBoard.foodEaten()) { + return false; + } - //Checks if the current selected option is that of "Rush" - //If so, "increase" the snake speed - const selectDropDown = document.getElementById("selectMode"); - const selectedOption = selectDropDown.options[selectDropDown.selectedIndex]; + //Checks if the current selected option is that of "Rush" + //If so, "increase" the snake speed + const selectDropDown = document.getElementById("selectMode"); + const selectedOption = + selectDropDown.options[selectDropDown.selectedIndex]; - if (selectedOption.text.localeCompare("Rush") == 0) { - if (snakeSpeed > (MIN_SNAKE_SPEED + RUSH_INCR)) { - snakeSpeed -= RUSH_INCR; + if (selectedOption.text.localeCompare("Rush") == 0) { + if (snakeSpeed > MIN_SNAKE_SPEED + RUSH_INCR) { + snakeSpeed -= RUSH_INCR; + } } - } - return true; - }; + return true; + }; - /** - * This method handles what happens when the snake dies. - * @method handleDeath - */ - me.handleDeath = function () { - //Reset speed - const selectedSpeed = document.getElementById("selectMode").value; - snakeSpeed = parseInt(selectedSpeed); + /** + * This method handles what happens when the snake dies. + * @method handleDeath + */ + me.handleDeath = function () { + //Reset speed + const selectedSpeed = document.getElementById("selectMode").value; + snakeSpeed = parseInt(selectedSpeed); - handleEndCondition(playingBoard.handleDeath); - }; + handleEndCondition(playingBoard.handleDeath); + }; - /** - * This method handles what happens when the snake wins. - * @method handleDeath - */ - me.handleWin = function () { - handleEndCondition(playingBoard.handleWin); - }; + /** + * This method handles what happens when the snake wins. + * @method handleDeath + */ + me.handleWin = function () { + handleEndCondition(playingBoard.handleWin); + }; - /** - * This method sets a flag that lets the snake be alive again. - * @method rebirth - */ - me.rebirth = function () { - isDead = false; - isFirstMove = true; - isFirstGameMove = true; - preMove = MOVE_NONE; - }; + /** + * This method sets a flag that lets the snake be alive again. + * @method rebirth + */ + me.rebirth = function () { + isDead = false; + isFirstGameMove = true; + preMove = MOVE_NONE; + }; - /** - * This method reset the snake so it is ready for a new game. - * @method reset - */ - me.reset = function () { - if (isDead === false) { - return; - } + /** + * This method reset the snake so it is ready for a new game. + * @method reset + */ + me.reset = function () { + if (isDead === false) { + return; + } - const blocks = []; - let curNode = me.snakeHead.next; - let nextNode; + const blocks = []; + let curNode = me.snakeHead.next; + let nextNode; - while (curNode !== me.snakeHead) { - nextNode = curNode.next; - curNode.prev = null; - curNode.next = null; - blocks.push(curNode); - curNode = nextNode; - } - me.snakeHead.next = me.snakeHead; - me.snakeHead.prev = me.snakeHead; - me.snakeTail = me.snakeHead; - me.snakeLength = 1; + while (curNode !== me.snakeHead) { + nextNode = curNode.next; + curNode.prev = null; + curNode.next = null; + blocks.push(curNode); + curNode = nextNode; + } + me.snakeHead.next = me.snakeHead; + me.snakeHead.prev = me.snakeHead; + me.snakeTail = me.snakeHead; + me.snakeLength = 1; + + for (let ii = 0; ii < blocks.length; ii++) { + blocks[ii].elm.style.left = "-1000px"; + blocks[ii].elm.style.top = "-1000px"; + blocks[ii].elm.className = me.snakeHead.elm.className.replace( + /\bsnake-snakebody-dead\b/, + "", + ); + blocks[ii].elm.className += " snake-snakebody-alive"; + } - for (let ii = 0; ii < blocks.length; ii++) { - blocks[ii].elm.style.left = "-1000px"; - blocks[ii].elm.style.top = "-1000px"; - blocks[ii].elm.className = me.snakeHead.elm.className.replace(/\bsnake-snakebody-dead\b/, '') - blocks[ii].elm.className += " snake-snakebody-alive"; - } + blockPool.concat(blocks); + me.snakeHead.elm.className = me.snakeHead.elm.className.replace( + /\bsnake-snakebody-dead\b/, + "", + ); + me.snakeHead.elm.className += " snake-snakebody-alive"; + me.snakeHead.elm.id = "snake-snakehead-alive"; + me.snakeHead.row = config.startRow || 1; + me.snakeHead.col = config.startCol || 1; + me.snakeHead.elm.style.left = getLeftPosition(me.snakeHead); + me.snakeHead.elm.style.top = getTopPosition(me.snakeHead); + }; - blockPool.concat(blocks); - me.snakeHead.elm.className = me.snakeHead.elm.className.replace(/\bsnake-snakebody-dead\b/, '') - me.snakeHead.elm.className += " snake-snakebody-alive"; - me.snakeHead.elm.id = "snake-snakehead-alive"; - me.snakeHead.row = config.startRow || 1; - me.snakeHead.col = config.startCol || 1; - me.snakeHead.elm.style.left = getLeftPosition(me.snakeHead); - me.snakeHead.elm.style.top = getTopPosition(me.snakeHead); - }; + me.getSpeed = () => { + return snakeSpeed; + }; + me.setSpeed = (speed) => { + snakeSpeed = speed; + }; - // --------------------------------------------------------------------- - // Initialize - // --------------------------------------------------------------------- - createBlocks(growthIncr * 2); - }; -})(); + // --------------------------------------------------------------------- + // Initialize + // --------------------------------------------------------------------- + createBlocks(growthIncr * 2); + }; + })(); /** * This class manages the food which the snake will eat. @@ -504,96 +554,101 @@ SNAKE.Snake = SNAKE.Snake || (function () { * @param {Object} config The configuration object for the class. Contains playingBoard (the SNAKE.Board that this food resides in). */ -SNAKE.Food = SNAKE.Food || (function () { - - // ------------------------------------------------------------------------- - // Private static variables and methods - // ------------------------------------------------------------------------- +SNAKE.Food = + SNAKE.Food || + (function () { + // ------------------------------------------------------------------------- + // Private static variables and methods + // ------------------------------------------------------------------------- - let instanceNumber = 0; + let instanceNumber = 0; - function getRandomPosition(x, y) { - return Math.floor(Math.random() * (y + 1 - x)) + x; - } + function getRandomPosition(x, y) { + return Math.floor(Math.random() * (y + 1 - x)) + x; + } - // ------------------------------------------------------------------------- - // Contructor + public and private definitions - // ------------------------------------------------------------------------- + // ------------------------------------------------------------------------- + // Contructor + public and private definitions + // ------------------------------------------------------------------------- - /* + /* config options: playingBoard - the SnakeBoard that this object belongs too. */ - return function (config) { - - if (!config || !config.playingBoard) { - return; - } + return function (config) { + if (!config || !config.playingBoard) { + return; + } - // ----- private variables ----- - - const me = this; - const playingBoard = config.playingBoard; - let fRow, fColumn; - const myId = instanceNumber++; - - const elmFood = document.createElement("div"); - elmFood.setAttribute("id", "snake-food-" + myId); - elmFood.className = "snake-food-block"; - elmFood.style.width = playingBoard.getBlockWidth() + "px"; - elmFood.style.height = playingBoard.getBlockHeight() + "px"; - elmFood.style.left = "-1000px"; - elmFood.style.top = "-1000px"; - playingBoard.getBoardContainer().appendChild(elmFood); - - // ----- public methods ----- - - /** - * @method getFoodElement - * @return {DOM Element} The div the represents the food. - */ - me.getFoodElement = function () { - return elmFood; - }; + // ----- private variables ----- + + const me = this; + const playingBoard = config.playingBoard; + let fRow, fColumn; + const myId = instanceNumber++; + + const elmFood = document.createElement("div"); + elmFood.setAttribute("id", "snake-food-" + myId); + elmFood.className = "snake-food-block"; + elmFood.style.width = playingBoard.getBlockWidth() + "px"; + elmFood.style.height = playingBoard.getBlockHeight() + "px"; + elmFood.style.left = "-1000px"; + elmFood.style.top = "-1000px"; + playingBoard.getBoardContainer().appendChild(elmFood); + + // ----- public methods ----- + + /** + * @method getFoodElement + * @return {DOM Element} The div the represents the food. + */ + me.getFoodElement = function () { + return elmFood; + }; - /** - * Randomly places the food onto an available location on the playing board. - * @method randomlyPlaceFood - * @return {bool} Whether a food was able to spawn (true) or not (false). - */ - me.randomlyPlaceFood = function () { - // if there exist some food, clear its presence from the board - if (playingBoard.grid[fRow] && playingBoard.grid[fRow][fColumn] === playingBoard.getGridFoodValue()) { - playingBoard.grid[fRow][fColumn] = 0; - } + /** + * Randomly places the food onto an available location on the playing board. + * @method randomlyPlaceFood + * @return {bool} Whether a food was able to spawn (true) or not (false). + */ + me.randomlyPlaceFood = function () { + // if there exist some food, clear its presence from the board + if ( + playingBoard.grid[fRow] && + playingBoard.grid[fRow][fColumn] === playingBoard.getGridFoodValue() + ) { + playingBoard.grid[fRow][fColumn] = 0; + } - let row = 0, col = 0, numTries = 0; + let row = 0, + col = 0, + numTries = 0; - const maxRows = playingBoard.grid.length - 1; - const maxCols = playingBoard.grid[0].length - 1; + const maxRows = playingBoard.grid.length - 1; + const maxCols = playingBoard.grid[0].length - 1; - while (playingBoard.grid[row][col] !== 0) { - row = getRandomPosition(1, maxRows); - col = getRandomPosition(1, maxCols); + while (playingBoard.grid[row][col] !== 0) { + row = getRandomPosition(1, maxRows); + col = getRandomPosition(1, maxCols); - // in some cases there may not be any room to put food anywhere - // instead of freezing, exit out (and return false to indicate - // that the player beat the game) - numTries++; - if (numTries > 20000) { - return false; + // in some cases there may not be any room to put food anywhere + // instead of freezing, exit out (and return false to indicate + // that the player beat the game) + numTries++; + if (numTries > 20000) { + return false; + } } - } - playingBoard.grid[row][col] = playingBoard.getGridFoodValue(); - fRow = row; - fColumn = col; - elmFood.style.top = row * playingBoard.getBlockHeight() + "px"; - elmFood.style.left = col * playingBoard.getBlockWidth() + "px"; - return true; + playingBoard.grid[row][col] = playingBoard.getGridFoodValue(); + fRow = row; + fColumn = col; + elmFood.style.top = row * playingBoard.getBlockHeight() + "px"; + elmFood.style.left = col * playingBoard.getBlockWidth() + "px"; + return true; + }; }; - }; -})(); + })(); /** * This class manages playing board for the game. @@ -603,557 +658,733 @@ SNAKE.Food = SNAKE.Food || (function () { * @param {Object} config The configuration object for the class. Set fullScreen equal to true if you want the game to take up the full screen, otherwise, set the top, left, width and height parameters. */ -SNAKE.Board = SNAKE.Board || (function () { - - // ------------------------------------------------------------------------- - // Private static variables and methods - // ------------------------------------------------------------------------- - - let instanceNumber = 0; - - // this function is adapted from the example at http://greengeckodesign.com/blog/2007/07/get-highest-z-index-in-javascript.html - function getNextHighestZIndex(myObj) { - let highestIndex = 0, - currentIndex = 0, - ii; - for (ii in myObj) { - if (myObj[ii].elm.currentStyle) { - currentIndex = parseFloat(myObj[ii].elm.style["z-index"], 10); - } else if (window.getComputedStyle) { - currentIndex = parseFloat(document.defaultView.getComputedStyle(myObj[ii].elm, null).getPropertyValue("z-index"), 10); - } - if (!isNaN(currentIndex) && currentIndex > highestIndex) { - highestIndex = currentIndex; +SNAKE.Board = + SNAKE.Board || + (function () { + // ------------------------------------------------------------------------- + // Private static variables and methods + // ------------------------------------------------------------------------- + + let instanceNumber = 0; + + // this function is adapted from the example at http://greengeckodesign.com/blog/2007/07/get-highest-z-index-in-javascript.html + function getNextHighestZIndex(myObj) { + let highestIndex = 0, + currentIndex = 0, + ii; + for (ii in myObj) { + if (myObj[ii].elm.currentStyle) { + currentIndex = parseFloat(myObj[ii].elm.style["z-index"], 10); + } else if (window.getComputedStyle) { + currentIndex = parseFloat( + document.defaultView + .getComputedStyle(myObj[ii].elm, null) + .getPropertyValue("z-index"), + 10, + ); + } + if (!isNaN(currentIndex) && currentIndex > highestIndex) { + highestIndex = currentIndex; + } } + return highestIndex + 1; } - return (highestIndex + 1); - } - /* + /* This function returns the width of the available screen real estate that we have */ - function getClientWidth() { - let myWidth = 0; - if (typeof window.innerWidth === "number") { - myWidth = window.innerWidth;//Non-IE - } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) { - myWidth = document.documentElement.clientWidth;//IE 6+ in 'standards compliant mode' - } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) { - myWidth = document.body.clientWidth;//IE 4 compatible + function getClientWidth() { + let myWidth = 0; + if (typeof window.innerWidth === "number") { + myWidth = window.innerWidth; //Non-IE + } else if ( + document.documentElement && + (document.documentElement.clientWidth || + document.documentElement.clientHeight) + ) { + myWidth = document.documentElement.clientWidth; //IE 6+ in 'standards compliant mode' + } else if ( + document.body && + (document.body.clientWidth || document.body.clientHeight) + ) { + myWidth = document.body.clientWidth; //IE 4 compatible + } + return myWidth; } - return myWidth; - } - /* + /* This function returns the height of the available screen real estate that we have */ - function getClientHeight() { - let myHeight = 0; - if (typeof window.innerHeight === "number") { - myHeight = window.innerHeight;//Non-IE - } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) { - myHeight = document.documentElement.clientHeight;//IE 6+ in 'standards compliant mode' - } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) { - myHeight = document.body.clientHeight;//IE 4 compatible + function getClientHeight() { + let myHeight = 0; + if (typeof window.innerHeight === "number") { + myHeight = window.innerHeight; //Non-IE + } else if ( + document.documentElement && + (document.documentElement.clientWidth || + document.documentElement.clientHeight) + ) { + myHeight = document.documentElement.clientHeight; //IE 6+ in 'standards compliant mode' + } else if ( + document.body && + (document.body.clientWidth || document.body.clientHeight) + ) { + myHeight = document.body.clientHeight; //IE 4 compatible + } + return myHeight; } - return myHeight; - } - - // ------------------------------------------------------------------------- - // Contructor + public and private definitions - // ------------------------------------------------------------------------- - - return function (inputConfig) { - - // --- private variables --- - const me = this; - const myId = instanceNumber++; - const config = inputConfig || {}; - const MAX_BOARD_COLS = 250; - const MAX_BOARD_ROWS = 250; - const blockWidth = 20; - const blockHeight = 20; - const GRID_FOOD_VALUE = -1; // the value of a spot on the board that represents snake food; MUST BE NEGATIVE - - let myFood, - mySnake, - boardState = 1, // 0: in active, 1: awaiting game start, 2: playing game - myKeyListener, - myWindowListener, - isPaused = false;//note: both the board and the snake can be paused - - // Board components - let elmContainer, - elmPlayingField, - elmAboutPanel, - elmLengthPanel, - elmHighscorePanel, - elmWelcome, - elmTryAgain, - elmWin, - elmPauseScreen; - - // --- public variables --- - me.grid = []; - - // --------------------------------------------------------------------- - // private functions - // --------------------------------------------------------------------- - - function createBoardElements() { - elmPlayingField = document.createElement("div"); - elmPlayingField.setAttribute("id", "playingField"); - elmPlayingField.className = "snake-playing-field"; - - SNAKE.addEventListener(elmPlayingField, "click", function () { - elmContainer.focus(); - }, false); - - elmPauseScreen = document.createElement("div"); - elmPauseScreen.className = "snake-pause-screen"; - elmPauseScreen.innerHTML = "
[Paused]

Press [space] to unpause.

"; - - elmAboutPanel = document.createElement("div"); - elmAboutPanel.className = "snake-panel-component"; - elmAboutPanel.innerHTML = "more patorjk.com apps - source code - pat's youtube"; - - elmLengthPanel = document.createElement("div"); - elmLengthPanel.className = "snake-panel-component"; - elmLengthPanel.innerHTML = "Length: 1"; - - elmHighscorePanel = document.createElement("div"); - elmHighscorePanel.className = "snake-panel-component"; - elmHighscorePanel.innerHTML = "Highscore: " + (localStorage.jsSnakeHighScore || 0); - - elmWelcome = createWelcomeElement(); - elmTryAgain = createTryAgainElement(); - elmWin = createWinElement(); - - SNAKE.addEventListener(elmContainer, "keyup", function (evt) { - if (!evt) evt = window.event; - evt.cancelBubble = true; - if (evt.stopPropagation) { - evt.stopPropagation(); - } - if (evt.preventDefault) { - evt.preventDefault(); - } - return false; - }, false); - - elmContainer.className = "snake-game-container"; - elmPauseScreen.style.zIndex = 10000; - elmContainer.appendChild(elmPauseScreen); - elmContainer.appendChild(elmPlayingField); - elmContainer.appendChild(elmAboutPanel); - elmContainer.appendChild(elmLengthPanel); - elmContainer.appendChild(elmHighscorePanel); - elmContainer.appendChild(elmWelcome); - elmContainer.appendChild(elmTryAgain); - elmContainer.appendChild(elmWin); - - mySnake = new SNAKE.Snake({playingBoard: me, startRow: 2, startCol: 2, premoveOnPause: config.premoveOnPause}); - myFood = new SNAKE.Food({playingBoard: me}); - - elmWelcome.style.zIndex = 1000; - } + // ------------------------------------------------------------------------- + // Contructor + public and private definitions + // ------------------------------------------------------------------------- + + return function (inputConfig) { + // --- private variables --- + const me = this; + const myId = instanceNumber++; + const config = inputConfig || {}; + const MAX_BOARD_COLS = 250; + const MAX_BOARD_ROWS = 250; + const blockWidth = 20; + const blockHeight = 20; + const GRID_FOOD_VALUE = -1; // the value of a spot on the board that represents snake food; MUST BE NEGATIVE + + // defaults + if (!config.onLengthUpdate) { + config.onLengthUpdate = () => {}; + } - function maxBoardWidth() { - return MAX_BOARD_COLS * me.getBlockWidth(); - } + if (!config.onPauseToggle) { + config.onPauseToggle = () => {}; + } + if (!config.onWin) { + config.onWin = () => {}; + } + if (!config.onDeath) { + config.onDeath = () => {}; + } - function maxBoardHeight() { - return MAX_BOARD_ROWS * me.getBlockHeight(); - } + let myFood, + mySnake, + boardState = 1, // 0: in active, 1: awaiting game start, 2: playing game + myKeyListener, + myWindowListener, + isPaused = false; //note: both the board and the snake can be paused + + // Board components + let elmContainer, + elmPlayingField, + elmAboutPanel, + elmLengthPanel, + elmHighscorePanel, + elmWelcome, + elmTryAgain, + elmWin, + elmPauseScreen; + + // --- public variables --- + me.grid = []; - function createWelcomeElement() { - const tmpElm = document.createElement("div"); - tmpElm.id = "sbWelcome" + myId; - tmpElm.className = "snake-welcome-dialog"; + // --------------------------------------------------------------------- + // private functions + // --------------------------------------------------------------------- - const welcomeTxt = document.createElement("div"); - let fullScreenText = ""; - if (config.fullScreen) { - fullScreenText = "On Windows, press F11 to play in Full Screen mode."; + function getStartRow() { + return config.startRow || 2; } - welcomeTxt.innerHTML = "JavaScript Snake

Use the arrow keys on your keyboard to play the game. " + fullScreenText + "

"; - const welcomeStart = document.createElement("button"); - welcomeStart.appendChild(document.createTextNode("Play Game")); - - const loadGame = function () { - SNAKE.removeEventListener(window, "keyup", kbShortcut, false); - tmpElm.style.display = "none"; - me.setBoardState(1); - me.getBoardContainer().focus(); - }; - const kbShortcut = function (evt) { - if (!evt) evt = window.event; - const keyNum = (evt.which) ? evt.which : evt.keyCode; - if (keyNum === 32 || keyNum === 13) { - loadGame(); - } - }; - - SNAKE.addEventListener(window, "keyup", kbShortcut, false); - SNAKE.addEventListener(welcomeStart, "click", loadGame, false); + function getStartCol() { + return config.startCol || 2; + } - tmpElm.appendChild(welcomeTxt); - tmpElm.appendChild(welcomeStart); - return tmpElm; - } + function createBoardElements() { + elmPlayingField = document.createElement("div"); + elmPlayingField.setAttribute("id", "playingField"); + elmPlayingField.className = "snake-playing-field"; + + SNAKE.addEventListener( + elmPlayingField, + "click", + function () { + elmContainer.focus(); + }, + false, + ); + + elmPauseScreen = document.createElement("div"); + elmPauseScreen.className = "snake-pause-screen"; + elmPauseScreen.innerHTML = + "
[Paused]

Press [space] to unpause.

"; + + elmAboutPanel = document.createElement("div"); + elmAboutPanel.className = "snake-panel-component"; + elmAboutPanel.innerHTML = + "more patorjk.com apps - source code - pat's youtube"; + + elmLengthPanel = document.createElement("div"); + elmLengthPanel.className = "snake-panel-component"; + elmLengthPanel.innerHTML = "Length: 1"; + + elmHighscorePanel = document.createElement("div"); + elmHighscorePanel.className = "snake-panel-component"; + elmHighscorePanel.innerHTML = + "Highscore: " + (localStorage[HIGH_SCORE_KEY] || 0); + + elmWelcome = createWelcomeElement(); + elmTryAgain = createTryAgainElement(); + elmWin = createWinElement(); + + SNAKE.addEventListener( + elmContainer, + "keyup", + function (evt) { + if (!evt) evt = window.event; + evt.cancelBubble = true; + if (evt.stopPropagation) { + evt.stopPropagation(); + } + if (evt.preventDefault) { + evt.preventDefault(); + } + return false; + }, + false, + ); + + elmContainer.className = "snake-game-container"; + + elmPauseScreen.style.zIndex = 10000; + elmContainer.appendChild(elmPauseScreen); + elmContainer.appendChild(elmPlayingField); + elmContainer.appendChild(elmAboutPanel); + elmContainer.appendChild(elmLengthPanel); + elmContainer.appendChild(elmHighscorePanel); + elmContainer.appendChild(elmWelcome); + elmContainer.appendChild(elmTryAgain); + elmContainer.appendChild(elmWin); + + mySnake = new SNAKE.Snake({ + playingBoard: me, + startRow: getStartRow(), + startCol: getStartCol(), + premoveOnPause: config.premoveOnPause, + moveSnakeWithAI: config.moveSnakeWithAI, + }); + myFood = new SNAKE.Food({ playingBoard: me }); + + elmWelcome.style.zIndex = 1000; + } - function createGameEndElement(message, elmId, elmClassName) { - const tmpElm = document.createElement("div"); - tmpElm.id = elmId + myId; - tmpElm.className = elmClassName; + function maxBoardWidth() { + return MAX_BOARD_COLS * me.getBlockWidth(); + } - const gameEndTxt = document.createElement("div"); - gameEndTxt.innerHTML = "JavaScript Snake

" + message + "

"; - const gameEndStart = document.createElement("button"); - gameEndStart.appendChild(document.createTextNode("Play Again?")); + function maxBoardHeight() { + return MAX_BOARD_ROWS * me.getBlockHeight(); + } - const reloadGame = function () { - tmpElm.style.display = "none"; - me.resetBoard(); - me.setBoardState(1); - me.getBoardContainer().focus(); - }; + function createWelcomeElement() { + const tmpElm = document.createElement("div"); + tmpElm.id = "sbWelcome" + myId; + tmpElm.className = "snake-welcome-dialog"; - const kbGameEndShortcut = function (evt) { - if (boardState !== 0 || tmpElm.style.display !== "block") { - return; + const welcomeTxt = document.createElement("div"); + let fullScreenText = ""; + if (config.fullScreen) { + fullScreenText = "On Windows, press F11 to play in Full Screen mode."; } - if (!evt) evt = window.event; - const keyNum = (evt.which) ? evt.which : evt.keyCode; - if (keyNum === 32 || keyNum === 13) { - reloadGame(); - } - }; - SNAKE.addEventListener(window, "keyup", kbGameEndShortcut, true); - - SNAKE.addEventListener(gameEndStart, "click", reloadGame, false); - tmpElm.appendChild(gameEndTxt); - tmpElm.appendChild(gameEndStart); - return tmpElm; - } + welcomeTxt.innerHTML = + "JavaScript Snake

Use the arrow keys on your keyboard to play the game. " + + fullScreenText + + "

"; + const welcomeStart = document.createElement("button"); + welcomeStart.appendChild(document.createTextNode("Play Game")); + + const loadGame = function () { + SNAKE.removeEventListener(window, "keyup", kbShortcut, false); + tmpElm.style.display = "none"; + me.setBoardState(BOARD_READY); + me.getBoardContainer().focus(); + }; + + const kbShortcut = function (evt) { + if (!evt) evt = window.event; + const keyNum = evt.which ? evt.which : evt.keyCode; + if (keyNum === 32 || keyNum === 13) { + loadGame(); + } + }; - function createTryAgainElement() { - return createGameEndElement("You died :(", "sbTryAgain", "snake-try-again-dialog"); - } + SNAKE.addEventListener(window, "keyup", kbShortcut, false); + SNAKE.addEventListener(welcomeStart, "click", loadGame, false); - function createWinElement() { - return createGameEndElement("You win! :D", "sbWin", "snake-win-dialog"); - } + tmpElm.appendChild(welcomeTxt); + tmpElm.appendChild(welcomeStart); + return tmpElm; + } - function handleEndCondition(elmDialog) { - const index = Math.max(getNextHighestZIndex(mySnake.snakeBody), getNextHighestZIndex({tmp: {elm: myFood.getFoodElement()}})); - elmContainer.removeChild(elmDialog); - elmContainer.appendChild(elmDialog); - elmDialog.style.zIndex = index; - elmDialog.style.display = "block"; - me.setBoardState(0); - } + function createGameEndElement(message, elmId, elmClassName) { + const tmpElm = document.createElement("div"); + tmpElm.id = elmId + myId; + tmpElm.className = elmClassName; + + const gameEndTxt = document.createElement("div"); + gameEndTxt.innerHTML = "JavaScript Snake

" + message + "

"; + const gameEndStart = document.createElement("button"); + gameEndStart.appendChild(document.createTextNode("Play Again?")); + + const reloadGame = function () { + tmpElm.style.display = "none"; + me.resetBoard(); + me.setBoardState(BOARD_READY); + me.getBoardContainer().focus(); + }; + + const kbGameEndShortcut = function (evt) { + if (boardState !== 0 || tmpElm.style.display !== "block") { + return; + } + if (!evt) evt = window.event; + const keyNum = evt.which ? evt.which : evt.keyCode; + if (keyNum === 32 || keyNum === 13) { + reloadGame(); + } + }; + SNAKE.addEventListener(window, "keyup", kbGameEndShortcut, true); - // --------------------------------------------------------------------- - // public functions - // --------------------------------------------------------------------- - - me.setPaused = function (val) { - isPaused = val; - mySnake.setPaused(val); - if (isPaused) { - elmPauseScreen.style.display = "block"; - } else { - elmPauseScreen.style.display = "none"; + SNAKE.addEventListener(gameEndStart, "click", reloadGame, false); + tmpElm.appendChild(gameEndTxt); + tmpElm.appendChild(gameEndStart); + return tmpElm; } - }; - me.getPaused = function () { - return isPaused; - }; - /** - * Resets the playing board for a new game. - * @method resetBoard - */ - me.resetBoard = function () { - SNAKE.removeEventListener(elmContainer, "keydown", myKeyListener, false); - SNAKE.removeEventListener(elmContainer, "visibilitychange", myWindowListener, false); - mySnake.reset(); - elmLengthPanel.innerHTML = "Length: 1"; - me.setupPlayingField(); - }; - /** - * Gets the current state of the playing board. There are 3 states: 0 - Welcome or Try Again dialog is present. 1 - User has pressed "Start Game" on the Welcome or Try Again dialog but has not pressed an arrow key to move the snake. 2 - The game is in progress and the snake is moving. - * @method getBoardState - * @return {Number} The state of the board. - */ - me.getBoardState = function () { - return boardState; - }; - /** - * Sets the current state of the playing board. There are 3 states: 0 - Welcome or Try Again dialog is present. 1 - User has pressed "Start Game" on the Welcome or Try Again dialog but has not pressed an arrow key to move the snake. 2 - The game is in progress and the snake is moving. - * @method setBoardState - * @param {Number} state The state of the board. - */ - me.setBoardState = function (state) { - boardState = state; - }; - /** - * @method getGridFoodValue - * @return {Number} A number that represents food on a number representation of the playing board. - */ - me.getGridFoodValue = function () { - return GRID_FOOD_VALUE; - }; - /** - * @method getPlayingFieldElement - * @return {DOM Element} The div representing the playing field (this is where the snake can move). - */ - me.getPlayingFieldElement = function () { - return elmPlayingField; - }; - /** - * @method setBoardContainer - * @param {DOM Element or String} myContainer Sets the container element for the game. - */ - me.setBoardContainer = function (myContainer) { - if (typeof myContainer === "string") { - myContainer = document.getElementById(myContainer); - } - if (myContainer === elmContainer) { - return; + function createTryAgainElement() { + return createGameEndElement( + "You died :(", + "sbTryAgain", + "snake-try-again-dialog", + ); } - elmContainer = myContainer; - elmPlayingField = null; - me.setupPlayingField(); - }; - /** - * @method getBoardContainer - * @return {DOM Element} - */ - me.getBoardContainer = function () { - return elmContainer; - }; - /** - * @method getBlockWidth - * @return {Number} - */ - me.getBlockWidth = function () { - return blockWidth; - }; - /** - * @method getBlockHeight - * @return {Number} - */ - me.getBlockHeight = function () { - return blockHeight; - }; - /** - * Sets up the playing field. - * @method setupPlayingField - */ - me.setupPlayingField = function () { - - if (!elmPlayingField) { - createBoardElements(); - } // create playing field - - // calculate width of our game container - let cWidth, cHeight; - let cTop, cLeft; - if (config.fullScreen === true) { - cTop = 0; - cLeft = 0; - cWidth = getClientWidth() - 20; - cHeight = getClientHeight() - 20; - - } else { - cTop = config.top; - cLeft = config.left; - cWidth = config.width; - cHeight = config.height; + function createWinElement() { + return createGameEndElement("You win! :D", "sbWin", "snake-win-dialog"); } - // define the dimensions of the board and playing field - const wEdgeSpace = me.getBlockWidth() * 2 + (cWidth % me.getBlockWidth()); - const fWidth = Math.min(maxBoardWidth() - wEdgeSpace, cWidth - wEdgeSpace); - const hEdgeSpace = me.getBlockHeight() * 3 + (cHeight % me.getBlockHeight()); - const fHeight = Math.min(maxBoardHeight() - hEdgeSpace, cHeight - hEdgeSpace); - - elmContainer.style.left = cLeft + "px"; - elmContainer.style.top = cTop + "px"; - elmContainer.style.width = cWidth + "px"; - elmContainer.style.height = cHeight + "px"; - elmPlayingField.style.left = me.getBlockWidth() + "px"; - elmPlayingField.style.top = me.getBlockHeight() + "px"; - elmPlayingField.style.width = fWidth + "px"; - elmPlayingField.style.height = fHeight + "px"; - - // the math for this will need to change depending on font size, padding, etc - // assuming height of 14 (font size) + 8 (padding) - const bottomPanelHeight = hEdgeSpace - me.getBlockHeight(); - const pLabelTop = me.getBlockHeight() + fHeight + Math.round((bottomPanelHeight - 30) / 2) + "px"; - - elmAboutPanel.style.top = pLabelTop; - elmAboutPanel.style.width = "450px"; - elmAboutPanel.style.left = Math.round(cWidth / 2) - Math.round(450 / 2) + "px"; - - elmLengthPanel.style.top = pLabelTop; - elmLengthPanel.style.left = 30 + "px"; - - elmHighscorePanel.style.top = pLabelTop; - elmHighscorePanel.style.left = cWidth - 140 + "px"; - - // if width is too narrow, hide the about panel - if (cWidth < 700) { - elmAboutPanel.style.display = "none"; - } else { - elmAboutPanel.style.display = "block"; + function handleEndCondition(elmDialog) { + const index = Math.max( + getNextHighestZIndex(mySnake.snakeBody), + getNextHighestZIndex({ tmp: { elm: myFood.getFoodElement() } }), + ); + elmContainer.removeChild(elmDialog); + elmContainer.appendChild(elmDialog); + elmDialog.style.zIndex = index; + elmDialog.style.display = "block"; + me.setBoardState(BOARD_NOT_READY); } - me.grid = []; - const numBoardCols = fWidth / me.getBlockWidth() + 2; - const numBoardRows = fHeight / me.getBlockHeight() + 2; - - for (let row = 0; row < numBoardRows; row++) { - me.grid[row] = []; - for (let col = 0; col < numBoardCols; col++) { - if (col === 0 || row === 0 || col === (numBoardCols - 1) || row === (numBoardRows - 1)) { - me.grid[row][col] = 1; // an edge - } else { - me.grid[row][col] = 0; // empty space - } + // --------------------------------------------------------------------- + // public functions + // --------------------------------------------------------------------- + + me.setPaused = function (val) { + isPaused = val; + mySnake.setPaused(val); + if (isPaused) { + elmPauseScreen.style.display = "block"; + } else { + elmPauseScreen.style.display = "none"; } - } - - myFood.randomlyPlaceFood(); - - myKeyListener = function (evt) { - if (!evt) evt = window.event; - const keyNum = (evt.which) ? evt.which : evt.keyCode; + config.onPauseToggle(isPaused); + }; + me.getPaused = function () { + return isPaused; + }; - if (me.getBoardState() === 1) { - if (!(keyNum >= 37 && keyNum <= 40) && !(keyNum === 87 || keyNum === 65 || keyNum === 83 || keyNum === 68)) { - return; - } // if not an arrow key, leave + /** + * Resets the playing board for a new game. + * @method resetBoard + */ + me.resetBoard = function () { + SNAKE.removeEventListener( + elmContainer, + "keydown", + myKeyListener, + false, + ); + SNAKE.removeEventListener( + elmContainer, + "visibilitychange", + myWindowListener, + false, + ); + mySnake.reset(); + config.onLengthUpdate(1); + elmLengthPanel.innerHTML = "Length: 1"; + me.setupPlayingField(); + }; + /** + * Gets the current state of the playing board. There are 3 states: 0 - Welcome or Try Again dialog is present. 1 - User has pressed "Start Game" on the Welcome or Try Again dialog but has not pressed an arrow key to move the snake. 2 - The game is in progress and the snake is moving. + * @method getBoardState + * @return {Number} The state of the board. + */ + me.getBoardState = function () { + return boardState; + }; + /** + * Sets the current state of the playing board. There are 3 states: 0 - Welcome or Try Again dialog is present. 1 - User has pressed "Start Game" on the Welcome or Try Again dialog but has not pressed an arrow key to move the snake. 2 - The game is in progress and the snake is moving. + * @method setBoardState + * @param {Number} state The state of the board. + */ + me.setBoardState = function (state) { + boardState = state; + }; + /** + * @method getGridFoodValue + * @return {Number} A number that represents food on a number representation of the playing board. + */ + me.getGridFoodValue = function () { + return GRID_FOOD_VALUE; + }; + /** + * @method getPlayingFieldElement + * @return {DOM Element} The div representing the playing field (this is where the snake can move). + */ + me.getPlayingFieldElement = function () { + return elmPlayingField; + }; + /** + * @method setBoardContainer + * @param {DOM Element or String} myContainer Sets the container element for the game. + */ + me.setBoardContainer = function (myContainer) { + if (typeof myContainer === "string") { + myContainer = document.getElementById(myContainer); + } + if (myContainer === elmContainer) { + return; + } + elmContainer = myContainer; + elmPlayingField = null; - // This removes the listener added at the #listenerX line - SNAKE.removeEventListener(elmContainer, "keydown", myKeyListener, false); - SNAKE.removeEventListener(elmContainer, "visibilitychange", myWindowListener, false); + me.setupPlayingField(); + }; + /** + * @method getBoardContainer + * @return {DOM Element} + */ + me.getBoardContainer = function () { + return elmContainer; + }; + /** + * @method getBlockWidth + * @return {Number} + */ + me.getBlockWidth = function () { + return blockWidth; + }; + /** + * @method getBlockHeight + * @return {Number} + */ + me.getBlockHeight = function () { + return blockHeight; + }; + /** + * Sets up the playing field. + * @method setupPlayingField + */ + me.setupPlayingField = function () { + if (!elmPlayingField) { + createBoardElements(); + } // create playing field + + // calculate width of our game container + let cWidth, cHeight; + let cTop, cLeft; + if (config.fullScreen === true) { + cTop = 0; + cLeft = 0; + cWidth = getClientWidth() - 20; + cHeight = getClientHeight() - 20; + } else { + cTop = config.top; + cLeft = config.left; + cWidth = config.width; + cHeight = config.height; + } - myKeyListener = function (evt) { - if (!evt) evt = window.event; - const keyNum = (evt.which) ? evt.which : evt.keyCode; + // define the dimensions of the board and playing field + const wEdgeSpace = + me.getBlockWidth() * 2 + (cWidth % me.getBlockWidth()); + const fWidth = Math.min( + maxBoardWidth() - wEdgeSpace, + cWidth - wEdgeSpace, + ); + const hEdgeSpace = + me.getBlockHeight() * 3 + (cHeight % me.getBlockHeight()); + const fHeight = Math.min( + maxBoardHeight() - hEdgeSpace, + cHeight - hEdgeSpace, + ); + + elmContainer.style.left = cLeft + "px"; + elmContainer.style.top = cTop + "px"; + elmContainer.style.width = cWidth + "px"; + elmContainer.style.height = cHeight + "px"; + elmPlayingField.style.left = me.getBlockWidth() + "px"; + elmPlayingField.style.top = me.getBlockHeight() + "px"; + elmPlayingField.style.width = fWidth + "px"; + elmPlayingField.style.height = fHeight + "px"; + + // the math for this will need to change depending on font size, padding, etc + // assuming height of 14 (font size) + 8 (padding) + const bottomPanelHeight = hEdgeSpace - me.getBlockHeight(); + const pLabelTop = + me.getBlockHeight() + + fHeight + + Math.round((bottomPanelHeight - 30) / 2) + + "px"; + + elmAboutPanel.style.top = pLabelTop; + elmAboutPanel.style.width = "450px"; + elmAboutPanel.style.left = + Math.round(cWidth / 2) - Math.round(450 / 2) + "px"; + + elmLengthPanel.style.top = pLabelTop; + elmLengthPanel.style.left = 30 + "px"; + + elmHighscorePanel.style.top = pLabelTop; + elmHighscorePanel.style.left = cWidth - 140 + "px"; + + // if width is too narrow, hide the about panel + if (cWidth < 700) { + elmAboutPanel.style.display = "none"; + } else { + elmAboutPanel.style.display = "block"; + } - //console.log(keyNum); - if (keyNum === 32) { - if (me.getBoardState() != 0) - me.setPaused(!me.getPaused()); + me.grid = []; + const numBoardCols = fWidth / me.getBlockWidth() + 2; + const numBoardRows = fHeight / me.getBlockHeight() + 2; + + for (let row = 0; row < numBoardRows; row++) { + me.grid[row] = []; + for (let col = 0; col < numBoardCols; col++) { + if ( + col === 0 || + row === 0 || + col === numBoardCols - 1 || + row === numBoardRows - 1 + ) { + me.grid[row][col] = 1; // an edge + } else { + me.grid[row][col] = 0; // empty space } - + } + } + me.grid[getStartRow()][getStartCol()] = 1; // snake head + + myFood.randomlyPlaceFood(); + config.onLengthUpdate(1); + + myKeyListener = function (evt) { + if (!evt) evt = window.event; + const keyNum = evt.which ? evt.which : evt.keyCode; + + if (me.getBoardState() === BOARD_READY) { + if ( + !(keyNum >= 37 && keyNum <= 40) && + !( + keyNum === 87 || + keyNum === 65 || + keyNum === 83 || + keyNum === 68 + ) + ) { + return; + } // if not an arrow key, leave + + // This removes the listener added at the #listenerX line + SNAKE.removeEventListener( + elmContainer, + "keydown", + myKeyListener, + false, + ); + SNAKE.removeEventListener( + elmContainer, + "visibilitychange", + myWindowListener, + false, + ); + + myKeyListener = function (evt) { + if (!evt) evt = window.event; + const keyNum = evt.which ? evt.which : evt.keyCode; + + if (keyNum === 32) { + if (me.getBoardState() != BOARD_NOT_READY) + me.setPaused(!me.getPaused()); + } + + mySnake.handleArrowKeys(keyNum); + + evt.cancelBubble = true; + if (evt.stopPropagation) { + evt.stopPropagation(); + } + if (evt.preventDefault) { + evt.preventDefault(); + } + return false; + }; + + //listener for pausing the game if user change tab or minimize the browser window + document.addEventListener("visibilitychange", () => { + if (document.visibilityState === "hidden") { + if (me.getBoardState() != BOARD_NOT_READY && !me.getPaused()) + me.setPaused(true); + } + }); + + SNAKE.addEventListener( + elmContainer, + "keydown", + myKeyListener, + false, + ); + SNAKE.addEventListener( + elmContainer, + "visibilitychange", + myWindowListener, + false, + ); + + mySnake.rebirth(); mySnake.handleArrowKeys(keyNum); + me.setBoardState(BOARD_IN_PLAY); // start the game! + mySnake.go(); + } - evt.cancelBubble = true; - if (evt.stopPropagation) { - evt.stopPropagation(); - } - if (evt.preventDefault) { - evt.preventDefault(); - } - return false; - }; - - //listener for pausing the game if user change tab or minimize the browser window - document.addEventListener("visibilitychange", () => { - if (document.visibilityState === 'hidden') { - if (me.getBoardState() != 0 && !me.getPaused()) - me.setPaused(true); - } - }); + evt.cancelBubble = true; + if (evt.stopPropagation) { + evt.stopPropagation(); + } + if (evt.preventDefault) { + evt.preventDefault(); + } + return false; + }; + // Search for #listenerX to see where this is removed + if (!config.moveSnakeWithAI) { SNAKE.addEventListener(elmContainer, "keydown", myKeyListener, false); - SNAKE.addEventListener(elmContainer, "visibilitychange", myWindowListener, false); - - mySnake.rebirth(); - mySnake.handleArrowKeys(keyNum); - me.setBoardState(2); // start the game! - mySnake.go(); + SNAKE.addEventListener( + elmContainer, + "visibilitychange", + myWindowListener, + false, + ); } + }; - evt.cancelBubble = true; - if (evt.stopPropagation) { - evt.stopPropagation(); + /** + * This method is called when the snake has eaten some food. + * @method foodEaten + * @return {bool} Whether a new food was able to spawn (true) + * or not (false) after the snake eats food. + */ + me.foodEaten = function () { + config.onLengthUpdate(mySnake.snakeLength); + elmLengthPanel.innerHTML = "Length: " + mySnake.snakeLength; + if (mySnake.snakeLength > localStorage[HIGH_SCORE_KEY]) { + localStorage.setItem(HIGH_SCORE_KEY, mySnake.snakeLength); + elmHighscorePanel.innerHTML = + "Highscore: " + localStorage[HIGH_SCORE_KEY]; } - if (evt.preventDefault) { - evt.preventDefault(); + if (!myFood.randomlyPlaceFood()) { + return false; } - return false; + return true; }; - // Search for #listenerX to see where this is removed - SNAKE.addEventListener(elmContainer, "keydown", myKeyListener, false); - SNAKE.addEventListener(elmContainer, "visibilitychange", myWindowListener, false); - }; + /** + * This method is called when the snake dies. + * @method handleDeath + */ + me.handleDeath = function () { + handleEndCondition(elmTryAgain); + config.onDeath({ startAIGame: me.startAIGame }); + }; - /** - * This method is called when the snake has eaten some food. - * @method foodEaten - * @return {bool} Whether a new food was able to spawn (true) - * or not (false) after the snake eats food. - */ - me.foodEaten = function () { - elmLengthPanel.innerHTML = "Length: " + mySnake.snakeLength; - if (mySnake.snakeLength > localStorage.jsSnakeHighScore) { - localStorage.setItem("jsSnakeHighScore", mySnake.snakeLength); - elmHighscorePanel.innerHTML = "Highscore: " + localStorage.jsSnakeHighScore; - } - if (!myFood.randomlyPlaceFood()) { - return false; - } - return true; - }; + /** + * This method is called when the snake wins. + * @method handleWin + */ + me.handleWin = function () { + handleEndCondition(elmWin); + config.onWin({ startAIGame: me.startAIGame }); + }; - /** - * This method is called when the snake dies. - * @method handleDeath - */ - me.handleDeath = function () { - handleEndCondition(elmTryAgain); - }; + me.setSpeed = (speed) => { + mySnake.setSpeed(speed); + }; + me.getSpeed = () => { + return mySnake.getSpeed(); + }; - /** - * This method is called when the snake wins. - * @method handleWin - */ - me.handleWin = function () { - handleEndCondition(elmWin); - }; + me.startAIGame = () => { + mySnake.rebirth(); + me.setBoardState(2); // start the game! + mySnake.go(); + }; - // --------------------------------------------------------------------- - // Initialize - // --------------------------------------------------------------------- + // --------------------------------------------------------------------- + // Initialize + // --------------------------------------------------------------------- + + config.fullScreen = + typeof config.fullScreen === "undefined" ? false : config.fullScreen; + config.top = typeof config.top === "undefined" ? 0 : config.top; + config.left = typeof config.left === "undefined" ? 0 : config.left; + config.width = typeof config.width === "undefined" ? 400 : config.width; + config.height = + typeof config.height === "undefined" ? 400 : config.height; + config.premoveOnPause = + typeof config.premoveOnPause === "undefined" + ? false + : config.premoveOnPause; - config.fullScreen = (typeof config.fullScreen === "undefined") ? false : config.fullScreen; - config.top = (typeof config.top === "undefined") ? 0 : config.top; - config.left = (typeof config.left === "undefined") ? 0 : config.left; - config.width = (typeof config.width === "undefined") ? 400 : config.width; - config.height = (typeof config.height === "undefined") ? 400 : config.height; - config.premoveOnPause = (typeof config.premoveOnPause === "undefined") ? false : config.premoveOnPause; + if (config.fullScreen) { + SNAKE.addEventListener( + window, + "resize", + function () { + me.setupPlayingField(); + }, + false, + ); + } - if (config.fullScreen) { - SNAKE.addEventListener(window, "resize", function () { - me.setupPlayingField(); - }, false); - } + me.setBoardState(BOARD_NOT_READY); - me.setBoardState(0); + if (config.boardContainer) { + me.setBoardContainer(config.boardContainer); + } - if (config.boardContainer) { - me.setBoardContainer(config.boardContainer); - } + const reloadGame = function () { + me.resetBoard(); + me.setBoardState(BOARD_READY); + me.getBoardContainer().focus(); + }; - }; // end return function -})(); + if (config.onInit) { + config.onInit({ + reloadGame, + getSpeed: me.getSpeed, + setSpeed: me.setSpeed, + startAIGame: me.startAIGame, + }); + } + }; // end return function + })(); From df3d88ec11da90aba952b4d26ee911597814d4e7 Mon Sep 17 00:00:00 2001 From: patorjk Date: Thu, 13 Feb 2025 21:49:59 -0500 Subject: [PATCH 50/55] updates --- README.md | 43 ++++++++++++++++++++++++++++ src/ai-example.html | 2 +- src/js/ai-init.js | 43 ++++++++++++++++++++++++++-- src/js/snake.js | 68 +++++++++++++++++++++++++++++---------------- 4 files changed, 128 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 8577b786..641e7803 100755 --- a/README.md +++ b/README.md @@ -37,6 +37,49 @@ npx parcel src/index.html Runs on http://localhost:1234 +## AI Snake + +If you want to control the snake via an AI algorithm see the ai-init.js and ai-example files. + +Essentially all you have to do is run `params.startAIGame();` when initializing and pass in a `moveSnakeWithAI` method +which is run before the snake does each move. + +```js + moveSnakeWithAI: ({ + grid, + snakeHead, + currentDirection, + isFirstGameMove, + setDirection, + }) => { + + /* + Direction: + 0 + 3 1 + 2 + */ + + // This is NOT a real hamiltonian cycle. It misses some values, I'm just including this here as an example of + // a look-up type table that you could do. + const hamiltonianCycleGrid = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0], + [0, 0, 2, 3, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 0], + [0, 0, 2, 0, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0], + [0, 0, 2, 0, 2, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0], + [0, 0, 3, 0, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + + const newDirection = hamiltonianCycleGrid[snakeHead.row][snakeHead.col]; + setDirection(newDirection); + }, + onInit: (params) => { + params.startAIGame(); // This start an AI game + }, +``` + ## Contributors Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/emoji-key)) diff --git a/src/ai-example.html b/src/ai-example.html index e1acb6ad..d3ca29d7 100644 --- a/src/ai-example.html +++ b/src/ai-example.html @@ -124,7 +124,7 @@
- + From 2dd6f1b8d1c95f1d100bf038f75bfaa234723ee8 Mon Sep 17 00:00:00 2001 From: patorjk Date: Thu, 13 Feb 2025 22:16:49 -0500 Subject: [PATCH 54/55] game note --- README.md | 2 ++ src/index.html | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 641e7803..b3a2f430 100755 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ You can now play and edit the game live in codesandbox: https://codesandbox.io/s/github/patorjk/JavaScript-Snake?file=/index.html +**2025: Looks like CSS inside the sandbox isn't working properly, in the game it works fine though** + On first load sometimes the game frame will not load correctly and you'll need to press the refresh icon above its display panel to get the game to show. Original game is located here: diff --git a/src/index.html b/src/index.html index 291c88ce..03dc6b10 100755 --- a/src/index.html +++ b/src/index.html @@ -38,7 +38,6 @@ newCss.rel = "stylesheet"; newCss.type = "text/css"; newCss.href = themeUrl; - console.log(newCss.href); document.head.appendChild(newCss); } From 5702346689d4af03d7b5635005c34fa695d03802 Mon Sep 17 00:00:00 2001 From: patorjk Date: Thu, 13 Feb 2025 22:17:43 -0500 Subject: [PATCH 55/55] clean up --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index b3a2f430..0956f864 100755 --- a/README.md +++ b/README.md @@ -119,8 +119,3 @@ Thanks goes to these people: ([emoji key](https://allcontributors.org/docs/en/em - -TODO: - -- Add in what was added to Subpixel Snake --