From 4c59eacf34fe1d28ed999d7c83e19b44fbca196d Mon Sep 17 00:00:00 2001 From: flavis Date: Sat, 26 Sep 2020 00:18:45 +0200 Subject: [PATCH] add activity score and show in admin --- jdav_web/members/admin.py | 77 ++++++++++++++++++++++- jdav_web/static/admin/images/climber.png | Bin 0 -> 26306 bytes 2 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 jdav_web/static/admin/images/climber.png diff --git a/jdav_web/members/admin.py b/jdav_web/members/admin.py index dbbf5ef..d17c4e9 100644 --- a/jdav_web/members/admin.py +++ b/jdav_web/members/admin.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timedelta import glob import os import subprocess @@ -12,8 +12,10 @@ from django import forms from django.contrib import admin, messages from django.contrib.admin import DateFieldListFilter from django.contrib.contenttypes.admin import GenericTabularInline +from django.utils.html import format_html from django.utils.translation import ugettext_lazy as _ -from django.db.models import TextField, ManyToManyField, ForeignKey +from django.db.models import TextField, ManyToManyField, ForeignKey, Count,\ + Sum, Case, Q, F, When, Value, IntegerField, Subquery, OuterRef from django.forms import Textarea, RadioSelect, TypedChoiceField from django.shortcuts import render @@ -68,7 +70,7 @@ class MemberAdmin(admin.ModelAdmin): 'town', 'phone_number', 'phone_number_parents', 'birth_date', 'group', 'gets_newsletter', 'registered', 'registration_form', 'comments'] list_display = ('name', 'birth_date', 'get_group', 'gets_newsletter', - 'registered', 'created', 'comments') + 'registered', 'comments', 'activity_score') search_fields = ('prename', 'lastname') list_filter = ('group', 'gets_newsletter', RegistrationFilter) #formfield_overrides = { @@ -76,8 +78,61 @@ class MemberAdmin(admin.ModelAdmin): # ForeignKey: {'widget': apply_select2(forms.Select)} #} change_form_template = "members/change_member.html" + #ordering = ('activity_score',) actions = ['send_mail_to'] + def get_queryset(self, request): + queryset = super().get_queryset(request) + one_year_ago = datetime.now() - timedelta(days=365) + queryset = queryset.annotate( + _jugendleiter_klettertreff_score=Sum(Case( + When( + klettertreff__date__gte=one_year_ago, + then=1), + default=0, + output_field=IntegerField() + )), + _jugendleiter_freizeit_score=Sum(Case( + When( + freizeit__date__gte=one_year_ago, + then=1), + default=0, + output_field=IntegerField() + )), + _klettertreff_score_calc=Subquery( + KlettertreffAttendee.objects.filter(member=OuterRef('pk'), + klettertreff__date__gte=one_year_ago) + .values('member') + .annotate(cnt=Count('pk', distinct=True)) + .values('cnt'), + output_field=IntegerField()), + _klettertreff_score=Case( + When( + _klettertreff_score_calc=None, + then=0 + ), + default=F('_klettertreff_score_calc'), + output_field=IntegerField()), + _freizeit_score_calc=Subquery( + Freizeit.objects.filter(membersonlist__member=OuterRef('pk'), + date__gte=one_year_ago) + .values('membersonlist__member') + .annotate(cnt=Count('pk', distinct=True)) + .values('cnt'), + output_field=IntegerField() + ), + _freizeit_score=Case( + When( + _freizeit_score_calc=None, + then=0 + ), + default=F('_freizeit_score_calc'), + output_field=IntegerField()), + _activity_score=(F('_klettertreff_score') + 3 * F('_freizeit_score') + + 2 * F('_jugendleiter_klettertreff_score') + 6 * F('_jugendleiter_freizeit_score')) + ) + return queryset + def change_view(self, request, object_id, form_url="", extra_context=None): extra_context = extra_context or {} extra_context['qualities'] =\ @@ -94,6 +149,22 @@ class MemberAdmin(admin.ModelAdmin): return HttpResponseRedirect("/admin/mailer/message/add/?members={}".format(query)) send_mail_to.short_description = _('Compose new mail to selected members') + def activity_score(self, obj): + score = obj._activity_score + # show 1 to 5 climbers based on activity in last year + if score < 5: + level = 1 + elif score >= 5 and score < 10: + level = 2 + elif score >= 10 and score < 20: + level = 3 + elif score >= 20 and score < 30: + level = 4 + else: + level = 5 + return format_html(level*' '.format("/static/admin/images/climber.png")) + activity_score.admin_order_field = '_activity_score' + class GroupAdmin(admin.ModelAdmin): fields = ['name', 'min_age'] diff --git a/jdav_web/static/admin/images/climber.png b/jdav_web/static/admin/images/climber.png new file mode 100644 index 0000000000000000000000000000000000000000..73d7ae2a6c71690d99977f337855738dc07f6857 GIT binary patch literal 26306 zcmeFZXH=6}_Xiqv9A^fV(HX^pAQ(WTDJn=;Q6W?Zlqv+JNmme%8my?O$P;?ikz%9@ z0!B(u1PLvO0i;_3NN5@eNFd4GPvX4mez;%nxBsj)YmuCDcHh6V&ps#KK51sK?vHJM zU@(|Na{3g1jfmC-PmofzD)Bd0E>PY!x~a6KNP{4sCb?fkFfQONy& ze~bR*TC&rH*Vl44Z4y6sH}(3KQ**}}wjR8A%Ti1A&@T=0|6bMq`=3+ypKRISPycw` z=-7>0(szD;xYkqQnhs<6!1sjSxuP_F>5?!fcyXb_kR}n zKMVZ-Xo0=7`{pdX&dB)c36zUdcDoT_jZLhw%^LLMuID&}JwAi+qWI^apZA`q%A?fh z^NmUk$N&=<%$COnxx=dpMn;TQz$d4>j;Xx$#gP^z>(Rjz%~(%Rf10=xP@!V6}UH8!GqtWgxgIM21tg+&Ec{WthF7r5dR6;{Dm)HBWf+#OC4 zB&Qwd)Vm#<#}~f8s!UQ?jSlYXljBM_?Ko5PH#*q(b*6J>MfYHH!b)^%n**Y)OKl-m zYfzVv^mqmxD<>P`hg4!U6p8qE1LXF%+3u1!ki$M+K<)e>7paz~Qe0oIx=oYO&?c_h z+ZT-EXjN;L378*#JdH3uV3YE)R^2H>#1WUOqwKx*T6x2Gd`;OId0=_ii+6yCH)4kz zy2!0op%%&9adzWra;Iaw{RBy?DK%y-lp!&5H*bk)Zyq^gT zJ%D-u*!R%-%Be|q^i6h-d03oSYHE@b>cRui~_pesXZBM+W!slrUN%lhONND z4=X69-1_Woi?0<^-=3&B#4Q@$E{rw$b7w@sg1?t!6_izb!}|?sJa|gNQMf3VXvzPR zUSso8!t^U zLMu%9UO`pox_}p^LCMtLiYd8mol=_V`%}DVh`n;oS)t3eWfD2j$Mstsay|C&>-UWZ z7v5JE670K=D>CHP|0^~6u%R+xViCu2$X_MYIX=jODf#!hgT<-;7N7B2n4?%J+&PV= z?BDEfbUo}g|DlQ>-TpghCX|V}Hlg4$J{gSHf-&9aU#I;YBKXZSfx+ReYYUbd5ZP9N5O!!=xI{I@|=rD0lsVqmA zSaP@5`!ziD@{HhNbFv^0y5>wK)i5 zhl}TpN~PGM*X>$*#NK=J`t3VsIO(T_3iv^mojn;7^5tA=8)0H8uB%6weqY~9kqCd% zJ?9;cQBqzwbMRS9oAS{D?rWRCW7i&T4)8#72JPDqW@bh9j6KDsiTxZmu;lN2(p4R> zfjer42Mq!&gh5a{nZ$`ctTZ-_E~+r+tE{_hCk#_ZMRWfnOv#nyseYIIGVFHCC6i@v z?SNJf6K9h$s@el}RJq0PB84_~o8C$yVCeqs%pw1xv6}JVdqrlYwn9l#>{47zQAyHk zw1P7x>{1zHFs|!Zunkmq8r4NOYe0jq(@JBZ(`me(@sGmT-(QYrN@B{>jgf+{1A#@w zZ~9gI?1gLG66MG{Q8C-`!PA=Rxib-$-GuhA4RsJKdjGOAefxKVaYCWvPd;w{Q|&Y^ zXnG*fw^iXiKXmG}kfLlNR%4fdq6o-%ZxJvlpD)bMy$a^$+*J<~1I!RtQ2XBE;2g!# zPhJpqd;d}(7T{2mlm(9!mF**B@p`-{Kjr`aiLQt7)G!G4(@=jjV_;is_@6~cQ%M4y z5v+nHaI;O}^-R7HuClbxWL%}|{o<*yCJ0m;c`!$DTl3TYeO`bqPe#(aYeoj{(sG6m z+9xqK3+u1$H7-# zi$N3raF7wJ4okza+Oc_V{yV>CV8`SZaR}a3wZtKgdi=efiGL7MEVGz|eJi_Ig%!Pz zM_SYJU>AY#k)xKjJB*EnLmUjw2xN3>_fBJ&Bh|XpBxG5YyEe!gyXc9i%ZAv<#?J25 z{eK%PARtnKtJfJCDhQI%xygdHFfieMhtP3+lRI+(H9i{Q6tZ&$~*6aWiFC4Ppf`EUX zE(QTD5?BRf^>(9V4?k8jWi6yEUwu6Pr=u#Roe`JOmggsB8EV9wiT*DpkLsv%i$6^W zki6remdv6XQ}pA(*})f*`MC+W?rfg!d5th2>=3R4^K=A`?|9HgtlmS!OLa-qMn7Pu zEU!G5?~&U4Z}?tz4`rmfEUabRsb`LIQ_PLEMF|qM=VCuL%bfcv?AD?iGVBoUHGZB# z$Im7P;E+ujRc2x;IR3_3bATrBP|@`Lt5rV?7i8#AP9h{OX&Jg|Mp|JXb3o zd!BtZ7CT`1s)-$e~|d(y(|O zS1K%%RcNw)9XTXAmls-|jzZz_K4sVLIo+H;pvu~EM@e<-1uxOw+2mpu|I1B{Q;9A< z%;MAeCqKH6tdUM8*lG!!{^< zMqPQ~h2Zme4|Hg-R}QDyKha=k)A3pVh3C1cWYvjKn#F2x&)QdauzH4EDSJeOSWrDa zlB(4&N7iQd@Zk|#{Q90#g|Q$nggY?z`S{C&*G=(HJg?m-WY8Q5QPFZputJ-Y00d_Qd#w}Zz6lUi%XC(M=|B6ai$wWV5RC3dX}PTtKKUYD z0GcNU9dX?`ya!6^8B5;YD-3)qv0j!Ge&Og-tQG|L`_N;}1vAP5Yd@K~OP4Gi8HL>= zXS;3vJ}n(~*s#B2U(HBs9Um&ar4d2OoErT+U!m$J_EJxZ9X90Ojw>w)=t=1=L<-FL z6H9Xf)6t(}sXdm2roXWQ>X(4}?4c~B)^q=w z!6v)=@APsai|yO@LFnBL-^DGSkrO2U$v8Z|JT2tMrtYWonSd4u)H_9{?y}R#s$R=a zgv=N{);?now- zz-}RN|E@GF)SUP)!NNJY8ANZ$2m9QX%pUxQ4Ih-Kee@ZheA_hYLYk&Tyy`@?Iq51O zjHg`&=URnH)~@}!d3lj|`*vpg4)?_S#(b~k8ljP%W2eQo87rHWdNh9FXGfabw}+$* zNS@eHX_$f+t$lLp2v9j#Xav06lA>M3E6n{vmb&7S*xjKp`(pHTD{x z6bIeJiBKPdp&|!*DC8gVy)%Ok- z>e^ijWiAwr6ig3X8Ez5qh)E4RlHPS= zzQ)e_vItqf_WZ%L#ImPe@5j3qI{B%^_bN>RHUqv!(IsE!@Wse_Gr2UA}DoC)_{K)?-Is1Znq+x2Tey$AXxdo4f&ZR1^hTcU-=HL02{2 z;J08i|I;v|tH89>eyr$yo++}tn_JA~U=>8VP|Xi1U(AYKJF;=%y#+-~X>0^MN|QiT zy$I)o5})VOC7VH`2ONnsPQ-bQF`3@#fS&PwISV(g`4g<_-$T83dh` z4>3M8s7AdxN12D>;E6PBqyv5X*=qvE^%e{rW{kKJ&(jy+%(1#!)3uwQBiwYJ+UM{t zD09aaENMgP-^q;8fDmK~l;5aqmZI~K6$B`a)idTwIdEEDV(s(pyW-ky>)hk-jeUpW z;`dn76gK~YQ0nPcx@2b#B|R(Du{4f`6=@jQ*=uFe$IG7m!!jtbj=_$|E`sK zj|cX85huIJ6Y&>j;(J#OE1+gPEMf%-uFM^2qF=O&rtMa5Re<0*Y6f(^6$rxO`A6`0 zcMe57oh6~uFqXim#-;(f%Szq0#&(6%Z%2B!DS8*@>S{Ew#duT~1_0IHJ)b zKY9z8%?Nxp^`jnZZpf;@W*M{EOq6wM5A^V&84bAFG)6v7HWBUl8`!FEHZ$b^M<2QZ>V{2%H6LWC1{Q?fi*|_KSF%;|jQ|V&l5|;% zsO2;!V$5VH)v9XLs!VPAl=w^YoL0xn{|LmpS#LquNshdKSF3bOg;b=U%Xba6k@P;x zb+bqk9HUlGAujry;Wb`FZ|f(r7|fpj{nTJ6xqEGt4HvEZ>W@yPaE3ReI9TP}T_w`B zzdO7bj5paPUnW+4Wh2JPOk0b+Cho>)U1lie{nLy1^j6(r^OU!1tg+-5Mdv=!Nuze<0IU%Iv_qsAik^u2=;V%uwFaFGvGmp&aw zf#u;<^<0=gQ5~7P<7$IF!tf&TGagK9sBDD{1grJKa&8R(t|57 zCqHE6^1i*Zo>s5deRW{@kNh_AOS`-@yz)*z^-&CQT}ZTiWo_xECvN{l0)zRZDgwc0 z^Dv#(k=v3us%s-}bU7L=bD00EdQvu$p5!tM(fB;V!q+_h@+UyLP2sQ!Kd230wZ2^a zUSlVlB3k-Q{Lxe6A@uHv z+!l>-ev*!#tM)nF2-am zmtX2G!C!GUQKKfTg~aHH@BNEnSXzyS*x#3+%H3Jcn#C%>xz42R#&o^O@WRMcI_i;L z|7ny-iT22lfA}#0i}UYIrq`2nqUfzS%is-eUtZApx=rO82f4$K0{SpaZ;fIok@tiI zHBX5IpIHgLcYR9&X6w=Q=@oH%S1BONsF{&7@r+8pP;&0Pwa_!X;k8t6??gtPe3{A+ z9!;%3v~=0g52P6GxS-_Hq`e}+#$@CBBaLOc)CgbSN4d|XiA&|4J$?RGfj*jD+WSW4 z8#2&M=kO6@;+X`Fe$&a%{~W#f`2h&m8ela%`G@I@PlD%mV;%|gcOhcO@>**Tm7Cx& znD~l4!06G4O0LK5)(!(eiM_FllSenZ8--a5(uGUeiu8t@YM#2cMu0}I9TPa$nmYVF zkSXYVwl=BZY7x%x?U3fmPX4Q=Qta5;huw*@*TJEQGAZH3Mw2lFl~aGA(WVU9FV(oZ zWNpK|y!vumSZx-gTf{z*q+M(g;Y<~SG`?e0yL)t>FkA3ByuGS)?aOy+Un>r366+KC zhHvj1(?cdpJ65N>hKAjflfyQpYE)m?piJ?`LrktW=-uFr-aZ-P zio*GYbN`(NEj0jHoZIrNfZH_DKkSQ!klhl>Zce=F!{|}bAXA81zT;haF*&kj((&Zi z_`jce6legNktX-cm#Ig_Q8TW)qavsO`Z;wn_gW2mJoy|Mkc{DPe`t5i9XZnar9xwRuNcetYeVxTnpXH9( zjVj&eX$F>VerGZmi2}(G>ulc1PNSjPCJB9fg^|A}lb~+bnnW!4I>b6&6=ojTYOEZ) z>Q48vFS1U)OmFCn0GUHiGeu>U8XjL?+vbK_Z%RILaV=cqC~bZ}c^n#m1rp5UJnd(Y z+*3NBPq%C@NdULcHQ8&3iD>9Bui%tTxid`<%4CUQe50^wX}w|-|4_i2-YH98LUk1y zJM{V2bV)P27=uk)p7uA?*lcg9M3##iDudnynfNzI>lT~*^p6izy1Wk$sE_Z!f%-~b zHZQ94+`O$x*`o*6U;r0G4OLgkt<^!io+5Gu><>rCu%nZ@XYT;}vwf=6Rfu>Zb@*nW{E~xR7GnbEn8bL6 ztC*@BNYT(>^VgTB>q9E8*u6NBUo6-&R)qO7MO6yjeGr{0HHmFdZRxc!YAcDVMEV8JM(HWZ`yvzZ?OoD)69pw28!flFpmw60sXq zRiI&QjJ(B$c*s%`L%om%7yp!5IbwPu!xCrqVw6CzM|$K!Y-N+0hIOcFIeM4Tlh;`$ zpX(tgw~xFC1M3n5URifYlO3JBkI~?;UG%`z6FR@@y}xb;*zt{C-hgh%dDM>Q>)O#P zrM>S%A+u_nXRfGCZ6c`WQBwsz*1tdlF{f)+Vm|(QAIH7ows!FZlCvXB^tr1CQf9%Q zF>TR!5zw>sPH_$pydWUhRER7CPN(i;grE~gG)Vm5+>!J+7aa5iei1b#NBFx5CU(qP z5K6Y{L-*h7?a(Tp5BsQ_(5YPo#-#@6RA>z>#P=&KCCQ6mqO2mIAWPrJFh+IxluhTu zv1${O2C08^Tq8Zox?EuOT@RfOB=&%UT7JNDnyE=MQ!D)1!ChzD_2&^FTl zeg`y>69i3MNCZ<<*SRV6a{QlmUHA-88tY&qHqt zC`Me$4yCs$o_&E!@nH(zIoPUAq(3lG{{)15_h!XlDes>x?7asU{Tjsjhj1>?+But0 zf3!vSfq&S@2UQucQjmm9x`Wwxcj#B|G?U2F>|zpS*flcXh%A5jNZPz1xrQ}?)k;J| zDCFZmuX{(HK~RcZoH3CgD};P1ZE7sVpYL@CCssd0x0Tko${gOw12>lyiRxOfp8KXS z$T*%3d!f9^kM*jflxyKzysV0*GXQ9&cLw7vNl*Nqlw9DX&T^wHZl1>IWI=b+aWmPs z8*97O4tmIymcEn%Ws6PF7VsFROFjTsL2Qop`ykZ^sG^pHnLFN!=IfQ9UY|-ZCVHPn zLus^2%aUNYO<(z*f!qs^7DQVcwP0KLl#YVGrN%BI{#!?`5^)(jGT-vPIes;!PP<=? z+Cb7%yeIWGcv5HfY!WtFj=Y<_@TBQzsWMT$=UtI??m*b_L|&hj8{9t zXoq|<8Fg4b!U?m;_F6BhR27KiTliAMPojb(Up8lonmRW%q%1$Zw|FTJYajz1*oA+a z&iNlfMjpA!@cGLH==N1dnBDzpl2v=ZCeO#--QSjFZ9$m1ZIZ@4+A^J9y5xE~?kNWI zF;v^=P}Sx53(NEE44L03CS0zpYRrqb#SwTDGS^>#>mN@O**zBiAre|auVmBQ5~ zaKcPn5^aetuIGE}L9%5{Y7weM)b>gTNIydIHvOTlXA5iJBiMyD#)V2oLzA@3Yw5Bi0?0_2OPLVsVIu^z-RJAltqN-6Aisp3o(WKmeG=^GRi>AmOrb>pi?n zItShdfGw+BSqd*L!bXP#%1xUYaizT0YUusi@aTgQ5wEy>fW2_Tux(PzZsA6Jzlx+h zN>s6VJuWhlbFF&|tMPt~dr+dB#%|YWoj9qnA000Z^1$VRNWW0VnP<>nyeG9C87Op~ zNojY)4Z-CqiNcfC2dr1nZ>hlb;^S&_O>ChXRAXsD__|HM-L%y9?a=!+HC!gbm>^Mx zr1e`Z^(XEdfwOF73Dzqx4}Y(uGVoJgqK?i@USQc9u!9H7k)_!^HZD&zc2SXzQmvfH z7`e<-f@sR1;JBZ>)_#Xj8BnDT%W7z`drrH2wM}w~?RZ(7JCL~;Bz}1%rek;P#&%f= znKRWgIEe=g{gg9`XTp?@+uaVk+h@&@M5Y}C)O28$a`E(srI6q>tcsa`B(pff(2Km2 zSb4FtXcJD^oU9XY4)y0lJ##beS?{&LhjzavOC21lNR?9^x1Kuqm&d`S8{J&z=IIm% zG?Oq~PB>H4#kr}Hs5k+XON#c`}o+4z1J5 z|J-Vyxy^2Y9zVFBAkb>JI}WY1qttGO?;!@ zAdi=~+zcn8N-s#M{OX6!GxnDjum*3_6pwS-Ut+_qcW1==hq>t^db`ni^zZ4=pK5%N zzhC1|@w81T+P-$I^s<4Xv`9Xb<6P)seHcF7c`dcQ3B z(8zo%G`5|gr*Lf|U|I`p zkXJryJ*NJ7ZHj2`rW))Id3JpfX#g&&*R3s`gaYgEqK%8H2)G^rf=Ox&$A zX?Zugcf^4{-vmj&w+3*IypM4Qs}(pIfrqnFDpn82t-aN>?#sTC`Kc7D%D+ZaLjDVh zZ~`f79@CnSOiYx6s+%_0G`2DB(;H`}Df?7LzkHS7nR!tR27*`7k~4KO*oZZX)k}Nj zE*8g|?dy2isd8lTq#)YXsX*`Bcdadvp|&GzxJwPUzMZizyN`XR>9v4sJhk85Sje@G zt!TVxAl;a1sW~6{2p)hrBg>wcgLe!UF0U(;UfoWlF zqkeOl-8L8MfkewLUe>OaS8Ys>qptXED%1=T$j{wh1z!1NZ2{x+}FfVx)J$FR+U$+{M?&}hSEQvuYd@L{@$?Fv)!;1``j}It7p=y6L2i9 z84TJ!nZ{Z5@2#dk%LKaS5In+zWEXtkE>q`n7*q5P&}^B|Z;^Pw3Ui|g39@!Sy4A#Q zU7b?>EJ1Bhm3kZ`akR)*g}paGLgw!cWVNLmi5W=g(ufyMO&;~d17{1u`M)=iGGebM z>L|D_z_nA5Z~)sYr~^F%D(te5NWh!h(A4ewAD zTZ7Q^`X`HH*)-VA*hu`Kf){asZ0HJ|b~!={r#|PFA%5}v`L02@((L83uA-L0#Q0k< zMN_1u%i2-ZVk)SNcQj;agx_GlX9dQoBT|b>vm|`@dqaw=;|9Cu*b)BOkjU&Yfn5OotuuePuva9V3P~q=I}b?rB!1N)p@>6#I=KF7f&O@D*wRcT1PDGo8Mra z+WL~di$|MhVpqkSf)Je>RZFRkteyV`>r8>+`al@SuRJX0@i$$cKxWI`Iw}A@{V=hJ=G@+R-)_g0+rU}$} z;+_YGW8U69(w#EvOK#>h=1e8Yk^^sl20L)zHvjCYW7)>yPU~7S;Ej&!LLCRYpp0s| zcP(`N;plF$A?^l9cVRgQiLrd z{ai3fFaFLgMeO<#WJZPv_-A*E&x*cO&yl8BU#@Tac55y1J zH+y{GJ#Dlcv}u?t!X>r_FR#qMuO&m49_d+nBamqdUheeKB`sV(*k&<^IEhRb+oJMN zOqOZmjx{zTgR;bH%uX-v6t+c#4rC87b4YsG&3k9-P3GVF_qOBMzT96`P|DK?><*a`N&uG= zFX@t2IgUIXY5;LSRiqO5+Y9)MCuw>ue-KRj^1T_Iwr>00%~9F>Qwu{*GP?lo3n zNd-2;EmeT3X`E~Min>X%aFCoH?_o9vHva%~NX8nL>W=ix-oX-1KGX$pG#gNYdRNlX z^;7QyIQ|h5s8TM!=Z6&-Feu<~(R`%9bg_Kk0Yi$L1ZHkc>&fGN+oPT(vY&iCBxyUo z(Xnv)hwbr~5N_UsI&ksgu9Srr5MD3D`4a#70%Ly*BwEJyWgJ`KY#?*tC@OJTz*~6J z-L6^t_;3USr+B{{Xm8PO&icG|Y$c@O0-tgO- zzx6LaI{)&|wL7uf)~)+P^|y_V$8N$8Y+P@i7{$58osC)PdH8`Fa^zSeW@X#?Yisv3 z@7!4RNFGZNc zFm=Tnt=OVC2_hr=)$d&?IlOdw&}JL^*~d8Dq|{!nK4M(V+W<)w`SB)+(lpba*Qc?>nqi5yywXgKrr-xU}T`dT2U)5Scw-Yibb)Rv{ANS+*-m1`cX=|QP+ZOcLds!s+ z^#0Iy!pXDnTDxV+hU1GiKVospr3v~O$zUu;Fjk2v*zjTUv!>T!&KSn zJ2>4qj>wEE2Oedblsc2-=$W=m_Z+Zn--Q&cByLI(nmYgHN1g<=0$*H)pDFMid_8ii4uS5=+G^JRA5Q&qxDRISOm?x_v#TFY5SvrYSy%o8w?wrV3Bu$0#t$!!6tjtKYaF&saOdB|_FHowf?1vYN!VC(){O%G z#`#4oC4ph2KxpQ*T2MZo>}OZh^<^?-NO}v_?q3LpVfLj7N1SeA7rt%?VW@e9<~p`n z5Z+n!v**?q7|VoMGil2WLha>y6BtrBo?=VYWv+vo<4(ejgSrMZHxk7=e=5}0DI<{) zK+>BLE8-l1%*vhI2#=gubnJ|Asmj}0mnma-{|dcXe9_cCznVG@x4=vlQ{%tqaq#inOX1tSAN4YWUC-3U;-4%FSV}8UL7~BF5Q2FdxWwqHR$%r*X&l+1m!sWNmY=(CrQOc0UTdn)c zOX@V0sACp{#9?C=4Odj%nFrpCiUXKAT2zt7Svm2Yq*p()FiboXSsn{55X_hT#@w7U zKI&boyALAa+U&6f?ob-zdV=mg7`#hYWQzrq57IZ=^b@s}sg)Llpy3&^Sfnxxe(h9b zC&6I+W*ci`RvbO6cVWpFSt^*j4K{XK394l0Pvw@NKHayq$J`+!3p5Eo4=a=JfF?}O zs%I)Cjq{e)AgT(kh};|vC0CR@h+0}yv3+*s#5q@{@U2qozWBunzA8ei1C z3`L+L(JMZbZ@t(71oxgUqvQL!f}HJ~G9EBeaJ3nn0FCF@aG5V&kD)|yX*oO=5N%mG zVb*)O@)SEne5e*%dFE396e)EKaMl&;{?jTYMVX9iB)#Ze>>F4;a;Y3_XHh4>u(x4Q zsU#9h1WQy6^208HOy_A}o{;iEO);Au z6V{_mI&W1q^{7);^Kf^A>39MbV0%^tDwSkbHoEtj5V9Cg6~aQ%bsxayVX$tq&D%}7 z!`eD})Z^B|MK55{f@f8xn9Z0Rx$BRt?J)f%ppp#Ur?LnyRS?-;zhr~t7qG5?xgLsv zP3F3SYPi32zrs?2Ke5PB9F2l0|%*Q`}(oihn zsZqOnzCpE$soNk#2Gd2E=_N$_oM{$RL6}1jJ}6ldu+u^&?dsjZ6PRCrPW8FMF2+q) z-=x8b2Gi=1$XOlT=etLw;2O>mVOV(ms7C2RbmA{OL8FtChgG+$AA=misKLI8PHt7X zsHaE$t9xz{zKk+W&53;VsABsUbEheD*1y;!hkAF28cfA`;cRb_f?(|8_k-cG@TC(@ zNVu`Ij^l!CFZfgjUt)~a1S(r|*B7YBl4+^B==zeCLWNK3U177ms~>Vdd;OR}2NZ+` zs+?ZkT}jkdr@D538-^stbc5?q@iIgT0FhnS@pa%!r+Y$%-R$)R69wax{c2joq^&41vzpU;w}>sjL=3ujPZ(bx)0#yaXO1ZXA@jtvdw*g zZJ{1$(>h2MDgCY@uk5@TZ_LWWO~)}1uWL&gf%x}<+t{mxM%4E5~i| z6Rh7G3(5ILuxlilLJ=QkNf?^=T8}e3(@X{7>(Gs2EkL`Y)07cw*?T!AqHC;rS~vY( z)**0uR01HBbU}sJ#Vdh!NKX#WJAY}mPy!2tTVabfF6k@ES>0`lRBN%_HFJm3UHUh- zqd&C!6->6ms^2u?O1Tns2i)PX-8H&-PVe(jXb(sR)XT3(W38N6f#b=u-4ETErcn2z zfOrIy4etuFw0Fu#W<0~yCUeTtEQXC(U(ycw!OATVf(_O_>Itj6M-c7(=#ykO%PAsG zx%TTTkhbmt=vpJdZ!~KTLjKfUYlbqVH zPrYEox=t|Sr_=rSAW8YMAp|BZXG9k&R#@h=9z+TP2)A+aG51gMR`AuLq4v z!QiE?pahYEFGOfXX6_1CF07!rIA4UP&=`A2ujAG}*3ar*o`MV5#o@Fc)pm{x+qR(= z5}2<@kTnX}kRW8%`kT02b?lBX)aiS(KoK&)uwqG3A|n6zV@@1M>>cszuWBzv<>#_4lKxlZLw7$|pE` zb$108`i-A9gzFZ{&Afs!r}top4^OAoJ2*KUphghGLx0IKo|v%%8%3Eyj9KJYES00b z;f3C7?8n(B^E8y8;^YuccXwflyNrekyXCL01&|XeijEW#KK;CSh$wWoF?)?R+h{(2 z43VL_%uTEUw7FGg(M!kDh*ZJw^!aXp%+5kmur(-bt zvfuCUXWcCur}1y|0vhPI*^!#?EoRr*D>=JHbZpQW=V69njmH1i*XOyX(63L_tu!{6 z_yo#fwyY3Q+@U0}0p`Rj__{?X$Uh}@ozFDUU(8?{fK7n}s!P;45Xp+L?SFp?6^JjZ z>pZCkZ9GiW(akp7m}n(~+3j*A=g|-vo`Nr%1!NE94jZzLc--I`GsUpm2zjU)_ni!o z2omLmQKvp?Q-g0G=y*Gs@i5#F`s>9*t@G%Ejm|x|;g|&{AbjDMU=!|*)5!WMIdppT zkCRN5eB{!3Q53b$e4V4?Psxmb8-k-4=0!(VHt*j(xacu~VX(L$SvYaUJjL!HS%N!Lv|c9JDd)9UB=Ac>N0)Oj)wToR=`c!-^3 zflJL>gU(d0kr96CK?|noNhANAg3rR>`r1)uNsvm&KK{}Tr25+UJFeZB>v{^=JT53= zwu_o_kHaTn2xvZ2qGr4eTBhN474F%zh?C~r<3Kq>;GqMbVX})+=hK&Ht(W}#3vm*TS(b=Z7Z)_B%N|r= zCmG}HT#HeU5i7vP=qG`V_nuWZPua`M#t}#@o*4`T=!T(@+beh99KDp;R&?-!z)2zTq0{;}-;9O~&8xH_BcZzI%#FAW|1h6j!wn@e zG<&zrys~rDtN7Rp-Yfa_t&D~`JLv=|4=UFLTv6P}~*oWC_))?p`_8%9rQC3I(rvNtC@tg$pBCbDTe^pwayP$F25ML57|f<&Y?fMoJ4b zoJ1mHqpc3g)!KIQD+p_oQ)WTKm}oky#FKfanE$khj*wy z+<{=ETAJFWDlv4eyt=4VNY-1_kUMfR)pJY^wl)Q~@S$|htVd3ml0X&3-f231eGZA8 z1GSbv>26QGCBdw4?#^l&6x>lVFGH9rH#_4wc$@@s4_~vRD$9%;Qr_tFvHp^i%77J@_tW}i23Gjhm*Zmxi zHRHOT+-5u`qp{zo_RIM&WY&_^;eZ2m$1!453ExlM`B+4&FnegqUMB2^U9;#O`-juzt;rl-CB(qM>CcOg|G!8%0DQ!AH#P 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 bX9U>F+fNQ!>>pri5L3`MGHi0K*~k71dJF~= literal 0 HcmV?d00001