From dacf148a34da120a5d042f7649380ce6da7b070c Mon Sep 17 00:00:00 2001 From: AlanSilvaaa Date: Tue, 26 May 2026 11:26:26 -0400 Subject: [PATCH] feat: add compose and decompose numbers problem --- AGENTS.md | 2 + ENDPOINTS-EXAMPLE.md | 17 +++++ .../grade_1/compose_and_decompose_numbers.py | 42 +++++++++++ .../compose-and-decompose-numbers.png | Bin 0 -> 64594 bytes app/routers/grade_1.py | 25 +++++++ .../grade_1/compose_and_decompose_numbers.py | 30 ++++++++ ..._compose_and_decompose_numbers_endpoint.py | 66 ++++++++++++++++++ 7 files changed, 182 insertions(+) create mode 100644 app/problems/grade_1/compose_and_decompose_numbers.py create mode 100644 app/problems/grade_1/images_for_reference/compose-and-decompose-numbers.png create mode 100644 app/schemas/grade_1/compose_and_decompose_numbers.py create mode 100644 tests/test_compose_and_decompose_numbers_endpoint.py diff --git a/AGENTS.md b/AGENTS.md index f730256..912936c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -53,6 +53,8 @@ For a new grade, follow the same pattern: 3. Include the new grade router from `app/routers/math.py`. 4. Add tests. +Every time you add a new problem, also add an endpoint curl example on the ENDPOINTS-EXAMPLE.md file. + ## Naming Conventions - Endpoint paths use the existing style: `/math/grade_1/`. diff --git a/ENDPOINTS-EXAMPLE.md b/ENDPOINTS-EXAMPLE.md index 39d8f92..3efe8b0 100644 --- a/ENDPOINTS-EXAMPLE.md +++ b/ENDPOINTS-EXAMPLE.md @@ -49,3 +49,20 @@ curl -X POST "http://127.0.0.1:8000/math/grade_1/where_are_more_items" \ "seed": 1 }' ``` + +### Compose and decompose numbers + +``` +curl -X POST "http://127.0.0.1:8000/math/grade_1/compose_and_decompose_numbers" \ + -H "Content-Type: application/json" \ + -d '{ + "picture": { + "id": "cube", + "name": "Cube", + "image_path": "/images/cube.png" + }, + "whole": 10, + "randomize_rows": false, + "seed": 1 + }' +``` diff --git a/app/problems/grade_1/compose_and_decompose_numbers.py b/app/problems/grade_1/compose_and_decompose_numbers.py new file mode 100644 index 0000000..b3dc374 --- /dev/null +++ b/app/problems/grade_1/compose_and_decompose_numbers.py @@ -0,0 +1,42 @@ +import random + +from app.schemas.grade_1.compose_and_decompose_numbers import ( + ComposeAndDecomposeNumbersProblem, + DecompositionRow, + PictureAsset, +) + + +def compose_and_decompose_numbers( + picture: dict, + whole: int = 10, + randomize_rows: bool = False, + seed: int | None = None, +) -> dict: + """Generate number decomposition rows for one picture asset.""" + if whole < 2: + raise ValueError("whole must be at least 2") + + selected_picture = PictureAsset.model_validate(picture) + pairs = [(first_part, whole - first_part) for first_part in range(whole - 1, 0, -1)] + + if randomize_rows: + rng = random.Random(seed) + rng.shuffle(pairs) + + problem = ComposeAndDecomposeNumbersProblem( + whole=whole, + picture=selected_picture, + rows=[ + DecompositionRow( + position=index + 1, + whole=whole, + first_part=first_part, + second_part=second_part, + picture=selected_picture, + ) + for index, (first_part, second_part) in enumerate(pairs) + ], + ) + + return problem.model_dump() diff --git a/app/problems/grade_1/images_for_reference/compose-and-decompose-numbers.png b/app/problems/grade_1/images_for_reference/compose-and-decompose-numbers.png new file mode 100644 index 0000000000000000000000000000000000000000..dd7fcae6da0abeb1cf43ba3c2557f9f1e87c0d18 GIT binary patch literal 64594 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ν4%vh#oml&_Xr+G$Wb4ca5P?`r z?N-yr%a9M{0OTwpJo3k*$JC`# zy==%5i;#*VJeaM%77+EpFY*@MI8(9(x8sV5k$H0tpn-aok_byJ#>L0vJs(>t=m>Tx z$!ONT)73Q{yDlT1ZK5}9_r?UpGxnHG!~6YCUBMD55(5g>HI(B4r`JjBQT5;!* z*M&JQjUgl2A{&5Lap9q;j{HJoE1B=^`l>Msa7D(`>~{!m_6Az^ap{}{Nl6gRzER*w z4q_^}&A=uByfZH%O4^?-yV6wOAv-&L~qiHEnZqQT9 zCGDha#m^(q-*qNgxTCExIj7(SkJU=}19!dP^qFC9CL}vWeEITMxW^eP*1=L|6Q2C1 zgG(Gy&yO7apD=qP&6cSA9uv@*HT^!`zWD!Mb0M|0x*fZzLRBKRF+o_y>9YD-P^*|# z7fgp9`us`^=Fh<1h?LhpmP5`jY{O1C5{$WxEDa!mYB+8e!*77XDFPh2MY)7U)B->L znas_;dw5#=k$n{Sn~5k-Kw+`5!K4kLd!5LJ^jPGU9P}UAE|aWhutb1Kw~3!`B=B7W z4G?#YGpl5s109fZ~61K=c3eYe}{q_7=UohtD4Rk2ft`Kh9zQGGWqW zQZM|ffn@%L`h&VefwSswA)%;&bP-%!0t!{{4CWA;&*XAKzfEGDQtWJN{vF1B`qTTn zZhvmmiGuQCe*b3Q)93~waX3>yST}O&=_h`O1ps{q|-bt=jaL#~mM2G_m;&9Qa1}=i@7A zKr7YA!0Ts#D_M5y$$&=I=QbVYfMEXd5A0EZ+!DC{zilQ2WXr(iXytY(E;du#Ad0G8 zck6JLiot&t6VqDw$BA&a=tFandSc%Ro4Ry>8^7ik#+I$_IHH}dkXi4FWeWFi;Kv() z1k-5c<80Qpwy#Y))qz9Z>x~a51iO>D7n~X5KGQo_KYxCSj2102^1IQ6AciK1zIL$v*x@e$LFak(c6+hEaQ8`SNc(o7R=vF)bKcu|}RFhk~?;Ax# zL0~B&OX^ZY1q75XC8#J$M|w>x6bU8t5=uY?mIY9h-g^lUkX}Miq$s_FP(z9IUPI5F zaee#Vv(Np`-sgpq!;myo!?|h#B@Bh4^q(voCkLcsecanW24V}B?&-2x&hp-;y zb@`7@&3TLDZ7oZf$4etCHayADe_fD{m6er{|5!8P*W6q#a3s#-740_Fk~^fg!r#?o z7{U0gVtKYHVtMXLB05-J9{r3*msE8d>s{hDNq@A*Dt_$|6BIP@8{>`_8~Y^x*YCLz z5E>_0h_#86>KikQo_pv0N&i++Lc8C!+Wlg!M7ig-cp2vp%lMV$8x>3aWo1K9YJTP+ zvE0J6+TMW|5PuBf1V>X3D}Vvm+T$WiHuxkVcwOzF)n6P((CCck(Yo!T4HJEWa|P=` zOfeS0t*hIjF&KZle#fp@i5Zcl=<2e^fyW1_FvKW29MPYXH9E0>MOE0Sz{uD4B_sQK zs{!-!TQIKz;!TU51ZHW(J_Da(GgN9jKU{&OeaZ#y_r%Yu@2sOIoU#b4I%D$>+C&?c z3e3w$d83PS%?|TKFs0RJL&LSZ;KLr639|b}riu}54%fHiD09bm_t?LXc@-Bc#mL;@ z3i+NPTVPoXd^HMH%lQ!PTF0_9*VU+x+nu2=X{~1;rVc*$UR<)!ap(Ku&^ROKjxa9s z3|Zmdoc@D0#bqcvpE~m%-9neN-W)|w$hV6g^H{g{hVS~6xV49E{IHG=5bo*iEqgu# zQ?GH!WL#hWvh;bQCsWO|tf7H2jDs3A*Zf{eztU%CjV)^bMA{nVS?<5>6i`2DT-KTN zuH4RHIUtsF1DFTF(uXhrDw&e=J7(J;EksUyA0SJI|~+kJ&Jx+o5j{d=Mz#BR}eruyOmKx)~!x$|>!u9v7g zpF-BI1v}O(Ntd)jAeF^2F|rsBEkn4dNm`{rd{?~dYm&yPT1bM0$~d#Ge&0p<6Xy+_ zHckc;KSV_p!qLN5kt;7z`FBMcnw307Rqzf2SvxydRG&q0K%P{WmP&$a9Z6f@3&O)I zM(15PUXz5y8Aw`7$^Ek*6`8S@6cp|$?$xG8!%i7uc`pTri>V$mX!Y(g6~}E&=&;{- zanMSBM=#7Sy(HYe=an-L^}YLiJN`egoZ<({?Rzi&=9J2RzO!>SL@Q^eb!E0{ym_-}f#(b#dIcXsAWyw{`&Q0o zXTUr1_G*8=bF|@&#EklS@!pe4}ze{EWy_2TH@bMRswJ~}eO!F`PA_T2l& zk6AGD!6W2wH}6G%iYRm3V#qo{nv>wLn{Rtyy4zr>cx3F*&^-3VJsgGKE<73H0T!uf za5!}|!ab^f-v!&h_oC@egI$aaIw<%IRi`ytOLxPDSIYMQO_fhGf}yoXtEGuCA8}{+ zsL6@@gqbqRd3JX#=K0+PipVW6WM*OKz0^Nnw>BN;x$TmX6)uM1q?pV9^&|_7Ryl;4 zX1G)-JG^qu?{KUBH7UV$pAgR@uzE7+bsl_-C5xUEW-->kyHRXfEZO$CUfyB)a_FCm z>cUaMvFE&~Bj*ZJKIkydj}4aA@B4;4jrb8rp`t=%q*hOcyw1}L$<{nwEAO#vP44PlKZsm6dd#U17?ZuUJew8r&6^`S5v)vHE(baQcCguhNJToM&@hYNvrt3a_ z>>oa9cpYT+SrRoq5%KMEQsQcsXUVMK0OK0Z^Qg=eREN^Uo zyuBgb%LKU@9}*I>j4^5N36nkV-QZp)!{&UwC(oip#h`{bGe07|dCp6sbVb3uxH!5L zG=cH_O(^hP9F;Y_-`8l34$A$SPT_(cWhr?IS6bx+v!L#R;TQMyJ&sL3LDJ!o=gr*Z z(>H3hIbD1EsmJ)C&pw*-X#3RGB4L@W#v@G92=Q$4koslGN;=98>>SZ+W1 zlu#HesL&wocoB8F_TrE`XW=^zHrnSaD2Ad1HIlX?o9ZNF_*bFN?v0Pus(%$xma=~& z6I7=s?Y|NfwuD2I zWwnK)g66tIRwR56l%$t*bspsev-+qWj?KQ<**O7wc)B+At%8SXa%Zj4rFQj;FlEQH zUYSeO#onR{m7IqhXvM*tolvfup!=O}-fic?I8EG(+D@n%BYo*?8l&po|6bM`KU|6m zW_5M_T5wM+P)2z;tl{$qFB94nTo1o$|1%mjgX=7NW*fts3-4WBLsOq;zr1%(>e&D_ z7Y-*Q-zbkuDXlKEgzGr9KzKqG3cMvw)!v>u73kU0H8J0v8_Q8FI?!6tu)z~7c$&pMKW0lJn{WtrF#ArI(5)!RZ`-bRRS?oY z;gcLA+{eKU>v1Tm2J7pG9lex>#23r`=`7jmpmgAsYFGe6+Iqg=%V0nlb-I{Yc8dJ& zhWKseNMMiV(`2k&(T3$vu8MTM&3u{%#|BT3k(KAX9){26%D|9F+9+($A$O8a(N}P$ z@ITbHU3NQ;)QaWx@?0jSd_`g&Hm4!_CHL#&lWg;%X>%|gXf7X(2i`eF$;` z-gGPLnJbukLBo+rjw3-BU`|4GBLdVuU(X6k4wrVbw=l8t8LzJ(;Pf6VZroQ@ZaxXA zPddrEn5pQ)`r?Q~{fa8^2RzO$Jft1Jz6Bkg=kWZ2@KI8N9~S*$qd)0_CXKkvb;aLa zjS@Au*Q}jjK)wc-Dh;j#5h#zp&eYGy{+|Z%WiAA3`9&!khWH7e%b!Jat+(U}J3ovT zZ~AvEGAiY~b6(3c*$`#s76)@q?7Mm2^6INR^W6M8_&SF6lS)nwlf!~7`m$;@Ic&Jp zbLCP4nw5b+Y++#SIsx2tNb#k2Ry0kYfX!*`%@7Z7YER}nyTf4g8S0T(sPt}&$jbi9G8jOo?hnvf7^2)hAiug5UaL3;tCg=Mr zWA%fUf&zn1QJ|u@vPCjGj;IP}-0iBH( zmx!_cxo}fZ@PSRIg-(cJCLt@xl^$lr=-`fsHfW#EWad+nlG0@2Sn6X7UD2=l(&$)i z;jhw)#Sa(ECG(ct2It}N76nB`Dc=EM#8_dKHM-mwV~FhPZeas$dA#dlL==*!eo zmqM2pGhT3;Yq35ReRLY8sAE5t6?~!1@wpnac0~eKjh$|DZgWQCBDKN9OcM1CE644) zc!pwdO{*!_yi9d(jFPzd;*c?`PY1u2jo9=Oz{zaeHZ()|5>p}q*#uNsiNaV-C5mM2 zN!4}1TPh{i z9Sz~R_CaqAhxruU?ubE&_tE(h{%ewufCZWI^L2v z@LiuLR7<=pxK;4t%2VF}o0>KyObgQwq1i;dFl0sPQ%=lxeMOU{Y051RPloN~a)m+{ zZD#f@))tTb%Z&#HRYQtHHLf*R=K4;PSDaZOPRx#HQMYwYjQ8CjW~^IV*Jx1Yq+Wdg zMrvEPzIF);ZT73JE#%2M@wu|SgZ-G38=hLM*+A+z%Kswx}H=*Xd-!;>zdL4d=EQ?|EBxN=*P*fvW4!8+fU@U%Mt?OHHyXX`uAw zTRlpIa5qO4$d_4R$P7ZBo_iT&G0EAUREiMG`D3y&(E8Tmww3+e1M+z-(uv7NM)BE9q>k6q>X*rwNj~OBStLwGn+)#D(C#Iib4!WqC#F!A3*| zwr)?2N6xLqrN)!w{Sb-Uin=n_m8zVlpBs_tetgh&xF8$mo@%!{Ea`ivY`M;8!=^*L z=6p@=YW*nUz*xDYwNe1gao&V;r|Q|wy@kni3d0v~_nH-yVtE;Bci#($m%boAaJ31Z z>pDUUsE&!nq#viR?L&T-moXo!v79jXliTG{uNi%ZGr%l21QQqAK-tHsl@%-iZNP!C zLWUWqbhMLxCD;FO?*vSi8;-vxWHRqj(pto&-FbX{d%J%rQ!U=&t;O!{UaZA8k*ZDl zM>md+*O#qYTbF1k#m|Dkt>xFmL@Fqf6{m9v@@Inp_3ig7S%~NN6VfJiuh1rkyy#qe zm9PKUwbg0ZoVeB2b_T0Hb?xe)qtSY~u8@A^-%s7E(m=u0*)aL#4_AJ7v#%eJ?;|o! zGIQqm?yd(D86YaoRrvnmH@SO?lW87_k6PSP9?jE_x5do0=N{B%Mc2p6z&qk{ZTRxC zlw|Tt6g=UH)z#G0J;ULpk@5#r;`-?=$NhY;TgL0;ZftCBmYTQL03WGEo$ug!Sw_Z{ z0+SMz$v$g{V}0h)v*xRy{ofxfDLnNXWn_2@F{eXXS3T`4i9cOi6`hn+=u8LieVvLl zy|>s9n$(q+Trt}!6<_K^STU_~NJee(UFGA0tK*gW3k;%d_=s=PLp1YA-hlZri8#-} zkqsP+rb+M$$3#(B?R8)%YZdB*jOUq8V?7ol_2LTX#AZ%_9fU2L+eR}0Biy}lENMyF z{%!d_^mMJagu{rFNZfvL=4hrT-0#Z{IuC{ko2pu8U+G(DXnOHuMSkZ24LlEMk7sAP~>-O*9Va zq2_wh(edWYDPN?@EDs$nsr5EmJ15yED?zu;ZAkhHd6gV}zLavtIE zCS41ZS-Aj)Izxl_sZP$abm~lSyx;{LbFep?C{{R5vF;kC3)fV?b#-$q?Z?8gI3LP9 zuuQLmWXwqaDTuiVN$E)X@pfP|-2=$&Pq$YM{Zay9e^%Uqk)YPmjSODWdvg^V2qM4v z++2@E8CTA5<*xV9;aRVx=kOgZj7R7Y>rfxIqk%bph+#W;xJ=aZF)&F2OOrMzSKAFr zv$6mA=XF)YP-*Tz$rZXYl;-L((<;l49`>X8C6BW|$NYf}m=rKbT~Ey0H)boFAJCi< zGL){-82H#5OfowOd(+2MZymQ=Kkp|{K#sVM7H*P+uWx;pN*9`MXQ%`Zs-Sx4>dnmyy9m13z@Jk z=AED!NW8^z-b9Vb=>W|T#_c6=;d*6cvdn#q17%cAQ=OPt##?pH>u|kP`#9Fmilr(y zH&+fdd#8LD&hEZmDX^;6!!srPOWkid1r&4^0(i9kn=A{(ygPTgTKi?n>@= zhfJxXS5-qONyD+j?TR|n8WS{cRZ4grtgy%PbIIoL!EooESC1^4a0pJ80N<=^y%^}( z?92s-CvfCyd229Uu#wYn62@8x{P5MG-LxqtC^(nrJJv8Sz0Bmj&)(4smiTVE!3?zo z(HVbRby(V=rCj@a9WG7*@ptBuQBKi4xw;QXsp?m4?+o3Seu|`wLrFZOv2$L2zP?hF zkmN1%{X#?G79SL9zW7>lcQgiVl=|(#jZXB@SIb6t^$WGpBEIZh46o;H^5^M<-!pAo zMdk#ln2ASxRqclMhe$ZOvocub_HE6`WenDlJlz^nzfd%gaqJoPq?) zdR)0DU+!35D!=Vz;AvPx$r>JmmDkEqP@_Fs8X8^6T>Vo%i7jxg;tvLnbSs46OHL`L z{*uUMtUZ@Yk;5N4-=(brLC`crf9t8*ptl2E8`Gz1cair89#%UYCHPw;I->{rKA&$- zysheLqt)Y(*_z{<`BTnsvQmpDTpyKH!l|I3usJ{eczzY_r;$(E1(jd5B&^#$T*2+l zW7ao+m9bEYsMQ8zd^yxvk^K>>jvr<_m;BKK%hcqu<5{cFz6xs;41^Rq)zzy{w=Y&G ziROSMP@V8O>#fv$9@r?>MJ$Ka>SaK_LFFzIsR=K-4|b(o<2%k6Y+|TfCc50d=g0Gh z1;>%Evb62is_}h3^=4P~7fnyHaOZ#%2Iws{9BNCvhP(b|Z0DcFkw(WByuVHgRFy@S zxX#9sY8hZ4JTTu_Ir3uW^3-w3s*m^HvXh}gR?OYL3~ikvPJuZ`X>^9SRD4Kf9sLg$ zz=?EW^3p12YeR#w1>9fRp=PTuPvBjd_n{ag)h50pITXa5&O)Yb@XVF#*+cGp-4X>u zxsIwHXb*05)O>SfSmXt&OkH1qODweM`<{J$dg#91V_Ab z=9b=s)h6VPZOAn&oTA(~K7MmrOioZWZ@vCG>gghf7T{MbYhxeqh7-z{uH9I1;3e`} z9(9Jo@#_hMf^-FYDr$1-ylT(KmOq15a2|(K1ocOSWmxPGDx0^*-GQslf2!)&Fa5(U z?F3!DUUuWd)b|%jmruZKrWTAIT}p)MKg#B47j4W0rQBb%e7LkX9gn=Cstw)EKv9+* zJWK*omvPwgp9cB)R zARYF~59PX`194t!Iah(hc`DpfS{-$v)52SNVWz~Z1I00C^4_Op#-ZTajL?YLLvSyQ zhIa=jEQQoFd3NWUNQjtM>VSI;q0*WBYiY^BLp4C~<*-Np$G_?Jb`FapGCnnj%};r> zZ@u`GeSXvT8UbDV#!zhE(A7qxXD~-EA|v3Oz}DAjrP;z7WL=L$LWpt@tmY(4l^vs$ zF^zjT;8o;KRvGlDnd8{-vW!letM3-=DL8sg?w3}yTZncTmBo-9<(cC&iEi?T8Lpl> z$PJ8W^M0Ls$R-!>FMoKsdn;LZc>5(XPc>U6;pVE^Xp_IA$LZbiy&^xdk3qG2!@U37 zst4mi@~0UYdq5ck{j~e1OVp2PQ0B)!=D8Ue1ch?vOJqxkdhR_RH9ahLEFgG*>M&d89ic+aW7}(`a9LZ!dX4nz`O8uDmd*y?v&QrC{;EF(> zegG1clndTFDSK|G`aygGrqQTydDJ1 z38pF~)vtQ4Z|%{Rm+Rj@#*VH3?Bfqm2W6n|KrgQz5Ac!aa#s^8vqzk+rR`kw80kE{ zPNIH}(^*wru>DGTX9d+6S3PbZC5mES(u*8shjRHhxZ|CmSv>USYHGbr%Ct)z{k00P z+89~WVvaPCrN?^E{!yuAkYxoYbN9ugw|k*6Pqq$x8k8eFKG_9KaBIk)+u3M&;Gm=e zI$~gKG}Dhzins;7A<)ofH%z}cg=JcR&=Ga;!v;CH5(GugFUOVLSb9ZW>i+om;jZDe z^<=?^bX@$Rh}Mtl)@MLcqAOWe*?S?`*-_Zy>ahQt(`!TEEEMGd&K|UAq-2S%*?LC`7mB%{XF`2xZbuJkxrH7(p63!D z&Rbx9-;eXNVGV=YA6~~GCPG}ss;n~h2-{}Z-~BBzD8bu;`>K^|ulDD6x*MWA7DTDn z;7X#2&ep-5nmxceL!Q6Lh5h4{(WqR#as- z+unACgJHIux-LkmZ3nINku0dj^f2nAfaH@lAJe^NEn1B9`t4I>+izjt$rjvHU-VP# zHdmH;OmUlBhdA%_FrF|SjZJTFFO*QqeN}@3n4UYAr0y^WYI=5C#mSeZ=8u?{Ff2!e zFbHd8Wo5-#9AC`nk;(opY^pXTnkrM7Z7njYR}wX7RsZDooAqPGt@=RivyxUP*`uSj zRauOQAn>TvoH$jIM8`LzE1@9~fEFUFvF z8R&xslYO%19+JWW(jxIp-7}?D`_hVp@}R-Y0Zml3>&Th7-ylhSs(y~KNrapD`rqJ{ z(CqB&bLZIHetBik-Z%9&vQ6~sRo=OdbDh5>^Oj46zv&jp|2dcPe}lIC4>-=PTR`9E zUZqfEYF^v_!^FtG2d6gr6DMLUPTFtwyjzm8SteRXe+2Rjt;a(2W&$}8eML!tW8l)u zYL}`x5&y?;mPR%~g?YhtJ>#i$bfCRPBD8byoc*_ZhO|HWzu<5F<9mKkuW6vnRT<)@ z9v9_Jp~3SaigJq9QsWc`AMp9t>TrmDpY}Oiu5VrZ zO(E3}a^FUo1Eq+_!4xGVA|ld!7>zZ~=Ea4~ZO)Y#c0N=|(zpDjdbl^7%qeAEJ>B7N z1eCksVi!t-#_z8_FuOSTVvC6fTZ2(5=$t_(W9sF}uXYhZ80)3!I61#0QMgvbmE9dL3~Y4Yfz%w4X}4)jU5oN~bMDyQ zuk_-#??|aT0~T_=t42ZF3!>Vcc8?1@lP88sy=xNjT$H>2x}cYrSB`ZkBH{{dKc5@X zr7oGI8|}H3=c3I=1aRwn*IO5h@aV?{`?i6ot=W{z4;WP=gic2FW>A7(bS$2Z@(0hS znBSis@ZC)sIrb0dWZ#$J?5Eh9pL#^9)_}LgXS@xZvR{^;7!7xy@4KkJk9+gVjq2xV zQ{_-mSU}j`wGmmumoN47SlMkD<9z-By#hi{25Z__SLl1jeOOr|5>loClc7PbNOp=*^>9KR=pFz!5uB9qxRiRGh+9j{T} z+-?Kf5^!?Gj+hxklX$J8pH@q}u{CwNNm>+t!cdzfu^Q)b7X-=_}ii z5Hd-NnQ-^r`9T@lUwMip_;^N%rJgVS}VPror-0-2QI z0#VPqv+b8x3ytMe0|TwjVAD1CQ{|jiV+^q|SOF$%z* z;V~*=r$u|Sr9rC9SCvLtcqEp6{;W?Q@>)nv&Jdr!dxy2J(0XQ2EW3KcuNCB?#scvj5z%kcs$Z`0G*Q-FH7Tj1q@T1E=(!uA z%7`GohQmDx&i33dUVLSo<<<+E9E{X zp3O5(jUip+eK9-WJq3zX%)rYLyFIFaAmTH!*MHYfx3z1-5B{D;Q1xAW*O&Dm1KUB_A;EjZ8#e=Y-zS$%;rjbM1sTK9O&|C5xprFN*-0u{hf z3viG?_$o(v(fH+NgAIlI(khgQN--=XU7EX)F zolF4C;fq3cxfU=WjuOtIQd>)c!^hBFl9~XGF|9b&mtY(DIcd(0cHC*324cZJ0w!Pg zPWHU*hL!o*kjn)_V4EuQ@hj|b_}#9}*mr~qs%0n-K^@5|0bO+*tbTa+(xCw*)u+tY zBxZskJM0fHvr^6!13T$fe2h;AXxH{N_u2LG- zaf{!<5RU|DqWlKl){(=D1HE4&=jLz5{*$A3a?rpXDMf=Xc)X&IieQ&IS^Hmlr}t&{ zN(6`V$$3>@)!tVtcu6PaxmTta7Yj~2vT@hqpw9@f{a%&$y~A?()E)^IRcWadE z&!yiW3K;cG>skF!zELwIvv>FEnhbKV08m+q=J+gsbMYUmYdn`|I2U3`+vxZTBZaAU z%$HI!53@0ygA16M|$M#01|DKzEEFk%Knm6|~^x$)UM+2UEp{kgBS2!&D&0JpH+eB_QiT zt2Vv_$Nu3Zb68~tz@)8Ne#%@kfJ1zJOX!f*87WbRTfLoT25k;>D`E(uZRO8s;k*YW zn7qBw6Ql%j`Bi`Xrcs%r%zY*$zJd;(_pG&aA#FMXePZnA^dE0n>(@HJ($K?kb3-89 zcT?~ABgU48?uGkM6>}QL4#b9`MrY^5CSk6FFLh0<2JE%I^^9FdPg~PLP+-PZijh2IaU8alGJ4E*) zBF~vMP$s*LrFKljBwKnZWF8~dl=FN)8!YjzuGlz9t5j2IY|gIC>DqHN@T*xr^&1bT zR2nuDSWQh7NtLha_E1&74`84|o7&;M=7qAlbdh0@puES{%qp2_Z8UD>acnn~*5IGf zoHs3luZE!?0Q3$(iDT4(TrdX^BSm3Rz8i(V8?2|NN89%BN81(3CrDFQPmork^7R16 zrN0~ol6Y~THzmMW?;naG0Ac2bdy+p?;nxFtlzIQoigw*OFB@w%uiwj|=qsI%Z6}E? zj@o!mwdcnto4#B-C2tfe&*`aBW242FAyQ|jkn6=Ndg^RP*(R%*pPsb2Vp5Fk(=KUmQ|QUgCi ztUel@&Nt-$bT;qinA9(6N}S)De8GhpF#1*8`&QQN9)+Z*%ICL^gYNzEQEmqJ-}m67 zvSyNSKntNk@UrDqCD-y0k!qZZ9>KuVo*`^Q599N)BUT$RO@|aebLFjan?0Ne;RA@M zN`%|&>S^~y@o#-7(yUTr-t}cgorQ0kHmEvkMHHpe?rOWDD zCCJo(qi29E8B{E@Ywu*x;G%y2A-ly_t#-FPZ?1cfT_bmbJZNT6qGGG(e{${gkEkxQ zw8~^#e8|Lef5XF&pYhU1GfbY>p+{+g&xhGcLOS>p;p~94{U&0FoE~Sm<7m=;ZXE{V zzHv9OT43_VQ;*p1kk+&&6?#l)-VpN%8sz~FJijgko`!&$v0wsCJz)<}%-lE~*Gq$l zA?8y(OePkM&O%QLM~>Juw4=jRt_@ak%3?=w5n;_&gd4@Eu!m3>Z#C}4SKnbJ2&9Dz zP#WgFOtQh7n#mCy?Zlj(hN2$J^ephO^~NjqbTe| zkak*k2YdYoR~l(Ed58TD48(U%h?0`xJ-;dHTzj-$PZ`-u0mNyG*C%x{qNvEkL96i# zm-)40Xfy_BxSS|t`~KuN{9T)Y(WJn;tHTw z9)W#Qyj1Hi`OtWJVUXPf!I2FA*le!6@Cn2K7ahY{$FX&6}@`VSnu9g3PuQTbz( zjTOp_MZL0S-UR~_v>`J1Ip8@SgSyT%Uq+$6ukQi#@cjo5Y(dTJh>Y!}VJ;XyKr0D<8jA?_&(r;mFcPoxq8=Bb$xwnfra0_foPO( zoC*RTZxDe4C)!p0Q;;U7!LFJG%a>v1RrqVoxsdhXSeVUooJYwa8lCy>Lf>=G3y-A= z$w72>JsEG7E6FUXJr!gAJ`KcZF}SEIqAMj3Jm(1MdM+RXrP7Rg>~yxC~E0ol7ID^i5CiGS~vwD4{$H5v)?t<)s5)SH{o|iNI+!9T~a+M zKTaI-p3RPVtq*dieVgvsvX&*E&f9aWLviV`HN&D9;i#Lo6`M22#n--rn9X zKP4cQLeY%48f@Dttmp*kJ->mq4dholfpU(dk)Q&-VF_~h5~$U$3A zhPAY|wz`<{L!7L%_)th*FA4G^cBhl%Z!8OktYK;q0LxI;#!C(?MqJ@AdELrBu0l zZ~#W*Sq8NgCIt=w5;sg5AlaWg2IC;;)E4F<(k8eDouV0eg)Id6F*_MCvLmdk_%N9SG z5lG=IoRcDcWW{DTR1qwy>>`+U2tER+y62G@rD6B$|Z}my+E7AjY(z zm|Q%+F&z#R-PxK^)6G%G-lpi1lOzp32ZtSUi%3PgwlHx~#{Iy7n$RU353T*F)ak|t z^fP<#=*<7WW(#@37{Y|xK2r+~dYjY4uZhGx-6K$ct@SPRnlc=AqIX+=wv2KHiAxd9fqOE{|E zrwNT*f#8_c($-Z&acerWavSK4^&P;U2N@UAGep*X{+tEhZWLU0$-CG<2QiO<-_=(1 z^Sl+wI-ZmP*5&IipJm;*{v-}{+NCVE#QpQ&#YK){rd^AmZhpY4n+luD07?GaH9C~{ z0%ZJ~f?|g06l1O`;n}+A_*1aWK$DOfLr zmcg%(s)7YvB{JQtIaBZGrAgPq$ahHl2#EQ=jLiQbr2HE#rWhqbduK?=cJs>S*fJ08 zXvdM(Y1_K(fXZ`VDp4m+=0V4cnZZjV=AECT|Hf ztak~o{%C8S(BGWw`_$v&;6Lhx)Aiws6~j4Q0fWMkCF|&y_V!epa0Iasyrbg&Z{cO! zNzN0c_30Wj&4k|2TN5`ZF!0*$xA^tHqa^+}Ui81BJwjG`T??G#-O}BZ|S1jgwZ{Ry!N0;CK{VMIg(fzn>QyRKM8_m6Tp zkfTc8LuHvLAL86&>tbY7+38vbM?AmP@GbP^N59{=d+&nqB0|t^ngVY;Emy73Wx@b1Nu@Fwz%LaBFYMG7YF=2^^U7hQAHs zbXE0sa(1;@JPkh$77B*ill(`r{6R&8f21(rhdV5DsNjUcWZ(!l16o#kJgcXtx9rgT zi*9dw;rCltG9C?g3dCESTo3rYZG>6vEBV|A$KjarmX*s3cFeQ2m@(S~$eH0=V8I5& zn^ElrcYQW)?*J2c9&WJ|i0&+2nl|H7OS1pj5B~G0ZyKW(Eo4hzVI4zK_RM)!z*YuU zet25?bN97pwV4*V5lh0*=o=TG5THJyLxpAkF($v#2P)qgF8$8}mKL((9>`z~3P4yI zT3c_AUG+cOwJA{#c;z+u=31NRG06DzvuBg}LqPZ&9I3E;Gim5>57}{hrrRDmRPBxd z_6Cp$Y6>nmMl{TLbQZ)rgGHIo=ZM(kEUiR@$3-Uy(3p%YEi(qKXuts=VGV{G8XBhS zh{y#p*`cC(gg#YN`_!WC(aXp< zh5yMyen)X%L!T0DnqxzW3J%AkmaK8xDls6s2(jjrNDKMLvzH`>$Ka?ck8U5F?>TG9 zQp?t~-TeV1V_^-oyTX86Z?XgOh!lGIF>t@TY<>p*;vC>~mYN%_qvd^Ydm1`Bqz2PE zw}`h4=cU{h@fFnU@ejuUY!sk;dbQ%n=TFa3sk*_cBh(Wx6lYN-r)q_xv~-_5xu|S6 zuuZ|w9}d-Uc413Svd$vF7js{fquIu{TIX5yi&ECaLTS$NA)0fXY^g{}DF^%C8tMoEa2?c@UOODMvVQgBqBeqbnNJXPfPk;P}=s1wb|a+>f%Z$@&n z{cYUMt-n*rbPy+rW5*ixfyHl<47i(z;Yp=cNXv|^@<8^VL!jWn%r-_wUTvHi$RzkW zo;Idh3zFexkZgf5r?uL6qV)5RD(_=6flvnoEVSckBj6oA8RT(GWEDF0G{#bQT+w?y zA5a2BV3xI8AIL)$nlzcPbcpw=k4LibKy!gpUva;UA9&Px#qjB93ePRU)nz^4@=a85 z*J6U^6^8I_%DDMLAYaJ8RVTxeQht^PB&Woc_WRsllK##yNzWTyaCLX&p&6^?+`P>= zo{1qEdv3-fBOJ8#Y;N@AIG6l37Tf8x0$qh#Wp?*cDyMh~=H#YpL%q*@0x%c=tX~PkSTl<=u2-02Bd4Kx+n)UUr9Ir4`zNYLon}N&hj0YO~To&dZ@F zh2dF+QvObvuDfp)WoA;2b+l!?ib%6XWZGgfa|WN;PDb^>%46b8Np@R$=L&tI2D40J zbFAL%2Qyth^`&L^@EG@96P8mFt{vWreBnOw4Y9GE3^8B5lUHsWZX}C7-}(qUjy+#N z^WQhH_iTCKtaZozEN8DA?yvYa-hYs1D)k&Iu}AJipFbz3#=y$cdq4q4VaURK*HOQ3 zFOWw(5#X`e4oT`6Ivk~SF?84BXSfL{`{<@5N*kKDI!-hPgbUW@;>fE3aH{_8gQ zy$|f_d|v1S?|1jALlzo~Sp^RU8O~slsBy&z#c%s&TH`$H<5l$wjQqG0Fk73EWAvV^ zM88X(h@oHCn6YB2tV*1zm6ddF!`^c6JPQT<&wi0`fqPZAuwMYd@_70@9d}L!h%}hk%sRb9=))`2(`Fjr| z>xB<%T=6e!LWDQ#Y9!rz*n)}C86m+MeaoXEU+9nq&*@f@&5jHn&0gn`b<*D;@dKJM zAFCGmbDpiAa0_>cO*GwXq`oz`?)e-WMwE`%WM!T=DO9W$4rj!jAlXwWes^s;G6Yeo z8G>8{-0u=r>mFQlWb*CC((f!^2AhOKq=S5n|1MGXt_yk2DO>#~yO@&2tWwc#w4 zH&=(OMpMBsZ+7DM&yOgYD=M$_e?Il;_{#X3p%O|_TJ-(AJh+vz9kpr-P9G9%M-B99 z_rX?GdtL&~G;i2(ZkSqFAjj}RpQU*;Er~dhC`vmTtw#B-8k8lr`~_1PF(=sh_UAO2 z(+msk6c$lbR_ExvnR)b{s07sR4fc{Nx)mdqzT+0u25Z^}9JDHLF7|=~6G)G7P!mQ6 z^ozsZl9(nR+-W>AW2DWlj5aGv$;p0Ff@7;T7OFi=P+k;8a0&uY(H$oL}e=g&q`A5IXVoHy6hW~ z#0mX+3l5TglI{`3&7sTR`IEp_)!vWk-1ynj*4IOgcT_u^!=kh1uwpuG5syaQ($|u8 z{qRSuLH`eHX95l7`}hArQY7D!6rshMkUfOro3hKkQ?h5@$DU9M*>{qC8T&pnh@|Xc z>;~EQ31b^G{@1AQ|2gM*p5OEQ{^$IiGv|~Ub6@v$U-xxi*XQ+lzdt)ya^9AnLt*k- zevjAWk01IR@eS7S+(?H{nPgP{UsLGXz0M-~rzCa@4I-beOco*8k%x&hST^hFTePmz z)BJ6B-fGTwNU7X;>JCOm-R`>dC)Fvt+&lCtmkRJqh>cwC|&3_xg#&`x|DxN zedPupAK$@&mbQBTvd^|o$y!k=B>$o8k6&7UGc2J{!5b%;C*wJhj&BEyRJbpQth_MXI|_#}$kAr-))y()Sb7 z86_XM2W{2}dlZ9Hv)+P zCgVy}3y+-J7v9YcWr~98^q_=NSfuoA>86fCeUu3qg(^QHGQ*Ex1S(jfD(ISQM#D@1 zs`uE)9HcjEEiErpZ`0vP5q&xyp_<^0++H7Zc@Rp&q|q6#4D|F$9PykH$S-D5tNur_ z3FN|kI`5iL;KdWftN`kE`p2*WWs@Rtdo&*Lb<$dN`(^y@rgSmzC0MQ2Dd{VF*ygWb zl@o;qUZD3#OIeY3H^_*ufy1+BnauU=+~^! z!#Jh(nwoC!s!{lyL;Vq1dq)%i@8&418vjKg-6K33G>WlgFr^ zUp=Z_~VS^r1n?rn4=Y?|!YzZo;U$g~474D(Xee}*gOu^;ZV{-pt38pOYT#Y;W-*dayZ7#}HW)v{rh z>w8Q=!?ygcEd{$ZBH=pT9e%Df!%;x%_+ZP!=)#LNqfaD|0B^@txacDD9fM^}NWHM(Tb+%rG%354bt$^P zCmtuVrtu^9E6R7U=53SBVLev52poWw=IZji)m6?5RO zRbTFvvL!<(b-HU`i3`El{WB;nYDppXIS18tt^-VV-S$~scam{|D}#u?B^%I|?%d`J z;WSfPu;l74`z&41Q%qNGk}9;5=82A9Sq^TS92rs7LG22|sjp`crR955{!OgbGcCcu zUd$nITRHu{9$(}BCsu1vS(B2IQlLupBd47`Qg((mH)&EX>FvRmixDcjAU8b4>d&E2 z)UffyNxAZgLpkkV-;*xhLOysq%9C^#HbQ$pN%c_*Xmu_lBQ9x@(lPMEhrd8_@RR7q zqpePvMS}*{0@h_9N@B;5IvUtBLigCSZ96|}R*pjqQ^@6@F5YD?&WE;d6<7^0CE#d1 zpXo_SNv(i-zO2@u5U7H@e7$M<{=TQ(NZG^a!8}!#R_{}gtUB|h$&?QzSSNY$Xo>#L z&jM-!+6}q%Wmib~3?DW5;aTND7NmZo&jI;n`>LqBAK#~yCLJjXkW2F z4+j~vfn^LdF#29?dm@W>eJ;JW%ycj}=#(^Yd=5J26EQ98^6t2UPHPA?HE=F`|5H12 z@2EM&yRHWuQ>GsG{vb(Im1gbRUHU-!lCOXzIgu4DEm;8*KQXkTs_HOM#+;blb1La5p%wJ@W4Dl+C*^YV z!MNEd1Qx}GYMHNqnLsWO;eG=GVM*^@Avh1@?rX(hbTqj!5CMe6#Kkdr4i|$ZC>eWK zx#o1-*2IShrmN&56_PjxwCv-4E%+}whD-b=!Yd-Ys0J{qEZtUzw1784PO9aO`|6M~ z7+ZoTU)uQ^9SwA_Ggm)yy2CGtcou2FL#XTCw)Gg&jqb0Kv|wh?VG z3}WY13x_7e+ZdfP_I!m9g)!VU4JbfD0-^wtjlYdih#2gIT=-xD)}E-sO_e9n%-4?J zCQtd5j@r@P^vE7wlQLy9I2MP2?iTmFr(DfolpA<~N;3*sC@Zm$s^XEn2 zOpv?p=Vcw1$sCNY@sN2DJFLUOg>;jIYWr)e0@{#_wkleE!ApC4YGyU?{~@QbFF{G;GY{ zu5yA-*1p6#v9V=nbsr|!On)J7$ey9g(WeQdPru2_ zs{*Joir&QMhWyG%c~%HDqlLQx#PnWgFq-V`vVK$1IZ_Aaf`Y3nmv;}yP55>fdTMTR zP$fzqUlWm+AV`)3g+^Z*^LSP+9M&{i1$(`%DF1y_y4~{Ykt%^8_2`ZUM%196(R7?r zce-zemFMXBJHIKPk%9xo212R_C4OaLq%}+$s_)Bk_-P+Y-_X!9Y|?cH7!(mFxV)mN zTPByw-_r_*h`Y38QMzTCr3 zjtrHAgal=iJLu#^Jn2Fe-S+DDy~gd%46&Gk*uirs%H()U7S0#mP8PU(d;X6Q{wmtq zyBz2Df_+OA;t*SF9BnTvgLi)JY>Cm3?9DZkdR8vCCLwof-T;Nm!zdUi+x;zf{H&n3A{0G@!FbQCb>f#;IjgVWXQScZx!q4w?(S{mT{e94s#*IPZR9yU z8O{xkp9RO>`N3nQY2uD7pY!R##2@OcCc`(m<;fN6#5@Cdn-*$*0{16>X7{|B%vZGu z&yV#lZP$L9#uwCCtf|=V?#k%sSWT%M*>Tq?TN18|ZR?aSIjkKCpBl3HsL0?<%{N^P z@^zT*djbc^!MkAPbT^Jo#=+~9vHVuaTAswFf3ec=*=AjI9DeZQvam%h3B4RRjUj+CshiKp5#f=jx*z+=&tp3Mj~#b*_$YRYf%e{<*KoUcoF{+qjt++ z-&T!Qx^lcMbs_K?bN%g_=n=P)kj=2@G?R*sI`g$Y z?RdwiM_%W%R^9)UxIeHTxeL-v_ejfH2^9F2HZp`0sxm zEX+cbcw|UD*lg}hBwBXalc_ZP4C~yP)5roV^C!O>79SNI{Yey^YE3-nRvIinJox$V ztEk&U8@V?;_r|eu{K17nlm4%3ms4dx(7&&&UEp(V!cZG<#cZfu6%ie18uv^uL)B*?o2F$I2NDW7!K7q z@8k53pGHsQMFB;lm3slkNtl`iKHX2n#l;u-SePocWkZm_rZ8e2ci89~TIDcx!xuNn z$8fwdo-Ama{0d&f)7m3Ra|>itgTa+;)_ze41cgd$(DE5QxF&USvY{rh1D-PU_gFNr@({{WqVtw#4aCA(Dh>zr%w)0fPN~iW3M8Nj0q; z9jthyAs-E%9n5P}M*a>41su$qn}b{O@_E=V1G7w7tt2D_eK<5Qn%8dP zfuJ!X=!e{U@rtUweHcrQ_|Cn#v%g2#bhf*l!w@oUv)_R+OUQrYoY7ca;6SHJ(r(~+ z7O9m)Kf9GHMguE_q>D^KAM>D7Q*HeC)m$F^i`6SP;d@GdPPKmt^SJuXA+3>jH;PT4 zS8%)7qT6^b(SD*1)Zv_fe=|4sA-we&ppuHb{jB!HgBb!zU0gRR(Cma6Vv!Ndk~4{Z zo@#tr`D&Tp%uA39HtoxU(N!-G#6d!Gd|@NUY}6wN#4}&@SQ6IFA<$*t>by~~S;R~2 zo0dqc-6~>qx5nC5x5me)ak(dL!_}r9zS$sOZs74G8l+BRS95hI-4?^=`?KK0du=*X zB;#8jqd`nJ_?lN>;-cqR2*Q>r)4#VHWAHmROPQ^%^j?FcS#v%`vya$rlaq>PA_^~OzlI+ku9kwveP9IzPvi&$0+=2l7}K|JtDu7(4S5$e4 zM@(kZ%c3_O_Bn_mW%BfOd1B6^5$_JTd{0keZi@^zbz46^3?dF04G^81PpKJAmBt<& zdHMPvI*a*Kfi~=x!!%5NR7coGQxFjf!sX&ojtXuz!)iGSUyq?Z>5@fe?X>f&v#qj4z(3d(If-Ge zsHmvg9ajcn#2@RmVjenQDr(#eQVEB)k? z*e*w3Eo8Pj`qs5puZUfm)xb8Dn&>3-)G`vm#saOephS7^4I(!|rr85fciszllO0zZ0ImTfX{rl8uuN4Y4JFO& zg22591BU#^!;schlXKkUXz^;>#LJ!>syNNf#^d1UpKbzc=qVq#JU|S>zAFO@r_h5! z!LBqq_`_;I16Tb=ia#)Cxh`~F^(8zNY#%mSZoLJTIF#p#<2S|8NN*Z3 z+~oN3<H{A;tHOoQQcKDyTsN`X4(i> zBqP&GcQEEC$zPl|gVj*);RMHG5GjUvRhoz(2!|}9+^j;t)u}*VsHlEy(xPYn0t9mD zi$!IDR%dR+a-9*5x2~u5t`mHBKE;0YXNSOM@1&P22(v3V!O!0YfBMB;26*OL<^tltyWL> zmuKZ8rKF-H7JLSPFDnhUDdOdSj}nIipd+i;;q)J~vf(s{Jk>m6H-Qn9r7F!Yg&|;O zGbqn8WN}9c zy+A{PE|_mLsQvt_;bD-t&5zV5boACYu+EJG+)2mLs&0d-USmLs67dfL)Vl~Ie7C`! z;W%`Wn&nr+^LRvww>bKRC;pqL^zc&o=F(6K!%`EA(aIS_NkDUo-OstvLo4mr=kb59 zjM=_Frm#XKQ-d3Gc)T=nuHyJ38uN+U`l;HZSiiKAzEOYfFoORKu@SKwYyB>ieqlmn;uZFMGz2`f+h@RVWx(_Unj zfkR>Gv7b*t;lW~46m;Wy9NlsL1c^S2w*^hy|M`7rbs($|Lq9F=}EXID;I_Oz=U-RZkN%V*|H!Au93d%yHC;Prcs*mHJ8To)o4jZLCYQ>W*H zyPF%d+Rra8P50AFU(AnV>o57WmuTq(cX3#aXIx!vVj<^ho^ngS2E3<5 zZv3R}PKRrP_S>MgC_(#mL7-^L+q;UHX<`y{_%=_4JKMVs#K*EnS&*PVGW^~W!D-t4 zq~b@F#P$pGCWc0VG!43N7E!~-MyZJ9nOp2OmJ?{wMc?C~Ucg$!+g+!mK7&WaHtFJ{ zANSdbmxAedO$(gEWB-NFn#nQ#-V+iO<#|Ls#hSJ_apW^fJH>-X$5Zfe{Tkpd&uel}39fIO48BS0hUfD@2%| ziC6|}*5#fW-)fBX4+TZV1b}w@b#JwBEEmiyZYiAb%6=;is5?c8;1|~mXHFpFZE$4| zC#IfWpbfc7yev}pA5s7$2WC>OlC{|{7tMh#ps{~xaY_sPs@it^EAh~f+rY}SgX>1zZ6 zF}J9r2iCIN-6r)FrH#f%nGB)}2Z)^c-Aqx3Y2S~k96bB3h}oVxxg-fbxu8(xq5if3 zRL(XGbl>VGz>h9f#B&AOMq%RA>ocdtB<`d1t{N$88p&j2spHsU$FfGJSvg<sjBwHN+0;H=zU!*i8~l zw5Ko`57pHRjjxDmJWLqU0P6?PgZ?H6x%Xa*?W(LcKR9?$1x7OhpSXVcr1A?YN~-pg}>A9E}{gijC1lVt$q~8udD$F zd^n9B@!U9ZqG1EDosRcxj}(;IG(qc7}(sz+AdLR>zaI|G^C{T~q~xQJRAepW|JDs0wU z@7;j#R9dO1X}vTnEDT-pz0_50yT~@Fzg3HIcZtwv0ev=Tlsm{GXrI%F^Q&D*-jPVG zoc6$DwwbkxR*p6-0Ae;w8#BoaWkK}Bjzvi!Y|DDy)nOxA(- z{LqX|as7AwO74&MwD&P*Adtj%n8S-U@b%g%jrY^ibC743b8DjGlP1rxFn{*xad_=j zJ52WWYDcl5A1(?Ywv~OI+qGCSV16|V_&)vcP77+zzWkV3abPheB4td`$2qqEOESMk zn}gSAoa;Sxz=GjjjobQ{~9{#)@(A+#~%DeAwZ9zR3usfSms5zYPRgA+!<)$zj zbz(g&^MY3%bO+i+cJ7Sk7OR^nb2>R;$ws4tYuX)sD&Ot#UGslVasHl&9{16Oav7Qj z%W->`C$2XeFePipc#!YX>9*^b_~zg?n@pmsK=BMLAU@3p?5gR-An^S(y2^H#mzKKPwtha2d5c|#kHIWV_+~sg!6`{zJb{sqki@mxTfc=qf&W@`jX@lvUou@4!5Bo5!d@Gum~#Ta?z5q>cwnEl%wN ztl$ENIoIf=u&F!ny0g~(MW*6VvTh=OgNF=tx6Ehr9Cd6+WMm{1yTT@~U-L3aU7Z*4 zLm!9+MP80vmj^}0BWEN@1D=9fEB0csg*>6^U?<8+$KBRBG2I;snlz8BAKER=mf$Td z%r$JMqFM#Hs;pdWY>zq<_?o8iz>o=SG{1u-H>hCD?n=}gcJ{&N)e48&*|@}b6n`cg z*9mZ^esT!B9B{D{_vMoS`VEl#(E*j82Jqg@mQis6)$8I}CxO_~W~3~022TPS!@Kj9 zSph}kB(I<(3B;O?dP9e)AyLMirV4&o-`$II`T2?e_Z{pjKkFVOBtDcoM9=$k_JBeddeju1 z%?RJsz?jW;+b>VJK)W}{n0q_p_15l7+dt79`JkJoB3ATOr*=s8!ZvRqJ3xKc_jr5G zo;|A%e6VXArb+dizQ{S&zD;8@$SoFFt0;}V#^1UY z?>v`l+#8OJZ>SmzqT93GcQSLIR+jSB4lilcCcAYxU!l4`atkz__kRSTB0J)41Gghk zGdC@G?$LWX)a{XAuUW@6r!2ld8-s&{Z4H#ZrDVKTls#8zqcPQYL^=G$U~!SA@66RGd*m3%-)7IDGG+JmNlwMNn~RZT*w?uu#}NP@SLNU zsZ-}{aR1`R|sfvSne0EBq#Yfx?PNDWJ%D3hI|@X3CHQsjM=$cJYVO(o*Q| znl+JEok^fV8i4Ubo9cPz0+{YrEd2eR+-k?)lD8SCkAwy{*}E$SKNo#Php$+UZ3+3Z zqN$$CAYzyE5P&=3vYk9z&>JNyL$D&C=2aByU0NT4rGOaU2@5*|gscWMc{ccx7kQ+m zUxGc$YQ!>F`rjltlRD(xos?dot~9v)A$;|e=~G5x*5BJa0TiYqp4fD)qT$=vLx5L3 zyd3m}O`9Pa-XxG)^-4>V(0f`S?yUtFsoqPO z-$7acY5C6O0J7ga0@33S~;cb^9qqKY+EghBUmf%3pG;2H(U zvLXo2sH*XSaxyknfwO)N79VF5W=%?2m3;pTW_y#rcA9J!Or)r%ptKa7rQ;Dr@2Pg`)isaj7M^5SF6lLmkrlRhrHN@ z2Y$3q9bfA_rghzTthdHD5%0f63h=48E2q}gB)vipFG1?mx(6uU0-Y`ojeDeg_a7P> zrhbiJDgsG1GSP$OW{;^EMY`5%AkB{P=aA#hU`jNcJL9n7q_MRubTFKv+3ch_^LRR# zIfG7YD%c@6$NaV=zPL~{Roy4+!1%J$>!r0{MatsdA`-u*&`$BUH96;Ax-UkC_DWds z`4k|wnWUo%zY8`F8*CmMsx9B=3)^TpAUirzPE}CQfFA0hnw;e>RHuQm1>0$R!2?`Z zBlxQAr!;)OHh@g?JzvBDS{1sD%uuqO4L)0hZF!B#MI~h04j~+D@Rvm!ZEf(Gs{VF1 zzVe0MqbMRYC8<7xc;Eyo7tEbO*o{^F`1I%<@eZyW2TDpk-ko@@>27!XY+$F2JU65R z<)H2Lbj1(k4Y(av)i(vnhQ=ttrW$-{uwLkiK6P=C1MPxnyg;uW?JlXY(e$g@RQ(l% zC{=nTMoYrOCUo*G!y~%tgt^<6xM1NhqlN(UFvG^g1FDQkHG>!J6|2 zvHRJ$Qe(e~>^l^gs~NZMqu; zsHb^@6a=GG^NOHxbQG*4exRLn1Jgo#aB%Rwx3_mq1c)T#JzqTaA_ogkBKY(a833kG z0D~G6|JOX&2gg6zHG2#G6Hr0)V1)<>?$}F%^ltA|kQB;kc8a)Q?TlsAOH=9X7nO*P zjddS-zXeo^+V#;1;znA^)MQ@w0XDjOV~1Hftw2};*iw@~%uBo`I~oqurBT01U$}FF z1Kk94^7xu$R^6;Mkxtg}^QE}j1>LssFc0R6Yv==po*+z5;Jp^2a>}g7B%^_ z5=ym6oA(=FZA=9ekE@!n{Qc~6SwLDl@dWVI21IToZ|QQD9ID5juY+)U{lRGX`=b2 zuHs9X+(PZ249iS;0^Rl`=C6r-LFhyH2|s|(`v3Y*cyw=YPfJbfJb91DVM(tvg-tV}k z-Anqo2~6leK;2~v>rSUk+Ap5SJDY*w=l?=Sp$PGgBzuZy9>eN1hjC` z`WCfncZl&a@MHf6%0m91Q0RY)4*y@iqUaARd|+(y*!P(`m7}^T_Q9mvu%t!pQ&w=2 zwJDRQh|PPV{`~nTQZh2IkX3>1XG$eYE=m(W^1JoAJ-(CTR+v^Kc>B?rb!;72-UXjX z`Ja4{t3#jHM5a&w>D&Jx;{TN6{dWOwfO^S{4HTd*;iaK0wRb#W;m5ZPA(k&N4W1j&bwDjA7q0@10o+$2E?%-D4U zZ+ksGJvL)0aSK?;Iq!#$Bd&GsVSRDut*07g4|m}vLIhN;u;q{txrd!WNSZhE@3U=| zZ;xQJ`g@<%2!)7|O55|#0mbVOqN3ROQ$noB1ut_j~mmAFra^NLLn&1R+g)BZMg zZI)jjLl=8XOyx|8$XOF6t~OLTk>w?%39OSbN%;)&`+&7c{L90JzB5m|`I2v}7ixjI2Ef(~;lab%}C+nPisr~9aqB;@#N3;jI z^ghg5E%rD5oK5dIT)iOPpnk=hNfO$^kH>s82B~y1QJsc>twszKuvw38xq&QF9xY$h zueaVoAQ;P!{NMk{1yE~ZQXM7?SQ61@N$D~y#P1Qyo0jC0>A;S5>w8LVN$re^qX*tf}hG&S7TaoZk*4q=t*HCORCB{CX|0-c5@cJ{j2^KMJys@+NhP z7LJw|7DLh5*#qW733;a3d-oYd?FWZV{J|EzEC7^2uwLrR1h?<)^73+V=eakdc93{b zp^AbS5b&(~@+I46K&w#G9XgsUT)3D*WM`S8k>QM@w^>(f^8T ziq`(&n%Ehz~>=lXvkMlHS_w5gZ*;O<{$ayTUo4>iF{=OX-5U zci<6Bs+v$}!`f~%6ENdeVyN_^43@$z*VLCP5+r*8UT9vg-9=12ovxz!Z5E9 z>WixX@hUVgT=$s-Gl-kB|Lt>A9txb+p+35*vVcN;<9D#_7Ge?=LF-w=Jom-NgNqbikF2;K*d zrTGYMFD}Vjoo{m>5Kfao62d_)C{O2KHFPjcMhjK!nRR$!9{lkGqvz^i$us@wwEOEC zNE{)7sQzNZ_-(JV6PfAz0@V~ym{W4E#MpmZFxVZIgWG^Df4MmHJa|3vq+Ts@@dF6= z7rEr6C{rPNLz)U4hVi)ogN0C_2f!W&?$%`8;*wDGJZJ5KF>y+@p!%0URD4JO2B+=~ zj7qY&&Za*m4uByyqt#r%gDZD+Kx=g7Y+IGjDr9|a%=?zwj9Z3xpDXn*FD_%E_3WlW zz};EYpIFs3On4VrDEW>N0aMpE(JFiVCK2kLrnb4NFTpnd9%!UiiH$mP(ODXOM$HD# z%@a>h8{E7Qo2{K=tv#D#EKnGXMufx znC7Z2;F3j6qxl~;W}s$Y1))CqzaCoejO<-H_)6-wsh-kopm55V>J-|Df(}T5O7_sX z%YR5I%R$4?ah)E&;!Pkj1yy%q8;xq^XWI=kFSJ%<_*(VKBZ=&w_#?Kuo2gVaL*+;O z2$Kp=?X%ehp8*~N2LG;&6`(Bq(^;waAG37pe_A4v$M9bnS764KPXStlZeuS%*M2aE z46|$>c_&BFdM+Y8s%Nl#@pLt2#44tu_QNDZCYimu4(-lv#_hZr#?D6i-v-LM6%_nS zAE=&V4WNgUn(AXPug`0(=*gwnRN-tsy=Ky@C9=S zs$Hr9YKivq%?_bHD~uo{E=~>a4AU<)dV^{Rk4_5SzL)qoy)o0kH>aYUa+FQHtqUw~ z5#2T~G0_!3-NKQ~Qdp&AqR4H%wrOSlhq91>!*q9y*Ht1rdgwS@v$b9HGcjFqvGaL? z-f?Sb*gFXis7opH-qxl*mnZN%kx?rHrG(x3Ig*9F3y9z|S^FymIrRFqibVp7>W_mEgFZujhv8!UzX9$(nPh0I~fho30}J&wNU zB?A&gM3tjIom*G=eq+AXAdhydZ$!-JzxGZLJNDjdWvD*lau@5LZiD|<;UY(f>Tqe3 zoepRps>EorZ_L{IDiP%i+lty4deR0XTo!& zN(@%A$>a7|hTdT0p*H)c+I@h8tZz_0OL=*eiI|1GWfA<*G`JbpQN&_PutHdqv#A1b2hfL9#Q}K4q#dOE7WEpadA5y2$0a=kz1&dry}mPmCZ|4 zSW2J4lAQ)WZ?#xL7J~hd1~1{E3(G4P7dHq7lM=KRKXo z>h9CNo3N+QmsT{tpFo>SDbyN92!^yF0G@%~fpxvjDb4t_Z#2ew+zoUNi znEMt*>;WKf+6aP9e@;+dx5SDvD#MO3Sr>ALGMMWh4BVo>Vk~;MSv75J$n|@3N>Wk* z&@HvKv&6B2EXsn9+}+5)&oRASec*K$M#xcq?~l+j2B)BrL6}u4lKuk?s}7?ziyqPs z*fa@kDTKS<#3)3s-3Qh^rpm^~#=xe5W00e`$ilbcNvDoaDH3=7_N`kQ)Qp2*QLT(M zZQ58F%Yoh2a$W^>dTR-17nqm+fpE*;{(A@~nyh}jNR1QrMmroX8O@f?#ASnk4pjWU zTmr>aZw3p!^3j)Jk&y|kZjE_KD}%eDRltuTq;bD#icKDMLwW)X{(;k zKh0VbRyHJF4e}MoabXi+M~_8PlyC%J1h>t`t10CoqF_)pv^`NBUW}AL#v~g)TQhQ| zVN!8^jb1evM&+@bV$_!&_P=b`FBmyxHRd;1fO8@@V#tp~i!9>&k7ucq%W(Ms2yQ22 z2fq_pF37Y~!ZB4fx|Q~%D|3y?oLCG^;5WMKDa3uoXmsNCOecHd&qeA~_y$OVV8gdb zS-xrQd#@-I0N?fOj3z{Zt=WM=Svrn~>Z|Z_T8cfTZxN-6lR;r$>o; zxc56hpTCrhEi5Ra0cnn8AW|JOs`#t+z6U{1nn`OtXug&Yr&(3tzF&mP}< z8|W6l%YucB=z|4vg}l_q&;fz}_-e0-YgFL0AcwS?}4bmJ_Y=|@t3Y7wx z#hf6qcKDD*%RA)dVlwes>BSTF^mwigKl|D*4FwcC5n<2<9%>S!BTs zj)89R((K^(0b;}fT*--YTKm9EF06xc#o zjMZ9Yi}2{%EFbZ8+2?e5iWZmfGD)PI$P1IvRb6Yhn72qLNXGfq6y|qG^8Z6#7}t3i z`0m2Ri=P4lAoBeQCVqNLK8gvvajcU*+ua}nX5VQiyNQ17ns(ns#4@Z3bkG-|w6k?2 zIC!CH-gcPL{O>Bm557Fc07;zNB$ktn&jcdD1|mY^35qhV3rxM`4wP65MK8@jXs+aw zNt0i6c5Lh=9+SqSS9@m9pU1|T3ZQRoZ5^>k zG~02WS9nWQ=|O7GB5^7}QYRVFoI-C+!uvkZ_~Vz3!(>p7%1{f`QfHF~KOn&%Zgv$I zGHL;XO^`=&&BN<7#AE()W^Gw>3hvuYxo>J0ZHGA$CtJLnYt2MnH0xO}>n*bLZf$^W zuB!m$5%Ph#dJ8eO>pKQ2ruOJUt|44&M!Wf z(r-Ck5*Ri9JEFtqa-K}RQ2s)m&iZeahxflK#?0>6t4y!&eABJ=ZDt6h57-tET&HBb zxLWu3vuUChk%vjKnio(j`51O(*8ycwd9mKLZeaHbs;@Q7MJp<8oQHH|D2AZ%90OQc z!;0P1C*00b?M4pN%akQ6Ib2RqOKp{D-+i%aZ&MKPns0Z320k}WujYQ~SloCZ#er!Q z*Xg#e&(mDJ33_HeVwcyTMhWDt#Is6bn#tHbh(4h8eQ;^Z*B&1HfjS+6UGmxwZhTb^ zACO?Nq(FN!Gi15r)A`{!R3ml1mCO6oy5pl@{C&OPxtKo+OH(*$yVn0i+$fQ3lnAd6 zUQa(HaH`n4- zB>1NWSW9);Q$fzn2xQg@1rC1|Msj}P9&lfVMefQ+Z(J1`8w*UJstkO&xK2sbAHD$k zLl2o~A=9Im!cF1LRF~K{m5WZFyJBj?2Qg($ID^b#nwj6|=KQul?7rMh103|*1G5GR zpD$R{&Rvo)5cr@9U>fXDL;@pqk3cKjgh#8xKy5tLa)1BbQRV-nEi51_{d=X2oLy-u zM^x$?HDYGvu4y)4U7cUu&lz3^7eagCG+M`^pl#hqp_&=MoVNc2(DVp@{RQcGpL6^Z zs6N@YZ#JDB@L0wsjRw}X1~|H1`3q3Vo@WxLx6U$NETXdojXh3~)_y0^5N{(%Bo#lh z9&_{aKLuUX58@}_rhuH&`muJJ(&hSM`QJI`5ng=90MLq#O9YHZdf(^z-7a$8|Q%P>b@yKMUQX#w`iG56|`*3SnZg3* zz*}9sSuJDk$%O#{{Uu`thuX=`y?Dc~TL+JvcN?g2bWGdoZC^PnzX;TZJc)L8?p@0K z+_|%lnYRz0S>8?nc6s_Wq>XM%G3Icpc)p>`Bc09Vvvuzr=A1aUT}xEbI-VjsP29}9 zXxbesnRXu?*Z}c@v>PSxS3zjp+S@u1j=ti{~c9?qv z=gXCZSC~8CX(J_Ng*5GF`l9Axh7Z`d0DH+|<`3T5WrSJAU4&n8|!^u284v z^R^<$KY+$zlz@93spvDaVaHwYEri07yjJgC=gW8>53!)wL&xtlu}J0o=bOO>w2h&(2OyI?@r z#4J+}p98TjWZIYd(<>BvO;|Dtct&1=Kuj+H9iuNtMfJLA?vGYd$jcJS#}=C2ZMY%ARr(?zO8pc4!ODo2Zj1x8}k!jMlbq;7Vt zXTWDNzx_2(+6)$tcRDbAjKlZ!B_dOYqN)t%CDP<*XdswpPoD)A8nNlR6`n458m?B^ z3HXv!Gp5e~uJB<@xWI;3I}!Xye<7Hj{No=D-pfBQrtBZRAmDLC7FHH7_bwuTgf0TV z^OMr@Xvb~*!m2CDkoCtCBT{KCzWZvEywsxbbDeJ~o$AUj6~A$7cu_on@gPRij|Meh zb+50l1-mgkkiSRt*$2Jy5AFF!7+Ld2sW|dS1!!t;K5yVV9YCd^hh%^S->0lBHu>|R zzPz=XSKw>A$s3!34+a)`gy69PPTzrpA_NlOUwMqTNSJnGY&=j1RLL8|!(f(7Jn2!T zh@T3Tik$Ss5+UGc{Ac0`bqx5|$0jx#tl9rRet_Q`;LHMcK-<(Fb zhsSPwsrqbhveD@d%-8H?aQc^3ehV!B;~M_PF_3?Kk^jX9=&H;XnI}=}&%|DpI^umB zR~Ty#K`w(;#~^tFZ2N(*O~1-BEq%`2iW(b#TYu#C#x;L}! zU##ie*>(+~7bBiVqet%DiS>0dfqSr8%axuI8eowG92~={W1^$!{P(7WeHVVdD;dxD zEzxYIR>{-gDP8^~%C4;A?jFI)B_#B>oxRoiu8U8_i@5Y_;%F4WZ2FtZ%tbq~b{$IN zB~yNQh1QUB>JOUh^LH_~daYYM43I}QM}NeJ6Vs0OPQ-`m4;};@?!gVD*Y$HAvn(%a zAMfmFKzDvUEg7B3&o4Z5?tUq`W9pz)aPfwGgOG?EEdj5poVFERWTK){a#~ufM%_3@ z`a0Nbf&rE?RttZcCQ*%w|B{m|?E8v0JlqMssaT2tPWI7;>;6qgvHGO)3g zTmm1XIk#5Q+}tdHGn{Nl(yy^9WRlo>60KcqSk%=u5ccLwsTwsQj0og2piqrMI^Y#Fj^!~%TT#Xj8x;ej=QY4YL$a@{A~JPv8=k_oh1 zmu)vE4l0LNDk2Odi6z&q*@@F{92=CdYJClVe584BYMZ!!J`1`i@_SKPc zGm8Y$2kLRRQ(>1Nrj18ON6+m-Tk*88w5FF5+U?x`w@17Xk>CdN1J_ z4y{$8QO6;F*=1%$Ft2rYc6wqcOG5^&<2r>($YN2{gGISQTO#=f$+IU(YMjb<-+B9) zt4WyMZXy#m)N=HkeEn5g9p!MUq^nlCXj0y(AO(8cH0)yH< zUi2o7h7MBP#jv?NW=R<`PL7{=l-u~^elJB>5C13+DAB8$B@e{FV{A# zw*)0D?@jpcJBoVmwZ~}PqwI0lW?85!v^Sj7J%(kH+5_otGti_S=B@sTq%2$&og5ma zNvu#J^3wtD~bv&!Wz!N(WYg+#Q|pM$;DcJE^R%LkK#ilp@tKzGs^8m zK38h96ETy1cHlr;$+6_B-Mp=m7LOJE2Sl7@h)-iE1Mg^zfsmg;#!euDoR?0qL7D-@{i(kaHII z^E-$>dysOJZ|CI$qRH(L5QUc3zj@?}hDOy{ku<|8(#Fb>+=mF&KSWPpb?eOkWZgsbFW0Xx!zi}~ zcgHMnn1y0iZ$e?z`rGqt@BLj1oNPit&}^Z!2QO`IerQ5&QfOPo*X^hoZ>D-J*v>7$ zO~{1084ohFN6nbqYCRcH9Yy-<@Zz1l9k|@|C%64piebB-S^fI+JA02$mCxHiJ?Sb` zS)AwOC03L7XWz0TeScl{zh{$zq+OyiY>26ucV=^!H#hGXQk&+!_Txcu(;P_lF!*S@ z=6XAe1GBX?CeA&{>7Q0sK*_2A>cYU^FJ@_@M0cNTPck3U2fNn5TxlMK4g3M>ooB>C~+gUWz2jn99|9-DY+C zcA(ers1Tp{zQW{4y?N;GEr6nCl=owdCo?mtOg{Q5zkJH)dbZFTmoEJk9X$=GIXVv8 zRO)S!ou6{8ZEpUA@UQ-hB7ELE8?`27Ht%AF>>P^5v2)6;Ugt}$3xLY~P#Ul&Oy$7Z z^!|h|Wunf@?^iPSi?*Cv5Q|jTo-|`mkdDkY74F{P=D;HC_4L{|QG;PaTqlZO>_nPv zbPS?txg@k!>Nt+poG26;*)WYE8}2DK8L%;bE$D&(0N9jz!SstP+O>wWe2ha~rGhenF2tn(BNrloV{sVy`te;=@H znF>NTjAf$nPB=&M%W`5+mnF4^4k~*J?6gfs&Z_eP_`C{e3o!P zzii`B|G4sG9ekw7^{}bRNBY3co*mmbJDTkJgryvKOT-t+9(aL*`gPmmF2}`ts+L`o zz^A5mvSYcEmsqv$k^E}F=t@m>Aep)Sz1;A=BY_o{B;T*^JwoJ|a+Gk~4H00b+gWsh zCsImE9sMNH3i!xvjCDHGz+0UcW14!~f1}Cj*dMo1LFa&|K3iC9a&m6y9U8DL*QQZ?f!O$fMpIKI5Vb6&$>>XJpF4BrQ+=J&z3fo3%t>(f zt1Kh&(42QbOfo;4{fCFwE-pMg+$Af_%gWLczBVYbJd$0x>UM>yI`VNzWEfhXWa^t= zCS<|sXZz*l%Yvm=o_DZN1heUR1xZ#t#-nRW6j$Ccc>?_)rUbhwQYXFdIfa&!unt%MT13&UOu2@@9oB+LEij{m(Y~3vdx(pNW zWN#C4&R`5-{59A$L$8wEeG|+Lc zCBbJ9`WQI&a_QE&i;y<0&kS2;Tspax zh20IObxF+@ZBU~7FNM7<3@b4CP*A{YM`9KOKMgzfVpy^azu_z!kl z?pHln`nsONkP=dxTJ5^c$`d?2XyhDYor9M++olHhLmt*CojmlH&&x~&miWDcReP@- z!)5$oS=V1uo4Z)x?$&8V>Nk4RIFnTrjXdzl_&)+qnmm(X1)hz%x@ZG54oFghJ>gnc zUqiCV!x}I!NlP?!jpJm3aWzW(yapsT$58*1^!?(Tf(&4=cCgxScdfmaPVf~}S)cFG zrV#4Xj8|KE%!UC+5&-L)WI)1wf1;S{hT4LY9F9VXN;V0_%Muz2KSJxDFarWo#TpG_Z<4aE41j0G*e21H{Glpx8V+ zl%NUQ0|czu_Y$YQUr1GuM(|L_ePB~<%5~vF=3<`h-kheyN0V?pT)s~G@0N2J@OOO& z+u-MaP2WEjCa5I_c8jXqd_SMI=iodP96pa_LwNq+;LxG3P7103779@7nm^oiLB{h5 zD1wW<3XDLysC)++Z&Y&B?P$A|@AccgZJY_(YJ}(;+5WA7!W7*MK#e8N78UpUXJ*+(Bb~r$j0?PuuP^yt6K+#rIOqJo~Bb|aA z6!TL9drXo(AvpMum5mMNVpm7U03f0`#7;Fbz>5#7!9#>0SM_5wV8)T z!fVFFrlpkt*l^H-NxTy%5>fYtB@X$Klh9Jr92DYyQ>Ht-}(heSyyAVpqr85{s# z^fE#1(O5#09-DWSLXP!~`*n#_v5e1ha7Q6ZrHYFpV${?6eqAMUxxIwDFxuBLh&e}E zzs~2(f8Dd2_%?M9-t?!+p!(!RY@RDSwlt`@OfvWLXInrU8?W=N3SjPe z0mfgADEtt_bABkJs=LwXr}F8*R*9mi#DX-=)&Bf$@$kB3K8_0#T`Mu+=7I;TXrS2&f0nUOC87-J_X8uEH}5C>3yMu*Nw@~ z?1>_c_4)NPKfXPuT_{)J&F#HWIR>qDUU5)-Ug+d$P@?mOh5K10d-EtAtOU6l8H-mRZ1`(V>l3t?K}+@s_&m2Q}U9~}lYoJ%WEBn7*!0jd&u zSV{6z@@J89$FUcN;D{+_4eh?8UN=PKG&zzh2mLK<@>R=mks_B@A-aHuFrl~cS%>Y& ziQ5(2klQhR!KRvQ=x;RZqLm#HyJaccFs-3q!=-j=lM+sq1<%oro(9=3TiDG34$>%& z+I{AN2nL0vLZYI*D{hd++wy-Rh0l0LTq@P?YAXw*TNebf94LOs@nnl*V&M9iJlLhD?05*f|jwzN-s`LVpe z@k^Obg%W>R*G-=Gje{dV9!^%`<+ne;Y*GMv6S`Xh?SZVokn6Nbwq$gQ zPf6t7b=v$-itKsq$d|``Wt{^mTax^8b^X^OVzlpekz7kYWX-H^EC_V^6U_@WQhRYS z0uHzQvCT$j&y`~XWIV5{#N>33X8!&6Ur~&BDeD^lJ~?k`VNH_6ik{0;a}`bu%(TXz zU$D}XET37vA$~fL$K}U=$0ziiV35-DK#MXcAIyb)#{;XrM`gd$9xKpA`K>8mXibo6 z(0&WUOe|~f4iv4(&RH(xTd#ESYzWzHe+|f!QQbxujn~9qi22of=IVZBYR=6YH;5B& ztPbB-?tn?FaTr4}-Q|XlTSE7l+a{|G$RG_=3WtxE?Gw!IgC0zuXU(sB?X4Ad*Kzx4R9E5A-0WAUA?Wmdjz9;;s)n@WXj0+|o3X}=yER6&A`R)N? zQxMc?LNX*cIML)ZB(Yg5gKoY&#!KKLjAw68JaI-UMJA+`y^PV;NR|#5;FS>{hEF_U zYwy*1PCk+|GM(T5=BEAT!Vgt>-jB+@rzF*?=T_Zy%=Hf23^0v4L9(PwLF-h@$7&QpwLM^M04;NqKzh@lLH zu;(o5k=nngM@Se|^^Up`=}VPf{Ql6C!AxDrQ8i|<&$L*()|K~VKSRq#-+v8oO`x?5 z^hm4bPd87i@#cSjC@404YmQE#2i!4WI2$;WakTk3dGbSO=Z~4r}u%uFDZ%!hpP@L*E?J zO&+~zuPf30+rUkcWzLrReWWsI-c+0$Vh*b)Je03pb^}+;=in&>cuEfe(!%Mo8G$90=1Q0J-S@1u1EXVu>J*45A#rzOI@0pygiO9Bfjm!DF6!{04bOMN4IDTTq7r?zpXeKVH70;9D3m?8o6VF)&DSYwD?TN z^?_SYHiw?E>eC<>dJI3?Xfv#mZhbT%L+dh>l&xXxDhb zUhy8S7vt{n%hE6#PvLysEy`*o#IJ|4!?_$X@ZlbO^EAlb`cA-JY$qV8(>92W#kH4o z0ZA8q7G$DlhC)BHxCYDv^v>Y3Q+b5xFqZol3s8s@&}5}65LW9ypceBp#|{&!2x<8; z7FEYplbvG7FZwpk=iFpgNsw z)!?g3gQMrvx9Bh^qEoFTKuW5HZ};b@s*n2qtKUR2h?D))suE&#Sl8%ug8j$_JAhZ( z$n|1%ze*x6sJK-y_kL;HPcCPl5+lR*)KWE zF0i~j(j&W^kl>}Hog?Z}VPSFJwx3O|b4C1Dl5#|aO`pl~i;7b=&PO1PsJVHWxTJ-9 zzv0an8jX5iG!ot+#xXzwU3l0Tx9l7n8@pl;yIqO_?6|HKcLd4Wek?QJb7kU+is2Wx z;=AIS!j~^&A40c;S&&V@@{)Q!(%%MzgZjP65=wBF^_$iSfyV%B!AmNK7U|bi>SKn; z5*QpMzS7Y+LqdGL9Hb^PDkY|#3PH!uW`LO#Mqkv4KE~maXcD><^Ys^W2mb^h2|T~2 zoyz!P*oxcaNp|)T4wM_^T_4^ApQ-N)c96lQoWIp%-Nj6KT34fDDg_r#pK^GOsD+Tq z5#SDR+@Uz>VO+D+&YXF^S<(}-JX~T>ROi0XXNvAy-MY^jSAd1Y#N@nt=YIYYAJmQc zt`7=V;(-gmqGxd9y9Zd827%msW{6y~=qc23XPzUiD>x$=LTKEa*l69h?Ay0*Sz;Oa z(4TX2LN~teMp<_!-f@%kqj)D472PT}YaoCftp20+NPd9TLx>An+Cvc)a#A~Pz!@;2 zg1s(H9A;qf81N8hW@iz=L>RbH247F}eh8{>?qW_vSz1{M$;+FX`K^V3Enw*zV9apJ z?*JqR74SO1=-k`%&fwj^?eT(wf>uk;~iPAa4u6Lmd;6W)c$_*8owXvF8+UuBJ`C z>Ez7yslOkX33qhZvGS<_@_5oANTQf@t>G6>UERtb{+j8%H%Cegp@S^Y2}o74loPu^ z_WmD?V`asdg(5_fnV$`YlzF8qulhH*=FZff^g3*6<{m&)-?Dr?^JLWJ&PKipV}^M; zuGI3isGUBZy2d4MgqFc@;LC;jmi7<0hDJ?+%qqiUTUzl^u-#m)^P;naiK91%LTE#V zSOXz5Sdi-pd#ZvmHXnbz2mc|+mqgP`zwNi1l49J7;LoW=*aJDWDZ!YH-9 z)*E7gaLSXbRE8aq40DO)8yPR=W!gCnf4&Q{yW#&94><|q2|J4!77SA|dtHk*5F2lg z(nbIP&+SLAKb#S~7G+l5597T~swua%ym8((98x21s6FP17g09TzLKh{bR% zqWVO+8bDu`w$?r{Y*mjVR-Y;;Mg^2Ho{0T(elL3NJ@@7HS~QbCG|D-oQO0`_Zb&EJ z7csm0jDzo#caOOzk>7=Biz}=*>N{yy^a>I=3wSSmP(2B+NqNLg?H^t%u7y)=-yB=V zMIwT2s@ugB(71zWUYHh_1X<~d4iG-=ef-v*NAc?Feyp{+ z?*lf*whhtW?>n5a`Ga}$MaLr?+Ie@Z4P;UOz;eFROi;~aq@=n`prdH-n$dg8#2MKixp3bX;;xa2#mQj)!@H0b~+jT{;po;$j ze`ZJ4U%zfeiGx=AecgZ~NNeTu-RH6c{H1y2>je)|xVSd<+ERfH;!H?F>m3M-^&>+? zwdGmIy>2|uGBwsWe)OmsNt5+jjhlq+7aTqg6E5r9O1Oq`lDTkl5=Ko^EgmS@y|!U^ znL3|%-dh5|nXD0C{9*|_#6oIQ1ibsYu)06O9}z`Ly*u=3a~EJxuX$ShD4@E`e_>L} zaC_TO595WFH1SnmKb@dBwtJZ+^Veg9((=PkOC#?YxKF_|M5}mV;+}W@z#f+0|0#^1 z(B94WUdWQKa{}0b@F9Zo(S`zbBTx8t%-aI(_N}t_ze#m;PQJoCDjDgd&vp1{jn}*y z1X4tdQCo%&uLqfsvy`Jq^PY83=YZE=%iOQ3pmtp!DTKbqTLdX%;tNeMp{5sM&9NWJ aMCO5v>kg$P1m$;`kBXwkqmqZ_um2M)iIkQA literal 0 HcmV?d00001 diff --git a/app/routers/grade_1.py b/app/routers/grade_1.py index 6cbdf57..c3ec5c3 100644 --- a/app/routers/grade_1.py +++ b/app/routers/grade_1.py @@ -1,9 +1,16 @@ from fastapi import APIRouter, HTTPException +from app.problems.grade_1.compose_and_decompose_numbers import ( + compose_and_decompose_numbers, +) from app.problems.grade_1.join_pictures_with_quantity import ( join_pictures_with_quantity, ) from app.problems.grade_1.where_are_more_items import where_are_more_items +from app.schemas.grade_1.compose_and_decompose_numbers import ( + ComposeAndDecomposeNumbersProblem, + ComposeAndDecomposeNumbersRequest, +) from app.schemas.grade_1.join_pictures_with_quantity import ( JoinPicturesWithQuantityProblem, JoinPicturesWithQuantityRequest, @@ -16,6 +23,24 @@ from app.schemas.grade_1.where_are_more_items import ( router = APIRouter(prefix="/grade_1", tags=["Grade 1"]) +@router.post( + "/compose_and_decompose_numbers", + response_model=ComposeAndDecomposeNumbersProblem, +) +def create_compose_and_decompose_numbers_problem( + request: ComposeAndDecomposeNumbersRequest, +) -> dict: + try: + return compose_and_decompose_numbers( + picture=request.picture.model_dump(), + whole=request.whole, + randomize_rows=request.randomize_rows, + seed=request.seed, + ) + except ValueError as exc: + raise HTTPException(status_code=400, detail=str(exc)) from exc + + @router.post( "/join_pictures_with_quantity", response_model=JoinPicturesWithQuantityProblem, diff --git a/app/schemas/grade_1/compose_and_decompose_numbers.py b/app/schemas/grade_1/compose_and_decompose_numbers.py new file mode 100644 index 0000000..25fca5f --- /dev/null +++ b/app/schemas/grade_1/compose_and_decompose_numbers.py @@ -0,0 +1,30 @@ +from pydantic import BaseModel, Field, PositiveInt + + +class PictureAsset(BaseModel): + id: str = Field(min_length=1) + name: str = Field(min_length=1) + image_path: str = Field(min_length=1) + + +class DecompositionRow(BaseModel): + position: PositiveInt + whole: PositiveInt + first_part: PositiveInt + second_part: PositiveInt + picture: PictureAsset + has_answer_boxes: bool = True + + +class ComposeAndDecomposeNumbersProblem(BaseModel): + instructions: str = "Compón y descompón el número." + whole: PositiveInt + picture: PictureAsset + rows: list[DecompositionRow] + + +class ComposeAndDecomposeNumbersRequest(BaseModel): + picture: PictureAsset + whole: PositiveInt = 10 + randomize_rows: bool = False + seed: int | None = None diff --git a/tests/test_compose_and_decompose_numbers_endpoint.py b/tests/test_compose_and_decompose_numbers_endpoint.py new file mode 100644 index 0000000..e207a32 --- /dev/null +++ b/tests/test_compose_and_decompose_numbers_endpoint.py @@ -0,0 +1,66 @@ +import unittest + +from fastapi.testclient import TestClient + +from app.main import create_app + + +class ComposeAndDecomposeNumbersEndpointTest(unittest.TestCase): + def setUp(self) -> None: + self.client = TestClient(create_app()) + self.picture = { + "id": "cube", + "name": "Cube", + "image_path": "/images/cube.png", + } + + def test_creates_ordered_problem(self) -> None: + response = self.client.post( + "/math/grade_1/compose_and_decompose_numbers", + json={"picture": self.picture}, + ) + + self.assertEqual(response.status_code, 200) + problem = response.json() + rows = problem["rows"] + + self.assertEqual(problem["instructions"], "Compón y descompón el número.") + self.assertEqual(problem["whole"], 10) + self.assertEqual(problem["picture"], self.picture) + self.assertEqual(len(rows), 9) + self.assertEqual( + [(row["first_part"], row["second_part"]) for row in rows], + [(9, 1), (8, 2), (7, 3), (6, 4), (5, 5), (4, 6), (3, 7), (2, 8), (1, 9)], + ) + + for row in rows: + self.assertEqual(row["whole"], 10) + self.assertEqual(row["first_part"] + row["second_part"], 10) + self.assertEqual(row["picture"], self.picture) + + def test_can_randomize_rows(self) -> None: + response = self.client.post( + "/math/grade_1/compose_and_decompose_numbers", + json={"picture": self.picture, "randomize_rows": True, "seed": 1}, + ) + + self.assertEqual(response.status_code, 200) + rows = response.json()["rows"] + ordered_pairs = [(9, 1), (8, 2), (7, 3), (6, 4), (5, 5), (4, 6), (3, 7), (2, 8), (1, 9)] + randomized_pairs = [(row["first_part"], row["second_part"]) for row in rows] + + self.assertNotEqual(randomized_pairs, ordered_pairs) + self.assertCountEqual(randomized_pairs, ordered_pairs) + + def test_returns_bad_request_for_whole_less_than_two(self) -> None: + response = self.client.post( + "/math/grade_1/compose_and_decompose_numbers", + json={"picture": self.picture, "whole": 1}, + ) + + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), {"detail": "whole must be at least 2"}) + + +if __name__ == "__main__": + unittest.main()