From 73678c57726d4575bd545e7dcf0b7f44e50c3bfc Mon Sep 17 00:00:00 2001 From: Mark Slee Date: Fri, 8 Nov 2013 13:16:43 -0800 Subject: [PATCH] Add diagnostics meter to show time things take --- _Internals.pde | 49 +++++++++++++++++++++++++++++++++++++++++++++-- code/HeronLX.jar | Bin 83708 -> 83775 bytes 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/_Internals.pde b/_Internals.pde index da9a7c5..3497afc 100644 --- a/_Internals.pde +++ b/_Internals.pde @@ -62,6 +62,7 @@ boolean debugMode = false; DebugUI debugUI; boolean uiOn = true; boolean simulationOn = true; +boolean diagnosticsOn = false; LXPattern restoreToPattern = null; PImage logo; float[] hsb = new float[3]; @@ -216,6 +217,8 @@ void setup() { * Core render loop and drawing functionality. */ void draw() { + long drawStart = System.nanoTime(); + // Draws the simulation and the 2D UI overlay background(40); @@ -233,13 +236,18 @@ void draw() { debugUI.maskColors(sendColors); } + long simulationStart = System.nanoTime(); if (simulationOn) { drawSimulation(simulationColors); } + long simulationNanos = System.nanoTime() - simulationStart; // 2D Overlay UI + long uiStart = System.nanoTime(); drawUI(); - + long uiNanos = System.nanoTime() - uiStart; + + long gammaStart = System.nanoTime(); // Gamma correction here. Apply a cubic to the brightness // for better representation of dynamic range for (int i = 0; i < sendColors.length; ++i) { @@ -247,11 +255,43 @@ void draw() { float b = hsb[2]; sendColors[i] = lx.hsb(360.*hsb[0], 100.*hsb[1], 100.*(b*b*b)); } + long gammaNanos = System.nanoTime() - gammaStart; - // TODO(mcslee): move into GLucose engine + long sendStart = System.nanoTime(); for (PandaDriver p : pandaBoards) { p.send(sendColors); } + long sendNanos = System.nanoTime() - sendStart; + + long drawNanos = System.nanoTime() - drawStart; + + if (diagnosticsOn) { + drawDiagnostics(lx.drawNanos(), drawNanos, simulationNanos, uiNanos, gammaNanos, sendNanos); + } +} + +void drawDiagnostics(long lxNanos, long drawNanos, long simulationNanos, long uiNanos, long gammaNanos, long sendNanos) { + float ws = 4 / 1000000.; + int thirtyfps = 1000000000 / 30; + int sixtyfps = 1000000000 / 60; + int x = width - 138; + int y = height - 14; + int h = 10; + noFill(); + stroke(#999999); + rect(x, y, thirtyfps * ws, h); + noStroke(); + int xp = x; + float hv = 0; + for (long val : new long[] {lxNanos, simulationNanos, uiNanos, gammaNanos, sendNanos }) { + fill(lx.hsb(hv % 360, 100, 80)); + rect(xp, y, val * ws, h-1); + hv += 140; + xp += val * ws; + } + noFill(); + stroke(#333333); + line(x+sixtyfps*ws, y+1, x+sixtyfps*ws, y+h-1); } void drawSimulation(color[] simulationColors) { @@ -528,6 +568,11 @@ void keyPressed() { p.toggle(); } break; + case 'q': + if (!midiEngine.isQwertyEnabled()) { + diagnosticsOn = !diagnosticsOn; + } + break; case 's': if (!midiEngine.isQwertyEnabled()) { simulationOn = !simulationOn; diff --git a/code/HeronLX.jar b/code/HeronLX.jar index 98cc1c2388fdef0961d977acb430caa51816b2fc..437f8e183b12a37836dbf6366579650545c8157e 100755 GIT binary patch delta 10391 zcmZWv1zc3!)8^9M-QC^YNOuTGD~+ItNG~NRD6F!QQqqWk5+c$pjR=BBixP^2L5RS2 z_pa~j$NSeG+`042JTqs`IkR`q<#!rRM>-CPnIRT7AqECM1_t2ml|jOfg#ljV)3H!@ zgY3}V77ywUP7UxwS2aKsx?Tgspz9bWE4&k+{G(%qi^Sr=e*uKhJszeAbX5ab;bu9w z@JpCzJ$R1@;0N&G>6rMCK{lo&bREMKhpqsY6zbY2hvkHWN&@~6zaDjMG$L>ZAmJII z5kLZJv}U}!r>Fr8jC%MhLbgU>VqSn0rS6}WD@M{_U`UC>T}aqqmdFXI>Q(*mahGA* z{&&$WxBbNLU5k@wl8}G5>>|2aS}CkDhiNySaYbA|xAdyP`yU27nNHq0)83P7f?4`{ z`e8hqkxK^)We1TwyW?BoVOb&sZ_ds}%NHWs8l}MhH-sOx?rwx)*m9Xv?DFs5kXr82 z*uFf^Y`yz1_BstUjM<_qji5l<%B$ZMr|zOgPbtE~V!pJMVUKcZk5W0Ng`Ha00$je$Ea3<-xkp%{BWnJ{KW)C`m)RT>E=3(BEWl{i<>pj$ED9 zZZJ(OZ)bH&=<~MCW0p?X$Y)>bhWDL6*9hQ{jrknmR>8|9<^ z%?&@KmNWe}UEUI!Gov~>>e+H6Eca-2?fZO0Os-hqcOKkRNuqV3-$&N|ulh%4T8|P^ zmU;tPbJLgHQh(18Mj;obNT+)ZciZM8OuKffucfG&tdNDkX2@uMXAm}jANjgAazMX& zxAllXPR+gV)Tr;#s#wbrk6eev?hI?hh1+tg0o1>12?KhT1P;T=PGibX2bM}$e^UjV zNy)*?^^IYl@?opv9XGy{`JWCJp1Bd8d1#y>?$6Q;e7?!bghQ{mysI1X^Mfjv4VX5?V_JXqstarUs4nZi z#k|Nthd;F-_hzY%j{qhHPouxiHAtz~mvG_3O3;X&_@rg|} z@a@M_;cgPwNme#Qt_eicOFO6zTvy4?ydoGkOf>tX@pes8P}A-Bd;Z*)h-jbBe!`(~r= z_LLJNR@}_6nOt~82c`Cd<=FPGSBGa$Rg^#TG*KU>aC+QRj(gTkbQ~;Op60kPO1!XW z_&SIuW9kcWlh``PaEDlU%z(#2*Yvc_;wHV(Uc}Q{W6p1zZ>n;8Ds6kGIKS4g8yij1 z2^4o@^Bhci#=|F0)^M)%rUBS6ap#*6+B?w&{`K2WVN(3#RtA>G@D*)A54)KlH}CL_ z4HM08ZwqT3SAy(K-@Lj#c|ejY^lUJ;h(*c^$r>3HI8(FP)^M>Q_*b_TLLxUS)j>!1 zjl3)2;x}6^Ep7Zk)0Bz$*4GARCCO1aJmmr=Z)#S#VPO_wFT!m-%PkoEM7V=g8*1sC z_Y>}vUWQ!>t-t>=aG^d1dr7;YS|$|Z65*m_V9Q$C)%&D;jL-FJ2=<-AbXDOg5A_}1 z>5<#e1=AzcHAML;$rzA7g$dJM&n^{2U!Omd5GS7*)qgQlx(<{GRk9(lWW{A~_B1uXgklj=qncM901cHDszVXa>7)|Y zYL@uM25Jm=%YS`xV8R<_78ePWaqR|>G(%O{J57z;RASd4U2h( zBkZ?pV05s6#hwL^4^KI5=SisDs<_>cx!snBHi?zhMiImxIqkI5zkPc$I#`r-KT?=a zE{}0OsK9@qEcFfB-0M8$X?qi;2u?@*tnByM#AIasoC4|9!{1lkg6+aG@asgJ+I_5F zk#F8Za6edhnII=e{Vt-?(mRC2sd|NIS25*owGHfvQ>%TPT9}(Xy+LwoB~WK1f9(F9yQv3vdRLD}?@#;Q zl{o}{-z&C=!ma5#SU$!#eB``X(N(uRbN`Mruf*GBx?RJe3TX+`kr{1u;ljg$DLnq6 z%|R0t6|Z}y*$UYS1K*OB7k~6#8Jb#rRdUB(m>QN!U2jWe*lQumN{Uw;mP7l)t8iGh zy))-QNs4V*GP@1GTPv?-ae9RAzJYPGjO4xf7qxDg8|f2Cs(y;2ZlyML%x|^ZZLbrQ zRui~Awk_&1T`o`Ydfh7+ViL#Jbyuc7M|Zq4K)NNVB1wkvMK4WCiv^W$pQ3RMl7TTR zu#piq}?ChByYu)O&U`6tLU*HD>YDuW3PlbV6_?cL<` zruLi->Tv0L1P2{$%>1J}8A%@$<5vAWo@i~oc?!3sbNt|=vo)#R{H`t;D~PR6<9ZUc zyufTES8|Y_-uMK}CtQ+2m4W>%SecfGN{=Zm2qu8hmigxCcWn;Fl35J@ZwQS6c>XYeKL)f)h3nwWp3j^!BO&|2iz1jh4-6m z^DZZ|l-(SZ8xLm6xO_jsB(S}-k3LzKz)_K0|MPt#Y<_+`3reHRroA8Ry`OZuxJ*Do60f35oHjXWVWp=we%Td;mln{J{!`s7GrSc7Il`)t9&Mr_ndfa`^s}u%yr?# zFvLR%{c5QZu@us7@Cm`RMqLR6>U@12yT-@Ym*it8Ng zDvm!pDic%NiA@ejbndZyEWg7wFTgz;1H39p6?I-`m3CGqr6sFWuo}tDi!9B$DR9+6 z@x;6Aoqo%mMp?1pN%M)s39B6Sky|l-BvlV#G8;z-{;pPro#B}+m}Ii%wmq=QjIWi@4V&r_LyQ(tUAI< z3)=FoTjfCsA0JF{DK79-eRLDhEK4kLSgxkHe0XL0QCn=gMREE^J?n}h^F+c>9P49dfQ|4z(aRQJk(2$ z35P6C!#l<9Ue`5?g!U|fP!-ce0eJcI%x4p>d9UFjuA4k@BE+Bd5)(%~U9w~}U0(Em zZ;zRa_^z%V=q`h(=yU~?2}d!+nW|PU?_P(gA7V!mTvJz=c`Plu9&530dP(JNX~S8~ zTgy$sV=>z=R;Cs^tCFCeDPFfilkDSH&?}_tkg)|i+)L&o#G#o_ZP*g2_n13Pin4L z6#F-=QdH3HVvo!=ez;timk=scfZ-08f?0i4#*$ez6T-WJbX}yspP-q}CH=vUIq_&7 zJ83(X)y-u^UYPLqn0nvk&+@`+6UD^B42h39kn+M@73^9fY>DIn)kM~sk+?Rj#kUg* z2yA6YtG!zi5-#59c_8gDy!@r#RV7VsH)K`buj~Yg>2eDu6uzE>A?w69+Q>(Cw z=&uVZV}xGYW9q}a>pibO&t=3k`FOI_${ol@D0wSrr?!zAk3FY**p{+3*5%Lpjswx} zQji=#wo*;x?jj~oo;p)E*7+(?j|PVH-BsN9NFm@QDlgW}E>Clqh`eHZsq>iZ zuom+yTT6Ys`$pEQ=FG0AIwD-IH`VlEge9U_$9Ad<(yA^dECZby1&X`(tkfp2#a8T2 z95S@H6bUw)wR-gwkr^89S$ray4wSKDopbWu_D^rzCv6PV8@ z;UCOZ2jNvT$SR+{R)cCAhiY0D6(Zd+&7H+dD)Pa5F@rrLSV$dy;BKtu>${;A_Z~*l zVxKa-;E6Ly?P9sI*<5~BK6VQFnINQohe771sVMlt+nil+x|qK z3^L17#g=%?rzs2!ohk~EFQOw>4ZUFg%5Ap{gLiCNo9oN=SbRSo68Ti#Rh9nF~8$@5L0V(j=X%3o_y z{qltAzQjZ4;Uy`T*1JO=QZNF|$4V}BQtzzBw{2E7m>iBPrj&$B!2sRj~B&1A|6Cw{`Ac+4t`TdNG z{P7jyA)}1LCgz_?raZja1tbNSM&XLs5~c5nSvV7H+rFF$B}80Gnl@h|3LF^4&=pmv z=%<_#=Cr<|8Sy#u@h$9~hhJZ=3Om3&-`mM#Ik655@3_#K)zWYc(f*R!E>LL*zVI5FCl?6q1CO`>~VI#MWPHyrIxKHhYCR@hJ}1>qHvb5euQ{Q4Y^r zq`wBJbR#B+H$Hm&B>n+Ekm52^uqj>&R`P1ge@tdS-1u~eG<2;2c?TEEE@{>l=1A`* zP9#xIuPw|J3X7J(d1#yOc#1nsYg-VolK5!Z!8epi{*z>C-LZhJ`pTLYS(>Lwr$pcj z<;YI!?Rer|~+FvcKApzbSe77E^YsBBBr}b#UEwzM=C}~reoQ)H%m$0*b;xlWxB#7OG7c5 zCOZ=BC(4;aH!CjkE{AG5+e)SjHf7E!wFAIb7BydFO=Wn2hZ9v5)dVp$-G>x zim)mV^B{jT%)8w5i6KM>*C{)(nx(EG|DhmNvk?8v1s=B9uPVb?x@SMtWaMzNb@9*CrgTz|BrOL99tpwW2JH zRoA@oq)CC)p0JuE|F+yUHq(DoJnb2+2C zxI>6&!WY5H@MWufygNL{*1*&tp1Y=PRAooS*nNYcvGkHre}gpE!5#BYFn+ov#HB@Z zD;c5(M|s#+mQNBZoP*z6^Ou>zs}<1}^%64J zy_JNGW^G221(oGrSj#@AO|ak7^ji({ll0O#cM?r4^~3sqyDy&_gt)L{k);h%{?dMaI_C1?=e>ebc|zjC)T8oePf~v&D`zTTvHP;izI&v*r)2+} zYJ&L6 z0eP!wG^3FtEgdY#Rzo)i3p$5R)U0pV#K6F?hp#-OZd^6Mht8?t+lI%G=a$hUY)D8q zS3wJ7)>=4_hWb(j`ph~dgXGcxm@^gyysL)_o(|wOwm7UnC*+NJ?(67u6Fi&Hf||D; zCgh*uJC6kk-T`}P$nm;0T6iA#5-kJ;RYLi~*+V`-dEPE9ur6}MhJ@#jFQOxpm1|%@9IKQh-&`;;FfL<*9JFxpa=gay zs+*VuD1K+3CvH#SM>R6AuO?LHs^#IFr?_CU%Lg*HPB}^5{_O3q33^;vKjzz|Jje1{Zw=pFT6%@mlKk8x zXw`|CVBYhg`@=8XA)VsmPdlFuJnelt^0eFR^{!b@Re~<&o=;@siagA^oRhtPK%2~{ z&2{2NOu^L~GYvQveHYhavYU;|Gnc-pd;p*Ld=2~Ft~1@mp%i*zd0>nbyYB6`vc6mQ zwRm~JLGnS$r;K#Zw<2#CPA++l z-;5Z4uJ7LSV*6Ub1KvxArp=CN_Om}~ zv!2ad^TMnu%Sskmnh$UHpKcm;%*`}!==F{qU#OGmX7qqRs<#xGBPoNeQWCSM=zZ2J zx~R(-sVF({nZC=KrG!|a%*e$8NnCbwzMq99)Pas(A)H%rxzWgK$=*GtsL|`Qczf3Z zxqKo&r(bpy8AY(MZ%W#vV$%0#bQ=L{xL&Z8-cwHNO6fiK6o;Y#a_SUJ?^U7rB4!S^ zAT|vN-tAJOdAc~sYA@4jYg9KgF#~Y*X^aOXniOy%#q)R$Ftsf?oEEg zKDp|85^eOQU!qtEyPidW^RS=0+PUFHQlUh(R;JY}U3~-T)Q!2EOn*6P3Ib#PM_0lK zXRavnOiEa!cO3K2P0o>%R=#E<%U*#K+m~NoU5e*ExtyC7uOB!RuO6j(`yhzo!Ww-( z?qxb_W?801PAhiBBqb^v-kh#!t19qo)ayp={q2PPxNV87$+)#ctiPQJ^?GZ)jtRZ5 zaGo8YH_2Hu6g8WE|hTg3? zq6PWQ59p4>^6gK~bo*D(v7!!)(D{u1x`#G)IT1w*8E1Tu(A)+9=tkE37z;py&C@u5 z02;-_2R=hRp?QZGz=d*YJ|qQ9(UJiLAcswY8Uy)}hw1=01~K?OPih1^K0wr5O9N~| zX*6fk0d8ozQwE>}%BZ=N1)xCdTG#*=w8X>-ghD6+!2`&nIuYUx51@t`H-efM5Qj9n zynqa(f$@SiDCh+*pb81md;k-ImJi^D?o{{y^?%f8j&43cVVqW}R0h6ea@mEj)?@LC$vjvx~TUlOB&Dhh-AEE4eRvUG4V34FwR zMSz$c1hlpqyv!xR#x9DDfx&;yn^hXJCYPo{j0l5iqG;w&G+DABz#?R32w+lUq25*F zquy0(xxE|HP5~Lpz#qnQO!WwL5kLSMr=JK&a6C$ow>g9$T*Lr2c2ot}4j13y;$UEe zfwOUbx-e}}rsB|iVNa_dl~J+5s`H$SuZP$c1EkqdBl-K}fq}tw&IpOn5COR`RQqvpFzFYb|03`^kegI^BH-Hwhh9WCTf;1V|A?^T4 zfD5XFs-+ZO2uP6!QV5*OeiKnI`Dbr$p*$;sAWwEFfDc*%22!BXDg=sS8b*Xj2JfM% zeQz!ZUjV5hKw92&l**z1T4zgxe;k2Y%*QAi$1sRnOd8;T2F5@muA2HiMwi8M%Y5(NP}Q7nivus+a;No7DlD;CZgD~hO*`BSu!2PSv7!3BOF@4qvD zavQXyg>T=cfUF^kHWY&P~0Y+#v_9(4aCR`(jQBw4> zpX-eq|J`5hbs3XP;Lr-eAI@__Bg#g(Wo8qe+mony{`>6sUmuSg(1-hf9DHL&x~0L| z-2=yYeiIuOAYAytjigjS2!0><+dEKGks${r|Dq6WP*q6wKL#r(gXAK#L1+;Pf?Xc0 zG|E*>9z-@DqmkLiBnW>L0_Kj0L?K$`h$4P~0WMcgf$&lIGZBBEX8${?#45CTcootA z3=MkD1&8JUZt?T2lCKu+#Z-$90)-D%0K>C9g%CuY0>A^UuLwL(l{&CC#o*V9^Xp6L z8QPRY5#WSO3v7VkQ81nn*kjLcZ}2QL&sGm)3SaCYMkpx%sVB9Ae&`R- zoF2^dy!qXJG_!~@Ko2p?ta=Wic6=eoe141e4x&w?lmR9vwLDP3EFD3|%Nn8h8?WF~ z+nyY_irc`S^Q|Ly91hIV!BfYn5hkjC)`7kX$ipy!0uYfZ00%@~gi^M@g{*7evi!9M zR6&4$76il*&gy?C98pT&Imr6b935m0bsU-wTGusP@VSQ+1B3hAo_f0g1^fbfLIDZX zK#G%(5XI>lF+yMMPg{0I0i^4H04Br}wLd}IQGov@1UPL{{7sQU9Rw`DLHs)E058Pv zk5U@%L)I$$e^Nwk;hG=fV&FGIj9cKcJ->{e9Y7Sn)d5b3fM?4uv4k(8!B3Y6yW^yUImh`T}rnI>Ct+Jy(@Igt_LQhp-Gy zurhO40GtAg0da-{eo`%9fxqrt0EjtId24oItrh5+h&~0Pf#fy+TpFph4r{lQA8FSm#d}nRGyCobF$U z91(c|)Sx<8GzyYt{1+lar;UQ@C^5vPU5!vyj}3h>W;6vL(AR3nj9%SI8=qQ7B3% z;(wg0Pk-NEJDcphhMh zZo1guW|ix(!O{URiB$rG;d?JY1aABBQP|f2%@KwIzwrR1*gb#*22S7$!L1U2!kXbz z{gqQ?0Ag$`J{f%f0ACz#`|(BL79fx~Y^%`(HbgLxMp6j_x}=wZQxKzOV$*EdN@KQeK0_2`W{B}pC*sj$3NXEMUB1xHl!!uWhA`TjcIis5-USiCRzmJy z674x3<&jH6gbCaMewjwx^zw7u!{ZV=L8w=EwW}|b1^j{?%sU@7J#9L24qEd; zUteq(x@;CrvFxB{VdX}7qdNgl!pbow_D?FmUnjCH zZz2Bpkzy-;1aE80fSR;{;M=E}#-TgcjMw|f8a0}+{O+wUr+3VQGfsYZIxn}LB`jY& zKeHpuD8JBhlPG>qnU*~FlNo=XKVe#N$aSa`uosydxd1^ADw+WLN-4=h?+3@Egt0ceYbqZ{9y{J^xH;x_4&(ZU(FG4_YG3mzJCoFP?p?X4~TRD|-cDO+Itwh)w2w{TJ)C z4SP4H_p%xPglb_vEgDSkJ*eDoX*=ka-OD(6@Rj@CUbz3Z0ewzOQGH-!)+gKkCkdIK znqKa#T#P)hY+qWJzeP4Vjky&12;n(K*36-j9HB>jT|=nPTHtNcv~rT`)B`^Y&*f*ZdiU2b>LyhVpsnZ4c0-=8d;JjXoxh%?>TZG{n)$ zQKKAjSK#`_EMZ=3M{5vWUY@hML7QW z`(Add+$X|3*%O^nk(-1=N-gec8!qzA$a9*So%zkCoG8aU=OEnksZ$s*#;*2I7t?(Ug{nHk{~Ghwu;;!L_wU+T(Uu_bG^9Zq=Jyt(_3(pm$0tt0 zs|iHJHr%IEh;jyLwY8sjG?k{6Ps+VyC^Kr@l|u>pH;;7J=ujPH^S!89#SmY@$J|eL`Kfg5~o^o@%!vqEFDKk z#GKOb%(EDUnf81RPRxCLTjL1T^vw}+gVm{t?3iy~t~sxM<%rOWqU^eV9kb1kqCv3q zve19mFKVi;##&5jCXsL7@YhyFS^vIvQxrjp*m{^U>J%=olSo=hVM-<$zG27S@WIR9 zQc^K?_9r7U4!wjLGdaEJ`fPV0yPLE|i8_{xqmXq$Lgym34UM_i6?Hpxi^zmeL1iWN zQ#rH56_>GL{HltK+Tu5FV4P$+ zoa5z7pW)f-44ItAu5 z?A)dK9l=r&URl;DB=YhtMr>TL!yLh#L$-nyw79|N>@uK^2}p{aE)_h9OsWuWWbhrV z8H~O!|DnVAvOFS2U7P;mpcMicQ}M(2(L8O_EqVF@g-R(+wl^onHIu4U#zrr+dfEgy znh)UDc6K`2H*)UHY+AfcCAM8*FT9{i_la~yZKyVFdy&OKlW+0Wj=)EjuhPa5I(r4J z%3^ulN#?rj07kfnarW26Mt2$TjWJm=Bc;cd7yCJHErnDpQGer@A2HgQMh%f5P?@FVj>2AIhLTaY#qa0bwgTey64V&dkxO%nnwR-8i;J$Zlp58H zngS!U7VB;lio~qrvl8nU^;{lWQPZcVaqvs+uml^2^URqbgVT{lT-{Q0)T2(J4_o{- zxX)&~t&`ep6QXUy%iY!~cCO@6X~y@ezI9m-+zBJLjSz8dx!1PcBN=wBx%LM-UBM3- zOw?G~Y%q%{LSCO0*XZqIJpVqSXDe1Ke>d*as7IXC4k|duv!KPwBK+Iy8`S3VP2@)5 zwy#C_)*8=|l{OE|E+y-@J~ZzgQO`;<*uJUCT4t9@G>wQp8-yjlSbR4U$IPvRBZc4SF~3T%TR;kNNqCJvjYBEPc#{htUNNi1zs2 z#O`e=pZn8fPh@-iI-Sn3N`zhEGZ!l3k*c(MT!%Nr&~ky#+-03(r;>dy{Q{AJ+d9Ec z9yh*x5OKDddcG#97M5LjsO{>|<7lbnvB7pdTAIfivRaLilbswxqM+qgc58-9)025) zJuBj-(KgJbO&5pLV=l|>$l>cYc`YXvDAO;9NW0YGFX#+Mvsjv=Wkb zdnfqZ zrlh7d9^UixzQcaq?V;A@RR_w`8kH8CiECBqGia2KhUQO}5uREenr2!>G7s8B(Ths- z+kG$kgA*T#NIl$*$4a&~@|ty(ByxXP4iH}$v6Vr^rnA`wzZv(f>(VNT7SYriLDL!R zIBdM*%Ey@Y(@yLJ#C$gmqv{%cMEy9|{rOw^PUOp^#e!+_wS=g6BjWUwpg^r)c_g;Z0xEBm_SP`IZd=)Tf$HX`uE9{z(-W3rVE!AuVYq|OCHve@QpcMCibZH$BxpK`FH(N zHTvaaZ%{bzh!~j7)F0b<3t+6Vv2f)UF63q0su}?Ed%jUfd})#1p?J@N~*}qnF-RukZuvyaxB?G)=*9*rfvGF3AVvOfcfd1i#th zfQT_B*OD^XSmpyU$aSQTM!)BoYRzkOg-HzOy==UyHbh_TA{lXHE&;(Jdrt51@EsnjK>li0U<9 z_|AGeZn)U8F)PaNxixBpU8Li3vsYSv5o)9l^C!L1!!^3Sqq}#-bUz%QXyBgNi<&s) z#2;9K38kdFtV=PM*hOxl3ItxNs8W9RyIt&Zk25+9MeZw99y#yGBd#(%r^G($q7&Qc z^nmrGM7e29_kOS2tZGO7;62MgAI^~J7x`VrYVz-SIw|&_o@@`Dqc@xxSQwd4-LSK@T~2)$*IdjXX+b z(>BI>$TZg%GU`PMW#X172p{d3VL~048Cnr8CvIOV4)2`xR^H*gMOvXk59Uffou4$? zGDuTM$*DT1nJ`J=-yL}H!&KJz+uRqU;onu5RRt^7?rWvWmkl(ES4$ozuM`hrKbVqr zXMdrbFfn4k$uGopx^%|Lpdfp-#HO(Ev5-B?#Iy{Tq%4S7^c)^Yw-B_+!c9z@qp&iw;EHWp%m0QCQUVXQ3 zVu;@g?&nYh2dAx{e%r(=N^m)}I+udbi@3Wek9|;v!WUm}#1P>kOJSC9`-DBR^jH2B zWW)48R^+8Gixa3&SryInrlq8WFdrHQo9{Bb8LOePyROAKk;G>&h*F#^%9W?8u-4#+ zoR<`w@6ZZnq`Z%(Q)utX=7lU}H7l}5Bw$ht?SDx=CV5wA&t?A$;WjEs7;w=smpFa6 z;y0C^BxUdGbXS)=djSfOtjHdhy40a@z1AS)wb_jh*LQE1H{G|~=P<5y4Pq1?*-zpV zUOxvcrQE-Rr#2{s*Cs-r(2jV6DMkknE8*jZ{oX{Qt(x?4-Pp$~#zYMc;wnt+m zRufH3Dh6|Fqn4$JhbzF?ky&ugN^>{J_Iwr3C=eNBY&B-GL@He6;ww8K6=(8yeK+v?bI}Gs;KxRB0^v7%#x-Qo z{)Exmnekxa{mV(E9ODj4{FIqDP1h(ef*!I2QR(D7musB$YUGsjuHC->!)S@S;Ip}r zbY-KyzjMv!?b*98!|Ua$rj_hgA3UT>=d{4SU5X-Q0X5L8;Qak@BFT;rS?wtEKENC9eGowBnSUytE`++J!9s{v56JtuU&ZB z_VG8Fme(i0;cHD0JZ@SSV$QU=d21&XbII8~yvOaDsHSK6txz%Jl~-FY^BT;b_)~fq z7TOsRU`iVssP zX*xgQ^VY42E0sP7RTo3D_Jx}Bek;u~6=~a;^?@zvrwP@D_@Jj<_7=c%tLuhQ`lh*$w{dtNsj2XWd%Vz3_h_N~oQ3Ci`BNXH zDN4w^_2RY8iFBjfu*0&X)lyz%*s`LTf2~_JVa=FeBMtAju zLY`yCI3nna%GU0PV zcf^wFFEvH^-Xj@Gda#ciV|ZZWG#te`C+{01P?A}6@zx)M7KaxG>;#h85(HX&r5N#@ z+xgw6TxG7b&Fr5LDq<6{)DL>v`fE%`B-XMqn~M1%qIwimX6j*+v?8|$gnPZIHH#&w zJQv1LjZz`qZB|ad8a4P0b0U}5DAPz9?`glRBP{3raVf3GP21ZhpP{^rMJX0^bUoqv;?Pd8CxtSv zSeb+wvg;JLt9J7w*LYpp72Jp`7Di5A8*?*wX>E`3Ztg=|g)f@Scx6O4}b>afqLd2aaQZ#7T_miQY zp`jt-s*TfJ&D>a~Th_%Q%P#q5Oj31IMKnZ-y6xXoUcSpP0Lt^RA>ooBhCxQ3d(G5u0tJN=zU zo~UBBvljiYh02D#+>ka#%4M`SE~x0HL{Amyy5$?6TYVmyQnq;Z%52JyWXT48igIDL zF|+RT<&}olQ)^zk31wOrWd86+EUiAblIL;pqPTy?o9L@F^&&Rxf(E@hyWv0}<^s~Q zc0EWi`cGjq65o0Dr>uF|FnJe-8-%LZA7YOwR$$9j0e8R1N z3_h6DL33@*rEvE=TRgqu7L31`xc>o@+OxWrbdkeCzxrvKEPEy8t`5un8yDoJ5>CXF z?Pnok!_7Usa{}dU`jA1YG#nZ;9bE3iwmHNkku^FQwB8(9Z*&i`cb_EckBQ{R7|>6o z9Nd^ru4hsH$`U89zJBl^BYNkj)A{t45aTzyW$P3-T74y79Q=tzpKn?i)?R)Lj5Fg| ze6K|m721J__`=*is;w7TQ^#!S5Z4`LieN7pilV|#!f~$OR$aTX`qZr_241UeOAIid z4XVicj8<;C@>_5C8;RFB;=0I?EX*eJ!w;z6To?6qvY({NyFEBV|7KfH+aK9*i}*uS z(W4aJ?OiIfyvv$)ih8YzYNX{&8Dz#upFz{(_+N-#m&O%&Ecpj z^9@xq?9{7@ecOt@HS;nvjmPF@caolQ1o%^Ta!mD~>n!t|liCT(e8=zPUO>PlixOWd zZ(oV&b6hm~DEJJh+Tiet+^|RgOfW`{YyHtG9xqnXa?99|4yLa=Ao%;Lngs9g?XUsI zDgeI~R^;-;3FX{OIH8-zniQt^#rE-GK|sS{B~U|j6CR>Zj2GnbceNT>62oN(Lq z94=Ik+cYjh={0DZKI}}kw;4{@@@c>c&-_YY9jtx80<5APh{7>fgSv2Tq;C!35HgG! z&YxjeElwbd6vibe7sG}_Y~tu}nffQ?62lIe9$dh^6VFo2Iw&B(!^cRZEBu1&i__{1uh4}A{7Go-TX%yitl##czBM4hu*Mu zb!62IrT+M&hwtsJ_0@`=Vr8F5VLS{*4Cz9?PCg-*bs`{?=PmtVa`N`L|wfwx_*w$=E*f_mLkj-Q^Gch z(B)89v|y0%V715BOV5={ce>?8eV>0e^|5T!nm!A72-#ZQYTUTMRyi;0|G{sMCaQx0 z6TdeptV>DO_WVXR6~}W)x=V{?`lGf~%LAEXy{Uw6>1%Z-zrdX$=T|d;>Ks)_^r-E zZ>e82&rr!k@v>WqzoMjmnm$IysJ}whKVoB-`_vi|YJHalWJA$o-Z^$+g zwr9u}NT~C7Nn*qT34c=UY125XS7ERjcXG733oUU9a2_8DH}Ws7}whL?v_ zf$18S?Yqhgo|YYz&tq|p>NiLnARO`K3Xa1%G7 zxQFs^R^6j61QhV>nUUDohCXcRfg7g*I?ziII8*I6aTG0J${FWieunD=JV(hEPT>&d zC2O2;^Yc9XRj%6Z`%%`Hww!R$nzwav8By)t$0_Ik5ypon^i0Z|(pe~M4?bu}0-&n@ z9PGn3wfg{oTjFY$2>@Z(sun>E@Zls465tCV>|oetx2p+qKtKRH0B6+!@>*vK0JnP8 z%25IaIFmSP01fxKwv!&9!C}*kfCElaK?3=3j@xBpY@hkbnUCh6zq` z0WyaL0O`2_C0MZF2H-D?U<@}P1tTroM>>DF0Yw;5yX^MVP_&JOC$rN5l&# zzyf5!4BGJm9RKd}{@!)+0;(_!IbjBQ_y8{W&VUb4gM}2nBPXMLM~X;(Koh1M`2ihR zsDuQ#Z2vx0f@A`K6zkz5V3oCGSPhl31X`|9c>n%A3I#wL0RaBi3dRcn%=qh^*hX#! ztRoi#I3)p)vmIIot-2XbK}Kzm2lju)c#lHuxgl-Nf13RfVW0R&@$gijPo;=sn!!BS z2_9z9QxG7B)4e4K1)CNH(**$mILK<1i;+0A{tFZ0;qe|bosq!GO7er0LPw@3A%Gb$ z17(E(e%R9CUB7w^WKjrR$YYjX%Gf?-7BKg(WjSPtFRp@3P+E%PY$0Lz>G(cz8_5G$pmLiCRc7P#7SG>m8+9S@jvxxb%N2 zRtG*32E^dNW|!$B-#|(vkkWB?b2?Z>T_i{;^0&t#P~IPOvGRI6V3+t2=na8DC>SRK zNWtz{ciz7vhB6C+>VJHcn$55%b4~$69RQz>;P9h8d=gS498>6&Ka34ko$FY4PJm*f zfF$fSCXvGO4fK_tfEo{v6+N#__!Vslwg$@fPj7X9}>6Rj)+qrl{i2H7y1ed zUQZe1e;Vq8z%l<;po%yk3tNYXL)M1guyva^Bgppm!B#YpI1vC@XF}F|$E=He4z)pY z2>|{r11KT^xp4M_T}=5g!!BUoafbwL08HEuItlhd_b~D0kl6i4ASH0WbpRD5A%Z37 z$bw$*e}@G@FRB#{B{dEuC3GyQK4<#_#21b8bV+~6m$CD<6$HP5%^)?EDykd z^$%kLGo_BITz1Gb+`%y-k<{R~zs&w2vlfkG>|#!VO43I*`qB_X6^HeR;{fCTf>{s< z@PPHwM+?a3L#6IC@P#yh1liC416+u+Xb9y>$Dz>q5Qjz|qGZ|N1{$Ep24|D~pQn?V zHX$kj>i%o!Vn0@fKyV!mh{3~8AsgY#4$a%QC-Cstjwzi3m1O`C_!-PUBdEdx74$xI z9akzYIE>GTWhp!fZPdqR2l!eBN)W#YYgC881{6_)CuNUTfqw_p|4mG@^iUhrJqs|x zf#G8-G>TTxtUSJ?Ek1@ckzm$YfCa8m!&xZUWH}7}ID52pAY~zNry2&0WPvlV&unwx zdLQId7n;Y%ANcRJkfspW1my|)>_0Rod5NuT;s@#F06G{Hl!HL>S1{-+2Qb25+#zV( z1c9Re%s(H3C9RN81js56Fu|I#@(`%o0fSzD!Fz{bXxAZ#{nbSY4$2>8@ZpfK?}dqp zUh4ld#Muikq4MM5y@amg)9(Ukq;Ry;#wtKg#s;w)GmPMC1>g)k?f@6nM`mbAnS?4U zer()>QWXIeT=oARdmugGV>%1(Kzl_%9_~@DBIKTT3UZIY=1$Rrw-k<&|9wa#%|HbA zKTuZ*0$+TBKqfF0`fU;%XdsxQj0PGKB=jJP9t+g72y2cj0o;edQk5ZVfzL1|r3|pZ zUGcV^NPGgNSU~*0D1ABF@Fx|Ud96MUS8l-@u} z$H%dY2