From 7b0d45d17e2a9227a2bf6b3f4b532ad7a2c646a0 Mon Sep 17 00:00:00 2001 From: DaInfLoop <github@dainfloop.is-a.dev> Date: Sun, 16 Feb 2025 13:03:40 +0000 Subject: [PATCH] idk what changed, i just need to commit so i can start proper commits --- bun.lockb | Bin 98401 -> 100630 bytes index.ts | 158 ++++++++++++++++++++++++++++++++++++++++++--------- package.json | 2 + 3 files changed, 134 insertions(+), 26 deletions(-) diff --git a/bun.lockb b/bun.lockb index 8645e16810d0129f42544bef74a516dee14212c2..0b0866a4b08201dc26c41bf32eb82627cd3563f7 100755 GIT binary patch delta 20064 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 delta 18868 zcmeHvd3Y7YwtZKV1L?ql1QH13FeD5H%uL7$COJu%O)~{l5Jd?PAwVDlqYODgWC${Z z0vZryZ~#OZL<CV3uA&k}MMZH!P*Fj-fXWq7@vYT^<avR2f4}ej^*;M!W!I|OHSArx ztNQez&hjNSPxxytj%(L4=&KfcqPos`d(rdd4bOb=`43au7fft(%i*0fHpm+y%U2vO z6AG_OO69<2U6%Z868ld*Me!GnD;+<gB)@d{xbgX8Co0O&VI@<F#w*G>=+s5|r;wqL z<MT?)TEB|QFM7A@6`&}=$n6AK8?qy$2HDi5C~UPHG6=HNB?pPPviMqx(g?IUB&(f) zq*~uVtCLQ){2G$YeT8y1*8s8(<cPcpBl6LG9NKh)N7^zBlI7n)ncWRWWy&B(_V)(} zk`4SpR>J=W6xqQAO*T=R)qfejq5hX>l(KDInWHu<dm7mxpoJJCvxnyooiGC37nYhX zP&S~Pt;B(HI2Evo{B1}MrzP^qzd<97A>W5=0J*NdW$r(~k@U|(ChLCzNw>TQi7w0h zYvFN@-yLQt<U_LI?U0<5Np{7Nd8Okfja8Ix4J|!C>apYg;Pl^}(5LJNead&xD3boJ z;fjKP{ujYHkP+jGhSRh}WQHnbioc*VucRbziejKaRy+?gIAH~)v8DOr6$P>|uSikm zqnra9gI3vbaZ}54_lzrv&CeS)vW>^e9}=M`7?a;<rYKDyheD6--PK%CFh>7bNcQtN zWN;Z0Zy~`cIA9m_hhztRQIR7ahKA{hj^OlElr4kp@_(V69c@F$?C1^*knK&i2XqXQ z9ykce0qlXa4J;|kACW(K6EavqLUQCgTU$K1jdefFMn31R7?Ls4%ht<)<Xk2~(ld=9 z*{~audOzEqI1b5yAGQaW)z&iTr3m<+7Cwjqj%>CqCqlB}u8{cWkHsHakO|8;r*GY; zDDbX-n;l$}N;#v7a!<k7g7H%n<>44>z{?=%>e<kv2Y-sS+I7mugk)KYL!dwlPC<dL zKMu)?AKG$nyk${gL1BLE@S(~Ua9UcPAfIqGE6Yx_su#r;PspE;ubcyC_4Y}Ybo$Gi zTriG9y@Y&@$7%jFIPG0;k8`Ol{mF{b0{QL^mfb2OhquO-{ZNj6%KU{$&@qEktdO|_ zoQ}N&&W@&_K{w<WTiyamdqYz#I|3oeoxA>5aCY<!WGLiOTkmy94s^FIH<|gv75^xE z3Pw%JgMEt9FU=ZIDkNj`g4g0Dd6Qy?jvGE@!q}pMA}n*O(k;hEW>^DQ1kR41vw7+G zyzvuC^Gi2p$ab}w4ce7yHS;(mOz<y<tnRpZ;Iwl(B<)FsWOGd*IUz-PC8hZjO2(At zk2M#8Vq33srd(gkSC((n+ilq!lGS5vIetn}er!RhGPJ9eUu?%+OO!L<n|8Ch3AJTm z{`isOhL<XN!-nM-jW1PdcDM9~jT<+*0M<{;D?zj>%J|aKVTDDCygN{fZrsCa!--vl znc4QKz!7hGl>V!ulFn~FnjO`1$L_$RBK&O7C!6-ydu?=O{GbJGc4l<c#-+b{I(OCc zJGKRd*A!{;U~r~ds>q!BK5Zi!LRk1+G9<*SURGpPeV=-lkU<T6>LDR>8u+xDs-pOy zqRPYdy=oU#Rv~j5G7(1p02$KQt3IvDoKT;38kv}THipcY8nP<X=NeK2JxF)sG<97K znG@zykJOMA5L$q&f*2eigBtp@$FP606Tzz5mtZ%6)sVTNXvih2pfca3C<p|<B10N_ zwb#J9m=!9+yjty=R?iqCDs-+Xs~Y*VsmP>lLPAB|T2tnP`?SyPOqZ<8N)5#JdYh?1 z(^l7#L5+RdZ^*<{vGXvm>n`lbUF4zI^Z+x_D<n-jj}*u1lDQ4MT0BCCV>L(aDgeu( zwXRJ_CCLS0X<8bhpc6FUEBJVNkj#njX)hr&%gj8C@kb({Xj@Iwwh=aiA7SYuU>sx( z(>1?<vGYLF$KE=!%Hz`}Agrw^LIrh49huYA=L$f~n~v8yBb9(U=DcX7%m>4OF`Nx< znbXXtok1oCV5y{GdFTm-F45kcx-zJ_Puqn|&Tb7e4$jt<707IfNX)V7VW^Y9EHmiw z9ra{R3!m#GGGk<~&@?Rsccned=3cE27#0F_N#$k1GAGifeiAGzAUq*5D9Y#Ja@AiR zYLuq-uP-a2eA-rIShLPB`4No66!Nggt5ssHqnpj?)_wr%;V{=tSg*RtUJ+^9E~Km} zXA4cR!B}<Bf~y!T%k1u@Fj>{grv@~XL9Kn-oeeFIsT`@c7|g1J;MCp)qfPK8YzoGX zW(PxauPcX4GGu1`nU8+dFB{3KHa=}|xS|YnhN$fXvy8#OTmsJ<3DVs#O-*bpt8VbA z<&9-fG$sN0RtGeht0+U&GPxTVCss9wa_@g*Tfi7@)};TliL7YrQ)f1nRS<`o%Aj^W z)zwVqwDW15n<>gIrY3vX4tA$i5AJd|uijrNSU<B2ZgE`%yGb6xG$*xiT+bHn1!IH= z-pj66z$~rHNLh|!?es`kZ@PYNqzsDnxeg)YHn|`=Js^q+ctV?kl;t4?%z-Ew6z9_- z@vLdNfb%&5%<c@g=5{c9ZbH1SvtR?IJ1$M_-b&`g`?Qs<{;Z10`W!4(9=ah-Yt;JB zMzEOVwU#*vKJ8UI(~5ysZ4{-i<s?MJcrZppfXr>`)t&|8O<>0%nB`8!N4Fa+*O*h} zS_p>40;au%R5#SYy#*(QMxzDOm3@)2YSZLLqh(NgpLPkERE9@kWbd|r-V)JXZ3!5C zWW~TSFl&YwQwi<B%$S<l&Rle>ka3sU5XR<;zR~m#M&n1Sx0%lg{2pw$r3DZ7jZu`Y zCd+N%RX4}TpcJ2aE=K00__S8BmLJS@OT8ynR-tTVtPJw{w17B8$+p_8@7213(PQQU zugwADN?@&U{{XuQ3?_KJ+HYW-L#*s=QUl}vjDD=w<Ktyjs!x3_UIul<y_z6%I{I8` zSm?TOmbFDlU0EyM1LNwY$lP%37m3dHl?%W2N|Y5h`7}Q=*)cX4biBt_scCKlzpzX$ zh)UDalbkUy;3k4uQx8|EyOU&4x=#yi@AQmqMe7O1X05Gqc6(U`mA7q`nlQ_&Hb|B^ z89sGwvaHDPxmw^suDk5jE=?WLK?eDJ+7rmYqY@_^K0nbxR``5sSc<Gd*|-#IKFpm@ zdj`x3jmiwK8t9c3nLbxH)J>CzlF|d2a7LoN0M-#qrGZ*YIEOVcN-X3BU|C?Ax#HD? z8m66^5ne3`j5A_xXIc>$?}Pw(xRF=e2WG`FqrE1~<{FGLtdzZNhFM10axkmE+z_w! zDHtZ2@eg+drOBYqK36`*+DEz@q`96!>P|CqgVSYIXP-6zHyCFVBTDdUkAiXGGq+&% zXu7QE;&a8~VKIx_j;jzUpSdR=F!OlBxnP0S0L{$+vqGgZ%Ihiz!`j<8P1}wXCfEv7 z^-G_u=;m`(W#aCTy;9O#;c!t7hvgcIR1Yp++7n2zDFjiZSNkUz!^2v36S8Gc51&?y z`v46y6OPyl2J69ai)*LAI4+d6^Qw`ZWYEn%tsj~|L&)R}zXXicaes97YVUyA72wCf z&Q@Hbu_&+R1LN=!^9f$HsI#od@wwI`Gsb)#d#key(tYaX&N4^$X>k~})d{PP{gZ`6 zdtF<=;6dz0-*=HYJ$>qpU1dd2pH_&KfI~qCc$C=ORR;C)X-ARC^$!t=TcS-jS%J(U zm}^?8m;+k{hDfDBSYhAkCUbiG)Zp&2qPI`$+1;8<I8gU$elXm*mZobP%jjm;S4ee` z?)GVFR1aCz2b(DZjWK}dq7<+CP!E~Y_olL1ilPv_s!J6dk7wpZNz?~w0^xuF8r!l7 zBri(V^N`@Wo@D)|_y}e;h;7Hbs!J-g0@z?1v-Ikc<yh^_i<0%QrYive7F+Y8q#o8r zr3Qc*H?Ji0Z&tukV_sL2v>cOVUezTVLY$lRv&>R6I?UAdI0u+*>u1wN%;;oiP;#VQ zDCL>lM$*$SxQsbB1JuOcZAu-IS9Qs9Y;9(FFBamW#N#C&QOt{ydV?)$N>1u9fc@m# z`IIz$EGLN-#sRds1fX*#0=y_)z*K;G(*R!AlhiK<*zp{I_2$}go-HdN+1~<A60ZdS z6&Koa5hSnbk``0~SSgj40Cw~Wz<LJ&UX<jolHj7GK~(_t-v(Izjx7(fe>VJ{o$)>- zFG^bQF~AC+*!%<}8~Pfc1*dHJJtXzc*!&zMFG}kD2yh@j+x!wF`z`woe^|iUlmWI3 zWNWx6nO_HzS#Dd_CBa3>WIg<0gCVwT0LhLULb84nn>U5TKc$()%almFpp`9euw^^Q zKqw|bvf*S%dgLZZUX)x_vhDKDc7AoqtS<Od8?p~1d0+mqrBM1PO0J!8HAxF@u`Awc z>rpa!o6W0BRTkdb$h@Zp*;;qlTGb_6z01z0B+s*XbxFVFBcHOsE~lhBM%%o)WIJPp z9n(mdibasrEw(FAGFgH@^yg$dpE3x1rp^C<BnLK2Af`EzIcSJ&&9xh(WO5$<(4qx) zJ|&Y2ZBEG$mp1=TWOL~AwK=Qou)lIpcGwMEO>zLc?DDHgH_BhJ%PE;WVDqa<7QJeh zhdGJrvX(qFpix;JsC@)AI_eW!os!8<?fheQ{?#Pw9k<J`C#iD6ZtqJ-@~@o8K-#=> zs_)589y{RD%!`uv-`krJ85{{VXEXF#Lh`CES>6iZK-vJjt|nRj|GYPIwdKW4njKwj zPi8suX?Z#cuIiGZoe8jh7QidZ{Cj;#{npvGA|*3A*_=`Zx={YTH`B*|@6CVj&42IB zxDjyuy*F3iqyKO2&2s9HD*5|RUDS{_4;vuA&2!7AhUvm3e*s%D)GY@O*F`P4Y4`xy zW0+gI^L3%g+w%v=i(q@fYD?{&0dnJTw=BFz7jF3+*uZ?ZY&t?0^<=?_0W$C&w>$(E zA{&n!Aa{dJAE}E5@*vpA5pEe<po=g$rC@*zAL*8#fi;qCM-7m#gDn`Pi^lRJu*n5( znK4=y5pv$>0Wx}&Tb==HDm#uDAdiAQG)5QA<tebaqusJsp)Mlj%EAFMb&Om74%SlM zJQntWJvCMrt>rIZD+*!XI9=QzH;sdRV_{#BF51f5i(ntvUa%XbRt)>b!M<W$#LDNu z1{T4-5?#d0f)dzQ4Ew+mW#dxV2R6M_7wzRiu#qLOZ@ex#$SLDtUn%SZ^UAgpU?13m z3A*SgKLVRP9`;St@lD;liLh@1>;ub?*^^-(*h7<aktt72f_)R+^0CRf$d>0(mO9BT zZ=Irx&T`!p*azmiR~KDn?!B;YvRm#1>n_Dq*f+&3^QY?KX1N{gB3RfoUFb4z8tl8* zEf0Y8k|EP!-&D7pFkKgY<bJTgX>QqihAwht@eJ4pb_A@yj4XqF)7|p^GF{v%4}*oz zaLW#UT?~-re%J?g66|)FSPuKj+;UmDF7A*gz@q(b*>$Ea2FuEsun+74*xfSwKG;_d z`|i_4o;(khIurKI(#0^jZWinVbKS3te3^Sc?7I*4fsK%2Htd@P`)2E+KyC-S2o^R+ z7o%m~9N2e1>;o&5A#-8hY}hwf7vto9u)sO6Z=NoSW$`@N2X+LkR7O_7zPYfkLKhR{ zVX*Lduy4LDCdu;oun+7c*c6%g0PL%PeGlkjsyqP}Js<Wh(8Y9Fxd8ToT>vYS*$ZLc z1F&zQF3RP3u+#;xZ;>wUlj|12J}}o}UED8o7sI}Vun%mG6qT@V5$vnf#XPwk>>^m$ z5?#!fc}rm5V%P_^K!!-zR|)&1E*8oCV1Y|u-%?#v%HpN459|n-l#$C|pM-tObg@hx z1`A&b`<Cm%kmbu^AJ|E-l`_$Qeam2<p^FFQ39#tpuy2Jf9+H(SU?128ur)G!CG0a` z-%4Gqljp%wSHQkix_CscTLt^TTo3BvF`4@y>{|)@z&1#+8uqP%eXDh`Np1(b2p0B` zE;h@&hhX1>un+7h8S*gfTMhdj*2Px2A1v@8*tbR(+hy?@*avn5Y=?|o3;Q01eQR~G zQyvBjUjzHr>0*~GUkCfZPJ%rr6W7DOwXko!E}oYsz@pc|zDIPiS5`g(`@k-My(F_A zg?;N`-=n(NFVBOeJ_7q5)5Xhj-D9v1%=Ne~4#?ccVc(;$59~E5Ho(5eVBZE^9F*I^ zE`o(^)WsVzZzJq`9QJ`7k|CR5-v-#XNf&R+{a}F`Vc!$FI4p~wfPG*`z}}OQn_=H3 z*tc01N919!@F!s3le+j&mOlymz)pgFBom*4eVbw5Q@Z#>o&bw}683G;#b>f|3+w~C z0QR}e-U|Dkf_+<caYCL4OWgwdw&~(axo#Wm19NTH#YvgF9rkU7ePG{6@igq)2K%1Y z#VNTR>>^m$4qbdF^LD_#?XVB*j0|}O_B{>zp3%iwxgRWW2khIai}SL0C+q_|0`{Yf zd=~aS1N)xU#RYj7EPN;I+og-2W%(}H2X+$d7n!(whujw&;O>MEH~6gU?+qC&v-eIl za|=fgFDNNelqfvk2O+nSOxRmTU0P#D(4G%Op!2`#q-W0yrux`%{GWh$!Hx~Tw%LfS z?%Run7v1c5vua^t&{4kA!gcPVtoS{v?D8Mh#jJk<{FsHeJm%$ae$>jf^Ugw2ho3oa zwe$Gaj5>TvFwoBX0g^g=HL-#fa9seH<a?B^R$iI%FFTVTulYiS7l+7lzR=>!C|(x< z=JA7OcYyl80L){(9sn=Cs$(AOH3WG53NVlF6B+@$_$E&%k>>xlF<<Gjk>AZsMQOp7 zafSb`$nP#^H#?5ny})||^iE%Z9_a`4S7gc`Q62d9mt*3X`7VKPu<ir~1AHg56j%l< z2MmBtSt(ck(dV`;NNokS0owt-@tF@i0E`DF0+Rr`tQ*h+$N_o*j2ONH8wv~qh69;E zmXL$~Xi|132GbLu(`X-^LMQN<ur5#!2nIp`zFNB*7y|Gm3!fqP0DFPY0ltXgOP9}p zMZgk(?|S$`icj2AfO~<dz%*bwU!d^i((M4>`V9ca0b_tdU?kuLQh|=ZGz?-oFaz)d zX8?vELym8fmjDu21}p~*;6Y$D@DQ*DSPQHJ9swR@oIHla<G==BBd`g00@w^Z32Xtj z0^5M6fgQjzz)s*<U>C64SSLh8*)SxB1B^7jfyf5h0_}hsff&F8)CU>>p+FeGC}h;} zO(@@v@>L<<ck<oj0^}b6B9Qg~je#1#AISRxcnvrRjO4rj0whKOg#cfDbOreCB^l@d zqySz3U$ODaQhtYJe(@3q$(KmYfEGX`5CzOaNB09&NWTHR3GiJ_I*<V*0Es{}(2`&6 zw?d*d@DwWXg=lx6CvX#x0r-Fez(4@L=Xa*&w<I@1HUao`RSwYOcl^P1G(eud+@_2- z+rNM;fc<jaPyw`Jt{(xA924!LjY$B<76CAV8OdBz7}bn!4Pc}P0kwcYfO(E=>m z#FUw{#aZKRz**yraptJh*amHH3DA+8Wjc@!<;=DKngfwQJV1xh>9GK#;s&4%K;N-0 zqoo}{y|#P-O$B<Iv&r?Cv&mWIY;qQz*-S$k-(i}wv=Q<G@GkH=@EouL*bVFgmI6-! zPXdboMocFl8|Vxy0QvzX=%4?y!dxgAQqIh=uqV(57!2GA+yUGU3<P=roY`EU7r>ci z9dg#w?R0O*z5v^y9{H^R^_VWBa(`d|;AArIHULp)Dw7jVMV1W$*eE+?`T<}*Fce^3 z1uzeo3pn+Pk)8wG56lA4W|?vy5;Fm(!|J1@h2=mV;0NffNx%$%o)`m62WV|6Fb$Xj zOa>+b6M*qR5ikxI3lsvQf#Ja2Y|$C<5M(%(vBO~iEg1#S(tMx*7zvC3IDmTqmeB)_ zC#cW#5P<E`AP$u6-3|P={%Db-aJ5Rz<Fv2=rb__2k$IdlP7y7yUgo43SJWk^K0U{@ zGg!D^DdXrFP);Q(-U~SKFcoQb;*?Y0>5zHOz}Q#`K#Q5rc9`eX<6zhpJv$qq=P-~m zQ;8#DbUGFN*GWHMm$5T8>U6|7VO+2crmJ_n5WE=Rlo`NMzz0aq{}LoBfyIFRK=ua< zHv*3W>wpJ=RRHr>0xJMEv>aFlFrQcpJPfP`9s<??j{xg|4Zvf-<G^O%31AcFe=Xot zdK&4Szz$#wK+cA@0b7CXHh1!#vH7#r@*N9bv-6&Z+ylG}`~%nz>;ql`%3j1D7VZUJ z0O|s-0Fl6}zyUi=&Q1>lZvs`oLEsJG9iS2LHt-g32>2dg{z>3d;3wb<-~{j^a2`0v z`9F=sCjcvc44eT@0UrVE=orAxzXiSlz6L%6jshP79{}w52=G4e9zcC|%68c%+oEyK zfWAW78Vvk@9K`9odZ+B<bKpyW%CxrnK&i{YIhN8hj^1&kY1r!kJ>?ie1HJ=R13AFi zw)pc;JL3n)pMi@2T}=eK1pZ>nO)+ZL7Hy1#+Tw0wQ*Dv4ypCw%p^c$f8mA@4el;?y z<9=1#l^B;0mzW6G8V}bI;hqhsUK<)Cf0^bF$lTc-8cEPd;CGP5yLCj8`m)$n(=9wg z{Z$yP>WXjGjsZs9dLlffQ-D>~_06)Bu`9OJu^UHK=S<UqH%{-Iad*$+D<w@`#+|6^ zDRr5V<R6gxey_nl96WJFqugaIt|$B+=fF~(yH>aOI_9?KR|eL+mJt(-Hk_kSi#C)c z&q|v5t=R_5!`Fkgj3Lla&(t#R4TcGw0*x)K;T)1$-~NN%YaaW>YxkOnpb0d-2o~*H zeWF?a<KH<3)imlv%Y9nZbI?qo<FKo1MnVXzcg{a;*dvBLRP)KL_V}RToRE64U%|`j z<@Xk&q`l?Rupnaw>pC9~kGf~BmGg(aYmOr^F6qj#tbX%8*wSoZP7q3x;}Y3#d@bWm z)b-d0vHaf;A9U+y>HE4sBh_j>sP^*uBD}}7hwhx|8YEVK((UIpMX1`rGRisq_4^pH ztthI?$ErA6#~4yyv{1iv8#C*Ro@(2=#ygaS^^9f>AS;56wGBjgW9Oijb22~`Gdjd2 zrNkv0hhjvy@pc1|>v4{QEI!)gw%pj)ELWw_+#w-GdMJ!?4vrije5_Qd)%2oiwi$&} zLX0A4q&R16Mve45?mKm~H#AZZ$7sYk&GORA8}E4i>5q?@brVsjtPe3>WL@VR&%~u` ze(F+n?_Ovm#<h=YkJT>3I>=II+UVj}!{t)5B!MG)Kg6gLhLJf3&mP;i<-+f0UGLZ$ zsJpJdkwp#X)KLAU4PH6D<ZHLB(E&S51Ea+a2*W!X7~5Kju;z$N=XBTn*JsrJ@X)be zP35E{40aNf8i_C$rg~Nb<5RY5A7b-|oLjzNXqI^C%ILmmU<5Zr%XSYQ=M>xbTQk;$ z?z}bH)P#+=u|ti;9%#-FH6}O2ycwa!s|`g`%33T7Sd#s>J-%~s$C}HYwcExJos)7m z_Iqwk-!}K&Y?mbC88gf{-V&4Atr3<M=OCTC;l)Ac9ymVziW&xWt_ixd)m6)~aF283 zuIrRetDfKA)pAr~d)V%1c57%{ZiJfs8ydkaEnisUk9T2UPU(w{41ajF_MLpEALnS^ zxm|M?uM9kyYL1L9#-Ti;Z=0*v?AsXYMAvZRVU{~RI4xe=y^f~inr2Nz6ZL#!BRvw$ zIKFq{z{!t|Fk;%FylaH<0v$CZ!sy)`(so>mb3UzV<D7a&UEM#kT?+$dM_4D>-bwjh z^nN2O=Ss<g5r!`UZTw|G>b3~u0pxpd7>=KP{dKdJpN^Q?e;{gdokxTmjxhF7!#PHG zSMTHfPvu5un{6k?rQo^H49#%$=Ln-NW6A9?qCM5zWlfi3Z<6O45#&Y0d5mLdA;me& zSo@=&mJNKiwzWYd#X-Y4>=)eg&D+vTqUT+)FvDZSG)1qyJjRfwXu~;B8T$SMonL(X zjWf0;+8E}sHkT)k41D6%`P*jOmL#@Uiao{_)V)q9PW2dZtzhG9kMSEdokNQ)%euAw z@%t8`W?NX{@Mz{S5}IKg&UweFkMzmO+w$f}dmQkrb0Tu%50mE%Tp78`EJ=#%h{pnt zF@trTvz6g(zKJ}xcvVZgZYnmRrq+DDcY4y%FPrq?n#r9T{YEu4-b7uGb6&Ij(U<Fg z9Izn$ibmh2%Mnf~L(xP%O!>JwjYf@p_foGb3eMTmfluD~L*$r#@0%sqWjZL;La`_k z%LPKVZd<scjmLNgZF-zjr_WD5oqM#~@0oU+xI3L7@88^L)&e!`;P*J^Qo|Nbj=cQQ zAui9hAqScpW1#7A4ye}tBJH#;EA4fG`}pV0jkVOc##Cd8J=@&a7mbzT&y_CB1s6Ft znlmPwdz_=MO2?ljuJ1m7sy!CmSkN@>wL>}O+97mp4-_{w>O{fvzxvQ_({t@M|I+*Q zHLI_!|AD5p`Gh+QfwL;7SO=69{}Io=Py0Xf%A;3&;T&mRUw6fG6Baz5b!Cp7n*-xD zNAcIT|B~;y`fi7ZA;n&n>?JSEg;mB`LK9kJ2}Mih)>&;P%^sbl$c`@KO<Ng-W+Tps z?8ZFKS>tWBKQ5en|FiGG7A|}Lz883$)5s;4H(&bTiw9bpRwr?Rban;Hx-b{Q&gsTk z;j1~u9JcL<>raoVX&Gd0`*x$oo*OI&m^Ps^XLodLcYI^%hjqk_a&<>@&%3r+)-4^@ z92>iHV%pQKeB!r9RX%H*9}}GWEBwzb%^8EWE+k!L{yf)S!ELWNA^1OPRu7BoC_CHf zzt2y~wfxc^PBmXU`djykT>DDqrw#1sMqoHIf|<9sD|^c^mzHXsIHitR_WWHl>XVeW zZZu}xh!w)wl&`U_VGA1*VyunD%6IL@-iqMmc)<2J=Xf7^W5tv;quwom9p1QP?xYXL z7|AiBr{`#l`LfkNvUJNIm+EaU2<1l#^A`9b##oIu>}UCS<7ABRsvpK0&DgVZM*V}{ z-8Ou;=tQ#VAoJ6e)w6mk)))gt)qaLo?IEW)r_ndeJColgFPfhy@r=ji+&Lc~bH<qd zNv$O>R&Ub$G=Y)OD5FIj?tm@vMtU6D-y3h-7AKNC<!GTUA804fh-kI;_-cI8V2~m= zJJEO)8dvL?mLkBN6Z0EC|M8piyU!(>W5Pm!m%2$top_k*oRN=+s<9?_ZSqNLY#s3U z1BYZmL%oz_42s9|2gbD!JjFS*A1|bF*Bg01p$2ZaxWpvIJ~!`gymfZ-!~N$DRz*AW zGdk9dWaCrz<{YTsedG9<b+)#+`-+A?*$7U6#<kn9KY6KY2je(2Q=HTLqd)%f==|SD zEV|N`bB=%2S^vuqmps3NHdzC4+Hj=Zmd82ZziCJP-TU8;y5~w;j^?ElBQEjJm<jhd zKiJ`%5LbmSBhmao`ag&81+THqY74U-+JZxKekmX@WBQ0C2fun6L+)rza%ie?IT2xC z{U!i@MdHV8=axR-@CRrl<HH=La(AlHGYPJ9ennujd;ZKhCkDiu8fF+AO*Q<~aDI1S z?cqH|hwF}AXlq~-vU&+ue@!*sN)q>|crWm9dzhP=X7q*hI6pivwo!cgFS{?KsKQ(* z;Z{e}k+#E(ciJPC7o{7EQ_#$+bfadnND7V2u)b6N#T~UXENksKRfJ_2J(I;v>gEh% zE;Q8VGIqU?EJg{nNv6@eBYJjz1fcMhM`mOmJDQ8|=T3$jJvP(06ODVEUn4k}`SF`C z&VBG1`v$=}=5*gV(^z{GhJi8u=7sE?X&gh%6z2yCB8L1}IqQyweeIgKah#tl7<EVd zpuO(}w4%M{eWMg-8Zl_Y<NOxFgVSPMCtv;<Z*uq`$@!R<X$*lz%K8xN#;rYZMA?zg zFW;yNtUesLvKemREj`J1Hh<rk#c@|!U!G}fVO{5!7<zv^@zU6$7u(tXMqTH(8b0fs z{pn}9mo~B04!qYn6R@tQ<2f}o(-@wL_g0Q4|5HCT7M6*|TOGyf|Dd+z-ETe4k4_xi z>f1B?mh=`JS#n$whW3|vxR&3s=MU{_y;~c4`-bvuUoXOESbSEaQxz<Sb<*MYYk&R@ z?Pg>_BgOf-h;KHZ>_7JDm7(-qM?U(X4QordvUDMq@VX!wKOtc(WL@WHBBp*n;?Ugs z-$j|T8kdMk`}YlJMk*Yin4loyKSf>V)liT>#d<ZlFU1JY5Lq?RF)m|ZhDc~q*~7X4 zW~Fv`Q%tUV`JAnLu*_JWA@Yn9#lmA``Gj}Z=}hruJ!4~E(b)K@kJz&7v%aEZ>VE+h CXLL9K diff --git a/index.ts b/index.ts index e771046..bf691f3 100644 --- a/index.ts +++ b/index.ts @@ -6,6 +6,7 @@ import "dotenv/config"; import bcrypt from "bcrypt"; import type { StaticSelectAction } from "@slack/bolt"; import { inspect } from "node:util"; +import { scheduleJob } from "node-schedule"; const sql = postgres({ host: '/var/run/postgresql', @@ -162,22 +163,30 @@ async function getTemporaryToken(): Promise<string> { return data.access_token; } -async function getAccessToken(slack_id: string): Promise<string|null> { +async function getAccessToken(slack_id: string): Promise<string | null> { const user = await sql`SELECT * FROM links WHERE slack_id = ${slack_id}`; if (!user.length) return null - const data = await fetch("https://osu.ppy.sh/oauth/token", { - method: "POST", - headers: { - "Content-Type": "application/x-www-form-urlencoded" - }, - body: `client_id=33126&client_secret=${encodeURIComponent(process.env.CLIENT_SECRET!)}&grant_type=refresh_token&refresh_token=${user[0].refresh_token}&scope=public` - }).then(res => res.json()); - await sql`UPDATE links SET refresh_token = ${data.refresh_token} WHERE slack_id = ${slack_id}`; + try { + const data = await fetch("https://osu.ppy.sh/oauth/token", { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded" + }, + body: `client_id=33126&client_secret=${encodeURIComponent(process.env.CLIENT_SECRET!)}&grant_type=refresh_token&refresh_token=${user[0].refresh_token}&scope=public` + }).then(res => res.json()); - return data.access_token; + console.log(data) + + await sql`UPDATE links SET refresh_token = ${data.refresh_token} WHERE slack_id = ${slack_id}`; + + return data.access_token; + } catch (err) { + console.error(err) + return null + } } async function sendGET<T>(path: string, token?: string): Promise<T> { @@ -480,17 +489,22 @@ app.command('/osu-profile', async (ctx) => { app.command('/osu-leaderboard', async (ctx) => { await ctx.ack(); - const cached = splitArray<any>(cache, 10)[0].sort((a, b) => { + const cached = splitArray<any>(cache.sort((a, b) => { return b.score.osu - a.score.osu - }); + }), 10); const users = []; for (let i in cached) { - const cachedU = cached[i]; - const slackProfile = (await ctx.client.users.info({ user: cachedU.slackId })).user!; + try { + const cachedU = cached[i]; + const slackProfile = (await ctx.client.users.info({ user: cachedU.slackId })).user!; - users.push(`${parseInt(i) + 1}. <https://hackclub.slack.com/team/${slackProfile.id}|${slackProfile.profile!.display_name_normalized}> / <https://osu.ppy.sh/users/${cachedU.id}|${cachedU.username}> - ${cachedU.score.osu.toLocaleString()}`) + users.push(`${users.length + 1}. <https://hackclub.slack.com/team/${slackProfile.id}|${slackProfile.profile!.display_name_normalized}> / <https://osu.ppy.sh/users/${cachedU.id}|${cachedU.username}> - ${cachedU.score.osu.toLocaleString()}`) + } catch (e) { + console.error(e) + continue; + } } ctx.respond({ @@ -590,17 +604,22 @@ app.action(/change-leaderboard\|.+/, async (ctx) => { const selected = action.selected_option.value; - const cached = splitArray<any>(cache, 10)[0].sort((a, b) => { + const cached = splitArray<any>(cache.sort((a, b) => { return b.score[selected] - a.score[selected] - }); + }), 10)[0]; const users = []; for (let i in cached) { - const cachedU = cached[i]; - const slackProfile = (await ctx.client.users.info({ user: cachedU.slackId })).user!; + try { + const cachedU = cached[i]; + const slackProfile = (await ctx.client.users.info({ user: cachedU.slackId })).user!; - users.push(`${parseInt(i) + 1}. <https://hackclub.slack.com/team/${slackProfile.id}|${slackProfile.profile!.display_name_normalized}> / <https://osu.ppy.sh/users/${cachedU.id}|${cachedU.username}> - ${cachedU.score[selected].toLocaleString()}`) + users.push(`${users.length + 1}. <https://hackclub.slack.com/team/${slackProfile.id}|${slackProfile.profile!.display_name_normalized}> / <https://osu.ppy.sh/users/${cachedU.id}|${cachedU.username}> - ${cachedU.score[selected].toLocaleString()}`) + } catch (e) { + console.error(e) + continue; + } } ctx.respond({ @@ -1090,12 +1109,99 @@ receiver.router.get('*', (req, res) => { res.redirect(`https://osu.ppy.sh${req.path}`) }) - ; (async () => { - await app.start(41691); +enum Mods { + EZ = "Easy", + NF = "No Fail", + HT = "Half Time", + HR = "Hard Rock", + SD = "Sudden Death", + PF = "Perfect", + DT = "Double Time", + NC = "Nightcore", + HD = "Hidden", + FI = "Fade In", + FL = "Flashlight", + RL = "Relax", + AP = "Autopilot", + SO = "Spun Out", + "1K" = "One Key", + "2K" = "Two Keys", + "3K" = "Three Keys", + "4K" = "Four Keys", + "5K" = "Five Keys", + "6K" = "Six Keys", + "7K" = "Seven Keys", + "8K" = "Eight Keys", + "9K" = "Nine Keys", + "10K" = "Ten Keys" +} - console.log('⚡️ Bolt app is running!'); +async function debugDailyChallenge() { + // Daily Challenge!! - cacheStuff(); + const tohken = await getAccessToken("U06TBP41C3E"); - setInterval(cacheStuff, 60 * 1000) // Cache every minute. Ratelimit is 1200 req/m anyways. - })(); + const rooms: any[] = await fetch(`https://osu.ppy.sh/api/v2/rooms`, { + headers: { + 'Authorization': `Bearer ${tohken}`, + 'X-Api-Version': '20240529' + } + }).then(res => res.json()); + + const dailyChallenge = rooms.find(room => room.host.id == 3 && room.active && room.category == "daily_challenge"); + + const currentSong = dailyChallenge.current_playlist_item + + const ruleset = [":osu-standard: osu!standard", ":osu-taiko: osu!taiko", ":osu-catch: osu!catch", ":osu-mania: osu!mania"][currentSong.ruleset_id] + + return app.client.chat.postMessage({ + channel: "C165V7XT9", + text: "A new daily challenge has started!", + "blocks": [ + { + "type": "header", + text: { + text: ruleset.split(' ').shift() + " A new daily challenge has started!", + emoji: true, + type: "plain_text" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": `<https://osu.ppy.sh/beatmapsets/${currentSong.beatmap.beatmapset_id + }#osu/${currentSong.beatmap.id + }|${currentSong.beatmap.beatmapset.title + } - ${currentSong.beatmap.beatmapset.artist + } (${currentSong.beatmap.difficulty_rating + })> + +*Ruleset:* ${ruleset} +*Required mods:* ${currentSong.required_mods.length === 0 ? "None" : currentSong.required_mods.map((mod: any) => + // @ts-ignore I HATE THIS + Mods[mod.acronym] || mod.acronym + ).join(', ')}` + }, + "accessory": { + "type": "image", + "image_url": dailyChallenge.host.avatar_url, + "alt_text": `${dailyChallenge.host.username}'s osu profile picture` + } + } + ], + unfurl_links: true + }) +} + +; (async () => { + await app.start(41691); + + console.log('⚡️ Bolt app is running!'); + + cacheStuff(); + + setInterval(cacheStuff, 60 * 1000) // Cache every minute. Ratelimit is 1200 req/m anyways. + + scheduleJob('30 5 0 * * *', debugDailyChallenge) +})(); diff --git a/package.json b/package.json index 768b291..ceec3e2 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,10 @@ "dependencies": { "@slack/bolt": "^3.19.0", "@types/bcrypt": "^5.0.2", + "@types/node-schedule": "^2.1.7", "bcrypt": "^5.1.1", "dotenv": "^16.4.5", + "node-schedule": "^2.1.1", "postgres": "^3.4.4" } } \ No newline at end of file