From a620a9f4c5eab8e0b1594cd5a18368f73e8adc53 Mon Sep 17 00:00:00 2001 From: Michael Freno Date: Sun, 4 Jan 2026 14:53:30 -0500 Subject: [PATCH] perf improvements --- bun.lockb | Bin 475162 -> 472039 bytes package.json | 4 +- perf-results-2026-01-04.json | 1645 --------------------------- src/components/Bars.tsx | 82 +- src/components/blog/Card.tsx | 16 +- src/components/blog/PostSorting.tsx | 12 +- src/db/create.ts | 4 + src/db/types.ts | 15 + src/routes/blog/index.tsx | 263 ++++- src/routes/index.tsx | 12 + 10 files changed, 303 insertions(+), 1750 deletions(-) delete mode 100644 perf-results-2026-01-04.json diff --git a/bun.lockb b/bun.lockb index d61967cede6cc9a1478e2f873c02522e0c24b30b..9628a29680e787bb193b66f8ddf24c826ce8215c 100755 GIT binary patch delta 72032 zcmeFad7RDV|NnnpXXY?3JB69CPLh3J&M?fe@7rLQ83xA~W-v2m!z5-@ib|zdTui8` zl+uQTQlS*7P;b3as!57Ur4m}d_vh=n&eZ$!`+mN+&u{tbckA4`Jg(>c+V|^qmZ`L) z(U)H~ytjR;k4L_GW^dT?yaUm1b&mhz%l#MLDE-U{OsUq*zh?2;)G?_OyHxhbt7z54 zCf>SpS1s&g5A%6ERXm=OgRAz{xAO?Dj*+pdyngXQa5P2`t&a{z>!IC@HZf`&{n6Ip zAER}NcgW}t^jhpPqbrRT8BI5uV6?Z^?j@}ZsE1xd24P0OkI?pMqleKtgzpx0Hdqac z^K$0SEu81^yi2)F3E7G^LRX^=(M6~36w@~n{{$-SJb+$<7UdMCWl+Bb^p(Ur-BpLbgE9oIOJ3}z z$KquTO6JU^StNK0E(H{3F9_ymc|0AQzP=7t2PfCpA~TK5by#NByqvs(Lp^k*B75pW z_F_w6xrM>({G#kMFY#p_6lSMq&nNFu*b<&!Fr%H20oYRcP-llaHQ%u+H7RyT5lLuK zFmF~q{=xBjdc>kKd)lHhL`{t@3Fx8BM`g$|QOP~MkJ0?J;N0Mh^t8E|g_-16x38{E z5-Rb_P#OB~QPLHc6m^QF=RKaBdFie`*iU!a8dRE*ncr?f{#=hImS#vrnxOP;Ne+W1 zeV>(?l`iSCg0nKyg82mx4$$#D1Ko93au!>b(S4{CJU27HAcLX`b7df$#+9oSzcNVI zeJd(aJ`2}vUuSq`e)q1^GYdR(hUj4rRmn3{+o7taFHBDhl4*lsn%6)jKQAg(pBF61 zXg4Rl=x5T2{WVIT)G7H?drE#7t_vRQ?5^Cz{s2lBmAvDWSFT^YjLOI`|4QYAPR|Rb zr88m|M`_zXT2Gr5s7*MPoHaLRy2m?4hc6_a@cHB;1KVw^?w3eZ_Q78g^mgp z6513kMPodkekC`V2&pDQe^fTimZ)@aO;k3@A1P4wvy-TVA4Y4Sd!5}8O)~2-d{T`W zh4bdpUwKl;=|vvTi6ouNVO08TKPvHd8_gnWdS^;V(eubgYY~1Ny#~FStnGG_bl>iB z`q~}rx~V#sB&W!p8WTNDcf~YR(q5XXyCRxFlN!!-uG%e%6Q}DmRiF~9UYcGJyGSLY zmX?>+t_wAJXQ+<%A-TAzb7r_Ra?uQ3N+|bPHQ#WTmDg`Ytyyk43&WlRd zhL&V#Ntevg@%54}{=cs2(AuqK`p=uC3*-Pv4`wa&+=VSInBJ8p@wy3HDmo=wS2Ub- z5+17Pd3sFjpln~nzf5mRgSyURZ((|uG87vy#AF7bSX*T$|xDv7sujLyC~*~?T3oj!l&=yv~zN_Ebo5`TJT_KeKz zS;hGaC`{V%8TFHGzaX7si9*X3=mJAKt7oAuU@cq*;%2lSnxDn`;}wN1GhhYtT-y0I z`APUzR94PiH|lh^7%fC=co>L{M35SjoS`W#so54W0Gx6HoSn8Nr3^WHZeu*7kyo%rx#!QOR5&doIG0)H2{ZQ965aI&sE|zE*_j2I%?bB}cD?5bkTKnG zt8U3^>?YWG&iU$1im$&-4@g~9+EdA>TBcKlj?SBI*ZsH|E(1H8tAb3xE7(%(NmO!u zVTJC;UDz?$&)lK+#`S0&?0Zq^hOoQbflMj+`A%J}&rs>74^WA)6^%qgm#m`TTseO{ z1IaiVzL;i6cwu4Y3~BDKVLBbxmCPCKX6LVP&ev#CJO(Ngv+8}i+CQ(-&A1VjPVqWA z{6%A*Mx%sx(Y5)8a4F?5T&h37XwTJpbRNN$X>}(m@n)maJq=K%UrNcFYjpEIx>skI zmX|)afa*>lf;9Ihr87=it1C1DmFAy^S49ic+Gk~^<>mBUr|qm6T<%EkcgkzlFK$mR zvK%U*GRwcG6tUkzrMf#%;o~fwYgSG{W)53RLH^uKSznvi>)OrRpu=aP(p?-GSwZ@B z??#=^++g;s%)%_sEf4COK{iUh#U<+>(!<-XOs~f#s7!~+M34#$K_$ay$Vg`IfroW7 zpEvpdD*b&YS_>^er9VUQ$C~t^QQm3t$uB5kHWYh2c{zo%GG^y{zTcz^E=Oe^A44U> z1E}<8Rxoc)Ium71MqW-<5DgZjFQf-T8_y<_ar@1BTxJA|$kpR1h08e1U_!`i+Y`EB zYtR~$Pe8l0oVhu9j|$Lsf!wR$?x7UFMYntf;j)n|Mx{c8OT0WZJ(!>FnFN=Da!vS5 zV~;U9=V{%OThZFY8w9T>UE2$fXcyE*TR-9C)rqft$8#E2+p5c3>+GxJ_paLL{8FcJ z@y)bKdMVAc+J0WAy&aWG%!SK5`ma32#D8d~88%er*Lv3`VN@=!tg$*EU@&2 z1@4nxXR?tVzX6r$_1YVHB&)rt?YAgjX2)K$Ax=-rE0ViG=!*Fyyq=7VG8Oe5(mlQm zTMBv^TQV-fb{CY<6cc~P+j<9h1eN$JQ8FwkM5SX=On5J}F}7{Oo1l%bn|UQYBU2rZ zB&>2&*ZAULoxxEw2EG%OE#m=HPV5p?t^zZRJq(otqP?*rQOWPuw{$^gQLzu9lD;bq z5RDX_i|2Q@Cfr?&zG-wmDnt7ODlJ%vO2TARS`d#)MSiw)yyK`;_<5rbpi=Q$QORej zv$bB6;+RuzUCHb9%8lK#)nb;Zu04YA)sqh!FJ#v>8#LnXmNR0c4JNOE0;SuXKyseeLmF53hqty4O${*jvBR6{vSX_s|z;XZRkpH9GS*A|$ecM-mTKru6iz|12V_tYX=xtMuG~yK>G|{WGC5qD z{-|ee=((D}JZ{CFQ$OgQJAzgv-5AmrO9oMwbb@$*teySXRnT_W(&h6r3({v6dOWxN ztj~~zs8m3nrZa*Co|)K^Zq^mu#qOIx-KbD@0k^^Q{O{q_2@hS)#+&#Hexd)Ri-W)D zt{ZN2#XWjXG^GNPupTNE3jC%knxBz5CzBp&{JS2i3vg-3UD!1x-XB`;H=36|%ROy7 zVN1o25?|E!JN++f;$wg$+;0MQpi*#|$8vk%#s!%L@_tc)Ww|YF?6ur9V=2|yY&Xdw&pUz+U^Fw31>!OE6< z(v2|M6_tYXB6NXY5KnsY6e_Fe22+7Lrb55b5UF5VT25g$bEP?xSsGj%iAM@1AGb!g zR<+!9osCL@e${lw6S1X$!Kl={V|87@rl{CG;L@exHFQP4hf7a9fh}{0k#)nT*VGN= z0+^pWm+^nJmgTO;6{swuTvS??f=Yn{P^n0JqfuyGY#%BG{78l}`Mxk2hn^XevE{@W zh)TRw*Xn$4LM46wx)RR%|IVkEL+A-fPDpw6Afa^SY5X!~)9UM*4@V_~`gENP)t9KW z@C8&Ven*t9_`BFLw;nO^?lAVnXx-514TvY}zq`rsBmt7aJR-^l^e0^G2B`GRtBrKV zPovV}jK(_NJ=n5u<^G#??{D(1XgHX@0$qcQY!JiG3!UTe{~kJth^b(n|Nxm6p1~k7LV@`5Cqh z>1!>mV)tWkisQ+=@!q&qbx+;b;un8ZxbHiBN4T7VyHRP#eP|2x^WttAECfhP5==m6R1#D}WV#rN(JtP%OstTO1>|~>HHoD{XXVHnbRN$yq?bArqD+?t?%TT(P*{*TS2Qy_BRwy(AiruqXMd9$if zP7>*;U$Oi2SVZB2H7IF|N(Y4sP9#h!P!ld4HhW(BEZ&3g+&f-pWEs9HQCEC1Djgll zFCAMJbXI0T0axw-Y&dVB(vA+ORI4c})vPpGhi9i3WCio*c*bJOcpXD!ywdY!Ao4wdRGmI_ zp{YfBnq6EnE4`pyVP2*u^b}GsMJN1nlAh($=v~QZUS7^DK0(T#Z7N!0nl88~Sa_oh zbm;BO+u?3}^Ql$n{rjIr=!Sl2^h30ooEa%IEl(Q?NSLli_G?r&mMyb%2d_b8229S- zt7Jam(&3FV^}sDBTzZ6yOcoE}o(?9zN@y$iC+T{BxRR!qdm8CwKwMkSjNL?#eW7fw z&d4$LxGcTCvy461XpGTcXXtdtjXrBMW}ePxg|TO#&B;Gt^nqNxQ8vIXmi=LRp6<%y zriR;$X6EZLzQ@>EsBGoKjkZQ*9|;ud0=uKq^)I6`2jS)e(vyNM zJvL%KXNGtJ0GYES$jmN?_1Grkcj+owTrZ%q5j}{?j(7(uL(&zM$=L^$v*IXYDg|%6 zQBSr5#%{Mr^BFk>?U+aNnqkXizO;zrQ)>K`i7@{rU99&TqKnfuh<69(&PFt#$I}ufxs^$nPGt z<;TkpcRc>x!Eg6e`lIlxn(^Bs`XBXqD~CI$hQwQaoT#AzE7eKn-?h%Vp#g8RO3taF z@zyveYFNO!(@EyvgU-5P0k5~Rb81+;)!B&}9EU{D|}&W3!06n@U6x-*p2s5g|8XQU$fa2 zzODEMy77Ll@WnB*nw3=e4upK(s5;K6vGKldS&>2K^w>DxXeP!a*Y_m8WY-tQPMqkZ zCiV))qXW0&(}C5PQRCcbQ}Ly`zC9JbDCS+7%WlG_i#T23i|1ydQ#^ogmK)E@F_7;1 zX5pLaq$c$WcRfymSlknT=YO2As;B&P&?uQ&C0`Z$fI#o6Jk(LOS5R9SN? zHUg_Fme+}SB-Tlu6tJFj*75HL&dEsuyA$iXy`Ex2{nk_`d2+yVoOS$r+BrEnVAtfr z5=VFyCpgJ(4RexH1J-(HU24Gol#l^B;YqWEcpjEB)YNS@f{MP$U@{EApvW>?R zPjpL|JrhehfzqeZ3M^@$<-`#Ggp-^eu-mjXLnABNo`WT+y-wLszwZgGSZBlVIIG-A zo*A%vvPEWLYMc|XnNt)`n+cAV4D+*4<>h2aCOz|_CQ5ga2 zfRmgNurCurDY}B*W*wYU8SW;O8SvfGfrdM$XU0*}b(sNsF!{}NGodZk(@xavfOXzU zo*nSD?<6BhOkWPZelh~qRwrssz+1VqlQJjXUeU$l=|xhHG~B*`HP+3je6rsPI8k#0 z)-6u*+<^T9)3TzwthUZcLb9ExtbqMiHyu*hDI3lxbazU#;;nwpNrDP!*+81kx z+q8$q3n~`aE$KGhNL+AUh(PLk--~S?jWg{1nK0QfZZP3 zOl4Z0;Uv!s*iXVFksjGkv1FDpvUB`)9p;!=%=Rq5JpgNfYXzAD%dsSTpHrUUw?Dv= z{oGx`b_|6`Ikpp=>Gw?%%k9h6&bqvS{Vw(xH>LD{V<##<;G4io?CG4&pb_|}IXRUP z`lfR-KVXN^=d$d*?%e8+B~!vZJM6_+G9+P6`AomH+c{Yfu)hbGwL%^poaDlQo!8sr zNg`e)M+WPHa}t)s6qO~xR2%O1J&ZNTIXyYfK8LR_ysmJ&RX~>>?!?UX`&MI3a98Bl z_+*YpxND*n6_k2Zk~Z5p#`3w=7A)y2dWSvW43^X`!VPOoLDE;1-CWYJBu~nkgpE+pfI{t0Eo!le{Qkw`RDd95ymyq+m%aJWh}v+~P#t6!2Zggq`U$x+%_D?ySSU zgx$-vxfv`D*az8*WE1wNU<2mu;EMS)$!~YVGHn{>_vK=-;-&6|6q0Q39J0K54Tqz5DRcJe0c3$I@dZz4N@W7{~J1h!LS(Sh5?BMboIk8hm;p z$b>tG)mgS1J9?z9nI5zeSkf`>1o17$()HhuPa0pz?TRZ{e^sp`P0_>0;MhyCB!_T! zg1n3+=cK#6+rOGHcL%Zuj@FA>Pt^OcDkh`vZ7g<{VR3df)~n>_E);tRmc-&{nB@1} zj1}*s-rg%>EGxr}Bvp6}E2YBnjPrOVS6Gv=rc_ujVoj^CqQ~>KxeDthtiRHo!1^m) z_e75eK&7O-JFxyL{ZlL|V8S{RkW^vaf%R9qkFl88tO8l<-6!fX)u&zomP{B{&r-kj zm~--ufOX1=x-($cA-jr>vPWRaP;e};u5QJWox7$xOh01LLuLl`PuBB{nC!31up}2f zpsyN>1DeC-dOEKwVbo-(-%i4kxyJnD;N#x0GGL#B$$3HTvi!atlRTb)yL&CfC+pgh z-NyGO)*z?R+&HehC+`l}edx~aI+R&EA4^K9EW4upB$l+7$w1ggSZwQZLBeXBs_RM^ zbALKkFEp_63-F1?bdPc}yZXcGew~XCoEDkc+D)RjH zpjjRdS0Bc_oR}|SjdydG{;ZLqdyu}kH`ZBK8nB;*$T+d*QOcKCGMjCgOTLbo?rBP^ zZpBwoNBba_#A0{n2HnJoS|6~3vo+%cqnt`}LYB;?K3GzBcjnu7V@Y0mZoP*kt+d@6 zQ?0qWr*v&b7>nNKGPE2^Vq!6e-Y{Wo{df4iRkNJZjq%n%=j6tKZ*3OE$#Stz;FF2V zGAi`j^|E#2Efq7IgA7ZuV;WP%Jy@oDIo5u|k_K`(XT?V3go5a6Yrb>xp@6l`i7E^5 zn44S{uwS01vt?tYznkXjB5474svwq(lb-1cOZwWqVfl_=F?%>t!t(S{!x>HAjmPRp zERGH;b}N>iy%M$yOJ)-Lg~O^cmd<@de#IjgG1p>AF5LS#nGa%de_k4AH!P^=VQwKw zSf&#g{WVyFNJD5>(o8G zts_p<;{j`=lgz){opp}~?5YcOTJFU>Sq#RCckh<0mdycsFE*zrAM=##AZM77O{d*a!@%F+Ik!+-*+svjO`}6M^-(CN^TJt})A+8mC~%TxW~raCru6 zjB}b!`~#nCBWxT@-QG9rso_p8YmpPRHQ;*zrtdM|pK}ox7>M7@~(g{>MrJldwjEb>_$KdE((9#F~-|;@hw>&K@Q{w-o8X66fTefYrc>dRgAbNao+2&bpTab~Q&2rnxp^$xLG~ANTw2 z!%A^?u<-l;c0=-w#~LNvdf172HQ@UedxX0o4_vJ~liXJNeYapukn`4iauxBbgLaY=nb-ZZ_tF%@(xQ2U>Wn%RwmEIbk z!s>zL&I|hrmdx`SvfOm`j&A@J;=th$_!>*9$MHAKEUebq^dZ(&Lg@HtE!l2+8wgo4fkHG(d6K!u|L6*^{=glkMbUF$nws5)Jb_a z-hKqAHw<|e{vJ!_c2##bj@hJF22TjQ=o}^+U-cO%EeV^6C1GwZz8A%EH<%v`*ZEC& z?(dhP`?1=RhE>N_w->9Iv*E2cU*uNlm(*3gBJfCM+yl?P56cwKJ6mswB}MqW+o*`^ zi>>fwhkW*<_`13c;+XfAZ*x*UiuX3$?v#EMZ;#)uo50{~@q6#s?nIxCw_gLw2JBVA zUM#xjol@Y)=XFi=Y`*V#CuL^5eH19W25o*fHeyF;pv&0&reMjSxz7gndaN#3w1bEC z-8(&eQn2BLUg5jsa}jyQpC~>eaBwhm4`azbhsB+?980cM^xzi1-FmlP9$1U~b{^JX zH;l`)y&G$www7|qtgx8&cK;W3n4TQVvHI(njQQceEYdZ6DO5U_ckiT^oYK$Y?e)OE zZUSlD>Ax(h+jvhXflQ#(zbvY>9!oY6_e8W$nlSEgG$r!oiZF6X#48%P&YF7ExP?+R0pu&<|mSX7=WC`#253BxO z9i|VVu~^c{jO_l{aEv7Pt<%c;^a$#=GR9(cBoe*N2;Ph(tDc>-luZU}G?sqM8?;|P zcCe8gj|~^YeYV_#Z?aoTj1wF2nohwqWz1(`btOpO*&Z+!n_uluWbLv98eFP|3>vvyWaf=om1b&+no;S!Q`0O=l7Nza#FsF_Z~XrlpAm*zKPC;AA5zr z7ecA{65YUU6|Cy}p*ket<3mW2Zm(dTe}&Q}SNOJ7_^KXvi@4k?-1SJ(-4(uCAIL|& z!lvR&bsAml6^=(&uI|4>WzEB<+xsRy68zAMk9MN3#(Rrg@qKh6)V2;MLpd(NH%Ice z&*O__ESYSa(``@bQDQcpU3aV^1Cr*OZ+!h4{Z(edux5@l>Qp;yZb}t)#^r8 zukh3S+{xMSD?@~Dy6bEDamaTwJ|0O3{R|&heSCdB3HdhSo9wb*#OG%Bsr!^bwCC_8 zNuWKsT<^keRlS?aol}3r`@RJ71iX(AWIuCHqkVC9D!w6lwsJ|`ghd9w_X@|u!vJ}X zJ0powfA3|TSzT(y+h1YJY0vh;dT9E&ingqH--@#gf@)-0alS9`CTnlt3+{f}yAf}i z_F7-^{Uq(3jW?*hhw)C*-W$$U#9e{ckYaAjYq z(r_x4@U;}SA>4|yPvV{GMqsz`#(twxd_-9Pja-a*9`nUsFdtC(BERLU!tSHcMtt+# z(3`&tJ&S#W??#tR_}=5mmU!ORzgH=h$?dv}{GvvPeLud=l*Y5)hS&&bHCTpe^@WVK2c-AdK7PWWV>TA5^qWr%(7%cRHCp8XJKj4J8T}#5aF*O7r5q zRey4#7sq@1{-jc>kl>D=^p3{<#xwRotcpzS>n`a9&qLrw-qyvE?TYc_jheTydSP)~ zus=uq911JD-|zbgtE;?a=u5rK2_bhM`$2rt6yC((?XfeL)v0RqLi80`^&4J_^WJ_% zrBtUrzeBnbk0!H_I$hPvs*?K-SvVF?#KYpeTdt~<8diLm?-!4HpoY~u>~1_C;_-d_ zi~Fee0&jf&O5Qpr9u14I_#iGhF6`A`iCWX@ZHN6<(S)V`upz&B)TCNubu*p^@c3eX z=NhCo)M7?FfOiaeakg>bevLH<%bnTws6Vu&AC(_5mJU0QC1b0@8vI!?fZX+`V)b&f z_dS4@=V(guUBDZ!y=^>JD8ekfJ#|&K;gy5TeMi*3&9dC?VsBwLc@ay7h#flB@AG>t z{WR=bg)hl{q&$yry!-J`?=Z`45_dQDsFhgKS=F8LBe4bVljr?=FZ@o z?q)A%=s=%k-e(eP8&(ow9CTmAMpPn+YXs@85m=+J^y6wNmP{P?;_UkXYl_?qeDfr{1;L8%8YSMaqb}~Mh z!So8NVS};Q@VQNvS5qksN!PPFjg!yKz4NQ9Q$lt?;#6uwhBm5(dwl&u~4{w6@?!!A;du!EU zIJGzRFYl9hhiiHX?@;ZHzsB+mbiMX1c;z(W@{t-FfgwG_qrv)E>l#%WL)E(Sm2x=+ zc*5oV-Y2kRSR4ZQ8uI0GfIY9 zd}a7XxxVl4F`*c_zR{MuUfC2miEfWp(Kk>+wFZ{^;U0ND#QuQgrnBF~C(YmkmLq;& z?S?YxPPb>$;T!MrvXA`s4&k~+5BY5$-#?$AEf&)USTf<=obBuR?)m_+RIojds92JV z4*LL0uEVsFH=aB5ZFZLFkvRJid}BkgyqB7&(pGfWz^3XHYCqXjccy!0`#!^(=C-(B zjLe19Zd@Gj^;V~wF;|Y_O?SO^+I687D=piCm8j$NZRQqC_pQU1py5||N9 z>4)OH#jRCodz$wLWLhZPp3)}NnY_d2eX5O0>A=v}ZYvA)^pH63oVMx|#NGqZo0F8$ zxSif*bT_A9{nhEuVEr|8e_+XCb7T7Yw5Q|MhE{ak5xg^`2)hg4p_kF6&9rg_)?~Gz z1v8?f<$mc$7jipR#hBS&Vae)o)7Y_{bak{BoN+H;Np-xcd>Zqkvu>{YK<*ol zmFLcgH}F+7&)c$#yGnewbg{VVxa0gO-qG6Ip{vDZNvQYUuBx;f{dE8|Rfk^R&7CEF zW(mF=7uvt!9Y-bj40(#*H@bVp)OZxHj^n$=Uy(;1-YlK+B3^kw(w);O*7D5K<*aqR zsog0DUz&y;ds?1+?R^oiuCQ&#nMtL}hSCLC(jmIDPGY5K>qKmLFWLCq_TGV)8zJA3 zvdn~?)mt`IH}Dy}nc7=FKGYe$QoQNPtr0#`BfiUKI?H|yuN!*q*v80zMlry&W0KK#cI~i*Y zP&75(-UyU=rjNyS$(+^|D96${ zNSYRdD=LRI3#+4!$%;`}oQkP&_WSr`Z>2`O8{BA!I@OoPj~b$)`%&NGA-eJUL1`zJ zDV}G+d>i_I>&V@@V=N7N=`}wyWhM*a!)zE)DY@ z9jQ_V5WU@~&`A|@J~kYK=ja#X>{sw55}Ed~!(TI6uV+4lX z2?x=ZxAFHB=kmbm6p#hfnLsnxACXPpy*C4A(<3j@`Q*{K^05^jm z@5+^8@h;-yarRMsGV_?iJoi*fRHug0g_{#q^f2_#M3o{sW`Zh3?T029Q~5>#i}M$hAw-7H2Te8AVtX<7IEf z(l-scRD6f!7UkYP+wud9j_!vRlkrJ0?)>%Mo2*WaWMg{|8t2am~w++M_{4EPtggPR+Ihq zVk}vP?x)H2AuL${Y)8~DY^vS|SpZx=Q?VpdYTJxV*J7If9Oe%@I@NL}&Ft-so~BC2 z(FfzFS?=4k)Q(km?=%%X9(oLF)-Tyt4Vo3J$~*J!a8N~eu>ui5*+AU8y1m<23_zCO z`)g2@CX&svnU-fBahO#+W?jPS?KD~(=j}X8rA%Oe_RpfdDs=*ju}X$s7ChT!_SW!?Ovwz*bf&Leh$Rb{FjnCcs6x_g%QIJ3f#=-U zXRA|CZ`(O4IvKrdj!Hr859jD>1?%bsK8u*E&u*@|Px-yi&Q;MVRQ7^UbvlWYGdoL_ zg1oO}sZ*$ZeKv=OTS&}4zr6x$rdX;hk^cYgKh4CPzlZu>5>us0t{vv7l*ts7H7`_< z?|r=7GyaJ4`g2uuDn&k@t5QTgd8$-2J5QZL?I-ed3v^f8`B=JR7vhzG8$|X4iD9>AOixm6}XNP8F!qspL7bQ1>s-8cX@Y8&(%GVhwTp9K;G>S*mOtjjTLB zG|6Nrim>!nF4k*UvT3o*nAMlC%*w**v7lnN;IVfx77tXjA{o(zj{?Esf6~xzmsN^$Pe6A?pLBOX^A$h2Yy-BB`qo?ti z5|(bJH2NTxS%dUl)x|m{H+yFBP%L?{V)t9`_ujl%MbDyY&qDjUUr+rWpDbthZDMbm zCF&I6_JJkbb~N4Y_uWv;{wF)DH>G%IX@+%2jh$^5SYxbWANPw*Vf0m;|Dd@jMfrhf2_V z!xx}Zz>UUUgi1d0=ey+fKhU0T1|=qgr6%G3P9@`8Ot@$zm0D)iXNTf%vl{$&6@Cvq z5`7#MdowE8JZbDLMxQeJw9#i!iT9kbw;J7sN_%&p@?a;U`g9 ziXR(ZZun=YyhNqiXN-*&yW{*Npc(-`nt=Z=R5q}ymYF3~Rw}pr9&fM>GPBMX9`}m$3(+(o*@8(V}Be zsqk16o`OpJDTYr&rNKd?#nbUf7p0@}`nw9xFkDnBFb@?}Xt=0kI3JbxMTUzCztQL- zR2s6(*tcm_O*UCF2p-Sv02{s6L|BDN%~u61KV-uHu2O+AxCA|B z;yrG3Gb%mxq|clOTO<}QQ3-h3M0^I7mcM{X!Mjm;iHf}kmH4k1E-D4TYHU#n-)HnS z6aKo<1JZtJ$zecM^aE60qLT20vHwphJy&kxpD}tCm5O|UN=45b{M|!3jN|2{c zWpfDC14x4Us4SHwudiII3@>~BCNVtf9PNfe7pOM0Ucu|Fym9gNCLRQO0#dTzAguI?OpyYL*San13E5>4XL{lZ;BI{PQ6Bzk9Hhp84lN@^25A|2#-CBmQ}i)F<3O50d{p zNdEI6`Okx-d7%8~L6WBtF643-|K~ySp9jhR|2#;p^zHoYIjhYEl|ITlTqTY2R#z|M zvkohJw0EM47!Al84R}ZG7O+b|qcMOZDsv1VV+`OO0moES0w6L0us8wmzB(k}pn!H` z0moI*Sir)ufYSp0ty+x(v>XRmISz1AofL3FK=1K@57mnCfaT)>7X+MEJrV)2iGU4> zfKSwU0p|paoB$|S>m~r!P5}Ha;EWnN5in#T;OU8gv+AmVD*{rJ0AH#nk^q~N0M(NL z=T&ktASoH}vVgCZodSqR0c52BE~woCb_r-S3GkiDoCL_21b9clMHMv}5IGsJcrxHe zbx6QL0h@x};oeJ@`XT6@pcbY=5~o8hTk7HI-U;3-mik5Xs-?!Jp}$z_Nzq>|<(+~4 zW~mg>-z~LG^bbo_Nk{**)O6JHsNLz_iI$~m&!oh)LGmx0NfpA>J^@3f1DekQ_*CvJ zz!d?<1yois8Gy}cfMpo~TOAXSGy~8r6Hrwx%>+cG1I`Mlt~$*I>=LkgHlU^|7mzU% zFmMi_wpuj@5IGBQNx(I#?_9t^0h{Im>Z*$Z7G?kvvjFu~Sr(vWCcu{sh*AmJfD;0C z2xy?J9KiC~fb<+dBehjP>>NPdd4MJ=I1g}6zySdK%BB}1S~HEq~8eWt+on?oe!wH2oO-gMSybx4hZP0YTpD{y8uvl6QIA^Ct%1z zK=Z|bfhu<~;EI6b0tTy?C4kLEfMrVnL)9?>NjCzz6$6H=rNw}VMS!ycMygIFfL#Js zmjFhqase4P0R}DwB&bzO0g;OVmjsMceQyRF6tL-LK%%-RVBr!#;w^xQs_Yg(%VL1< zRzR{!xD{|hzzzYEl(h`7yabTG43Mg}3W!|_sCye=stVo)I49tMfS{^@6$3CL090y1s~47>}Ft5)3wh+Gc1Bp_e)T?sfSVAD!Kp}Htw;R-~28II{?0W07WX{9>56!I|M9J*1dq`cLLJy1uRxu1;pM3sJjYKtb(fm=L8%OuvFE) z53qJ6pzuDxEoz^DA$J3sJAh>>*8yA+a9qIcD&~H`=6e9k?gy+;#{?wZ3+T2QaHm?j z8W6Dxa8|%d)oBf2mw?r40QabJ0U7rJ1}eZRwMqdZ9l#|4j_SJ>a8SUewSd*?qJV|> z0}|H(lqy>XXt^5TD+R1m38jD&0(J;^Kv@p}mahS%KLFUEwhD+9sqQE z2(U#heFzY-9&lE`)2dS$V3&Z^Wq@Z@xqyrffPoJKwyISR10pv9E(zGK`aS|UC}7hg zfF0_hfQ1hN5+4QZRAr9>T0R8uZ366837Y^X1ndy-lCmBHEH4A3KL&VNZ50svFre<^ zfLB%UaZZ)JYPZNfReLkCUuBBCruK=vuA-hm4yas_H`F1KH&x7&$U#*ka!4IRRMKN) z+ieTk9#%`Y03sd-oE7kn>hu&5-&HF_j;L~xqpHW#$T77_NP;*tAI-a zu2Fqo2OJcz>2*L|by2{=y@136fcmQJ0HEbQfbR`JluCF5a6-Ti0S%P(CSdt~K>C}2 zMrx~o*w+Ac4+5H~;6cDS0S5%csM?1BYhMQx9s)E|`veR*0BHUept;I@3vfliaRDt< z%wfRhHvr2H16rwL0+QYYbbA}nMlF3C5OEN2RzN$|=^el>0ju8ubWr62G7bR-z6|d<$?%Ko`~b2;iWAO-BIT)I|Xc4+9d90{p7%D4^xr0N*h{50!8Xa6-Ti0ddND z53u|lK>B-t-fF9W*mnVS-vKMQprds_Q8LpO!j8G>m~z18j{wWc0h#KUfTYuaZl3|>sHL9)B0dJ36_BMmodN6;u=)%jN0kf6 z_yjQUb3m?I^*JE&Q@|ww`Ks?(z(E0<&H@V6MF9)T0f}D#7O1i>04+ZQ_`U=bse~^9 zCj{&eut-_w0L#w+($4`FtE~cJKW8}Woo6_URq#CE+~>qNaGn@TRqd|;YtI4-zXIH% z_6ZpB1)%xYfMqK8Yrqu&#|7N3V!i=v{t~e48^8*6OhD2(K(`BkJJr$)fQa*evjSGC zPTvA{30VCt;2u>jAmb~*!0!O7)T-|QkzWHY32;>3?*Rt|Z2BIsT3r;d@EbtlMSxOe z7Xd9V0DM0H)~SRa04D_O5b%JqegrK47LfiUV1wE!Aoe>z-Jbvts^Cw6a{>+sC{wjB z0oHyGD7*xCMC}tWMcXn z;^5l#37fm^@SSO~esYIB8}>iL~V6Q=S`oaOnW<{x~H_nLf0Z(iZA z+_nAO-d1x`jz*0b_tEI3ZC*Xr>C=^X!bMg+p$?FL?5X zPe*+?KC{Q4Yp3Uo=-KAXccarDQN4fjMix&P^Y0Cxzm~D3a~}POQ+Utu*Umbz?Zay?8E`{UN+{jGZP z_3_XvJm=x&FCJNcI{I{t(JOAsqaWf==Bf?9dm~pDh7Gq4t=`92C;h?LH@C14t6U2Z z@h9N8fOk}k7qCmfGB4nWItEys5ynIh!#<{#h7lps0-P1_zUmYXI4EFsIN-P{7qHL^ z80Z81Tdnc|T805G2{@_xRsx(5u&EN@Lv>NW@^C<6Wx#1wRv8fM1Nb5UpQwZgz&Qas z1e7bw2CS_FNVfrJ)K&oZKf4NYRs|7tr82<>su298s$CVZIRa2v6>whd6Od#BnpXpS zt#Yf8@*8zXpLge2C1{2rzrt^HGs0%nQpt_2Q1nd&9ED}&t9TSjI56~?NP+KjH0z}pa zoE315>J$w)C}4Fopsp$xurLxZumPaHTGas1G74}>K$Pm+5O6}kriOq9>Y{+<(SXE8 zfJUmU5g@h!z}FbiL?tu^oD;A^K#a1Q0M<4Hq&ERHQ(FZLX#}X-6wq7+n*y!~I3S>f zsvQH^+!#<818Al82}o)JXnq}_jmo_a5YZHHTtGV&(+sdnz_Mn54(gbIj2J+->j9nA z((3_{*8$E7=%P9`2OJczx;dbmDi^S@8DQWI0KZyw1EA&gfJ*{;sJ<-#Cj@M20fC}4F*K%y!au&_N~U?;#twW<@KWe30|0m-UwXTS*o zn>qs~sfz-ZcLXGM0i>$3E`Zoh0AE+YRF%*ba8AGu0YPPT1FY=~Nbd$nQ(FZL=>n+R z9gwbq-2qnw91t)|)%F86cLfys0hwx_fTV7K=COb|DmNAo(H(GHK$eQ>0oWyASr0&t zIwl~)59rntkgJyV1VqLH&I-s^o#Fro1+0z(6smFo3wr#I_S|0&qceMMml!rcU828YEu4-L6i3_F;Xlb21V-F7An4D0Xp zzSBWXi4R+{^V%U{&sn~W{A8=zPKugiN$i;X^sM>(kBvOn@uNe&=I0jYkeXjEl%&CG z{uS3+qn3^en;I%H!q;>F-^i0{kMqelf<9HNMuzqG{XB@ALXGiVJCx>0UUM_s%m4OT zn(gNEUG;ZIxL@ciIf2&NSv$y%Y407Qd*`~H#}cS~lv`a>t?Z(CS)}&-mnNw7iD41G zt!bvzAKm&rGy&FqmdUt_S77z*nFW&GvpGlVo!dLCLG?0z%E`AEOP)sE5tt=0?d%-+ zKN$0k+MO$t!^T-w|DEM2VR7DyD!0Bq{2J{@3+?@1(H1RQ$BCQB^|!xB9UwrGyC*Uv-=n7Gb@! zvwARWw6}Wb|L1;oEj=xx^|(8-)$2T@{|~Bd(Z<3nyWCCe`{Ysn|F5Az3Rg$T&{ykm z=|bt2omXaseN)-=AJgnkTNMT-8eln zn^AUF4XG#ftp1-9$sOS;^YYRQ_&>+y{V`14eP>u_?=8c3?!PnaZmar7{KmUBd0arF zq-s0eJf`Ql|D(nHYbNslNt0$cmfCes*rz`C|NN%Beun^f4NJ z3lm3ff&8-5eaTPDB#z|9Paxe_YZFhtw)&9yIx0UobK}WZRks)>zc!OHS^CAE&En(L z-av^H`hIf4WPBHxky0>8XE877U`YVN9?4U;eJZa1t8Oe!s3^yPP% zyqMtKOhow-Zoq}K(y*G?eGKy(RttNeVX=lWpz^C(_tnENHZS?xOYWQwxoXl{UP$`DB#$VUOn`BrU*l*HpyyVw{ z;%$rj(=hqPpybyM_r3fEO(vPtO2XUYelQV(CSnKJkA_V*@jAllNiMwPCynCmgo`vR z-LTHED8ptN)&fABAvV`G#?D zd#-5YDKKgICAfzj-hItC@nl&)iIY_&zo(RJ`rw}D|HLR8x@Vz*eeu6V{a^!` ztunhqKf>&fe=tmD_aYN-fMHG1n+zL>e~p=h@;zE9co43eVM~e)91P_5{q776u^}+| zLASh0OuV7^Ka^Z}$qzWiD;v*c`dlW|&4vxf{|ij!(=9N(@+T-fKjD%2w9LdSmL2M6 z18*}>cBl^|1+Uu;8;yU5Vap9016yO*3YgTDKltF`|8D2L?lSSlVg(FaY1lYeQ(1p9 z@$NQoJpSe;;ys2X!rrBsGRf{WYy$o@Fqu%R44a7m4%0LD8I}Z-E|PiT7$!SyB@^#{ z`8l%qWvi`acD>am;v|@iaX)m8Vf-Zn&jvGg%CJJkI(_u2kGOim8OT+)7>8*{1&44{<*n@_p!;%bp$gr8P0Wc}w zQ)b{S{9R1MhYibs{bE+cBZg(da!tHPVX|w_#(hntrIk;bcysViCZ1G4eg-TZG8gx! z$?uua&(X7h`9zeApEZfI@fR5OoMAbzLc_Ki#*Nmq(6DW$kX)G84Cjteyh1#@hRE#Y zRi#&9m(KC3_2Tg8oqZOEXIK*+rTUNIUSpuWtt62I1s(BDax!xc#`- zaIfPI;NHN!i93ipgnO%!dSOZUGwnLzmtW@9#nr>r$3^1g=YW@SS8!Kxzu@YrqUGTo znqP;v8SZ-A=hXQuPA)traUbENv0GK$lJMchvMyvD$h?<%E>l>htV~gvk}?Hl%E=6q zSs}AP23-bO22}>}F`O(;S;(@p$WD@mlhZ{`6FEKPu#m$c6DNOq;%VG7VQk^g;&~1y zm#=L&xo|y?+ktxlw-dJu_ag2k+#cM^xK~x9rQx^pR>r2K;g{9h%flxZFQ$i=;3nWE z;zr@*QqdRJ5BDs+whi|@PJWcN4p)kM0Jk2u0rw!T40j)H4NiXCwFGxFE(bRQcN^*D z*JV>s`59YBTwD1)TofMp38DP@Zvd`2PA(=baPniyXj}taLtG{xP4!0Gz4YwWlJZ=YWi;tsEX8CfA6}UTacjE5C$QzGUFe;m+f}!hMbV26qAXE$%zq z_qdC=A8^yC$|tJtt>H})r(KnVz=M@6n66pQykk+|RhnxGOl`zwnf+b}PbL^q!Ad zf|ILN5H}r{itCJv#6{u4a8+<}huDvk&p=+s9oV^QMYv;)lwXs|yaN8Q!MVMZBNm#^J`}5^+n&sUa?$ESPgvj*6m~M#qGX zf;s1$9dnK-n6vWsxxq$+neTi5TkEa2)^p9Cy0^}*Q&p#O=u3SW^FgZ);G0OQvlKa9 z+tQ3hi{W(%TF%p<>Ds=92FWATjSW;{xVCIO*G+D5Jj3PI_X$*P8r)R4$#B!zjPxFb z%jG;4=m7i%1OiooD!^T2dpGa~v2TT&4x|A*t=kOz1tb9rfK9+gV7&&P$V|n<24Eeq z7FYxP39JUrLfK5XGl1#9RA4eN377zk2gU(BymKjXX?{YOx9QbpYTFi$=ftp%6TlgO zr+O!WQ^0HB6>t}L31k60G0Ft40r!Dhzy;tYa09pmTm>!z=Yewo%h{jb`T3&k;yqp@ z{0)yQvL_Qc5J!+RAp7ymo8|1!%9Q7O@-rut6R1SSVeSAq`8?a>cb*D9QlnTN(xPOo zP5cwQGnBA7<7YkW&#n?LyKK1kz&jv2$3K4m2z0P`Hr)_ArBIKiyg52y+75~CVW7VrX`0DNst5Bjbol%I_SO6T)(i zfWub;Tma^A0@?Kdm=n(mSg{f*2jZMn0V)IjKmfo2nNtnmfJ(yHkDv3BaYR8tZJ-Xo ziL3{3`D43N)qu;NUm60PfbKvypexV?=m10lF+gjeGY}1g0Ud!TAOZ*n+5MV=z-V9;FbL=e^atD_XE0}g{N9hv!vRJDaS#rLI|Sf8j0CvDfnl;64|fE>d{#aN z7z<3KMN74g@l)`aqcLVr!~1mL4OFdy`vAjoCEd%7#LM&;hy2r zIR+dBjsS;&L%>1c0I(m}2kZs7qdW!oBya*a4IBq@`Z0&WGUXWqwix+E`0?V^6gZFP zE^y<6K)!&NK5%cty#?F^ZUEPTYrs|DZ{P}W8Mp-SCPXm|2)skV!ynH_EbxvQg325& zM^XfCHn`t_FTfk%9)SN;>o}3H(xDVj2g?k^aOcZ$v=OO$bQ12C5 z8{s7$vuG+F8$H6~5ro1S)Ktr2c7{>=+z2sae-g) zOPQ5g_jt}g3=;ks?kC_Q@Bw%W;6HI+>Kz{N6-6lfXjYL zy3Fui7%jQ9ObcgE( zxB?Y{asVqWFS`|Fm;GGu%=2aCnO%k#{5$~<8QwByCpTopL_zSZ1=Iwp1JwXURwIw+ zI`FFvaIx2g8w{`?>rniacjnZ~A?J7I#q&cr9$Esw0}X)sKntKb&0b_U{eE0XcbnWZ4hD_#8_5L#PD)L69R>BH~CCi*O065p2V?~EjjPdZxnJ6VO>~h#q zfE+en#ktO{fOEzQlt?+%qXAYh2JSu}4cG#3f;IsgfmC2Uunt%YtN~U7oZD5vGT;wD zsf5e9{8zwZDKG`#RHXn*fO!B{wz^3$NW4Y$20qJB#Mj^JX!W*D=Lw4IOee*b2$-; zAHQ>)N&>|8pF6NZ=A3W>6vbkS@vc-dma{_UvzxQH^77-Rsc;C-iQN7b1#Bh`#F&p~ z#eYGL=Op==E2hHb3bjyv=jTQ8bF%C%mR&_(PTkA6{5eogvvO}W5`OHz9N;>UGpFp& z%Gj)IMox(0w=%~&7f(*T3P<7p33+!e3ngW_2|4|9CLjr6HUOM!C86AGIWmREMWxiM z+?L{a6rNcA?2!QERKN-2fP3NY0d@g9fo;HF0Ed|jaNWt-X>o!!11!%i%h_bPiLT-D z=k}?zOAf>)&)p=s8O{N?`TZYjdeGI8%Rjeyl=5Noa%I{AYz5K*g}VdKoYU<(lj83V^|`AD8;nboJ4=p=IgtR@ zcdoN+ z!WE7R@rpaTC-8C#xB#35ZUASvs+`8db$|uu02ZDBa{FC_-vlUQ-rv9#U?Scx!@UGt z1kM92XMc9D0xVbjSqDFJJS;zJj{kWeiMQb12B`NYtv^}J(wfBI!|Oxf0l?=MiUGdh zy*J+ZT*CyJD1z#EfC@y-$Q`&WPy&)fTIfVsT-&4%B1 zpgo|$I~@3@O_4z2V1k>G2+iXJ@#Ud`wgvFb5QZ1)hrmMFFQA{tkFn0$bsk!|+bJHJ}6d zV1w6#e9FKF9Lm~|EvD#pgntQu6T*n+9sDvtX@JdF4sKbXJixhcfWXQbryJh+jEc{( z`0SHURrquz0^n_ZKIdu@z%9+!V^PmU|L0#{P|R`Lmv! ziDIjTfurc+jK=4cDutj}ggL(hE#$xr;pSA#vQ_{`*b*+EdGcvnJN5%w18o3BuM#Kf zPW%sZvrsWTD`yf{JcZ1aj4Ku=iv5*JsK|3xM1{u(^4)=M0B<{Wg}W4PEZiPIPc80Y z#o=KmOvCM#|BXWv;+zbC{~bIJgj)lF?!(U_6)*T_pGue0wN(qM!#&-6{oOpsZmTvT zkl(!AJdr+73aL~H?LW1*o?7MMAm(|yc|g=tmTc&>Dtvjwm(>OhTefNgY-|yz=%JO{ zP1;*rEr__Ke`_dXtJcn!J0;x4N_bTMgYN3ZZv6~|6OiCOWy1SuS1LR^z3`nz9q#QG z;EO14lH)e5o!@5=ihxiu%;xR4-I{O^kQ!h7R}eX~fMjlJ#V~C2REES8B0o1DTQ&9E zrnS|T0mB@OD|?@=f2?t&d|?`Pr7cML+|_GQ9xtHoaH zUrc-^Cdt#s%|n$0i5(>Uf@?l|zTwgogJd&R+pe|KT>`-wgptL&rPP^|+8P8eH!nXo zFV%bM4T8o@LsPaRWu;&tT*ypl@hzs@m)14c8#Gm?Js|qF2EhS@E`@7X-WTjX+Cboq zZBE{ah%Xv-vBr)D$y74ifkf~=E3UL9O#c1#@Tb9Z7aIsis1^w7d(;+={+pbJ1=r>W z+U^)x!oagNq8U4oN*~l4ToFyEo7npL)*EXD10#&Sc*0_B=qAU=^BP>9Oqfyc!{*^f zOY{Q|CE?@i<~5j#?nI1ZsS+F=fma;7^(ybQY0;*S!9#(0yZNa8qz*f^-nzXYaP12y z)N=WyT8pw-k(&=HgX%b~V+}kfU=1Cv4*tHs?5y%qOuisIqPsh_9Rwb4P4HLggyN=R z-~cyY45~DIm)3_)?9zIx`%v~SqzFG}tsz)BdOy1^WOsn_o(|GZ6n<)gyN)bep({r<)FXziLrTBMnm~R8=h&c1+-5= zpv*m5TRmS9C<^X}YD*ih@8w!h?$vho<*Oacu(?{JgWq z+cs&Ki}3Kkhr3cdoZ|*mw7OtT7xrqKsGC!necCPf$im%kNU$t1-LHM&$0zBg2tU)k z&D646ss&i8`33;j55AGann!Hy-}h+cOJ0_2Y%fn}HZ~@=16nVri#z~zM``E*WV{P) z;I}@s1Aov|HyZOyZn(E@?OC+OYgd3)?cwHyX6dDxOW(lL{UH+`C-!@tQsey&17RC^ z9)zM3)DVvDCU{(=9<>*ANH;du7g$$j1K|`TTzQQ9o$u7+^c$3x5;TLV9f9sbC@OAEm0u2RT*PAhIRl{r^#%dI=9fN43fnd{-yvpn*4q_JH8K76c~{{L8JY?Dgd=?54zY5)$rZ%XA(SKKgpr5rgCf znH`00Q$4Ku{T3c zht-!X(K%oL)Tl(OxsdR@0}>-gDsfV4>st)f$^udCXgc|9U!NczjXd4ByHb^egp+sG z&fBw)$@F>}HAW2m-A=kn(`Z3_N$vO*|J&Zo37T+owFX;1qOEQJ9G#DjlX z4KND+c006)Of$AOEdKb4ytQQ%$3he`~F2*=emmI@{}~Q6zs;lQ&vBDso2K zg;ftagYGzz)|`Q;C#9eRrdwyU_V_7(R#l7v=4Z7Ia&N6WT2AT<+Nd}0tbbruRYc=~ z8iWL-Q{-8MKTVCYwKfhuD!&R6GopS+(~=WgTm#cvvPvV`0H&@H2s}&qR5ZH#cb`-9 z#T4_oD+;$2qN!-m;Qpfz7M#4Kep$|5l?O!DAUhIaH#AbJ{2W z%COa#xKQ$WjGUG((&$w=IC^Q6kxg4smk(DjM;AJOUfWsY=t@;Cz&NfHdqLYsW8pzN zFQ79mf#|qij!um}Q!$|NHZkcQZvI#vQq~2OcocM)fsi!+xP9-~t+FaI zvBS4VpcX>}8)iop38H4Hk>>! z^Sy)CD%;DJV(*}Pbf=U%C>6^}^zx3@R)dBz<*wG2O5W9m=JE{DnaFLT(fr;1_X|y7 z{oKA#G5gY+yISu&8Vv|aqp5vQ+gTk%tM4IJak}V0pYLgl=#E#D=5u{|_2|(*4$JKx z*MBo#QER3pzLQnzzP5$0Q+266eCwf3jVl?%y@e0T5GCs(ORB}3?KEtBx6+&-?wLJR zm1*65lx{r`iozlfZZsHKYz{Z7-NqJT;w88j7%*ID(OX3ov64kt- z)e2lgH&Rz)!G*jZL$;gJjfE&mf2_TPAA(PPf;6e>ORXz-W~Uv4`}%84sXMdg%`CbfzAqiWk^z9iU_irpUcx@}M z=BJGRJS0XgR{e?OnE^v_}2VNx*LC*R!~PVavh!Q^Ull};g; z?hOdyg!ti;R`bPIETyymsuiXj*X)GHF9EU%+H`WRj_v%$k~Iq8GeGlQR*AD}FG=BfbB~7>RAr+2JQz(+gy+Jo=PcJxF zk4ULaIA3=UFBk5NZHp1u+F%>EAm_JGZ%r-OkwVkbx2Vx^)Fe$1QzFHU4{E()&QB2` zMC*6hOUN?=*3t z#hOp=wUtcfc9CkoxU{hndnRXc{0v0{DDnfhzHT(^114YQ-K5I4YVh}7-b-|-%Dm6R zorDu@08zI|CVc!nw9Echb5>~7N$}wnY*%Xd5lfLPc;%73Q|kl!lg*c4uD>5XJXgwN z2*9Qb7se+rxO4X`^eUrbT}yO>58=a8I7z9l6?%W}+d|#WV#Tn* zk?Z zit;3Q^R#CQjsAp+Z`@Nd)T=`wH~%*K5M)?Ygwr`_zz4xHSWzA&DR;VJ0mMinxgEYW zl)}X!RlX8vpl^Cf4d?mCsGA*%7v!SF{GF{8Nm-!!W`n?nE_Hd*zLe#|27 zCygoxt^_?F`FJRg>KrG=2q&uc1+n;0_togYp*QXQ zg6_qdu6{wc6-u?fVq*K2ihe`;uRF zS0&C@DwVp?PwFWL4v?&uFd*Y%%Laa5dD$oC4WD0d|BhLx>p-buk0SbxXy(z0@8}9s z;9Cs(6D<;IdADC5j8^1<-rfsF8I+if>KlYS76ReH^X>L~oxYtzW_Se!dCnD-oo?b_ zsh(V1QsY^zyII}0GHE(YN=PWZQVW%!)IkHKJE?{SldEIHrE*)kF}u*0A(tD%9CCSFroI|s z%l}|$%&WO}@lsVb=@oeRS(61jpdN+hhcUVf%``%$w$d6Sp^^Smf>e4t0`>$&_TEtu zJf7^JlQbGhmY7iK3Xhc9t!Lo;@0wF{R5Al`I8me)nyhFj9Gw+-+z$xXz68gno=O#C z6f2k&Z2-ZyD>@3UC=Mm>mfCAlk{6lSEa8fhXICR0u!vDuI*DrX50B6DV7{teKn>ZE z!WfHT!2YHg(?XVViD=S;iKT zm+C52D+t0z5V%9Bcdtiq#eM0LO}r{&)R8908sl+v%S5n+k(H(r$vaGx6yJbm$Z^aA>>|swxXJa1g%=6SqYq8 zIbXIklyfO~EZ>`1twzT&_E~bKB6542eR6pg)1~cijiPDrZ{OU`$ z&?WY~NsTIq9vG$AA=8fvG?c<2>SQ( zYr5^B8)wgce*i^1SNHN);Uhj;Gr>zXPjTftKfUIiF&{A@ge>sssg7po0)DPC&1j>S zP`m(|CjN!dNN=GyJu(xTW6Pv!5!B5s)T@YK=XZRDl>RLtF?|CMH4_i;P=}Gh8<6n8 zy~<@s4ewUlHAs-Bw1@R_2JJ2)*y@aDN;M(AfJau<(G6TghB&n1D{fG(b|X`B>($dMTMxr$w>E|R0+#=V_9iwSlbiDW5oYZj$;Y7MQifPV4Kk~$O<1ZLfVDnHX%QU+Sp=%v3` zVe&XB16bdvp3j!{oV&bvc5t+JOKXi_>4CEyX=XY&*m9 zl2tf`y0;`%z!%SAEgiazy2qL&QV2O(B2}#@z!Dv@KaICU)2Kx|_)UsIDP!!{RI~cI z_++$|^S6wP;=3*s~58m?7|H z)`Daj1%_rtGNsuGA)58cbjLxkCB3~6s!30#9`+FKO{OJq^}j8a@?ZPz&Kh2o)?ubP zf>$|E({wRq+M{u{1B1;N=H5_ux9RODajq%WtDcZ>Eq|gaw%s(d94{()afW=3UQB^H zWMknHX)ocWzwIPvyY|hv`Fi^Eo~UCA#WBM*McSXAwSWIrtFWTTsKStwt@&*+?FQ4Y z-%`n{SDUZsedT`NVwh)22~|yog!{kvPY*i@GhA_}L6IaarNVl|vKb8SBy4Mz{S@f+ z_bCJ8&{C=i1{-PGKQm>9U;eS>AB&>>&yrL<8uSf9r`{PSK-ryY@=KrncIX!7yQleT;9 zDrwZ{9L0ZiWl6o#qrR33YB0(WHf%NNonZC0VDRMgLfPxv-F|xzYG8C;O<~OF4F+$^ zq@BTE(A4fKo4A^soQ2Ms>T76%Gv3>-rk(7<|0P`ga5)uImKIvrd)6PdEYx03u1>7K z`#P##5~)RAjx!A8!BttOXs zerQ+xrPzKB^h-81Ke7oUdz29>YX06t?aBzv_0`u%iND*U%-<^-4CW0|c^PD~nNF5L z!F7~-p94qyHbo@XJb_UcGZ(IF<2NUkMR}QQmQ-vritXfTe@DFKB91HQ;Ur03K`9hr zHD|VvMMXq%V~fQ?)UPc-U^a@~8ng%*OT{{RNpij777tQ=V4%TNPDNTai? zt9TmSr~syOn#7#e+c9#K*}VP+rh6KdD2EhR1A|+hoBs^ohO3)*GB849Nm>(Ciz;Pz z`xzu{)2Ii+>buE|!Vy;2OfEfrZD0&eqb00;g3OrtIc7&oA@#F?L9%2;YRrXknn$$_ zl9g$c$ziw1jK3}hd@T7c6SE1$4hJFOp0DNfxbXx1%rFKjl8b2+SRN^R00#GbTcZ2a zJaT)^Vgut{8pVO(XPhqe?@#ZB-_G1?I>ErOl_f{kj*hPMHENncQZb!&v-UtRibMMq z%cnbbeyCH^z-XLK(_nW^R5}%AcR)IYqf9lE)2Sxj{gxmk&o6x zQz6OGAY6zG`t_v<$6NLTYRno^{Zp7$ZjR{rB_hpp!N@M{Qdw!?ZB1%dp^>KMK?-w) zt(zW{daW8OpMLc!(UX^)7-V@9wH+i}JIvgCYTtbq)C3Zq*m-)WnjWNNgw?;58GRaT z%XInMb&VW1(kvXJ^RDPcrL@~>4jd*YH^J7o@DVAOgCn*#_^o=U-w}dm1qhMH8AfGk z!JkdBZs-kXAEgOyLXc+3Q9A7=RMBreDkZ#STV0LqCL#U!CW+Jo2*;?jyWr(#bxc~K zMp=&Pf96Z}FfcH8;r)xAknptS=u@Ay{Znr}hlCGIJbhKWj?ol%m~}ALtUUO*oJqSi zD?V_6g<87t=dF@1Q~Dh{E-7zyIkj-M&&5E=ZhR}_AtcraT4Ps0;mJaar3T5D<5a{0 zHn%+?F&eHrH>mX=htC@rZjk5^*7e(3uVQshKQc%foS=3HtM4Q;#{Ri@*4`7h+zpI` z6EuUhC&`R9rr8CjwQFr^V5CFB?W&%~)Ya^+pyEX6N#m3w~IC~mO;Wr_i+1@Yx`aH4lqchJDa*KvhqJ3Y+vcv z{s}L5W#!_soo~Zp^=^m1t%7y?kGG#>oXL}3SjPTDReXQAh0ao_cW#yv=BJ=Pduo=Q zq!K>p?_~F9>CXvMBFn|eGr2#w1E`m;A!~9*WzRfic_miYOf5A5v$QG~!yQAbVHo#v z<8?P~7w_}Ks`uXra+-g+W-HDI#EKv%&4()ZV{Q0|+WY@Vwk~&5$Q?@Ke2tcb3RZO8 zUvNO!Pf(#bagE$6!?K~*sb^Kx($?3dKCDNDHzt+JekIKRc(H}MtKF{Cu*yQkLc_q| z`gHm_r6QzX2Hs2X`_oJ7#x8v~l`p28P*9Nph^}@Cc9oMrpy`MH1j*Ms7Hm%_mCs|NPnN z>j6y(gf-TIf$hnJ5fgVmc(C>3U<2d$1KJCQ-+eIjV61oVc;M26Se1d14GGr*JJ<8g zR&7thA-ba7@gWtdhOmJTrT%aDx$FxAd!OlIV6=pU``_p;SD#IMaOC&=3=elodClj%% zoJbw2!%VKw#KZiwn-OEpTi!na0v3+EBT*d^ZW_U7+cf)7we>Pd!c&8=XS5#5^}ujaxKs zG<7yFd9jJi3~`TG3P&`uCb|XjM!TJ+SO%S}fvEGo)$WT^d)JIa=>F%Ju{)1F=$!iX z2Qs7~$Kh;0>NaiH9~$*``0z3fQKr=t^OE(OU}NMj?VMW)-nii|>+#0TJ9&#cq?XWB zzM-zgghDoeKg{-HbKX}ao;FxH@@~hN=aLPrVk~ZjRcw$h*?`-oyy+}&c1t(^ZkB)_2DOxy`#MG%Xa+-X)Kb4PmvQHn$J z=miz717hA*~WBsC!^3rRcg(G$1K%jS89 zd{)poi*6uZC4TA9gnz_nI;}m@tw5meLQQwKbec!yI^f2(`MX+@GVXHwCIUbA|@R`^2 zJs3H>_L`i26FSp~x`MsN=?yKYiy9R~r|M#AD>sM4dP1mtnuE&+p8isOp%L|j%JRVu zovbI6(Ad4B=k=iSXVq&MATqAzvl0yhCQx+ z^@hvdPQcCz=aO$ube1JqYb`e449(_~5>Gci+)@pCPu1%q(sA#pRefwqtOJwhl1T}H zSNnTsJ+xHMeox7elsXKF8zcj|_KW5Td3kMDi+U!XaoxK72mCM)5~=o!?I(@Q8lZ8@ zr4racsH}noz!#`R65Ko3Jz%UnCVcMD$m^{7A(bDjF=Qbwj~X zis2`!z*Nb`Rr#^uXQ=}yJS(_)(J_DHj2}%#{1+)psvRy^zFEN|82J>*z|SiB)=;of z)Qd|QF(o!eUQ&->DV=MI5n0l}5W&%?##a^14-p#5Qy5#LE$~n`5^VhUf0b5_hyGrZ zG`ah0tbB2rgUcECrLZiqIhh&U@b{Uxz|x zieLVe{3X)N&sLv5BSl4VjRo8P#w5yok{9KeMh8>vA==e5)AoLjjxvOKnG8=**=@ZLFpwbzF-O%Kbh$4woR<34`>^cF zCr4iI$>xbHKnY-IWLMt@zo@iCT#bu;@~QH=%|indsS=kB%97$+Gr?aUV2Zz?0=kXK zI+{N6J&&$DAI9%5>zPtmbCi2aFl@lMnAN>e&B<1LWf)6M43?^%kZ`Hq+;d}L%-P?M zaad`eV~i;!H^)r4c42yMaJ@86X7sWJ66;|`6I#H;FU@Et-u2odQub=??_aZFrzjk5 zi>bigkP<>l4Ij38D1mc{DC>8eX03)Mp6G3Ack$)&t4+S)*y8R3 z?#wW`?7Ysv2(q9EF#Otp!KF2@)KZJvQ-<|0FnUA6m2l0$r0$=R0(u%G6D?>x!ul=; zgJ=8YJJm?3d!enDfzcXi=1JnV`o(J6e~v7O{9-c5r&!`fo1GrpPGbFh+H}f68{2b* zCDSosrX_i_#(kYSR+5TkC*}=a-0gfQOJ>W*zP(p;@MK9Z7O7q5sZghhh9n^65GHspX=MJIUMj$iz z#Ro45vTdkD+Z<{T{7yLDZEWe~Fm$%3r$J4eEiGZvBwNZHCB-3(@Iv;8>-M|5M;=~c zNWKz7Zg-L+c_jQCgOV-LRg$lSQ&N`0KWBC{Bb=xw*9j?QKMGSeu&pN9i7rQB!7tY` zO&;bHbK+Z4%87f4asfT|dWtoo8!e_^CYN6m&(%_u`5MmQhqDIbOy8fw*d1x3zM+;Q~H&| zkno09=?2GKA73bqX@xc3h|Xp+(Lu|rFPigRV@G-oBNEQPYJpLj91eu}gk7w6U?~0J-EtHTrsi`wDuJFtZ(3eTbWEx1qh^-7%XhP7ou$gt zTGm+&44%G}Y4*{g_v&mMYATF|<>?OVQu_5C<;iIx-j%klbks^+R{CP456E3}mEK9I zLrR}8raV=j1idNcY4>Q(B~s*w6y3YHH?zQzt~^uYG<*81?vTywS+)z=_e7VkkQAZP+<(qGhAX*){v{fz15nf`Ej<5x{-i+c zVRBnn>YKfC_LIt3Ao6qc0r~lhyj+8-W|muGKNR;mH?_Ds<<)21)<$2ZT~vzO&{4}3 zhQ~x7%|mx8JP`Jl%R%4MLmJ`z(*8QyXZ)<@zn0)t4|+aS3L&QBv@MP6k3I^WjPOwNQvgT8K;X$6fqcvQbH;fRjCqrXcmi2 z;Xm-DgdtG&4=MSHpIcwoFlJ!;nt`!6rcc{F!lPyHp&34q&$aa z(H2TY{ki%7Qm{WPkt6(1IZy`Y{Nj<@AWa*AWqwqETHLlDo}o#6lyqvNVHg+{K({6% z8_VEgtk)j^llzuJXOH@s?2WEvU_K5YmnmQts6sB>cPOS;`Vysa=a}D#305l4vMLn8 z;gxXt@c;ACS0j&;nx99*9~D{|*^~&CTKg|U+K*|vJRE7{K}Yld&d?%tZoky2pF0b= z2jTIDI}N`Xn6X%)y zUwMSA=xFFV{_{>HcSZQ0b}mZqnO~=*0Wr}6jx&&;c%`T6nrwvVb~O|^J)?|p{R{h+>nc97sW7AHQc z*$Bb&e&wrfVq@mZ!K!|-aiX?Lbu0(yMhRgvtA?I)IfsM5jS!q z!A`(-82-)^f1xTQ&!5=w8K5eU?+;Xy4q#c*sn@`shc=cT*`=wIu_bo+2O%yBTPEoB zHEKzlvTNRaSn6>p>nLKDH+D^HQ^6TRh|aRMG!9pOQDuJn0^@l}fNPh$4Lz88%@Be$ zeQQ(N4BVV5R!7>*Gqe8K=H-+-;+CRxkRM)$QfH%2im5~4v*7lxLp5ij-y4Sz7BE%W zk9{W8H*Sp`X>mIf+f0d&@M`?2S;ta+u11KPiqfv$=Q{X|DRjs>_1Yk5WAOQgYAKdm zT41FH9sCtCl^mNs|5*N8U0A0|Inm!ith_xJ7gxmkR-pHHL&~29(H*4EFaHmvyhT{? z(r4g-=qHn!@nto>@PJ$!1(O@>q%RgMncQ~q(D_qWHTN=TFC9!Fb8_T9|5)Ud`swOP zrLt**@$8G9btfBi<(Urgcmc6|=kk(ukjETM8s(_-Hn?~0d1i}s9b>PyGBCCHO7t~mFDsV~Cv zi~_Y!-AG#5PqTCRoO;7}9wc5^+(K&Jh}z9VN*x-}4A$WSCbwIBSjhF*)BYx4$~Cwi zBt;=HuYWYc?8e?z8g(FiOySe25#8djUGdJF@p1PG+n?*(?>7$1+wtD2p^)(TP+g-V ztEaTMz%7|OTWtPJYeX*dQ69^{um(e8T&`DRzfe~`fE0gzqT1GoBADR-2DdHKKOA0a zPXx@?XnI8Ui|*SGmuf<3&V1wn_ux)0fc0&{$b((aF#5{=%6nQEHCSMHr^E%A#E)nq z?S~KP^VhN3S63XC63suJQPfRnLXQ^U9*wlM&L6+wUy9L!B*9+S3W;K)Ot}>uL|(Il z5SouDU~-u~qd7fGLYz%oP>F>|Q*;Zeyby;Tzgn|T3(1ZUn^*1G9U2Elg*B;Xd2l1{C}C>vlZP)M$)18J(wE#T_28djf+3JUvm8QRoVWA zX5iSG!WZNIvG^-?Z;eG8N=U)g8CXTRRm^*@iQ3fmLupL%$SOI@gZ;mg2oed+N3nzsv}t^rg6|C`N(von?Z9re8QY zEdv!7s;evmTc7v=v6ZM#O* zYzNzG)B$cjC=UD@H;Rg^K-e@ecnVai_n*6`ot-0%j<|p4sX7e_pX6$Gxxb4F8hc69 zDoQeH*GXETul`>3(X^%b6Ohc{>6xlVCyD^WuM-$N9>t{Y-Zj*J zJx;rjcCji?-CNjjZ?vPZ1SdGs=cczmFtC7mpR?{RZaTS)U6JjWI6;$R~y?6vuCB{hA>&OTC>M?Y1 zED9GnVab{pT8OZcDt72Bt8CYWO033tr$bk1R5HImw`@s|mN&&(A%2rX`s9X8%$1~H zUeN$vrshaE3O{UvAy&M`{fP|ZZb266lij6GDy4_iB|UU9vfgQRI0fkt4^MqmiYPvsh`ZfBCFiv7`b1JpSQ#1^fxZyurMtqVZN6uW?kcG_C9Kc4wEQ}vzu`HB`CQlj9qb1c6YGRHJp5XI%D@rT zhxAHHB{*&}Y5A}dRj|gxNrZSC0a(<Mgzm{F~!D>}?WZ>5@s7{q(Q(&+BQQ_p+>FY!E3>K+eugQok~{-crG`?8G*m+Ib53>|*P+xS4VBuey>#t*U$Lt1 zI)uzRA$H3c=e$(UhSCx+{N4?f8pgQq$DVh4UcVn0+;~w<2Mm*{>HVio{_dIf_@vm4 zh{HPWie@6L^yx%9{Xbru2~5WXlmCtk?;H$Ctu-bzFr|gz(x=pD-1?7@E(;u7Kd^Q& zbr3SfH`nm{duj`u1twBn}#*{C_v0{hxNM}SonI#?RPYBEAFs*(rP$GJ?l!h=2xy5l5pj4 zR%SL`g|}z5{?hLqmR{LnvGIa_M031zDrR2awm`pdqGboXa~Jz!O~GQlV;_F$Llw6D zPzv2$@usPmN|UzXj&T5fdn~)h*@gczcI%~5q3x1eQFa@!3w}3tIXv8w72Zfc*f=_A z)7JxGO;!froom7UextftbgF;7&Ko)oUVKq`gJgnoo*ukY@Gwe` z-y_s_Prs8XOl+IJq=E4svvmJ(kG%mAtZJ!U9kkBk>>)|=H$42*y zbnO$}w^xq=(d79>(3h8D&FODYlhc>fx&md)upJ9A{_l#70XpYWpk(?bb%EgO{|j-S B)o%a* delta 74396 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 N;;oC`TUM{|{{Wt-ELZ>l diff --git a/package.json b/package.json index 77abd63..c924057 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,8 @@ "playwright": "^1.57.0", "prettier": "^3.7.4", "prettier-plugin-tailwindcss": "^0.7.2", - "trpc-panel": "^1.3.4" + "rollup-plugin-visualizer": "^6.0.5", + "trpc-panel": "^1.3.4", + "vite-bundle-visualizer": "^1.2.1" } } diff --git a/perf-results-2026-01-04.json b/perf-results-2026-01-04.json deleted file mode 100644 index 4a445fe..0000000 --- a/perf-results-2026-01-04.json +++ /dev/null @@ -1,1645 +0,0 @@ -{ - "timestamp": "2026-01-04T16:59:54.705Z", - "baseUrl": "http://localhost:3000", - "runsPerPage": 3, - "results": [ - { - "page": "Home", - "url": "http://localhost:3000/", - "runs": [ - { - "fcp": 160, - "lcp": 156, - "cls": 0.04666640980253497, - "fid": 0, - "ttfb": 9.399999998509884, - "domContentLoaded": 166.79999999701977, - "loadComplete": 562.6999999955297, - "totalRequests": 105, - "totalBytes": 8451841, - "jsBytes": 4421934, - "cssBytes": 0, - "imageBytes": 810035, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 7, - "jsExecutionTime": 0, - "taskDuration": 56, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 152, - "lcp": 184, - "cls": 0.04665493133921685, - "fid": 0, - "ttfb": 8, - "domContentLoaded": 163.89999999850988, - "loadComplete": 580.5, - "totalRequests": 105, - "totalBytes": 8451841, - "jsBytes": 4421934, - "cssBytes": 0, - "imageBytes": 810035, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 7, - "jsExecutionTime": 0, - "taskDuration": 104, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 136, - "lcp": 164, - "cls": 0.04663327383504485, - "fid": 0, - "ttfb": 6.399999998509884, - "domContentLoaded": 141.89999999850988, - "loadComplete": 602.1999999955297, - "totalRequests": 105, - "totalBytes": 8451841, - "jsBytes": 4421934, - "cssBytes": 0, - "imageBytes": 810035, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 7, - "jsExecutionTime": 0, - "taskDuration": 0, - "layoutDuration": 0, - "paintDuration": 0 - } - ], - "average": { - "fcp": 149.33333333333334, - "lcp": 168, - "cls": 0.046651538325598894, - "fid": 0, - "ttfb": 7.933333332339923, - "domContentLoaded": 157.5333333313465, - "loadComplete": 581.7999999970198, - "totalRequests": 105, - "totalBytes": 8451841, - "jsBytes": 4421934, - "cssBytes": 0, - "imageBytes": 810035, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 7, - "jsExecutionTime": 0, - "taskDuration": 53.333333333333336, - "layoutDuration": 0, - "paintDuration": 0 - }, - "median": { - "fcp": 136, - "lcp": 164, - "cls": 0.04663327383504485, - "fid": 0, - "ttfb": 6.399999998509884, - "domContentLoaded": 141.89999999850988, - "loadComplete": 602.1999999955297, - "totalRequests": 105, - "totalBytes": 8451841, - "jsBytes": 4421934, - "cssBytes": 0, - "imageBytes": 810035, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 7, - "jsExecutionTime": 0, - "taskDuration": 0, - "layoutDuration": 0, - "paintDuration": 0 - }, - "p95": { - "fcp": 152, - "lcp": 184, - "cls": 0.04665493133921685, - "fid": 0, - "ttfb": 8, - "domContentLoaded": 163.89999999850988, - "loadComplete": 580.5, - "totalRequests": 105, - "totalBytes": 8451841, - "jsBytes": 4421934, - "cssBytes": 0, - "imageBytes": 810035, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 7, - "jsExecutionTime": 0, - "taskDuration": 104, - "layoutDuration": 0, - "paintDuration": 0 - }, - "min": { - "fcp": 136, - "lcp": 156, - "cls": 0.04663327383504485, - "fid": 0, - "ttfb": 6.399999998509884, - "domContentLoaded": 141.89999999850988, - "loadComplete": 562.6999999955297, - "totalRequests": 105, - "totalBytes": 8451841, - "jsBytes": 4421934, - "cssBytes": 0, - "imageBytes": 810035, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 7, - "jsExecutionTime": 0, - "taskDuration": 0, - "layoutDuration": 0, - "paintDuration": 0 - }, - "max": { - "fcp": 160, - "lcp": 184, - "cls": 0.04666640980253497, - "fid": 0, - "ttfb": 9.399999998509884, - "domContentLoaded": 166.79999999701977, - "loadComplete": 602.1999999955297, - "totalRequests": 105, - "totalBytes": 8451841, - "jsBytes": 4421934, - "cssBytes": 0, - "imageBytes": 810035, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 7, - "jsExecutionTime": 0, - "taskDuration": 104, - "layoutDuration": 0, - "paintDuration": 0 - } - }, - { - "page": "About", - "url": "http://localhost:3000/about", - "runs": [ - { - "fcp": 428, - "lcp": 428, - "cls": 0.00008728592484085647, - "fid": 0, - "ttfb": 22.200000002980232, - "domContentLoaded": 132.89999999850988, - "loadComplete": 851.6999999955297, - "totalRequests": 103, - "totalBytes": 4514246, - "jsBytes": 4423537, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 390, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 336, - "lcp": 336, - "cls": 0.00014995421107413841, - "fid": 0, - "ttfb": 19.799999997019768, - "domContentLoaded": 274.1000000014901, - "loadComplete": 979.7000000029802, - "totalRequests": 103, - "totalBytes": 4514246, - "jsBytes": 4423537, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 295, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 392, - "lcp": 392, - "cls": 0.00007936278292181069, - "fid": 0, - "ttfb": 24.099999994039536, - "domContentLoaded": 327.8999999985099, - "loadComplete": 644.2999999970198, - "totalRequests": 103, - "totalBytes": 4514246, - "jsBytes": 4423537, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 346, - "layoutDuration": 0, - "paintDuration": 0 - } - ], - "average": { - "fcp": 385.3333333333333, - "lcp": 385.3333333333333, - "cls": 0.00010553430627893521, - "fid": 0, - "ttfb": 22.033333331346512, - "domContentLoaded": 244.96666666616997, - "loadComplete": 825.2333333318433, - "totalRequests": 103, - "totalBytes": 4514246, - "jsBytes": 4423537, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 343.6666666666667, - "layoutDuration": 0, - "paintDuration": 0 - }, - "median": { - "fcp": 392, - "lcp": 392, - "cls": 0.00007936278292181069, - "fid": 0, - "ttfb": 24.099999994039536, - "domContentLoaded": 327.8999999985099, - "loadComplete": 644.2999999970198, - "totalRequests": 103, - "totalBytes": 4514246, - "jsBytes": 4423537, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 346, - "layoutDuration": 0, - "paintDuration": 0 - }, - "p95": { - "fcp": 428, - "lcp": 428, - "cls": 0.00008728592484085647, - "fid": 0, - "ttfb": 22.200000002980232, - "domContentLoaded": 132.89999999850988, - "loadComplete": 851.6999999955297, - "totalRequests": 103, - "totalBytes": 4514246, - "jsBytes": 4423537, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 390, - "layoutDuration": 0, - "paintDuration": 0 - }, - "min": { - "fcp": 336, - "lcp": 336, - "cls": 0.00007936278292181069, - "fid": 0, - "ttfb": 19.799999997019768, - "domContentLoaded": 132.89999999850988, - "loadComplete": 644.2999999970198, - "totalRequests": 103, - "totalBytes": 4514246, - "jsBytes": 4423537, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 295, - "layoutDuration": 0, - "paintDuration": 0 - }, - "max": { - "fcp": 428, - "lcp": 428, - "cls": 0.00014995421107413841, - "fid": 0, - "ttfb": 24.099999994039536, - "domContentLoaded": 327.8999999985099, - "loadComplete": 979.7000000029802, - "totalRequests": 103, - "totalBytes": 4514246, - "jsBytes": 4423537, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 390, - "layoutDuration": 0, - "paintDuration": 0 - } - }, - { - "page": "Blog Index", - "url": "http://localhost:3000/blog", - "runs": [ - { - "fcp": 656, - "lcp": 1940, - "cls": 0.00011959311402874229, - "fid": 0, - "ttfb": 78.20000000298023, - "domContentLoaded": 413.19999999552965, - "loadComplete": 1915.7999999970198, - "totalRequests": 122, - "totalBytes": 4632398, - "jsBytes": 4541689, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 103, - "cssRequests": 0, - "imageRequests": 16, - "jsExecutionTime": 0, - "taskDuration": 1297, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 552, - "lcp": 1216, - "cls": 0.00008675864890769677, - "fid": 0, - "ttfb": 32.70000000298023, - "domContentLoaded": 490.8999999985099, - "loadComplete": 1442.1000000014901, - "totalRequests": 122, - "totalBytes": 4632398, - "jsBytes": 4541689, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 103, - "cssRequests": 0, - "imageRequests": 16, - "jsExecutionTime": 0, - "taskDuration": 980, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 544, - "lcp": 1732, - "cls": 0.00007793539541739004, - "fid": 0, - "ttfb": 37.20000000298023, - "domContentLoaded": 158.70000000298023, - "loadComplete": 1629.8000000044703, - "totalRequests": 122, - "totalBytes": 4632398, - "jsBytes": 4541689, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 103, - "cssRequests": 0, - "imageRequests": 16, - "jsExecutionTime": 0, - "taskDuration": 1246, - "layoutDuration": 0, - "paintDuration": 0 - } - ], - "average": { - "fcp": 584, - "lcp": 1629.3333333333333, - "cls": 0.00009476238611794304, - "fid": 0, - "ttfb": 49.3666666696469, - "domContentLoaded": 354.26666666567326, - "loadComplete": 1662.56666666766, - "totalRequests": 122, - "totalBytes": 4632398, - "jsBytes": 4541689, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 103, - "cssRequests": 0, - "imageRequests": 16, - "jsExecutionTime": 0, - "taskDuration": 1174.3333333333333, - "layoutDuration": 0, - "paintDuration": 0 - }, - "median": { - "fcp": 544, - "lcp": 1732, - "cls": 0.00007793539541739004, - "fid": 0, - "ttfb": 37.20000000298023, - "domContentLoaded": 158.70000000298023, - "loadComplete": 1629.8000000044703, - "totalRequests": 122, - "totalBytes": 4632398, - "jsBytes": 4541689, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 103, - "cssRequests": 0, - "imageRequests": 16, - "jsExecutionTime": 0, - "taskDuration": 1246, - "layoutDuration": 0, - "paintDuration": 0 - }, - "p95": { - "fcp": 656, - "lcp": 1940, - "cls": 0.00011959311402874229, - "fid": 0, - "ttfb": 78.20000000298023, - "domContentLoaded": 413.19999999552965, - "loadComplete": 1915.7999999970198, - "totalRequests": 122, - "totalBytes": 4632398, - "jsBytes": 4541689, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 103, - "cssRequests": 0, - "imageRequests": 16, - "jsExecutionTime": 0, - "taskDuration": 1297, - "layoutDuration": 0, - "paintDuration": 0 - }, - "min": { - "fcp": 544, - "lcp": 1216, - "cls": 0.00007793539541739004, - "fid": 0, - "ttfb": 32.70000000298023, - "domContentLoaded": 158.70000000298023, - "loadComplete": 1442.1000000014901, - "totalRequests": 122, - "totalBytes": 4632398, - "jsBytes": 4541689, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 103, - "cssRequests": 0, - "imageRequests": 16, - "jsExecutionTime": 0, - "taskDuration": 980, - "layoutDuration": 0, - "paintDuration": 0 - }, - "max": { - "fcp": 656, - "lcp": 1940, - "cls": 0.00011959311402874229, - "fid": 0, - "ttfb": 78.20000000298023, - "domContentLoaded": 490.8999999985099, - "loadComplete": 1915.7999999970198, - "totalRequests": 122, - "totalBytes": 4632398, - "jsBytes": 4541689, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 103, - "cssRequests": 0, - "imageRequests": 16, - "jsExecutionTime": 0, - "taskDuration": 1297, - "layoutDuration": 0, - "paintDuration": 0 - } - }, - { - "page": "Blog Post (basic)", - "url": "http://localhost:3000/blog/I_made_a_macOS_app_in_a_day", - "runs": [ - { - "fcp": 748, - "lcp": 876, - "cls": 0.00007054605994204926, - "fid": 0, - "ttfb": 251.20000000298023, - "domContentLoaded": 583, - "loadComplete": 927.4000000059605, - "totalRequests": 138, - "totalBytes": 5055597, - "jsBytes": 4964550, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 129, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 354, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 792, - "lcp": 924, - "cls": 0.000056656700102880665, - "fid": 0, - "ttfb": 287.20000000298023, - "domContentLoaded": 594.1000000014901, - "loadComplete": 1019.1000000014901, - "totalRequests": 138, - "totalBytes": 5055597, - "jsBytes": 4964550, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 129, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 353, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 1004, - "lcp": 1132, - "cls": 0.00016702569561240116, - "fid": 0, - "ttfb": 416.40000000596046, - "domContentLoaded": 550.5, - "loadComplete": 1677.8999999985099, - "totalRequests": 138, - "totalBytes": 5055597, - "jsBytes": 4964550, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 129, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 332, - "layoutDuration": 0, - "paintDuration": 0 - } - ], - "average": { - "fcp": 848, - "lcp": 977.3333333333334, - "cls": 0.00009807615188577703, - "fid": 0, - "ttfb": 318.2666666706403, - "domContentLoaded": 575.8666666671634, - "loadComplete": 1208.1333333353202, - "totalRequests": 138, - "totalBytes": 5055597, - "jsBytes": 4964550, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 129, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 346.3333333333333, - "layoutDuration": 0, - "paintDuration": 0 - }, - "median": { - "fcp": 792, - "lcp": 924, - "cls": 0.000056656700102880665, - "fid": 0, - "ttfb": 287.20000000298023, - "domContentLoaded": 594.1000000014901, - "loadComplete": 1019.1000000014901, - "totalRequests": 138, - "totalBytes": 5055597, - "jsBytes": 4964550, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 129, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 353, - "layoutDuration": 0, - "paintDuration": 0 - }, - "p95": { - "fcp": 1004, - "lcp": 1132, - "cls": 0.00016702569561240116, - "fid": 0, - "ttfb": 416.40000000596046, - "domContentLoaded": 550.5, - "loadComplete": 1677.8999999985099, - "totalRequests": 138, - "totalBytes": 5055597, - "jsBytes": 4964550, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 129, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 332, - "layoutDuration": 0, - "paintDuration": 0 - }, - "min": { - "fcp": 748, - "lcp": 876, - "cls": 0.000056656700102880665, - "fid": 0, - "ttfb": 251.20000000298023, - "domContentLoaded": 550.5, - "loadComplete": 927.4000000059605, - "totalRequests": 138, - "totalBytes": 5055597, - "jsBytes": 4964550, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 129, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 332, - "layoutDuration": 0, - "paintDuration": 0 - }, - "max": { - "fcp": 1004, - "lcp": 1132, - "cls": 0.00016702569561240116, - "fid": 0, - "ttfb": 416.40000000596046, - "domContentLoaded": 594.1000000014901, - "loadComplete": 1677.8999999985099, - "totalRequests": 138, - "totalBytes": 5055597, - "jsBytes": 4964550, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 129, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 354, - "layoutDuration": 0, - "paintDuration": 0 - } - }, - { - "page": "Blog Post with multiple images", - "url": "http://localhost:3000/blog/Shapes_With_Abigail!", - "runs": [ - { - "fcp": 2088, - "lcp": 4300, - "cls": 0.00019789763242619515, - "fid": 0, - "ttfb": 1480, - "domContentLoaded": 1821.3000000044703, - "loadComplete": 4132.20000000298, - "totalRequests": 165, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 9, - "jsExecutionTime": 0, - "taskDuration": 443, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 812, - "lcp": 920, - "cls": 0.00015847958851253054, - "fid": 0, - "ttfb": 286.5, - "domContentLoaded": 633.3999999985099, - "loadComplete": 1862.1999999955297, - "totalRequests": 165, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 9, - "jsExecutionTime": 0, - "taskDuration": 367, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 808, - "lcp": 936, - "cls": 0.00011160022437327193, - "fid": 0, - "ttfb": 292.80000000447035, - "domContentLoaded": 578.1999999955297, - "loadComplete": 1314.3999999985099, - "totalRequests": 165, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 9, - "jsExecutionTime": 0, - "taskDuration": 257, - "layoutDuration": 0, - "paintDuration": 0 - } - ], - "average": { - "fcp": 1236, - "lcp": 2052, - "cls": 0.00015599248177066588, - "fid": 0, - "ttfb": 686.4333333348235, - "domContentLoaded": 1010.96666666617, - "loadComplete": 2436.2666666656733, - "totalRequests": 165, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 9, - "jsExecutionTime": 0, - "taskDuration": 355.6666666666667, - "layoutDuration": 0, - "paintDuration": 0 - }, - "median": { - "fcp": 808, - "lcp": 936, - "cls": 0.00011160022437327193, - "fid": 0, - "ttfb": 292.80000000447035, - "domContentLoaded": 578.1999999955297, - "loadComplete": 1314.3999999985099, - "totalRequests": 165, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 9, - "jsExecutionTime": 0, - "taskDuration": 257, - "layoutDuration": 0, - "paintDuration": 0 - }, - "p95": { - "fcp": 2088, - "lcp": 4300, - "cls": 0.00019789763242619515, - "fid": 0, - "ttfb": 1480, - "domContentLoaded": 1821.3000000044703, - "loadComplete": 4132.20000000298, - "totalRequests": 165, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 9, - "jsExecutionTime": 0, - "taskDuration": 443, - "layoutDuration": 0, - "paintDuration": 0 - }, - "min": { - "fcp": 808, - "lcp": 920, - "cls": 0.00011160022437327193, - "fid": 0, - "ttfb": 286.5, - "domContentLoaded": 578.1999999955297, - "loadComplete": 1314.3999999985099, - "totalRequests": 165, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 9, - "jsExecutionTime": 0, - "taskDuration": 257, - "layoutDuration": 0, - "paintDuration": 0 - }, - "max": { - "fcp": 2088, - "lcp": 4300, - "cls": 0.00019789763242619515, - "fid": 0, - "ttfb": 1480, - "domContentLoaded": 1821.3000000044703, - "loadComplete": 4132.20000000298, - "totalRequests": 165, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 9, - "jsExecutionTime": 0, - "taskDuration": 443, - "layoutDuration": 0, - "paintDuration": 0 - } - }, - { - "page": "Blog Post with large banner", - "url": "http://localhost:3000/blog/My_MacOS_rice.", - "runs": [ - { - "fcp": 820, - "lcp": 1576, - "cls": 0.0000651823758097833, - "fid": 0, - "ttfb": 276.59999999403954, - "domContentLoaded": 646.2000000029802, - "loadComplete": 952.8000000044703, - "totalRequests": 164, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 8, - "jsExecutionTime": 0, - "taskDuration": 409, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 880, - "lcp": 2160, - "cls": 0.000051238950878504373, - "fid": 0, - "ttfb": 274.09999999403954, - "domContentLoaded": 693.7000000029802, - "loadComplete": 1390.8000000044703, - "totalRequests": 164, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 8, - "jsExecutionTime": 0, - "taskDuration": 1301, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 876, - "lcp": 1852, - "cls": 0.000055821799447016466, - "fid": 0, - "ttfb": 225.70000000298023, - "domContentLoaded": 327, - "loadComplete": 1227.6999999955297, - "totalRequests": 164, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 8, - "jsExecutionTime": 0, - "taskDuration": 1070, - "layoutDuration": 0, - "paintDuration": 0 - } - ], - "average": { - "fcp": 858.6666666666666, - "lcp": 1862.6666666666667, - "cls": 0.00005741437537843471, - "fid": 0, - "ttfb": 258.79999999701977, - "domContentLoaded": 555.6333333353201, - "loadComplete": 1190.4333333348234, - "totalRequests": 164, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 8, - "jsExecutionTime": 0, - "taskDuration": 926.6666666666666, - "layoutDuration": 0, - "paintDuration": 0 - }, - "median": { - "fcp": 876, - "lcp": 1852, - "cls": 0.000055821799447016466, - "fid": 0, - "ttfb": 225.70000000298023, - "domContentLoaded": 327, - "loadComplete": 1227.6999999955297, - "totalRequests": 164, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 8, - "jsExecutionTime": 0, - "taskDuration": 1070, - "layoutDuration": 0, - "paintDuration": 0 - }, - "p95": { - "fcp": 880, - "lcp": 2160, - "cls": 0.000051238950878504373, - "fid": 0, - "ttfb": 274.09999999403954, - "domContentLoaded": 693.7000000029802, - "loadComplete": 1390.8000000044703, - "totalRequests": 164, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 8, - "jsExecutionTime": 0, - "taskDuration": 1301, - "layoutDuration": 0, - "paintDuration": 0 - }, - "min": { - "fcp": 820, - "lcp": 1576, - "cls": 0.000051238950878504373, - "fid": 0, - "ttfb": 225.70000000298023, - "domContentLoaded": 327, - "loadComplete": 952.8000000044703, - "totalRequests": 164, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 8, - "jsExecutionTime": 0, - "taskDuration": 409, - "layoutDuration": 0, - "paintDuration": 0 - }, - "max": { - "fcp": 880, - "lcp": 2160, - "cls": 0.0000651823758097833, - "fid": 0, - "ttfb": 276.59999999403954, - "domContentLoaded": 693.7000000029802, - "loadComplete": 1390.8000000044703, - "totalRequests": 164, - "totalBytes": 5831575, - "jsBytes": 5740528, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 152, - "cssRequests": 0, - "imageRequests": 8, - "jsExecutionTime": 0, - "taskDuration": 1301, - "layoutDuration": 0, - "paintDuration": 0 - } - }, - { - "page": "Blog Post with Mermaid", - "url": "http://localhost:3000/blog/A_Journey_in_Self_Hosting", - "runs": [ - { - "fcp": 2768, - "lcp": 2768, - "cls": 0.00024232751351815682, - "fid": 0, - "ttfb": 2173.5999999940395, - "domContentLoaded": 2543, - "loadComplete": 4855.5, - "totalRequests": 186, - "totalBytes": 12817938, - "jsBytes": 12726891, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 177, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 1005, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 3548, - "lcp": 3548, - "cls": 0.00016448296440972222, - "fid": 0, - "ttfb": 3000.7000000029802, - "domContentLoaded": 3408.4000000059605, - "loadComplete": 4668, - "totalRequests": 186, - "totalBytes": 12817938, - "jsBytes": 12726891, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 177, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 1076, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 920, - "lcp": 920, - "cls": 0.00005739648450058674, - "fid": 0, - "ttfb": 328.20000000298023, - "domContentLoaded": 719, - "loadComplete": 1139.2000000029802, - "totalRequests": 186, - "totalBytes": 12817938, - "jsBytes": 12726891, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 177, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 1066, - "layoutDuration": 0, - "paintDuration": 0 - } - ], - "average": { - "fcp": 2412, - "lcp": 2412, - "cls": 0.00015473565414282194, - "fid": 0, - "ttfb": 1834.1666666666667, - "domContentLoaded": 2223.4666666686535, - "loadComplete": 3554.2333333343267, - "totalRequests": 186, - "totalBytes": 12817938, - "jsBytes": 12726891, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 177, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 1049, - "layoutDuration": 0, - "paintDuration": 0 - }, - "median": { - "fcp": 2768, - "lcp": 2768, - "cls": 0.00024232751351815682, - "fid": 0, - "ttfb": 2173.5999999940395, - "domContentLoaded": 2543, - "loadComplete": 4855.5, - "totalRequests": 186, - "totalBytes": 12817938, - "jsBytes": 12726891, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 177, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 1005, - "layoutDuration": 0, - "paintDuration": 0 - }, - "p95": { - "fcp": 3548, - "lcp": 3548, - "cls": 0.00016448296440972222, - "fid": 0, - "ttfb": 3000.7000000029802, - "domContentLoaded": 3408.4000000059605, - "loadComplete": 4668, - "totalRequests": 186, - "totalBytes": 12817938, - "jsBytes": 12726891, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 177, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 1076, - "layoutDuration": 0, - "paintDuration": 0 - }, - "min": { - "fcp": 920, - "lcp": 920, - "cls": 0.00005739648450058674, - "fid": 0, - "ttfb": 328.20000000298023, - "domContentLoaded": 719, - "loadComplete": 1139.2000000029802, - "totalRequests": 186, - "totalBytes": 12817938, - "jsBytes": 12726891, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 177, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 1005, - "layoutDuration": 0, - "paintDuration": 0 - }, - "max": { - "fcp": 3548, - "lcp": 3548, - "cls": 0.00024232751351815682, - "fid": 0, - "ttfb": 3000.7000000029802, - "domContentLoaded": 3408.4000000059605, - "loadComplete": 4855.5, - "totalRequests": 186, - "totalBytes": 12817938, - "jsBytes": 12726891, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 177, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 1076, - "layoutDuration": 0, - "paintDuration": 0 - } - }, - { - "page": "Resume", - "url": "http://localhost:3000/resume", - "runs": [ - { - "fcp": 380, - "lcp": 380, - "cls": 0.00014887656694577065, - "fid": 0, - "ttfb": 23.399999998509884, - "domContentLoaded": 328.79999999701977, - "loadComplete": 965.7999999970198, - "totalRequests": 99, - "totalBytes": 4494958, - "jsBytes": 4404249, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 319, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 332, - "lcp": 332, - "cls": 0.0002888629112714603, - "fid": 0, - "ttfb": 19.899999998509884, - "domContentLoaded": 304.29999999701977, - "loadComplete": 606.6999999955297, - "totalRequests": 99, - "totalBytes": 4494958, - "jsBytes": 4404249, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 335, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 92, - "lcp": 92, - "cls": 0.00035258505864398473, - "fid": 0, - "ttfb": 8.199999995529652, - "domContentLoaded": 105.40000000596046, - "loadComplete": 1785.4000000059605, - "totalRequests": 99, - "totalBytes": 4494958, - "jsBytes": 4404249, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 53, - "layoutDuration": 0, - "paintDuration": 0 - } - ], - "average": { - "fcp": 268, - "lcp": 268, - "cls": 0.00026344151228707187, - "fid": 0, - "ttfb": 17.16666666418314, - "domContentLoaded": 246.16666666666666, - "loadComplete": 1119.2999999995034, - "totalRequests": 99, - "totalBytes": 4494958, - "jsBytes": 4404249, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 235.66666666666666, - "layoutDuration": 0, - "paintDuration": 0 - }, - "median": { - "fcp": 332, - "lcp": 332, - "cls": 0.0002888629112714603, - "fid": 0, - "ttfb": 19.899999998509884, - "domContentLoaded": 304.29999999701977, - "loadComplete": 606.6999999955297, - "totalRequests": 99, - "totalBytes": 4494958, - "jsBytes": 4404249, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 335, - "layoutDuration": 0, - "paintDuration": 0 - }, - "p95": { - "fcp": 380, - "lcp": 380, - "cls": 0.00014887656694577065, - "fid": 0, - "ttfb": 23.399999998509884, - "domContentLoaded": 328.79999999701977, - "loadComplete": 965.7999999970198, - "totalRequests": 99, - "totalBytes": 4494958, - "jsBytes": 4404249, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 319, - "layoutDuration": 0, - "paintDuration": 0 - }, - "min": { - "fcp": 92, - "lcp": 92, - "cls": 0.00014887656694577065, - "fid": 0, - "ttfb": 8.199999995529652, - "domContentLoaded": 105.40000000596046, - "loadComplete": 606.6999999955297, - "totalRequests": 99, - "totalBytes": 4494958, - "jsBytes": 4404249, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 53, - "layoutDuration": 0, - "paintDuration": 0 - }, - "max": { - "fcp": 380, - "lcp": 380, - "cls": 0.00035258505864398473, - "fid": 0, - "ttfb": 23.399999998509884, - "domContentLoaded": 328.79999999701977, - "loadComplete": 1785.4000000059605, - "totalRequests": 99, - "totalBytes": 4494958, - "jsBytes": 4404249, - "cssBytes": 0, - "imageBytes": 0, - "fontBytes": 0, - "jsRequests": 91, - "cssRequests": 0, - "imageRequests": 5, - "jsExecutionTime": 0, - "taskDuration": 335, - "layoutDuration": 0, - "paintDuration": 0 - } - }, - { - "page": "Contact", - "url": "http://localhost:3000/contact", - "runs": [ - { - "fcp": 624, - "lcp": 624, - "cls": 0.00034250432081183314, - "fid": 0, - "ttfb": 25.899999998509884, - "domContentLoaded": 362.09999999403954, - "loadComplete": 4668.79999999702, - "totalRequests": 104, - "totalBytes": 5229913, - "jsBytes": 4478159, - "cssBytes": 0, - "imageBytes": 660146, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 6, - "jsExecutionTime": 0, - "taskDuration": 387, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 824, - "lcp": 824, - "cls": 0.00020064100414637185, - "fid": 0, - "ttfb": 44.600000001490116, - "domContentLoaded": 482.20000000298023, - "loadComplete": 1250.5, - "totalRequests": 104, - "totalBytes": 5229913, - "jsBytes": 4478159, - "cssBytes": 0, - "imageBytes": 660146, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 6, - "jsExecutionTime": 0, - "taskDuration": 389, - "layoutDuration": 0, - "paintDuration": 0 - }, - { - "fcp": 540, - "lcp": 540, - "cls": 0.00018063759509428048, - "fid": 0, - "ttfb": 28.19999999552965, - "domContentLoaded": 330.09999999403954, - "loadComplete": 1055.5999999940395, - "totalRequests": 104, - "totalBytes": 5229913, - "jsBytes": 4478159, - "cssBytes": 0, - "imageBytes": 660146, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 6, - "jsExecutionTime": 0, - "taskDuration": 349, - "layoutDuration": 0, - "paintDuration": 0 - } - ], - "average": { - "fcp": 662.6666666666666, - "lcp": 662.6666666666666, - "cls": 0.0002412609733508285, - "fid": 0, - "ttfb": 32.899999998509884, - "domContentLoaded": 391.46666666368645, - "loadComplete": 2324.9666666636863, - "totalRequests": 104, - "totalBytes": 5229913, - "jsBytes": 4478159, - "cssBytes": 0, - "imageBytes": 660146, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 6, - "jsExecutionTime": 0, - "taskDuration": 375, - "layoutDuration": 0, - "paintDuration": 0 - }, - "median": { - "fcp": 624, - "lcp": 624, - "cls": 0.00034250432081183314, - "fid": 0, - "ttfb": 25.899999998509884, - "domContentLoaded": 362.09999999403954, - "loadComplete": 4668.79999999702, - "totalRequests": 104, - "totalBytes": 5229913, - "jsBytes": 4478159, - "cssBytes": 0, - "imageBytes": 660146, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 6, - "jsExecutionTime": 0, - "taskDuration": 387, - "layoutDuration": 0, - "paintDuration": 0 - }, - "p95": { - "fcp": 824, - "lcp": 824, - "cls": 0.00020064100414637185, - "fid": 0, - "ttfb": 44.600000001490116, - "domContentLoaded": 482.20000000298023, - "loadComplete": 1250.5, - "totalRequests": 104, - "totalBytes": 5229913, - "jsBytes": 4478159, - "cssBytes": 0, - "imageBytes": 660146, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 6, - "jsExecutionTime": 0, - "taskDuration": 389, - "layoutDuration": 0, - "paintDuration": 0 - }, - "min": { - "fcp": 540, - "lcp": 540, - "cls": 0.00018063759509428048, - "fid": 0, - "ttfb": 25.899999998509884, - "domContentLoaded": 330.09999999403954, - "loadComplete": 1055.5999999940395, - "totalRequests": 104, - "totalBytes": 5229913, - "jsBytes": 4478159, - "cssBytes": 0, - "imageBytes": 660146, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 6, - "jsExecutionTime": 0, - "taskDuration": 349, - "layoutDuration": 0, - "paintDuration": 0 - }, - "max": { - "fcp": 824, - "lcp": 824, - "cls": 0.00034250432081183314, - "fid": 0, - "ttfb": 44.600000001490116, - "domContentLoaded": 482.20000000298023, - "loadComplete": 4668.79999999702, - "totalRequests": 104, - "totalBytes": 5229913, - "jsBytes": 4478159, - "cssBytes": 0, - "imageBytes": 660146, - "fontBytes": 0, - "jsRequests": 95, - "cssRequests": 0, - "imageRequests": 6, - "jsExecutionTime": 0, - "taskDuration": 389, - "layoutDuration": 0, - "paintDuration": 0 - } - } - ] -} \ No newline at end of file diff --git a/src/components/Bars.tsx b/src/components/Bars.tsx index 5e1ac2a..2de7161 100644 --- a/src/components/Bars.tsx +++ b/src/components/Bars.tsx @@ -265,47 +265,60 @@ export function LeftBar() { const glitchChars = "!@#$%^&*()_+-=[]{}|;':\",./<>?~`"; const originalText = "What's this?"; let glitchInterval: NodeJS.Timeout; + let animationFrame: number; setTimeout(() => { setGetLostVisible(true); let currentIndex = 0; - const typeInterval = setInterval(() => { - if (currentIndex <= originalText.length) { - let displayText = originalText.substring(0, currentIndex); - if (currentIndex < originalText.length) { - const remaining = originalText.length - currentIndex; - for (let i = 0; i < remaining; i++) { - displayText += - glitchChars[Math.floor(Math.random() * glitchChars.length)]; - } - } - setGetLostText(displayText); - currentIndex++; - } else { - clearInterval(typeInterval); - setGetLostText(originalText); + let lastUpdate = 0; + const updateInterval = 80; // ms between updates - glitchInterval = setInterval(() => { - if (Math.random() > 0.9) { - let glitched = ""; - for (let i = 0; i < originalText.length; i++) { - if (Math.random() > 0.7) { - glitched += - glitchChars[Math.floor(Math.random() * glitchChars.length)]; - } else { - glitched += originalText[i]; - } + const revealAnimation = (timestamp: number) => { + if (timestamp - lastUpdate >= updateInterval) { + if (currentIndex <= originalText.length) { + let displayText = originalText.substring(0, currentIndex); + if (currentIndex < originalText.length) { + const remaining = originalText.length - currentIndex; + for (let i = 0; i < remaining; i++) { + displayText += + glitchChars[Math.floor(Math.random() * glitchChars.length)]; } - setGetLostText(glitched); - - setTimeout(() => { - setGetLostText(originalText); - }, 100); } - }, 150); + setGetLostText(displayText); + currentIndex++; + lastUpdate = timestamp; + } else { + setGetLostText(originalText); + + // Occasional glitch effect after reveal + glitchInterval = setInterval(() => { + if (Math.random() > 0.92) { + let glitched = ""; + for (let i = 0; i < originalText.length; i++) { + if (Math.random() > 0.75) { + glitched += + glitchChars[ + Math.floor(Math.random() * glitchChars.length) + ]; + } else { + glitched += originalText[i]; + } + } + setGetLostText(glitched); + + setTimeout(() => { + setGetLostText(originalText); + }, 80); + } + }, 200); + return; + } } - }, 140); + animationFrame = requestAnimationFrame(revealAnimation); + }; + + animationFrame = requestAnimationFrame(revealAnimation); }, 500); if (ref) { @@ -345,11 +358,13 @@ export function LeftBar() { onCleanup(() => { ref?.removeEventListener("keydown", handleKeyDown); clearInterval(glitchInterval); + if (animationFrame) cancelAnimationFrame(animationFrame); window.removeEventListener("resize", handleResize); }); } else { onCleanup(() => { clearInterval(glitchInterval); + if (animationFrame) cancelAnimationFrame(animationFrame); window.removeEventListener("resize", handleResize); }); } @@ -586,7 +601,8 @@ export function LeftBar() { navigate(randomUrl); handleLinkClick(); }} - class="text-left font-mono" + class="text-left font-mono transition-opacity duration-75" + style={{ "will-change": "contents" }} > {getLostText()} diff --git a/src/components/blog/Card.tsx b/src/components/blog/Card.tsx index 71e1a70..4665eaf 100644 --- a/src/components/blog/Card.tsx +++ b/src/components/blog/Card.tsx @@ -1,12 +1,14 @@ -import { Show } from "solid-js"; +import { Show, lazy } from "solid-js"; import CardLinks from "./CardLinks"; -import DeletePostButton from "./DeletePostButton"; import { Fire } from "~/components/icons/Fire"; -import { Post } from "~/db/types"; +import { PostCardData } from "~/db/types"; + +const DeletePostButton = lazy(() => import("./DeletePostButton")); export interface CardProps { - post: Post; + post: PostCardData; privilegeLevel: "anonymous" | "admin" | "user"; + index?: number; } export default function Card(props: CardProps) { @@ -27,6 +29,12 @@ export default function Card(props: CardProps) { {props.post.title.replaceAll("_",
diff --git a/src/components/blog/PostSorting.tsx b/src/components/blog/PostSorting.tsx index ff744d5..68f07b4 100644 --- a/src/components/blog/PostSorting.tsx +++ b/src/components/blog/PostSorting.tsx @@ -1,6 +1,6 @@ import { For, Show, createMemo } from "solid-js"; import Card from "./Card"; -import { Post } from "~/db/types"; +import { PostCardData } from "~/db/types"; export interface Tag { value: string; @@ -8,7 +8,7 @@ export interface Tag { } export interface PostSortingProps { - posts: Post[]; + posts: PostCardData[]; tags: Tag[]; privilegeLevel: "anonymous" | "admin" | "user"; filters?: string; @@ -133,9 +133,13 @@ export default function PostSorting(props: PostSortingProps) { } > - {(post) => ( + {(post, index) => (
- +
)}
diff --git a/src/db/create.ts b/src/db/create.ts index 9d56c74..29dba25 100644 --- a/src/db/create.ts +++ b/src/db/create.ts @@ -63,6 +63,9 @@ export const model: { [key: string]: string } = { last_edited_date TEXT ); CREATE INDEX IF NOT EXISTS idx_posts_category ON Post (category); + CREATE INDEX IF NOT EXISTS idx_posts_published ON Post (published); + CREATE INDEX IF NOT EXISTS idx_posts_date ON Post (date); + CREATE INDEX IF NOT EXISTS idx_posts_published_date ON Post (published, date); `, PostLike: ` CREATE TABLE PostLike @@ -72,6 +75,7 @@ export const model: { [key: string]: string } = { post_id INTEGER NOT NULL ); CREATE UNIQUE INDEX IF NOT EXISTS idx_likes_user_post ON PostLike (user_id, post_id); + CREATE INDEX IF NOT EXISTS idx_likes_post_id ON PostLike (post_id); `, Comment: ` CREATE TABLE Comment diff --git a/src/db/types.ts b/src/db/types.ts index 5e909cf..b76ff76 100644 --- a/src/db/types.ts +++ b/src/db/types.ts @@ -105,6 +105,21 @@ export interface PostWithCommentsAndLikes { total_comments: number; last_edited_date?: string | null; } + +export interface PostCardData { + id: number; + category: "blog" | "project"; + title: string; + subtitle: string; + banner_photo: string; + date?: string | null; + published: number; + author_id: string; + reads: number; + attachments: string; + total_likes: number; + total_comments: number; +} export interface PostWithTags { id: number; category: "blog" | "project"; // this is no longer used diff --git a/src/routes/blog/index.tsx b/src/routes/blog/index.tsx index d054556..c04eedd 100644 --- a/src/routes/blog/index.tsx +++ b/src/routes/blog/index.tsx @@ -1,4 +1,4 @@ -import { Show } from "solid-js"; +import { Show, createSignal, onMount, lazy } from "solid-js"; import { useSearchParams, A, query } from "@solidjs/router"; import { Title } from "@solidjs/meta"; import { createAsync } from "@solidjs/router"; @@ -6,11 +6,15 @@ import { getRequestEvent } from "solid-js/web"; import PostSortingSelect from "~/components/blog/PostSortingSelect"; import TagSelector from "~/components/blog/TagSelector"; import PostSorting from "~/components/blog/PostSorting"; -import PublishStatusToggle from "~/components/blog/PublishStatusToggle"; import { TerminalSplash } from "~/components/TerminalSplash"; import { CACHE_CONFIG } from "~/config"; -const getPosts = query(async () => { +const PublishStatusToggle = lazy(() => import("~/components/blog/PublishStatusToggle")); + +const POSTS_PER_PAGE = 12; + +// Separate query for all tags (needed for TagSelector) +const getAllTags = query(async () => { "use server"; const { ConnectionFactory, getPrivilegeLevel } = await import("~/server/utils"); @@ -19,17 +23,61 @@ const getPosts = query(async () => { const privilegeLevel = await getPrivilegeLevel(event.nativeEvent); return withCache( - `posts-${privilegeLevel}`, + `all-tags-${privilegeLevel}`, CACHE_CONFIG.BLOG_POSTS_LIST_CACHE_TTL_MS, async () => { const conn = ConnectionFactory(); + const tagsQuery = ` + SELECT t.value, t.post_id + FROM Tag t + JOIN Post p ON t.post_id = p.id + ${privilegeLevel !== "admin" ? "WHERE p.published = TRUE" : ""} + ORDER BY t.value ASC + `; + + const tagsResult = await conn.execute(tagsQuery); + const tags = tagsResult.rows; + + const tagMap: Record = {}; + tags.forEach((tag: any) => { + const key = `${tag.value}`; + tagMap[key] = (tagMap[key] || 0) + 1; + }); + + return { tagMap, privilegeLevel }; + } + ); +}, "all-tags"); + +const getPosts = query(async (page: number = 1) => { + "use server"; + const { ConnectionFactory, getPrivilegeLevel } = + await import("~/server/utils"); + const { withCache } = await import("~/server/cache"); + const event = getRequestEvent()!; + const privilegeLevel = await getPrivilegeLevel(event.nativeEvent); + + return withCache( + `posts-${privilegeLevel}-page-${page}`, + CACHE_CONFIG.BLOG_POSTS_LIST_CACHE_TTL_MS, + async () => { + const conn = ConnectionFactory(); + const offset = (page - 1) * POSTS_PER_PAGE; + + // Get total count first + let countQuery = `SELECT COUNT(*) as total FROM Post p`; + if (privilegeLevel !== "admin") { + countQuery += ` WHERE p.published = TRUE`; + } + const countResult = await conn.execute(countQuery); + const totalPosts = (countResult.rows[0] as any).total; + let postsQuery = ` SELECT p.id, p.title, p.subtitle, - p.body, p.banner_photo, p.date, p.published, @@ -48,96 +96,185 @@ const getPosts = query(async () => { postsQuery += ` WHERE p.published = TRUE`; } - postsQuery += ` GROUP BY p.id, p.title, p.subtitle, p.body, p.banner_photo, p.date, p.published, p.category, p.author_id, p.reads, p.attachments`; - postsQuery += ` ORDER BY p.date ASC;`; + postsQuery += ` GROUP BY p.id, p.title, p.subtitle, p.banner_photo, p.date, p.published, p.category, p.author_id, p.reads, p.attachments`; + postsQuery += ` ORDER BY p.date ASC`; + postsQuery += ` LIMIT ${POSTS_PER_PAGE} OFFSET ${offset};`; const postsResult = await conn.execute(postsQuery); const posts = postsResult.rows; - const tagsQuery = ` + // Only fetch tags for the posts we're returning + const postIds = posts.map((p: any) => p.id).join(","); + const tagsQuery = postIds + ? ` SELECT t.value, t.post_id FROM Tag t - JOIN Post p ON t.post_id = p.id - ${privilegeLevel !== "admin" ? "WHERE p.published = TRUE" : ""} + WHERE t.post_id IN (${postIds}) ORDER BY t.value ASC - `; + ` + : `SELECT t.value, t.post_id FROM Tag t WHERE 1=0`; const tagsResult = await conn.execute(tagsQuery); const tags = tagsResult.rows; - const tagMap: Record = {}; - tags.forEach((tag: any) => { - const key = `${tag.value}`; - tagMap[key] = (tagMap[key] || 0) + 1; - }); - - return { posts, tags, tagMap, privilegeLevel }; + return { + posts, + tags, + hasMore: offset + posts.length < totalPosts, + totalPosts + }; } ); }, "posts"); export default function BlogIndex() { const [searchParams] = useSearchParams(); + const [currentPage, setCurrentPage] = createSignal(1); + const [allPosts, setAllPosts] = createSignal([]); + const [allTags, setAllTags] = createSignal([]); + const [hasMore, setHasMore] = createSignal(true); + const [isLoading, setIsLoading] = createSignal(false); + let sentinelRef: HTMLDivElement | undefined; - const sort = () => searchParams.sort || "newest"; - const filters = () => - "filter" in searchParams ? searchParams.filter : undefined; - const include = () => - "include" in searchParams ? searchParams.include : undefined; - const status = () => - "status" in searchParams ? searchParams.status : undefined; + const sort = () => { + const sortParam = searchParams.sort; + return Array.isArray(sortParam) ? sortParam[0] : sortParam || "newest"; + }; + const filters = () => { + const filterParam = searchParams.filter; + return filterParam + ? Array.isArray(filterParam) + ? filterParam[0] + : filterParam + : undefined; + }; + const include = () => { + const includeParam = searchParams.include; + return includeParam + ? Array.isArray(includeParam) + ? includeParam[0] + : includeParam + : undefined; + }; + const status = () => { + const statusParam = searchParams.status; + return statusParam + ? Array.isArray(statusParam) + ? statusParam[0] + : statusParam + : undefined; + }; - const data = createAsync(() => getPosts(), { deferStream: true }); + // Load initial page and tag data + const initialData = createAsync(() => getPosts(1), { deferStream: true }); + const tagsData = createAsync(() => getAllTags(), { deferStream: true }); + + // Initialize with first page data + const initializeData = () => { + const firstPage = initialData(); + if (firstPage) { + setAllPosts(firstPage.posts); + setAllTags(firstPage.tags); + setHasMore(firstPage.hasMore); + } + }; + + // Load more posts + const loadMorePosts = async () => { + if (isLoading() || !hasMore()) return; + + setIsLoading(true); + const nextPage = currentPage() + 1; + + try { + const newData = await getPosts(nextPage); + setAllPosts((prev) => [...prev, ...newData.posts]); + setAllTags((prev) => [...prev, ...newData.tags]); + setHasMore(newData.hasMore); + setCurrentPage(nextPage); + } catch (error) { + console.error("Error loading more posts:", error); + } finally { + setIsLoading(false); + } + }; + + // Set up IntersectionObserver for infinite scroll + onMount(() => { + initializeData(); + + const observer = new IntersectionObserver( + (entries) => { + if (entries[0]?.isIntersecting) { + loadMorePosts(); + } + }, + { rootMargin: "200px" } + ); + + if (sentinelRef) { + observer.observe(sentinelRef); + } + + return () => observer.disconnect(); + }); return ( <> Blog | Michael Freno
- }> - {(loadedData) => ( - <> -
- + }> +
+ - 0}> - - + 0} + > + + - - - + + + - - - + + + +
- 0} - fallback={
No posts yet!
} - > -
- + 0} + fallback={
No posts yet!
} + > +
+ + + {/* Sentinel element for infinite scroll */} + +
+ +
Loading more posts...
+
- - )} +
+
diff --git a/src/routes/index.tsx b/src/routes/index.tsx index bf695b0..443799b 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -65,6 +65,8 @@ export default function Home() {
@@ -137,6 +147,8 @@ export default function Home() { Life and Lineage Shops