From a6d5442af80dbc8be7e4b78ee883e993466c7a43 Mon Sep 17 00:00:00 2001 From: Jimmy Guzman <30631540+jimmy-guzman@users.noreply.github.com> Date: Wed, 21 Aug 2024 20:01:57 -0500 Subject: [PATCH] =?UTF-8?q?feat:=20=E2=9C=A8=20add=20`turbo`=20for=20cachi?= =?UTF-8?q?ng=20and=20task=20parallelization=20(#105)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/preview.yml | 5 ++- .github/workflows/pull_request.yml | 24 ++++---------- .gitignore | 3 ++ .vscode/settings.json | 1 + README.md | 44 +++++++++++++++---------- bun.lockb | Bin 564782 -> 567393 bytes package.json | 2 ++ turbo.json | 51 +++++++++++++++++++++++++++++ 8 files changed, 94 insertions(+), 36 deletions(-) create mode 100644 turbo.json diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 4de9931..8c9c47c 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -6,6 +6,9 @@ jobs: e2e: if: github.event.deployment_status.state == 'success' runs-on: ubuntu-latest + env: + TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} + TURBO_TEAM: ${{ vars.TURBO_TEAM }} steps: - name: 🏗 Setup Repository @@ -18,6 +21,6 @@ jobs: run: bunx playwright install --with-deps - name: ✅ e2e - run: bun run e2e + run: bun turbo e2e env: BASE_URL: ${{ github.event.deployment_status.environment_url }} diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index a33ed9c..951dd87 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -3,8 +3,11 @@ name: pull_request on: [pull_request] jobs: - validate: + check: runs-on: ubuntu-latest + env: + TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} + TURBO_TEAM: ${{ vars.TURBO_TEAM }} steps: - name: 🏗 Setup Repository @@ -13,20 +16,5 @@ jobs: - name: 📦 Install uses: ./.github/actions/install - - name: 🚨 Lint - run: bun run lint - - - name: 🎨 Format - run: bun run format - - - name: 🏷️ Check Types - run: bun run typecheck - - - name: ✅ Test - run: bun run coverage - - - name: 🧱 Build - run: bun run build - - - name: 🧱 Stories Build - run: bun run sb:build + - name: 🚨 Check + run: bun check diff --git a/.gitignore b/.gitignore index 1191814..78dfc96 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ storybook-static # env .env* + +# turbo +.turbo diff --git a/.vscode/settings.json b/.vscode/settings.json index 41860e2..07d8648 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -15,6 +15,7 @@ "tailwindcss", "tanstack", "tiged", + "turborepo", "typecheck", "vite", "vitest", diff --git a/README.md b/README.md index 2ed822b..cc21853 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ - 🩺 [eslint][eslint] for static analysis. - 🎨 [prettier][prettier] for formatting. - 🩺 [lefthook][lefthook] for fast Git hooks management. +- 👷 [Turborepo](https://turbo.build/repo/docs) for caching and task parallelization. - 👷 [GitHub Actions][GitHub Actions] for easy workflow automation. ## 🛠️ Usage @@ -45,7 +46,7 @@ bun install Or if you already have `bun` installed you upgrade, by running the following command: ``` - bun upgrade --stable +bun upgrade --stable ``` And to download new browsers for Playwright, run the following command: @@ -54,31 +55,40 @@ And to download new browsers for Playwright, run the following command: bunx playwright install ``` +And install Turborepo, run the following command: + +``` +bun install --global turbo +``` + Then to run the development server, run the following command: ``` -bun dev +turbo dev ``` Your application will be available at http://localhost:5173/ ❤️ ## 🧞 Available Tasks -| Command | Action | -| :------------------- | :------------------------------------------------------- | -| `bun install` | Installs dependencies | -| `bun run dev` | Starts local dev server at http://localhost:5173/ | -| `bun run build` | Build your production site to `./dist/` | -| `bun run preview` | Preview your build locally, before deploying | -| `bun run test` | Unit tests your code with vitest | -| `bun run e2e` | E2E tests your code with playwright | -| `bun run lint` | Lints everything with eslint | -| `bun run lint:fix` | Fixes lint errors with eslint | -| `bun run format` | Checks formatting with prettier | -| `bun run format:fix` | Fixes formatting errors with prettier | -| `bun run typecheck` | Checks types with TypeScript | -| `bun run sb` | Starts storybook at http://localhost:6006 | -| `bun run sb:build` | Build your production storybook to `./storybook-static/` | +| Command | Action | +| :----------------- | :------------------------------------------------------- | +| `bun install` | Installs dependencies | +| `turbo dev` | Starts local dev server at http://localhost:5173/ | +| `turbo build` | Build your production site to `./dist/` | +| `turbo preview` | Preview your build locally, before deploying | +| `turbo test` | Unit tests your code with vitest | +| `turbo e2e` | E2E tests your code with playwright | +| `turbo lint` | Lints everything with eslint | +| `turbo lint:fix` | Fixes lint errors with eslint | +| `turbo format` | Checks formatting with prettier | +| `turbo format:fix` | Fixes formatting errors with prettier | +| `turbo typecheck` | Checks types with TypeScript | +| `turbo sb` | Starts storybook at http://localhost:6006 | +| `turbo sb:build` | Build your production storybook to `./storybook-static/` | +| `turbo check` | Checks everything | + +_You can also run all tasks with `bun run`, i.e `bun run dev`_ ## 💡 Recommendations diff --git a/bun.lockb b/bun.lockb index adcf3854313163805701a9ea714e93744898866a..2a4066431f4215e3dc3669193379309acb0abffc 100755 GIT binary patch delta 109005 zcmeFad7RDV|Nno^;V>u3(qbnqA`PLOF=LKY%7{t{lgMD0Va70H8B@~?TBs>3k z2t_I_jHc3x()unW?F*H($Ml~1-5;;(I-0kidcWVF&*ygg{^Q(c=J9;quYGx4*Y$dx zS9<8F6Fz?9gj?IS`L@Tt{!5q7KjY11 z2?2d#a|W~sz0~fJ!k*PjCQQs9mIwQweIRgjAW-@$S|44H)!Np|b{FmZT(MnPtvVW&Xg82oYB`56;33j(=Ceo=v6;fgmQD|2l2$SHvjo&ObDI}j)- zt%;$6M&;xUQtifv<|39<>!&;oUIO!}~?97g;SD++ zqcXAMyjxG(Nh31~CX6S2e&)mizm93Pfg4bbR_$JP)Z6>+4kU5=Ug`e@;4ed_iXJq|E$4z|GF18Ht>n?1Bk_art?<<0cdYYW4L_P3YXC!zH$Z zo1w~=8s&_kyt^*7^=0%EN9JUVszdlugjYk=-u-=T|9#O9?&Vf%;ys&?P`_?}+Y6bf zVn5m6doQ8+2{{97WpgqoWsW8D_o$>sb#uDyj4S$hjU%l}2930r_9%i?M*S@7e@7Rc zfd3BK1no^cU11u?jGTf%)O0QCH^JPKaM2 z2VZH;2-g*pN5(DD02#|4ZLfepdwey!E~-mud!DU8IocGz!{s(ze94H9NiAm9k%5vx zX(&GsIF5*1P#HNHBQk#`pf>);s7B`B@Byhm2ztKeHu6?h%0>$C}~2E0i*C!_bFCG9Y-#!vwRTtGXt z4gL}6N$5AjZNiUA1A&hC&*Gnk&PQ9JlhG5=UDIrjTs+r1)E&Z<+kGbBCRS#4dHbPZE%XC|@3N`^v#(hjWWwez4dBAkH!kr4=-fxeHPh(3n4Mi-JmI>+%VQMIHk zs`%eu5eRfZYvCV{emT@uO96_;)zs(g+`Q_-zl1u?}(S!znx zF|_rx)jxcnoxMu|n#EdF1AOwcbMrGs1_JRTz}6*h9T+=2Q{j{IGsbC^KKKZ5%>8z@ zXOA73lRYYH!mFfHzWJHM*-iq12?aUXjCSCtWs1l3pII=DvN8f;K!k`KFEaCqsEbks zZC!3xu(TESvRZ^H!%=zTMku_&19rX0LzRAHT=Vi1Gc$%~o%EoMKahMBz6@ViMbnjm zK*JJ@1dLuqcew3xSZk|;%|N2USn52 zVW;Xd_~JbYS1l$zX|J)mYdHzvYv6}X2?XB7SF;OpG77TPbz1;_dq<7U%V#b;y4E|j zZs*W#W!|v5orhgoW_x8s=E#W}o{@X8u^6sSz1_vX zu8)^ruhk{*zi21HE2zeBJz5uCg(~{pPH#h1%=M_|KtbkMf6^69$e1vZ9k9sp-Y34vJ_GhQLnG>?|Mic}xh7Zrw0qV;)Y`o!ld1JCOIiY3b zGeek9FWBz$N`udq?0(+%VMlUOsV8o?rR{M1D|}sm1KzXYJy1=+kKrnO1A06K5&l%|ztcvHpREo)Q~h}qvjzQCy!hGc;4@eJ zC=@?q*`pFmTKw=8&oG|w-<_2XKEfP)bcr8z?Ahu6e?;<+Hd@l+XQcR%rs|QS9pV4! ziQ}(M8V8>!I7#^1nGO;qO)22togm^Thl5WH@smRQgb+U%{1*p;68}VS@JZmWP5?cJ z+KoTH;s3WAeSCwD_dw$->Hm}IfrEGY_{JXJ&=20Y|7xRd@u5ADT*2(t)fAtM@j3Rd zlaE{1l7V)~iqFo!nso7u;&%}7$r``oh#&a>>dqoQspI9u5Bw$Z6MuY`#t-;$|KNlD ze|q50EtsseCNPEjM=fLz9U1i3b*_m4EQG3wA&!*jAHW)l#B= z?;_7QjX$lprGC&K!;#seCbA<0uE*DkSA=SJiC1(qzA6%5K`+ABinodajz>>C*2a(T zsd@OyCwLqc)%E`)fQ7wu+{Cd{hI1SlSCFF~3e<(G=5xqMHJ*$%M&s)_+cFD&-k2JV zY)^gHFz6qN-bdAQFFF5F=ilZ08&Oqo5_*&(4#!YI7dG_1YSg?W*vyW|-ljHQ=GX~5 zo5(B}l|7+o3iXOVvB(@deqwfhX8z61ZAZm-_mv_0{3VmaYahzKJxIashm{&>8t(3hxs{y9`v?dXC;|M3k|Y+OcuLFQv{b>xGn zdN_Xj9UrL$a234kWLu&5sd-H1lu7FF+ghn1{Wz88WK5WlIU;Z~2{bn|3&u~(Wb>SL zicP3fa3(wI6vEYUHCx*PGlu8ot4X-S1Z{ho9q^;^HRY?Js(0-~o9#%a>8PgqPpI1aRSVm1ucFHD8dTL7i8f?AE{)eK z-j4G2-VsgPmBi18wL02?Tz`7dzdu^q-cMJ09eO$(kqC5L=~qc!QL`^f{z$d;zv?_Yei=?LKy@$D5!Jjs7Hx+9vxoIRLzT@IRO9`) z^B1GK{tT*dz6n*o45GcN-$kyUcz~(H;)#I|d)YND9?*jbO8DLdwqnhDd!ZJsN|yGq z^CF)+stH^`jk?&~=q|YW{{~d|O2w#>ce}{y5f{4)6BQrklzXLuOfFm-1Df)q^74l1X>Jj|mYxSk+7TI! zuL{JU$xj|-M|>1o*ZaI>+vI~MYyHu74DLWRM{@Ee>Mkp=A=}Oc#)2g!5STs2>vclA zVH>k-3n%8<=-nt#b8}L*Rt}zwjJ3%+)Si4a z)Jw;E@14Mt-^c6?ZHs(6!VAXR856(6Zo}85HPdN{3y<#zA27W%v-04|b}*^|ITuy` zwL>*<4V_j))r^a%CjB?4^xr*ih~J63wJd+*WZRB4s4`mQ^x!Gkb*%T^iPw}INjawz zE#7S}m)dSEO0Y}ydVF&qmb_wtjzMhj^<%O&FMDYd{o_ew9|2UJloI8 z9I=md>fWzW^~YN_A8+ePElbY4!S+Q{r`1ti)!$ri^(|D}W;v=Roi)?e3XA$ z*B({gC!(tJTEex=&vfzQ{9b(Z`Ryom9bVcNLmB^gvkmwRRb}5mwTd(+Tp7og-~8FO z;6zl*#}X>0!JL6=Sr~_^0TU-?`|H8iw|MWJ+`MG>tu}h@9GiV1)6|cipE-eZR({*t z?4ocSs_JaH-S%a{#F0F185JmKH$0DxHSiQ%SI7|3t6y$4)_2=|X*qNFB=}2Qr0R!{ z>~2v~`d9mVEh4J^Uz5@C=+^mmAG-lxle>6sLg z2A0~Ha>)`K?<`bToBz~NNA5NNElc&C23&+M?z0JBLp5^iPz}KYs0y5is>^RdHRACN zs{~(DumDw$#J`fvcJVGnHPyPJB`P=(Lm4(fRkIqX3i|$Ds~@Av@Fi4T$PGwd&ZNx1 zAbL(y@It3uQKfH(>UwMG`1ptHlzj))+`na!4gY;nu*3(OR@;Q9JZx(=2USLaM{LjR z#aBy5ZzMD=w6+EfTYL^lR4nD-k z56363w?h!Wyb7j_9X^ImMv@oYucVX6WtP>hHc}MUSh^z?)jlzx(yYyB2M))AjY|J_>JH zQ`oNb{P3Xme2wE3-3Ja+|f&(6bqf!$tyyNJ9%Z3Vv#kS>=#iXZ^P(lD0GIGJUJHWeFhIuX+$+|YQJb? z8eR-9=uORzMxMnx8?U;z;W84O=_MD&LRXyW6(R4O>6IbvI(rp`vB*fWNFnACUNAix zS&WyA7xAX{k4C=2I}b19O&t`C#G>49;88+)G&C*hB^Sj)+oN7lQ7qCV$)-y%-ER&i zB{;997aSdpoYW-{=t{a8elDY(7nT>gzl&FPRVf@tl4Xk-;bg`UPnp^AzZ0(qULC(*_q&*WgCb{A5oR|rH%v}Sz_}Qw zy5EtHF7G z$W3@kXQ$hX&LbBl!x87(@BiqJ@zF>M9&=hf&_5c!3a_hIepyQ7Ni5ZouB2yvKHsaD z5er?^(@UNii%e(S73NQw(1xB~+00nz=rpf_u=CPvessbV>W@b?)d?>rRmVBYs~ngT zY0B)NP7K0^tD@D0^$M7jV}r3^FR$pPSon1UyL!a~QX;i3un#z^dEF;RBYmA0@`5v? zk(vJzwgFGAw=F!bx1E2)q@RZ3arLR!Zi+_c;X6S@IUd60fB*=`g zov!35cpYtWI&V6j#@`Ozc04z%qod(A7m?1Z?3WT6evwynODwVoU`y6T|1KW!Ny-8g z=|DP-Wlg_rnRqI)hJStEjc3P1>E3Z($m`B{9oyH=kDxz4`r^6Du{e2nwmh!8$SZj5 z$TMuFwhSg!zl1!!;z22qd@RMXBlG~Ca{;+OKtN4{=6BDr#MkAB( z)MmR3t;ACu{qYQchIg7*JSHX7qQ94XXDm{{%BaHa%KjXlosL?U0t4bnnSi0B0ba6+ zg(m_#d#U46LJtn`%1kWsIY5nJ9G4{p2YShKW1$`CUeVlG_{mH%@QUZAM2be*G2$BF z>U#)JNtnx5MMEEr^or)iBF#p{J7vT4X!s($-u|++04rIUgiqqzJ)ecfWqD=uW1+2C zUd8-axP7*+24aN1&Gw2G#KI|~{do_VJld;R5DR@i+DpDG7V196E4nKdo;M~QfBP7( z;;vXEF(+Oh=0&I=$17SGi#!SZbIR?-WA@NbT1>j-#ygyT3Ki#iMT=tLXMkL7H>HGs z!#dlmoSza-9n1HTUiti#(7j{5qPt_^J%Em0YQL0li#+o1Ydtv6OTH%-{s}P9OT8;4 z)O(y)23R&O5E$VV-<=X^Fy2n;us`AZ;%R{W=^wgbyjQk37HXL9RV*x(a;AIy|N{-@JW-{SN-}HP4beL#zOB;@`{$mTKAnC2wbVie1iPe zkijPgKN^13l5V||y%E=#kIoA=N&u=YOivcgU?E?3dX*1$t&TCpE59ct(t}%;vxvaD z!di7y5fNSM zAL9+jJHqeVbBhlw3ge^UQoJE*V)z5B953~rlyI+Wl)0>pSmS&vsU#k{1Z#rN8kVYZ ziZ>05T(Ig-4FspAH9bj|Mzg9Uh z#X=`s=M}Arh3>u1D_a!{-*7!o9W>#>pJ0(Mb-(xql~s(j8OzoGvL4{DC#uD_)%vo^)fpF&|+uM1=OgDGLtn(QS#-JCOMZlzdvhQ# z!;jQ{Rv<9dkMuB>E%CV7fxwM^&F;bSTO3Zfg=aqgRbJ#<>aB0EY-qn*{eFYJhjpW$ z^N2Ztz_niLBTQqgVSZbB-R4gSD)$)HaKGFJp2nv9wXW4MhUjt%e~fjtpUL3cc?ZUi z_7+yDpUI7P1OlGsUbxwv>O!^kCah6@ydQj~>J2sVKG}?ACr9VGfk2^h2|YB|t9UXN zK5AaPyRO9==M}F?3IBwZ?-w<4z7nc{x3KK2x_E(7`0dBa^T%@1U4cNlZ@rFnt-oqq zy3i{si-n(F=!P`ZZjo03ShPshQaK5C`~5->jmENbY+Kw4op+Cy{8X&<>-Pi#i)nhz zfd2rFzxK1{9{Y5o`GW0}KB{x>{oe8Y8ivL#_R5}$g^#>95Lo0_@d2!-{PvE#&nqgA zMb_VES4Pgc#nI6I`@9NZ(h_@s&BC%$_zqyktCfJQlVsOTCI`Vv*+e+pCp~Ik;VprxlyC(4=VOHazWR{stO(1Mf^c z>a`#mX}Ijbf`4Z;)N7enw1N8|U}vJRE00SGF7qm2CoQ*i@ORJ93&mAdO-U?YGF#a5Q|NWGsB~@{A%e|>Ki;&IpFDh z-~K_b?1fk)_rZ7++7T|pyHFc$_>7g>Ak;@UV_mGHeB^zsetvdp^XaSXA(1Yd6b(&W z60E_YD^`2S z8)K0>fQrIliavaOwO6(=7OL~GSFte`?)R{E*z%`RLQg;J6>W-zk9&l2{0jHOQj2Ym z-pN~8n`4p9z|(gearaVz{eo*kGLkJ-6o>o6JbY(KSXv<^>GgX0Uw!M%9r*&H~SpZR#a9AbuZ z@h1niA;%^bWle2+6$_(eRX2={$0%Shvo>IkfM z#NceqaeNt`;@k7;4m@=i5Woqr;y zJQcs*NgW=5*G`A|$aPridfLLQdJ<2a$}#4uXk-swFFX!dcSa-8a+?D+EsjP;;dLRb zmS69cc$&|Y&(M5>r+PCq^vFq1+dOSeFUM0&xmTor<~q;b8N7?9bT;Nu&&2C8by-pZ zj*{6fpM|H<4w?-kILPCvaF!toZ}Dt=ICS~+#k_1>(J|X=jxs_bo9$!+0IyGz{|EFl+Rcwjb7ORA1@mOlZfW2t9ZGdRp`aFK$hJGWH{c&GVc++2oF-lRn|b#hAh zGOU|=x2gO^AcQ-KSy)$3L25Sf72!%r8S${K~InZ!*MH-R)zHBw^yyBo?8jKB*#}+)GW`QD`KMTD#|K`~ zPqFZT4>ci+e@Y48g2l#%wF!%z3akA`95C)ECTk4ts6j7daZ`&`?PHxGWsS$;LE=v- zp*0_SWxvG2zxts3my}SKPrT$`W8o>EDD%``Q^ISox|-r@zhzyIb&YRT-|ZjM zVH2nj~DhT)(k(B zen0q`P?a()Td5O%)E!9quU)JAhU!`4r+DC4Eb0mS3F}7Ry5?uyN{D@g#q9-FuV3Q5 z_XL*hi(`J(os~jw#VYl!y8Gh2a?Jtj8!Vek|NZe^eh#b9Pmx>^pCI$GxEcB_C0zG6 z{|1qqr(xOg+lOUGXv9C`z48f`4INmiTcz@S^fH$1(cZtu>r!^WYW)ZQRhnP!3s{SM zYZy;1p7O2c!C>GvzvmyuVvG1OrP{7w(EJt&rdDem3YwH7f~n!GP*9uWk164mSUmf| z`WCCJsf+|u!lzaPn$#mOb1-Apd;oK(G7KM4J;-&SM8mMyeX#Du;^q^pZaB!*B&!#e zjdw5B2%puc5e!`6Tf?wyXc?Bxr2>m5hNSIWGhVSmtjm4&7S;&WAksM@=s&*YVfj7L z$hCO=7(cd64prL@giU3mZxt~Wb%L=_VZPQT}o#8yT2QLMWR(!y1%TcyQ++3Mxq!901!t8f0PvLdN zV>jnH&ptdJgppsYPSD@vSVlPMUym0hR$Z_A$I);(UN=)74R%eyQaSz>8Hv_qNb&p= zU1(xmQ^6zn$k))b{5ZPNYg^CuXvlOQ#aRbWVg3`m@D4myOK!W4t&augo|s#;`OdS) z^?%^06nj5g|LCAQJnJr|CmxIWn3TvgEal9Rms_>xjy7ctsY@kPz3Sf!g<{8;ZxN)nP_`nUv)Wf^e%KBM}wV7!DCHPW1<{&98>8)RW8O;$J*}*ZpTaV zJw54t6;DG=H!tPJ4)1(C{~MWb_Xfd0Z&N&*tpTg2e{g;W>kML0+(MqvHw^mceo~K& zMjAH?2Kw5(@W$X>cEEe~U&87&t{OHH@6U8k{!7@AO@jV^sbxz@$NMwp19%r5C}BU| zr3bv;P3^R^w*lASbta5&S7_y9c$yq_{JW02&6rw#nC?OPj zn#$afF!+s|+o@o`A1luk>?+S)}LUKPa@y& ziMHj07e~V>cw9ytcc)_6NyI)L-hju$JswYCO#$`jf}NKjQgc z|3nf`wy|n^-G7ZnGV$zX7yK+5xd%`6=4ea~Kj5jROmXgQ+qJUui2U$|;b|G+JJt82 zk%f5bJv(+g@a)(HXGbITPKl3}dUgPw!dM0wAA_e7xcBCQej86Sm9KXKA%(_$A9h;s*IY7&SaRJ6rahgyrFSPrYOpIFM-;vazGc``}SMz6?p2Rh<~&4 zDP9LWz66;VjhvdyMu*3|-%jK4R4nPJ=wduI%WgwIlG`=$9Ogmc_(*^4~V=m zc&e|Bxd!jgn7{r@ShusPrn?UB&zPI={>-Ibcf0!AJO|_b8MYKpJz~Rt{Fj*B&iYYi@o^~SZeT~=afOqD(RnryY{h4mlzl7E6QKh`lWj##A z+03%V=P@>>@@x*c`~Niip3kUQx)`&+HGjn%V$I8X9-t3m_OtX4%uB4t694K{IYRp3WupwRVM<;&I8b8-0gm*LY%uT3ui&&SPeb;q80P-TMCg zT#BcKC1^G@3PvNJ;%ckmV6ZV7Ii@^hebAJ@?9KxFTN70}0w4BuQcc*q2+Do6^g1u@Io@(XqIiZIyG|9avsoF*H zMNsWbbDsbGdARY#jGe!`PQvQyUn`HwBA1Yvn#_}ByfehZC-ikzq(7FfGRmRU&+u%i z90kM8FHz5xm!^aVV)gW`d$4#c$aA2t6zZqcV~+Nh+S>d1gmdwDhHX+JZ(*r#c+_`8 zQbIqwS@Ecli?tMwR|q(5KY?Wz6Dkot;xd*2ukz}Y$k|w$)bu{zwqK9uj!;zYReAnn z<~IH9QO943!Z+ic?N{|RES@T`O|=?eyPdA3s@ZtTwXT0KTZN}>?+E|cv=v_4^HB#$x zJ3;M2*9T8Sz;gL?G<-K6FAULjJFq&&(?)6!ir<;(Sa>0xtu#C)~rezEX>^tSl^!f>=wi_>v3j3oM>?Vl^MC9+Pzi)==Mi3TuRK9iO2Q zBs4TK!<417SU;9wDx|?-Ci!yo;$fx;4c|G8OUe{qPP;zC9O~b+o;%#1Cfw3qjb(3w zKf)T~hsH)IbKUS>i)B-MhQ%Xf*a?|5-nR;|F7d6+Sbe=p-qdO`(yjqqSIfIO({7cdB&v@)TlXzDl%dVpK{4)#BfA}8$5Q_;v znH#)pyAp9#jEjaZz@rm+$bADAT}+JEv9wY&)7zMl7NhM-QQu!12I8gqVN96N{i98C z2DSMTs_8#=lL;2Pr$_9EW-J})0@i-uFg9z0!p zbPdZ*a-O}8{Hr580gneOGgBffu{66mYH)o;##zr^Eopcg~jeCRKiKZf( zF5kk{+-uDSn5bSVBg>+`TV3Qb{5cvG115scy{cyo860d0con44YyD~JUhr| z6xqIG_2-+uT)h5X@rIPh^H{bUr_N3aUS%rAGE`Sw#d9Z9IhL#W2~5rlGLO3Y0L{W= z;}<3hgDbRJo3;5+?mZ9)p;Sf6#R zshG%8^yIZBc@kCmnNUqi_Q2WEaL4Q7)1VkD%@j{y3SkZKCr-2L*&2N7!W-h#YT*Iv z8>~KlXqOqzid>JS2O^w%CNb=IcGxeNX{V6=Ds=~*4y5*)>31WYjc0GmSK^)Rd#nzT zZ}D{S;kqwMO1LS051^olc=o1GTlGpjZM5|JOVP*|cseH7uwR2-$9XTx7wwRdw=rpgr}Nw(&HiJXuR`H>KIl}EZzU`)PW~4Ki+DJN+{v< zIlhLko}+lhCEV{mk7*w*>1O)8+e}d@5wE$;l%bLA+ifVv_F>V`j@wQ0R6<+aVT#bm zWp~)Zxea0&x*5+-tEo|@)fQa$1d9X8Vq;Ha_C48?=GuM2df9k`sjKzg!qfa_I`Ryl z{ye*Wg-!5sGQAL2wY5>wSTz_0oDN^J(G%ZyMg8VL#!iYBuIM3+$k92`-F= zub1b4efuhwwl8~K{1Z>r;xQX^YO3FWXK$~0)*i}OVv=uU%B@_Y>C2%z(s-$T zm}ASDgvWtqTG#3r+yLFcC4GOqgU-g%Va_i;GB@t|r~U*yTV@E9CE&QKak}_Io`14W zT4@UonqX^ICcGgkA@spYlRSrEZL-R)J3-UEG2!z3ak(2yox)*hNi_8JDwBL0vD-gn zW3wpmjl^|$S}^Di9<=Sk(`}vY;?Aq>N?px#zm4fqgzH~nW@_DFG`s`1w||qA`f$9Z znn(BH!Fe^N!6Q`$ES!ti%YX3wB$gHn8qJHXd-1q~;Z@@EA7$A59Ph)jL#D)MF@Kr@6VV`*V^{jboqFS z>8}8xz&cYgk8!zpof~DHEkkqHnWFj7U!Xeh@+j#AzU3)9&AL z6BaioydquwIg`AY9i``Urf6|6xe<9NAO9n*#xHwzAZT_j4mQXLVzLtWA88GK&$jL% zwK`!8y8n?XJ)1%x#4ooK{zuw~U)mO^Zfd_8Jf%d@Si${|G|cZIc z_#8?bz&$_oztR#v$^RhX|4}+MlaDG;$LzT;*uebrzF@-t?2rEay+GhTe$}Z<U^o1`3Ao#{!M=MksitKPJZk2 zyO&>m4xx6g93tSa68x`u4RZL|&qd1VMV~*xU;D=qREuWTMC+@$2dR4ISh#|YlbSyF zGxx5zKbTOWNzfFg-fXT22dPjCr9qE(;Znsv!TC~EzBQ_{+M)_NO@Ew#CB7cQ-4n!Oopkga5AJ6u(T&f$;rTo*1?Hs?9N zs*3l7E58d|cvY=#b}rL(y)0NaLo@I);wV~w7x(W}c@K2)q%zZ;UhZ^|ARk{%?YFp4 z5tkfsP`=Re%k?Srcs(AUM6D&KynR+Y<9g+J(2|CXFSQkf6&M?^q6|ANyOQ5C!q<;wE=huz^2|zjF8+VWRDI`U9%^{ferX-^5Ms)?kb7Sb>_v zRrDkHBmYQL(ds&WwA15UcthtmL4#(?R<;!-JJI1*E?R5nw?(zmoPjFaBp06S!c(2! z&1rX3@p?E-L-`5x=1lodU?hK({b*F_a~#i8 zAfKwLbmQRC@u>QKay7S*VE6%rE}>Krr=ZICD#xYri=8jkXiRhdp;Y-yckyO8o#phl zYUa7s!TSEe@OH=Mq54!+Vx+3 zd-E|D;R&Z}QDv~sMXajgWpGvCSr`8~#WM>Zc8lN(xFRp}N6|Mr-Gr(huPD%|!e4da zTO6;dLT|Y6H(j_?>E3d_RMpw0LDit_1gM}7oqmj};h&@Y1a>+86{>{a3I2zw1H(R- z?su0?s`3KW-Toa^X?&!rX~_9iRj7vJQpKz3{6neAI>LoZRp60Mk8=E|5)5Tj$7x-s z^;`t0!s|O`~G^Q8)J>iqvkRiTpRE@4$w!10btb?4X?6;DJpWF1|&v;}@&R28|z z@&81LS|iY(zqL*A8uuJvgiC)YRk_(N{C}cBvyft1>P}_6%jQseq}fTdMv5`bMU$%a z*P=nw>@hAJHTHU3#kf&_oGRMQ&OekYe6|Zelq&pI!u6D4nTvM_wWo(e1d!}+6aF8C zxApV+yBZ!Sh&#T=-S)BCHRw>Ppf&ta2R!cLRaNmP;p+IcPS>He@n3TBr3!x;)%Ca8 zanyF008ioqO_@tNz_vvdv7P4DL8`+&RB`lAZJ0@X*Vgjb@9KNMBLBV2e@70+^9s&r$Vj&(ZzNDLKJAT>Lm z;DMOjQWrkm1z(5q6S$E->VVr(GFl7ZCs58G6|?~re*sm*mz=-J`L8(tHB|B6a{fC`w>jP6^aE7+eB}I3o&UK; zLST1;oi#8Nh zy@sRuNL9=z7oLqO+p&)4ql!P#`BPAR{sXnwT-Atr?sXFxsJ*wjjQ&nl@EtDRf3LRu zLuQ~n7w|_Nz0egPm4CPMrCME9qN>Ph$EE7ghn+8#|A_MsXo(AW)ae>j1w4+b%h#d$ zNX6GX|36U`_!RM_s;#BFYe5tB+jN`{TE>*naPz`ir=QnZTf2XQma~BV_b67x&)G4S6Y~vzGRnV!< zud0f7n&VQXKNA&?IxdwNbNnpFrRx9lYPxIaJb(&1-$kgZ$}r7wsr(C^UsaX9H@p>^ z@4}_(p-Ik{Dt)2z3rjF$OZBO$I@{j>SC`%B!v7Q1MQvQV`KT(k09A_@qpHAts6Hie zL#lwKEgq3C1O7*<`FE&<>Z&hY#!~saP<827j#pLjZ(O`RF5X_}f9LdjR3EAG`vEP{ zB&)#Cm{ht5f2T_LJMpyD)g`fJ_c5p{aGWyx3)M2%gm9&A>a10 zRmDzndWz#!Rq0#9Re@7c`E8w_h-zKv?06Jae#tJpYl6G}y8?81oQ?7m=*1spbb%bF z@_XZ}pbJq2^>_Y2RN?7@|3;O5kc&4+{V#hsf0V%p^cb`dRYd)>)cQ!()z>)xP^$20 zgsX+uq1r2Naq*=J_fVb6?nRY<$r22;`~g&Bv>Me%stP@fD&nKgUxO;%TIa8G;p