From 560fa99eed7eb552348cad41a225c4970c1d1e45 Mon Sep 17 00:00:00 2001 From: Erik Ostermueller Date: Sun, 8 Dec 2013 09:58:24 -0600 Subject: [PATCH] New UI checkbox enables user to capture stack trace of every 'exit' trace event. This is useful for troubleshooting like this: http://johnsrandommusings.tumblr.com/post/33371606685/javadbb --- org.intrace/lib/intrace-agent.jar | Bin 386624 -> 387403 bytes .../client/gui/helper/ClientStrings.java | 1 + .../intrace/client/gui/helper/InTraceUI.java | 20 ++++++ .../client/gui/helper/ParsedSettingsData.java | 11 +++ .../intrace/output/trace/TraceHandler.java | 52 +++++++++++++-- .../intrace/output/trace/TraceSettings.java | 25 +++++++ .../intrace/shared/AgentConfigConstants.java | 2 + .../intrace/shared/TraceConfigConstants.java | 2 + .../org/intracetest/agent/StackTraceTest.java | 63 ++++++++++++++++++ .../intracetest/agent/TraceSettingsTest.java | 5 ++ 10 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 org.intrace/testsrc/org/intracetest/agent/StackTraceTest.java diff --git a/org.intrace/lib/intrace-agent.jar b/org.intrace/lib/intrace-agent.jar index 19af344e539fb7ecf802266ad42a2b8bbdeef064..2b7f669b8ab4bc757237ac294d14e109a75d3972 100644 GIT binary patch delta 21715 zcmY(p1C-#vwguX@F+FYD*0gO~)3(jDr)?Y4oVIP-wykON&%N)zzy8b0s@h5Im7J<1 zyG~A>o(Zh+IV?m)8E^1QZ&>kh9vtd!LC z7tsgQKBiVL+$x;dC<-cz_UCi!IW93{@*d2FunPFM~jgP(*P6k=xIw%dGqk*f2 z@hK03APa6gPpfF{m5;^{E@sUrM3vN}ETV(!m0!6=%pGi*n9h|xqg?%<&WOz4mI4T- zTAyk^5a-c7L_-6KG9Od2!hLdYMAoKL6J0*u*Vh;I$iVxn-ZT0ue;hCi_v8#}rUgcPlgRZkjO%1-i)^Mx8A?UV=t3tG7|(qX6#7Jg+yuR7)`OPg7mn5I7KD(!j5+jVEvQfy0Ju$&er z-OJ{5B!VrBtL+L=qn0-q$+2gWF7Cm{ucF!lCXvISj5#yyAu)M;5d<{QQK2KYLpCj8 zm^+ErmKriv*3WfbtT0gj-b}kR#=D4l&5vZ!bCPxE?^>cj6^7<9C`z z(8Fzzy*Gnl+)Ilo^sr=K@tIBbM5J6PnR7h3>WBLlN*9J*Guje$XR2{ZqEcF(s>|sTyIogT(23wd%UFt0xYFhj~n3 zRwHb{k3K2c6Aw%*NS<=Y@`Tcu--xvI&fMwY?E5UJKfV&IkM=59{CXXxY84SR%Jq7l zyG)ejp!)P7W6y!dE0a!+-RWpt9_2JNu6MRyO8xW%gt_ff-V057<k1rv_jVR5t)QlUGVq+2qVhX|)bDF1Mjv4AKypYd9EG_S5FU9KBjJ`x{bjX+6e1 z_e2pTe5mvEtM*J6Z|C7#@GHDk$rHH>MmEh9L^X*}_?AM!J80)By!W@RsZgYUd?nzEn&`S2e+JnGPSJZQu?e%ia zJz8yc<$5ZLz5tdSE%EB+6h{l}_%mzlS<~S2uCXwMdwS9ZEWiAy{q4MS%8riU-7?55 zq}UY4s@QIpq45?`v1j%w1+Ub&4DG(fvMxwngPzG;M@kULblB;n`1TdTDbCM`$Fk6y z*#$tA$%j{MNT($5Qb@?sp*;UrpZ?gD!PmD+beS{_uIu;Dfj{R+emw+J(bt{qC$-E2 zV_?rn*9p-e1jG?fH=sB->{_0|$d(VJS|2ck-Y}8074+(wZxwaTUB_?tJ{S3RhxNJq z%y@g<9^hOmKF#iQgjEP|X1;@<)@0Fuj z^Ztj!#Fd5j-==9*&Hv%hXq^8K_^#daKVV(=8sop5Nyq>9Oq`26gzdM4mv@>06_Zprw3P9U~{yyer@sw)0FL^G9Os3>0#w zdIwjYLg)*VUW~2CkDxb&C^@#Pp@ z4nIVVL))LH$stqi!&z#zqI;}_aI1@tz;|#{rc@XXq$RzH{fU(6F;v9K$L$fn&|d05 zt}i2=B^HoNVxDBy;zR)dvTFT*UOtf?u>SqSMBI300NzJu(RUa)*1l^r9rUE6V$2$V zZF*PKr|5M9^COEf8V;p`b?pO-@Uf*g&{&4M9n3ng(XBVc$ska$-8) z8vLtBVk`UG)W!+G$oFw+^~y*L@>pc5i!~*YA>Vh09N20M!~%Mf8Ylwpl0?>nm?yW@ z+DOrEo*p0`qJM#FR}(~tbG(u28J+@48DD0AJEjT*1NJ#~0C&EmZtMeop2BAXZn7=5 z&yyGHV--3Thxap^9`=TE$#McF#KP<8pAGsIpk0nm4rbext6_*94&27h1Ee(VJ{}c zdHDRFwf;D=n(14Gr}(784HXsdV1Wk%2op(mwnDD8$bC>AlndJxw8dJd0`RR+eFd?-C~UaLwSD%8Lbt{4f{q z-Oh#{iRfyjZYXR03-a!YgVLdE+lzx3G`QK?hwWLK(d=THAsG!X7TW5y>OH=@plXgG zJ$H5RZf#XCjip!)5D5cdv<&K`0m6kEBC*+2Q1xGMj;Kye7-(FSCvjMJw^82eCS&P&yHATkI$bQn^bi<>-7fQ zw}zG~=9)ku8wm;GH~q;72gkFr6^e7K4JP_b&LP*YEe9%sq+%^H3m;xLt{rfVqSesC z`=NbSn^#R$Hi}hfO@XlvGoe-BP>|Bid@7SUA}2xsZ6#s<;QOgu_UX_A(nT+#{6wFP z7V;z9iqyCHbYfFdxF(-G_za)Cbvj&IrId+3g>{_dH$14Kl17)tw$g)RxU-D}=?{iS zp#4WXY1gQt_+0+_W(uJpCQ)KG6{dlP<~UP!<8i+_I0tchR7HORSKpPHZTv`~ zO|zvJ*G^3j3zr&B%R(nVJ>sHiK34)VO_ON}9@*@hVp6{yl(qgOHLF16~Tt`6V821^b-u# zm9{oXkviJMDQb!kiTrm4vlmJzhmsdsd-lVrmEOYE5X>x0qn4#Na8SSLYiLlTa2-Jq z!F5}@k#fvsx;L=TwJXRhU)RCnJG|wh zZtCGP;Y)wXAMR)A-V@&1BASvT6oW!&AAD99`CahaA7URpq+3MFPn_7%)xWAnV$x}0 z1V*UKsy`+VV1hqx0gv`Ckn@mz|6=Guy(2L{E{xf=!U{6|Ra#kn}AtBt&IV$4ZL3i@CCoaUc1`mH$lWSBxhIE$}r91|S^>+IGX_@`65hr`?!>LK8 z$_u-RP5WHSS4hj(TvH)Cj>sykm<0T(_N!EEyW-)1?Y8wks#$OZqcFGsWyE`ojb#og`T$>+of;i z?HFbINMZXBko|S#uwY-*UkvMElkO{#@qsws%aZBjsdB}@nc1|R+5`-j&tP5}<1_o( z<@iq*>*db?RU`Z52{oBcZQSl9?&(8nmK}mi;TCK^YRQ`DzDY&OYmp*EQk%OUUfCpC zdS$TjWluo`ex{Y#&qLrfRZOL*AI}*6v%+xAZgSSG_#+X|ItMQ@v%8fv*Wv;`r1j{J zQN9RW!g~Ljm;Hc8cPYIT115Q!?r#$E&DxWIgn=!fwW1@~eL_jPg}IWR8ikxr`g2R) zj`Tp;hqyXr>Dg7jR+O#?zQE;xfT)oiYaE}8l%eny7f!VGV!~MrnWA~=6u$i3A8oUJ z8l{nbSu>ivR06Iokk&Jlpj>kh_kr{<5v5fSrlbi{+W=#`T+b5UPGxda2`8aOHI;7;KixVB$cgvVweEtFXDL*dmqUiQ{h3u0-Hl z0?N8vLYb`-<%0W9M)z{F@vM702`_ZLl4lnH_$lyFR~3|aqh=Y!h-NL(m8^GT9p8_2 z841}SM|@g4FQZ{3=cH0PSeu5cire#rf2V>sjdzER6Z`kz4{NZ+erq6i6y8()k8TWM zKaPX!$`0*G+M#c5PaxlZFtkUweez6-(+!Xax_mdo{G8emjLnM^mlnt73MVf_q)X-p z5LtH$0zBCiBTQ2QAjK8XvU*HoZ>gfTUc}Fh9_d85ZO3xV>6ctZN>A_v57pfVsVgk1 zy`aRB)q+}ddmAZh4zOFEb(q5*;O4H>q|Z6}d7CYvaUF`7A9-{`pkg%rF)c({hpEkS zqix2~HFVgHIw@XBK6K=#L6CJcYOk#TI2Dm9S}Ga*+zJVHTZ0%V$LQOJJN~0G%_5^s zA65b*+=o&lMwOt{li2&xWE|CdV_IZ|os2idYd+VXScuoz{w+_1y^Jxx3xN<^LTjwpQ2`fE{!LqPcw(}9oY2CIa1;?d&tMfGuQ1lU z2w_eLkEL%uBk4EhuOc$23mOuTOU2nyvURz3&KqihN>@}JQajFJ*tsLW7&p=mE(?FG zJ`RD>02*xWREYYtYtDHC^p9z!Cl+&dksrP zXdluZ0|VMbVIdguPi%!x<)7AvMEsP`OZ=IX$Z$UJ-fMrp=P?ope4XuEo~lVv60jt> zDODRkC*<2B#_W%WvLt(aH`uL#g{VJ7mAUoI0_oYb`5;p{r@HpVp>;$Cj6JFYl;~8( ziuUX*LUk$FQ6_L)_l%4lI?dGc64>kG3vDUE%xk~7B<3;={BOFT9~HD zT8y$j_&x(#+)@N#?TlrsnR+h!d%B0;wvV%qx$<+4Ed&mNy#tJM3MB=O!j8GVfCR8= zj^0iPMwXu3Y0NC3@eMi=@>AqpMg1oC@8@{OU$|a_LyKzk_inDEOb8&7v`gy7AQt?y z4}#=#&m`ar<|_g7U2p4){<=fr=C39Z1|2GgYNYT24D{0N%7n(B+TLk7qP;I3tsQ~h zZc}iqc~5q5d1mzb0ldI=82;QHatH(28?-=1eCYQgSkZUD{NLT3zct(Jn0C-mwq)+8 zK^O?#{3~Q`T>n$7IrbRj2o8Mt*7bY^)pOuJCwH_(>>xteQ+UAt>xDg~2XyZ`tluQp zPBnS&-`4J$p38(C45d4Ihc}Cx!5|MlLWXwQZ7_{W=TsiUn=g}e>45dbotOR|ceHoy zK)@f^X@~9lwZn;`OX|Vd%N__l4ElBWud9DXBc6eJ3iHTkP<=5N0&GKmj3#uD!^4h%cVrT#9GxKmoa%dgCDH&1vqvJ`O2VEVuYv_Px6^tw11k zXBze0Gw{oQhY{^v0s@HNIUWMla5fkg+cgQ`or%YMC)fW-+7TdqriB2Kce(+hXIzLc z%-(IH=gfV7tbdPAg#x}qQ+5*WlcRcz_}L!jlc0CnIGjYW@}N*$sWxWVtjGcH#u7d3 zIcgLvm)gt}TqD9zqqwh3wx7Zf58=Vw&qiBC`osQ zhmtyl5&1UAvgEEbv@g4RWZzxN2d?O0nvEMvk)$l`W=NHxoN? zkqRq$BUxs5PwId70vrR5;7GENb8L!@!!+UDGwKa5xMm=rk6p3F46Zr7&vsDS6keUy zwnct5)PGNeGnU!(7qJnw&GD%PKc&i^KqfV{Cc|`#N}m@6(Z$$A-_mlr4rjo=a9aBjq<6y_BVPRIK@3rZN0B${(s|{OD0W zsm&3-aHlj9{Cr7HrQbSKbCnpU92JWEfsJDlO5^(!hf@m;dhr~#hXxvlkDZDYU*G_v z>Q$iJ3k2TSW?DX8h)gSVD$P@0<%YrvbQm@UCj>N5{xPpgr=^jNp9Bgi(uscinMe1bqN~`lFa>-bEYqK;YQvCN^N&v3P9A45rc27Df&Um?vknhk62Aupt(DI6(c>zJEld@AxUCpWsMP=Iq_~L_ zv)Gt0V`9&yD9(H@nf(@3Q-%vR&)T5}HCa0%$6+l(a1PtyC^FHaidy*x&^SqrK7m!y z*Ds&4yW;FWcLlWt50T}=L6CTWh_*n#Y2?i9rug@pKi66O$8<1bsp)4V_+EK77 zY)z}^&O-T)ci)=oChbmX`PHHWUd&TpI2~~ejdb=|YAiV!)qU$HM{={GzP6t)8xtdl2V#;rWAhTI(HrYNC?#yb# z2zKw>P!^dWD8$313j{=d+2ndw$gCs9w3!KBsKjtPI+i$nIFCJI(tJ+bAXr2>B6@acf;16 zsM~`g(%lh%yB3EStmA?}C86xK(@(`8RT9|3jUiRJf_1U^XxS$Tl-a2q)&mFZ6C!`H#bl=zWaL0vV^+I+auEKe4{F61wQ8npBNX(QV zi`6g>I#IBs#FpbYflF>g;&Dgo(=3NHp^TaRHdK~momSmR#nMLBsc6^W@YZh;WJ4i; z)YLM{H7vgiYg)O$?ke`FbCvee2}?)w^SPD`Tx~mI+VfV+ zCkIKn#w|G174Y8rIf+k)Fu;*@!m#jDQ)bnuI264SJ#zv>Yv|zuYLZ|uJ3w4BOO`YRF*QMQ6K_oVxlFk$|18&&buTa;OjkYVmUYho**oX$24e%LPzR-VV&M}>=t*fjzHSQ+h z?5{0_Z%^+8_Y&o#ZiVI?FRn}NIUgE;k_CU5VY%o zsJ-`A1$Ler{B8E|N&Br`jY9~OG2e-Zr$ZRzzCh=TXb4sR#PeSb8gq$~*R`iab$*F3 z4&9KQlQ!bSJz08aTk(ey!pat?Y2m95G+BB;O^eQd%!2GjKq2s;) z&_Q2a-gXDYoieU}jInB7BlPZUo-uLqAfyjmy%< z66kdxA#JW}twQ0Nng1!{nb674U|^&2gZ}Ik30Yj^D6IFT@7C^z*+b`MEoz|wB&@s< zwbR{KoN|oMvy(bmZl~4#3MpZQ)xt$QFs;HauT&VPpwh_DEWt0sJvG1_DjtkT2_S_aref%G98uqIJo zd}ohCQ|3lbj$8UDtooCgL4vhPkk+ga+<7Jv-4V6*w_(Xj=w%%u{AV|U%r5wTC5%}G zjPeumntGPhFv#CeXj=Ir-UP34^X|%z%A}MhI+*7Sm1o6v{82GQ!vx(f!OWj< z&%O@zZK+i_Q%^_!o6JREK=j*3$)QPZ5=IK@hVyn%Hu!s#BNNgOh~}(YmPB3WbZF3_ zfm4?WqpU$-D5W5K8`HuNuxU0*lh=-Q_Ly#MiMe${cXwxcy%xl>|AG8A@V1nhHT*|2WVr^%enC zu0vF5>8`yq?x(ek&$c@y~-#Le5ulBK@dDwmvYvTRT$S{#IRj zirHHyoQn>%b%R_C7;-Yj$6kHa!@i(1ZaVxvU%EDE)|5yudS@km&R*KrD7x?U+1!wP z>r85FhTG|bj&}c7e50?lJ(;(envQk{$07eD?1CFlX&^RDk7JlS2>w&WB4~X$(iBb> z2~U*T*9!}17gcBe6D&W)<;rrkKP`=tOXD{XJ>~SbsOmNyV5oKztU(wpX}=6k+oWrz z84xR+pBC=Qw|{g~Wery5b@=xor&XnIr?9hz{HkzD?|VwHIC_0spKT#DrhVFH)`H0S zKBy8sh&f38{!ApDAhC5f{-WU7fd`}v{2oGM|3l?zA>gKbF__HmvOZqu(HP&wP+a4T zrFLnw8m-t2!0a;@7~SBQU41mYjF-7%$qzE#(n8H4{(i^lRzmGy2Om|3M`M4h^uifg zy{0-&pY@9`M*x_fAfM8cRle_`BNdGQ@=7Gq3}M(K>qJyu1FKw z8HhIu2#5wlB2pI{psBm;%Kt0fP`uwCB}|SsLCAkA~Ronno%s1p{ic_dECWm zZ+7EvvSZy9Yrp0DwBw`Qus`W;;GG@D@pm{K4!k!WkggWMb3yi^0pH)Py>%#h zoFng+v-^shMsGl4Eh2Oxbk%s>_>3Qm2@uKYtx1-ZC5J^|<9rj@-FYq@CUpDN3EFKq z*w;X}WEYZVqP@1UwWy`CJkwoLZ09~%1yvliRLZKsb@C8vWA4`!CDmK(N|UDeN!WBSm;8bS%H(*5=(7Lbn=KyuwZR-wG*Z<8}$8C$bCfx9idGj_`ul*dk|E2 zEOHzjDTsy#Ll08wH)Wm)Tg#c%Bip?@$Au;2a8u|bz|d31ii*h(-fDdEw9MJS(VTzF zfO{x{Us;yFXc4BS2hV&#d42QRxtlFpT(D;cjj5QQJ<-rBG)`>|ORf|jRM)5+9^}-Z zoF3%Vs2mb>*Dwd2HnAI|A15P(!o!ze>n{Lth8wYkd%pLi&TRo%iNU+PpJy`Hv_t#k5D#`u3oSONcx??dY~Yqhhw5A( z<>6F{&?h~G{_{PUw9gxtpbkrE8K|T9+Z*`h{td|w=GO)bUpEouW}_4e&&qi_=h$BF z_^MrxmGeKMm=HE4NH12gOM0!g56}7iQA8&|z5)saMIGuKt+|=ZWy>-r8EMD5JYNH7 z%g;(gHO5M08A zt3q}-HS?f2CfaHXKbjR{pYeu>Mw?OT*7`szkxBHEnCOvb4POSZIEAb#)$drfHo!1} zh-V%?Lw5QdweXyac|+1>5EfBGUPuePB;kE<;!SHeC1J$vKe<_xG(M=JFwEZ-IMu(6Q+N?~2C2;vWDKB7X(Z~}-y zVg(o+M(q1mk$kr&D)DCD1$6%J-{R53T4bLh> za#~+i7m@CP+t;*gf|6KXDoLHe0sEh(v;MorAq`{UIP1|w=WiZ4#TuY7_}6sT6Dhp7H4@D>U0_x`+G2l0bQ*q^ zk%aV@FK9Et><}cA?Ls<*!=JP+2HEbwsD%%)GLETSt4{GoKfCg6l=AI?cUFw=!#rh< zl?EWoUfI@Q-4W-ReGkaBS>kx&!06I+u1&6Zlf7NtHfG&+A~!qA4Ry)i;? z9~q0!@QH*mwIq}6cc~>yvhyQ~mt)~OMnR{WJl+2m;JeLfFx6P^rm(H2kx` z9A-lG4jwkc`s9kXpPuZ-tV+ju-6gqW((lM492I_2`i$RvwZd;(smUS%$E^yobhqh5 z#lYy83f>ij#nH3zB?^@yss4cBgT`|p8^NB zQLfnQdC_8TRhHE!d0+W5Bxk%xui;H|pVcixp#v9$PcJrckqO}7zZyDG;G}DpUZA*Y ziKxfy$THGly?UG7?E1@q^9-Lq?2`u*)eX03s{@`NIgcPJ!#*18X*5}S;KL@d)isRp z68eQ_SXks&If8)vAzSH`3^OTCN{xiP1<1ON+9l%2_R|PIqs5^tFJmgAui0-;WbOX= zC7aRuCCNnfKQXG1S=PsRQ;|O3ucyXn~U#V&3ED}Cc*wGQ=}XOmxe zNLH2K7b?T!WOQRs`RdRz29H!n3kC+`2IKX4NbB5JTBz)Jt2e1NTOrQZc08EEsTa9!YldyDzUxKzt(ul!a_S(Lj4C%Ns=)@Cm+J1r--1)tt8XRhT5 zuGvW*^a0ru-CwZT=Z2DjVWX%*27Hvpu6>B#Ms7#<8RJ&f{Di^lC?JL!!_p5q#2~Na zaoq*wx#P)i>1An?PHT=mTILS%@&9_BId0h@KuByV!tt5_5-N$#E(_RjYAw19xYx<& zh$Y$WEzmC@pc#!pKxB}2tAcO?a^ey{?!IisH$K-eCEBO;7k`AL14Gl?vb<9EE`>cM zo}QpRr5~5>eH;ae4cnH+6B5>F8_o++f+-ZS_OhYd#Ik7qW!VD-%@QFaqY$}6?m^as zv1>0(`*Cf+RrzM+kI>o+M0PLV*HK0%++HC%OrPLgk1`y`Sq3BmEWX$qrD6p8Qa-T7 z=lhn&)9{g!xY0`2^h2iDvK^$)xV$cvYkzzN_^^*=li1)<+BKwa!fb z)-^YT*9Fs5I(1yUB%$<#Q{*+vOcRLI)o0?Us5XB<0K@IAf75Q83vERg>-*ivq1Mlt z%X2sAPOG6MiuIz(I-aOlB#%I^Nwie=for5#Xr(U0Bl5`@Yb_?XK;d#6>Sy6*D|g7D zpde{aZRi^_EgkA)^|W7C(MLDaltP;S{+4PSG zUE*fI>8v$E9oKDX$JaJ$)74|RBEX4%3$7G}o^WU#w1YXvTDsWMIQ&J8hJm?Lx=5KO zHCNhm^FCo^Cw6B!|Dkv?FrHA&l-5rp=$hwQ2U&bMzY>HBUa9@tNAryO<~p^9OrP`H zxT+eD7_anARzc?AADYE*Yc(s3ukr;tBGobgQ}Ve2lw60kNJy!OLyQZq9HCoYvJD^X z5+uv2{CBns=_Z2WwqSXao$zk#y9bRLG0HZkyqqm#9UK?MyXREhu}rwsmS!a z6~0;-HNL+cbXFAdWN2Amk1D8>qPku3X%%)_n_@fGq0a0Q)}SgyTG~~yw~H)#jb(2= zT-X?;g-UqLZ&{{|U%5`ySs1k>A#|(&8+ZdX&qG3h?H{wj9(A!2Ob%*3vK7@+!z9`A zdl=ue2{`+Va&C|hs1vU{stSs|bIgg@6D9)?YR8$<-ilVJG;+@)OD|d4tP;xNQ}m1i z*q@v@HMoc?(NGuS;BKTJ6uvA-kHkHXO5hw&VC%x~Ncs@Z1JzpF3bQ5q{xRUd3G<1! zcSn~3LrRwdV@y|WzWLtIZN!x);kiWC2j9o#ifiY4AH11gAor*zZx$V0-Hn>BpO1Sd zZ``lhTq_D7kCa5G1G2sbO!w@@UcLseW+K~ISmoDPCpLI9QXn4)_r47J+o|7Vwl%&< zY-?E3AUz&~yg^F7?#cR=9Orfe+%r#&A!ptJT^P{!m>}7KT?SFhPvenA*BV$7+tstn z`#%B5nr9O2Z$6EA!w(A}-*3;4^q(ajKop2X%~EBvGH|D#_H&ORxe0@HgxzgT~M(UN_< z$oc{;Ouk=E`LCbJc=$&CpJ0LjtS{r>`P=e8dt(3D(_PdZ84?|%F5frWgZ9ThVWZ8e z$1{ju0FT;s-%TZ%dz{Yu&b+Ky)#QDcCX#ym4v)K@?(}7P_S+BT++vm=7YZu7b$#aL zbcgmcG}$)ZDV_;HN=jYVvEF0TXxB~yiCqu7Bpl`#-Yi6L(+j3 ziq*$U)x1+^-N75i%jX!j^puJC{^GoZO&6tJ29W`ArNl_8;Fx~-j7*P}r01Gs{=7I` zHiz;FTc!gLF|TX^ein8fFWgS`OQ$Su-Ga7RWCCezkRhxkRsOb8x<$6GL!=$AG46_m z*^g1FHEhVtH`qr3t5OI3@|)D_xDqyk*4A*36jgwU3eJvLm^lc)6%@EnMC z58`3KSv1NbE^)aA-DG(~6zd3DKPN($L|Kf2D7fmcRifm17qIG6c&SFDj>>yPY1)2^ zM9(t>Ox>Ns&iSlGzW`^i@exrA^}`omkVE~L;%OKL2K z{62Ntnlg2&bQ>4G;@sTRC-n1Mc^}HvX9g$WhVQ!;r6s+9;NUxv+8wp51~N6$Paxe1 zCDMm!C5>q|!d#(Y@2gtW8=+4iM%3F#C_F{}*TX0~vfn|1jjY6$RXP83vPws5=lcUq zec4!o=_reU48Ep12XErvgp%i>s3httzl8FJRJI3YIz~=&Iu*u0>e;e;Qqt7E>DDDc zOMZze4la2qCB0_yRLW3@dZwuTk={n|y{@?L#)M7}JG`@Kq;!w2)2&?+S?-Wa=K;{C zjcP){tDel!FckVG75qkB2QEr1AXoX0aJg?j8uZlvu2rOvYR&Q4Y8@PypMI}*f{di8I8%EEy)ZdzrW`I-yi`wCR;1wSXbJpzONk+%pyPT zi6raj5vZ)#!!k6iI(Uh0GA^>N$I9v7A8Oa{(>zBH3G0Hq4Zq1!8hKqqh~5 zz!zwSzPk1*~jo$ zac35FnB;m)B!97KP;jt4S9vX07=HiQe zkVzblzd}v_z`##?opw5)$Wc}j&Ez&qO!@1V1UwQoPtn!-3i_a(WGe4!{sntKPu}`O za?F&|sS^_04bp27^cH3qmliUn#YF{GJ0W<&3FsJuxO^`$qeBovjO84*1O&$V2zE;5 zEK7nbx?RHkck$_loTg|1W~-z*iq_LEh3uDxop<{XCSJdzlucR)%1OOy=_hFRuCadj z%X1ilG3?d0dqmX(vWe5nUI`>lgp$ECo$*z_zG<83>A5USgDTg(nm|%{osGARRx@8t z9`GD5==_pzo{~)_iloZ93PR(Ck;3dPU1*7{dP0L(+zD73T$Az@i9N; z%?z~gNLwax8X^JTWu3Fut~=;d(vN$4z4YNf$R;HStDq*tv8O52{p>W*)V5|(`!C~( zp@*cjn?1_&+nlN8lSkjw3Q5gq3VA&v&-G-$KgL{)Nmo0P*`OvH0uV1C7T*t+9FE*W z|IoZ7J06z`48ON7WgF)m*Cy=qUHOse4|+0vVm#cQQ7Qua`IHt(f6TZWMr^Hh-w?}x z>~B!Ta&yYSPSGoeIny5cIbOF;*RIw_EZ;)yRIRn3dF*`tP~@tjy!LXk>7gmroc#JW z)^ID9S&PbNA;HK|t7B)@f9}9t{lLA>fBb05#rU&dS@;rC__E{oCS^lB19+RhFx8ZE zbiz3tgkK);+r_K8*iPTyjc#Fk>0=L-XMZ}L>kVUl;S%2CPrL0~^@&aoe-)O)4fR$# zI@;f_4|3`dU1>+0@VR?KJYr#INT*JIZofMRjLqMlJ-)(-!w|E!rG;3{PFtg2jNvq; zuh6qhUIW_=I^+Uq1X{D#-siQ&Nc1}cA`8+_rGGtu(lSclyfw%x>oW@wwyFJ$;uuI8 zh+_5!S)$n=u__rn1d=FRrDexp;VGUMGYfwMAOfN@yof=xk7x7B5*bk9X(|JNjyOIB zk3;5!khtjl@O`^idt~sXU+VYs=5HsHpnhA(XxIlHX@rf1Tp`3+!;Z515OrLmp==S{ z+AXmF>odW=N0_sRXt<~DjW4!!>C=}F?$~v0^TH z4OKf`{ndlC^3sit4yVw4S+T>E!(`hSGqJ;^!{lnGjxd>|gt6)G(%1vH$1M|MBM6pO z@~>CecisEqFeU5{=%+CSA0>AoVsF!Arv)EU#|aWOU!GEJQEyQs2>19tLL3G!Hhc&F z7SXLY%{+om9}NF;*fvbVP&CuGH)Fo&pVZwKQjIpf`C8a;ElA~zS+c;SNt;O4>>ANUY9|pKeroD3O8F6Q)7I%ANotZ?yb&VE=~yuMiN4~zCvu|kH@3FHTUI7`%#tjw%zxKk91B8RL@fv5PO z_#Zn?#E%|Dx%nzJa&5twB$Zhm#IVTYj}*Jn3{jb=6y?wIEk$x|LpJ+zaUJ%HV!NFe zv=k2qU2CIH`7iV9)f7>UJV1#Jd;0rXfY$)kI;>}|fW!&CIPF<{L1TG&b^-?Pd+T|u zm(O|fJx$@Dhk*FFI__OgaRHq2u!w6PYTxpAJ&waBE1l4a(nZInkBs7sD7fr==dtPE zoIAaNPcABr=U!^2N#|L2HN4-QM3jg#X&0h|k!tXakBSa_fo7(CC9k z!>&Hv=Pe2p8T46IUaBG_wCd#J!nU=HjB9=IZ3;~Z1OfLV;+~}l5o*@sDL4u#FnFAI^4VcBE?A9<_g;E-siP(|nl6xFYsvHEYwi*FQs0nD z8FGbr;`~Y?!J2eo=`)vn&_p{68j+>#nqsAyF@MfXQ)zv?os}KE55`Aio70ugld-D{ zo?Wzvt>?AKfr-%ZK63jDFWw$o50#f3UrbNN+%^HJu|}d+2v8h?xe{S>Z=t^W0GW8d_!WLeXaO$-;e~C3$sFu$F!z_&{i~(hx5Gz@LGuUzOUofm5creDmNH7Bk zM%WGneN?WTYJlv<^adBKdhe^a$3AEq^;z%68>}0-i{VD@hCX1q7Z+?B3Lv`SXra52 z*x>~Oz&=%Xrh86|Zen49@W{byBys2*mMes()=8{}H*1npBf6;UdraTx_DI@94;HEx zpT`?U#o_K91!aP+ytC_uFWgJU?XMslR+sOYlVz5&(sI^TO(jRO3qNu)w&f-Xhs-*p zQz|TRCFH2=3CQVZ5j8oLYIIyumukjb=M=|8)&^qi=2ep7l^9odH@g3iFISJh)b-yi zt<4oesQ+YZeQx3Zx5htIr2Kc>Y>xmM1o|H#0Lu%J8UOvWf!eS!SSoEgF(L{HJ^>QM(rKhq9UY$}Cq5|u=KMg}ArSurD zyObf9ZMZGh%Oa%uz6UkbW=}VcmdX%dBgRic(9<3)aLiw`6kh=y_S%%9^6_{D6;4uW zb&TUyN~1@m10o+m#BRrHQf=8m!L%--Ztmt1)D!ryV$exT^Vpgey(~M!bUHi=>kG|@Y8&Z>Iak4i=xhRIMPX3Kv-_Ww3 zu|YbFtP{F3M?YssL#2TFpbPZg*EM_-)`F^fKWJ`c3e*#iIKL?-->${pH1>p}>J#sd z**R=48S%*j`Ee57BwKaYTdE8k`wPeMo#fD}2%!zs{sjQOvKe#p%%h;lY<%t>aSUU* zl#FtJSmza>?|0(3kZ`A-tE#KJ-y7yV=a7drORMjOg-i(StO1kw=bekHS45h0 z&-8jS@6NoIlMzER-W$I>_Ms*qtju|b-?{6PZ`Ou1%y_mTKK3O`>qhIfxe0xX!jne_ zp1t#S-Wex+#X@w=7q9e~KHa@A?D@sPO`ko?XbO3w@8aScngc!oDVhhyEyE|Cs`VLv z{A^KFrq{bf@gQa2*FXDwrC3x|*qeU&sd4`-5H>t$Q%U{UgQ=iYOT*a7h8VT9Bt}gd zjG0v8U`sx}F7wB;ZBNNLGvREOR5ogfaF+g&?8qE;28j7Vx~H>-?TuA|1QRP z__Dz}7xLD*8-qHHYEs`cR>Q&!YUYUSl&?O>9A_+%6q`#V&LVb$31|Pu!~zmZs8TTQ z&^dg&5?^VNY%P(viRe>QoW4e71$LQK;mmIXx9tBd=cQ|N1xy2)D!gAVCJ?Vjqp{0+>bBj$0G$k;8P{w59(cbr-ZF(lq` zK0Hw_kz5}nkpzqAU-f*@8Zhg-(GbQ%-7%!%LL`Kd+ zQ7RoHkbWDqsdy`rX5rm+n26*Asx%rS#5N}l?VC?$_PxMv8&#ynPq%>Je5#V7!Q|~!%fQnNqtpbn0#0lwQ~k) zChX&y75g+0bW>M#HhU(TEW#JYT*NPYj1+bG%K>hEe+JbKMdyUCO5;>)A1sl$i9A3zA@<<)~+AULUBAtZs@2{S=5b<&PQ3)Ue?&j(Nve)wlF7)nla6Jrs?h0 z@&B7eZCM(^Tf@Twv21$r*IVRpxCJEd#CnX{Nj(^I;40|F&}vnT$=C13o!CpOl@y#y zq}D#-!4Wnb(F|}D%>ac)Xy){Po4qV*HiL+VEplfcr56$Q7p<3D4LprFB5u}AWDLRjil3AP*qyRPpRZyQt?PO0Y z1xO3t6==b6FIxC#jSi})lqz9$Hd43lMR!(9Kzf+ELF-<0r&+-TpL}X9OtFdiIG62* zFmwc@r+leezx zb|Ir(;O&M_lMwOkRRl&ZDcL2e6NzZ#bO1m8jug8;J%E9iUq2QJ8v= zhQl9Q5XJ3J1^x$-9JftRw&8x}Gk9n|haVrL<48;q7d90TB`i6FqilMLA-)h>LQG)I zQ8ae%5VoqXV(=%#`z$;9L*Zc>B7Ga?9-#rStBzRm4kp!$;)`nJfE=Jz=geGh|0ceEt*2ac@1PpqMbAqO6Fq`QaM z!R$grYJcR2R}r;>`a=3Dse7tN+??<-O*H#Ph^A5Mb68qL^;`NbdCQs;JHDl%#L8ALP?&t2`Vn^rjuafHK{)7BPT=PMgQH9hpO>M{ zQ76zll^aYwK@;%5;OyuHYg}axyZ}`tI6u2QIXtrj=kPRtE>tpMWgr)h<8G^N26sH>7|(GRbx2tRw)f8rDM5JUP{Brf=DjpjFs6y*eT>{qBs&8 zDYJtDh8&IN$ioRT6_g#r5Hg}gX-SXegydM65hRw;K=QXZJz@z9OR>rGGW0V3O+BoD z@u#tF(&lrdX|8MtRGh}%Y!-4vQ%+wa_8)NJtps#W==xwe+S&Obhkq=`XkSj`!mJN5 z!|1TWMIw2za(qOUleP?es&MYqRp2twtrI-Ypx+(qxn}zr8bQu)0N5K1W2T+rtP6WbC(`*jR;wp*#U|Yp5TDS7Rk5R&t@Z z8cWu%mI*=dc@>6ry9(_^)?nyy^$cD@-fV)n}*;usv)X{uu~KfBrwJF)Z0P3(gf*+>hIuMs1l)UtfUsXDp8w$u2p`Pka0ke7?QOt| zTUH0(G~hCqwS%cVprrvT{hlBM!;~y^J2*qGhDohBh6#;mL!Qlug3bYMHlpwCxq3ta zF-^Fvwc(DW<0!y0Pj1WG_cc*FsXe4L(@F4lGYuk>j~MW-He+Gi7aAZlE+I#Kj3e=d zatr9Vg#D>YIAUHR9|Ticu)pe3J)+@V-D^Qt*OW7O1qs8gu9b$srV6<^S6^yHb>TS< z|6YR`4!(@rZX|SGreTnG8A~Owf!lOwL$@9@>4ia%(?&;;`>hah6>VBw!Np+x6)tSN zLPMp0hcQ>t2)#;2leU{o@ek5|n;l;V#WnQyTo*UC`WjB&t=(LBd=2S7xD&FxJ^BI5 zZ1MNF>fP@#KyH7J9p^sMBf4R!?UNgBJyp**!R!eRGA2v~z1K0?FMsB6^D`XN$u}^M zr=_s;4i0%`E5?to9F%`zM)9))6|~&ICNV|^1dp5OV6TY*l5-QUH_n)f5mWHGg)z=i z8NfSlVLq2x=@B)Y%%qll-g~xVN3*p|=L@UaX%xFo6@&*K)E=5U(HWQ9$hk3s!;YTV zRPZs-iyFo~%9|5D^`f>=k=ehnn08>}yS`jEy#rm28_k9E0BXnXA#^Ly?~GU*!gPKR z(}}}+CQ>h$fbunJ#@x{olPC_4yo2+3;Y22UM&6HRM_(wIKpnZ)_0b~t>S8$|=PtI| z5C@%i={&OeJqCKfk}gc{r|)y2wF{l}SRmEt4^DvK?(Q1g-60TMgUe5{_qq3;@1JL8 zx~Ak^Qr*3Js#cB8V0DjSAu7p!fP@1Bg8>6$Zwrn`q=sQ@3l_^`O>>VIAO#9o_c5cd z0UnWX6GcQnqXKO!LuYc?O@HBLS5QeBj!Jy~@N$=&A=>8ZiF9_hPH>LVUWbha970~- z!7B{<{{1&F&MkO5gx(~rJh<>XJPa%%@Nw;?AWoxz2jcw8fSWyd2&`69kSlCl?Lc;d zb2m=r!8#-hrwwergWwkmIBeiF)wCTOwEeMx8g#Y+Gn(KE#Tb&nek8hJT!J}>)z>}t z5llkIwLF?$IK8$SS|<}ukI1XU8&Gs)(VgP{{B#Eow zw7^woG&StEEcVkvS#4rn9i_ewOIgxyFpzNdYY{ZWG$1hA)jf7SDYsoS6>9y<5D+v` z)+N!DqlEbdNrl^7li)oU&(Zk_rTk3fm7%%Q#Pa#o6XOBj=AzK+<4-Oy=*xm`%+()M za-*(M<#O1bmM!74R`bM=3+rr!(Vu#%uYlpBXm_S5bDZGoXkm2O!b6U;tm`BJjh#!s znR&k*!jO_9yA+Mp3M*P+e2@mO*c;9>(uVlasoJNy;wnd%W0RMvzU)dXUclGt!LB>o zm{4=|@_c5u>HP7kC( zLCgRwaAK1I@^u%glV>~+^&M?MG~d^7R)?0Bv99GoUmAB(&*Y3tp9kbHhf}5LuBm9U&`GDoS-kYrYD80Ls-LP)Yj>fYGS%7$+m`D zYp6i3MEdgHep4h~8=Ib*v{vuII|C+l54IX#3k0!*z3@UI+tYC8lx>S|pjnT@ZhsS& z(r&pzR57yE&NVe|>h*wSI_CE8t1x8yqJhbQZtiv8tD#2ldxTWGJZb$`P!y&O8I|+2^bn&&bTQCLfY%b! zl;2CD^og{r-xNPG#36lhh&mZNvHLZ-S4*PwL0D4KL88Smg~!o02WQYTc{s6IiD`1- zf?fA!10NP(oeX&eTf|(rtEP+ks{*=Ml$0->qr99R-IS5A7lYK}5o3{_9Q(^o-gc(R zH{8mFGXGoOk>(?WpbjX(#os{R5;MD*b388B@9`*0FZ8j>eYS!`Lhie_)wXS>cogS7 z1*)%E_3WASqu-m%Y)U}c^NW{*xNAKb5bH)zRY&`qp-i zRR}x!&UjzM;6xTw>e0o-ve!R-nJ0rgd5B%T>$h0$7a&k+CKBZW|8)&abt$q*nJmEo zvt#;T5#q9E8t^mq0wv70M_oDjsKXFIgE%G^YAL^ZhqF3umhtLiQKLmRkdoNzpggTS z$j(&U)1h6XTSuMocqqm@YxBitq=pC^EmHhiY6xMY(%r1<$Gy4h2ODl#6^C|UShUYe z?buw1lt5NT8I=q%F%ct>Gj0L=n_0wBrqxEZ4rV1@Oi4R|2E3%$Nc~=cjH4(o$H=~V zP1aZNQwH-~mW?rR{j)sE9kkOAyjpttuMJ#Wqxa(9t#pCAhF zf&;MEAXHK-R^h7EYD6sQBenipH~s=gJ=c?}j3j>|!IFRUoH94Cb!b)Mho>jeHOa3z;wqzjP%u zPP_7`W-)oerkJh&^;*LA=A&{%En zbABqqgeMk7?|**5SclSW(tklHD2&%>rcSskCi5~}?iUm*5Y#eIK0aT2t95GUJAPO4 z&@ZMp%At@2>9&ph_JeOM+yRn{Xa3Bo9fv!>GBa<1nIU?LGavruklr?Hh@NrB`Ay=j zUjz}lm+y6-9OmMCjXWHp4zJ|}{JH4r8~A^2v@l@rH_$qE=zQ=Ge~1+rf9Su29n|s9kmL~M&&^iah@XfX5)7>GeU0Ky6yc@-MI`|+>z+tOA^#c(Q=!28B~+Ob zA^s9aEdQd%v3>hThmAWE|1Vg`i4!6M1Q^))2QV;}#9SBpIs`Ssf2w7dTy zHgwO?{{l`q{>w>pQ2_j12}U{y5<9`6Kr(3nMEHMJ(0@iox;A1rnEH1{N8*HdMd+E;<$kvP3;K?I_n z5l_BYNR;@o?JcQf<*$>(ByZZ5UpA3h=e66yP%+_$jl<&_d^yNZIM3@Ec#T+E*CVS{ zY&UMzaz6Dk<)ICGRmc;|YCg7Q3rY1}30Vf69<(d+x8#qR5#p)?kvdB8?j)0yy* zC@x`244i5^64SFMrw{@26bURpe|Nx?7z9bucA_iRrxc=uZ7Y3L-k;FAXnimryGXkm zYhvBxpXldlx+XyCy6ow3ju}7+lhoXAAFvk`>2%WV*-d)pjQ?OEM<45-gq@>)NuGIGWAFNC27%o|sR+ z`pFWxOfTv=gl$v7 zr!!V;Nj;cW~A+hOh15iZNLbh06I!92}6Bi^m(!m(7zIy4kbJ#;Wh=blRAze;l>E{ z3Qf<1gE9FzfC2vGF3rfD0g(uk0P04^{4^JgP46$?J>@ zt{=>c3TXG&Yb>&G7P}(WYyLXCv0JaTb)UtYR9BpRj9HH+(33xfNCuY3DPptZj#MHA zL3n)?R+m0>qteyf@<)UR*mxQEGmBdy%mmSu9+nhf6w|h3N=YG^8LKm*)1xRo8LON9 zw(?p`MP^{4=?Eg`VZn3$-hlz3puL>?+Tz*2O1#gWEhtZTlwem z^t-oX(csJ5b)zAjqVB>k!W&C=V ztOdqjyA$epO7o&W{(d4=9=~a3PBzTM!J9twhbDl4ujs8))8?qKowmc7%4;3$hJ&g> z(`z~LCZp^9SyE&iSze~xS8rn%e$*+@BV4bTZWjOTvSMl9A4@kG4pH(@K6$bF@Qd>s`(?!D!kV3( z^gt-O6!77f`R#X2DN4<1xN92d5AG8|GN0u87JGRYgg=d>HiR65=XIrSBDu4HULvt4$?OSyO zl|!7Qqeb&63Alk1P?;Y|^X(#o_~awL$nc5Gn^2mcFUEKju>UBxG5)?0c_%%zk+avS zLHW3;Tw}4N4jd0hB8?06c3^thk3-2JOu{H{KINEv}2Rpo+6rZ6RIpM`m7Y~ z(68rhVY$-fU1%cNr6hX`kjUQK9mE4Y~MflX+mMI#A=lvNI5$Lgs%~b{K zRfb9{1Wv|+m2m~;sbrt1@N#SSSfSzutRR6*q4%X|2EDL6-kq2_@y3+Bp_=_17zXA} z_g_0L>VdQF{=a)2g=e371@^_=n2~3A`^w1)m+2_Aok;sf<(I$Q50`pQ4drQiON-!b z&QOzdMW0L61NYc}P3QSd#0f~cw3yCpO9Zqc*lyb303~pNDL*&rN3t@Ev|CzOoVz*- z4~e8_g;D?&v9e)@HSTbPI%YYEW;y15I%a5$-at0@Ws?;@<&{_W{ZGWEyqPt1DLtU? zJvq)sEC`gkzfI4MBxbKXEgyu^KK3{iFQU8eqCYp3cam1Th8!Ad%X7E0IEQkj78)cM z0*73d@DQHLU6z;uu?%&~QRD3TUr8Lj)u|3{lKT^!X@%x8vvt49 zyC$(%e%q!8_NB~=TDlSva8^*_7oOfC*cPn_{iwklu4#VA5V{Q?3=od9?xe-!>rZy_ z*3>zN#W}}n5Wg(QlLAGm7F*bp`+TErbO$ohFzgUGCz0C8Sw}j3LWxYM>dIM#X+bv_ zDJ$Uc%Tl4o82uGUP1pu4W%FYI4mulML**p|UzwKgT6g+sN9TACpynqGd%kQQwi0hy zPKjDC1J{~B=NUm*syUAL+vH~=gkB%1^*wr|n?|9mh>Y=Ulj}?qE+(Xa+gF*B@Oz-> zt6)(v8z)I1(-r5bgRpx9RNc1MLc14m>TxRwf1280Y)`hLoPrMZNx1V>XEnC8@ZR!- zLCnS>Og&9vRK-t6<}t>y^9eTgLyMF0@NXzDF+pEqQF~kYZ9@4o+r6@NHv@8FlE!p$ zHr_o2i>+?LGu81F&mZeCH$$!a-mbtLpwLTgxo;@mdLabp8bC~HKXTUW!&zZTWA4br#%`jhv zM?;846vN3G2|X`OTZF=hCSg}5|Bj1AP#qQ!7d_wq98DuwK@z6 zb5@uoMF$EKM?l&EP9tYa8M~t{dcpXXUWCSWBzv=7(^^7lK_KW#{;ZZwb6LyrqvubI zKFzYNLKRJ~kBqM=h`YQ1>AR5v*Np9~)%vecy7p0eU-7E5$@UE?aHq!{;g*VmZMAkJ zA_veE-UA z8dM~}D9!g#RvKYx{u3Cd*nk4%GULkc>k>lkV+uc_nh*HqLbf5?=^v3|u(w*O8BSED zOC4x;VeA@qJg`C&rd?yVI0r8)PVG<;c5aQ@#R5=zv~09^quk-JZO=aKjY-iDw53L1 zW8f`c+0o7Jqo6k@R=7I?Kem5$^u((BW!G1LAGWBRw{xnF-+pr<(7YPa7nf`_kM4#| zv_;y({}|UzRh>yC3E)gd+6C`vx)sg#k=cShIVv~w7j%B!sZyXU(BR4P7*<*l?+}cf z#CcTTO zy;0pxBv-9r_G4Kx$PV&BO`kOqN325y1+fzErwkBtvUn2m`Ca-1=7w>O{2;+W&o`8U zIy6t)=8^E!H}i;5&IX25AWdISP7n5Fa>rIH_>cr2Fy8L+RsVc&##a>deZlc*sWV14 zx3XnS39ic#$543zo)8mq)#m$moz;r>dGv-9YQYdM3m} zn&#N$KO;jg_4sr-LF?bLlrwCz+G-Kk#4{r~BuL6QVkqst=9kXT;Vb zvJXSgF^sgZmMx?`)jegPJxMcYO9!UY7WLxV z@xtbeiQb`&oLel(27XPD(B}uUUlt;0J=r#(Y@tOqi}il=zDjxPmfPc&`hozmD{YGp z7TB4w;|Ns&H#G^s;Lf@QRD|-DT^1f8HC$kE>@>@#6i+)Dw&P{B9?6VUpKg15t zj9-cbBB4AZ^hmX0hNnRAeyx#P0iT>c<>E)D1!E&>coDqL+Ykwr{=~BEf zhkX?bd`sP$M0+lR1ZHnB$w5?_b;d-l9YVN&qhq+2ZGYtH0g7B)Lju#bfK|xPYJqPt zTUDsf4bt7$?_PdBgkVBun+beN)2KpwhS$Gp>y^>br9!yx!oQ-rq5(b_`cEYl!G}0>RebfesAlmC?PfO3mY%1un+XPGoMhtJ@lO zz50Y?GEF4LEH+q&7L5_V^?h>cjcvZ^xJXt z1x2H~&r81OoN`8A(K$aExx(=YzkhjKKo||A&-GT;6&{^480n~-h?OSZlGK&s{;Wj= zMp{#ChL`WL2R~C~4YH7+hK9?|;(`h}80E_@FXjB4Z7>?pXC>lscfAu@YrIi^az@;! zN8E5mxIl}yMv``*(Iwv*XI%--T{Vk52pg|d%B446Rh6+m=~Gue(E*uM&w}M2knu-+ zQ!DU;WqCr%lAyQL3CT~2(h!mIL_95kdFR1bRokqP9otoikIW)OB)<+|AE`wYk#EpN zLSei@zKKB!@PS*zXcE1-t(%&nRNFvipYh~bO4Vl$&XeUOb9_5xecgLiJ@NbR; z2JAg7P$!r>1O6V+sYA^d`6sxfUQ_|`hXE*UfI)nZ8)Rlc*^R&FR5maYjf!v*w`wtg zo<6#27_W9_30ha_g(@;M^%V5Mrj(X)#P#F_*fOGIiNWNY^#du3dmK2a6G2?|t<>6B z!pPHkHWhFfaUz&BQwnecq!EZ^{(+=n{(KQzjK(#7cb!~1tS`zyp*N574ev9ayX@<% z(+;ZF>n(k-=sex6)Mg%CqHwK3L5n%yP~w8cOzFA0SdNia{E|cO2NEUEfKL6Y*rS^5 z$1@Hr?5`=%i~)zinb#C(C9u|ERLkDBEWYw{*r>>KkcAb|pQ2%JMp9Yg8&qpKU{r(V zE8;zT`Cu6)B*?y?i*?O;c1LN3&@hvYuA0o?XRPg1b7EE#4&ZV1kHce3ceXA9o2f0y z={-GLc-vg3BFecS>k-jwqcpiu*-+W@#E7Ssz0QstBsFw4kFpy#=1&Q>IkEb`tO7?Rysn5&!5TvOdgL%6?~CaO#I~!M%sCjU;THKy^z*9RN~d-@1;J{{#;YQPrZ}$d z0k?3a4#}dpp2K2}c|1F-oW%do$t}Wv6*n9?efMLJX&zqe$1f=moyzNS*cJN@qGFM% zwUCh>-|R-lyG>0XWhQhE2cY41rZ=v)5C$cU*>P(i73iV*M}Dv)n&*wj0x2xa=P;M= z3`@Gl!uQw`;(x^%d0mhQO$^dY09=p0KmDFoCL2U9rE_~BPjE&^{v{F1f0!AiB~6D~ zfiwi|diYZiVrF%HJqJK;52_^^WF>lJ5w@uC;O^{U2K|B+3*I6>`@wtR|5K9$MUzI1 z)J_HPv5ax#38g$CqLR{n5a^8Svg&C4D^n^+B%N6TQKczKr$zUNQn54ZL}WuycuS!q z8d~psB`pI79eWfpDMzcn1GQ0G=A4$<%mwKPZGxiSXuecTjW%`dn0~0Ms-acPJ~Qi^ z@7HOM-Z&m|B^|wbyE*g%tLnI<#!9M{I}#gea3aix{iM&Y#}rVH3;I_XW} zn5h$uT^jUg6zp~l!bdQBIH39R(85lqhE$D4EyZMf>5HI5Bg3^z#_;3o?D2VzX;MyS zevt?eCZFagA$XJ{GoquL`pmBnkM}d;tCl15S(5si_<-t1i+f;7#gf3yu0;&TfrWP+JSWa%IE0AEuj>Bl`%NCC2 zoQg*xG?qivv^dk|_Gy`Jrwncsj?+K!r`Jaju9F6CrW71#o@D(3dm=>Y+#MoAy<{~p zAvdbY@tIsWR}KJ@u|m{_yHhMyu#D-8X<+yekxYg%iUFezKkLDiu1n=y>^kyGQ#iFX zM%BI56YbuEACooUCfr$is9Oof96%OMm1cgVHRfY~hM63F!P+~{j`F1Cc$6Hwhr)p* zZ08o4mRsxivn%9U6c>f0RV8f zX02xNXluUWc*KfGsRclsaCuVjRSncmTuhP5yRXMLD#^wsnf@wte_41^uI*QHw^M=8 z6nGHj!Ef~oVN~cxVA~Ec!7-EHGY*jA9&qP%;Z9pZ+tW*GTP$UgE;n0~`o?dk+EK_)V9B}cl9ZjFM^cT8 zV32c%6bz5Q#W}@1U;HfpoV*kPPoij32q0}L?E zjcR<|6O?x1`mr2nXhCH*D#ksLeBe;NqkK0q8q9v-@We~sU*ez6;Y|67<{;7%jyaST zU~vO;o(|5hiNY^~$z`|6Hd*>ORDJO_TFtJI zVIj_KEuPw%bEfGCNALmvO-Pd^b~Bzz=_#fBmP=WCV-_8*zR*#<$oevKrGqO!eI&cX z2Vq-S1Gl5W8TY)e#WHiq6Zat2=mHfaMc@HcEPw!4eBZUaACDW!-YD70h{tD^mX5B>+M3RM>TYotifZksWyhRbCj7@q zTdi{C@~2g(0?)KOgsYB*;)}IAEJC9^yHO~wOy(bsUd+*WeAag&WnT){KW7XAZFzjk zY*Oe`X5&Bi=!~qjW-0nz4Bp3}Ek{amr3IwauEEz3fg`oGcXLHr>HmIBx8KXy>{OV8 z9wsSSgaV!SL)<;oN;#mWI?_$l%R+(VSGOFCw%mU3_Wo2KtItnTjP^!wXH!+-9{VUE z=*n5qvtN;rxjWH_>bOkm)FKuEj5-)?t*u4mt6f?i)XgxLtFyua)n@5RkTaRr>jzj3 zstQyZkLitLw}v=66D%MXLFzT2aIqdWUgzwY1^=Y?2;ryZA@=?#nRG$1uR7s6xfduD z{IU5%yJn%VxCPP3;q2=D2{O;X395Fys}rtRma3&TP)L2_#|T%^^XtkLI%QzO6cn({o6 z20`aNyR|U<93kfEvgXN!mwmp}vIHJf)CWTQmrl>pa4PAeb2jSBecshs#!O6A1*?97 zA&VJ@$DiTa+?D1DQ`V_nfsw3~`Ls|>R3mqM`%DEJ0_Bfg-Ap)A8u3?j&)VV_DfHwz zHd1pZTt~CQ6MnMNAl_5=HCMXs6)nl`I@t%houBp+fMXFbq!|sQ%lgnXhS-Zn$-~8= z;(3*@Ez6@Dbh;5X{sYgW-}tT`A^|?={7*G;Eww~!0@!zV9v8Fj!0qF^Ex$BI`>ng1 zCfSmm&$K8VT(B2JeYxGMwf-lAn}pqMj9RXDqv>%?ud!qGYhK3e?0kjZ%j8Hf8D7|+xb)H`O`+fRo5HvJ=wHNF0oaA z;IRL4ZgBR}dA`Eg!StY-Q#>nn7xSP0%n5w(vW2ncGv$ERY$4@JeHgb&%!G4|}Fxg94- z2NdN~H5ZjoP0=nbxk~usLWI1DW*$jT4pj6A&sHwbxiy^~S;5u2HQk=%-uZthZkCPP z#10paI)#w@S*TBx@@)>DYQ*Ov&k+2odJH;8OZ!YLS4;a)EM7~S!2$P)3{sUDm(wjY zaraU);hsy?t>7mTF082K(#;$#5vFl`tutq6CJqS~EhPM)SU8ZpL0Kkg-$|SjPx){F z$_AA_np}si-#$7RDu3H(+%pGhzF1kn8X!yhW8dXdxt-u#20`|KOBi`ZIq`DEL289g zeZByWW8G7x_3g4mizu$^rHTmK(H!$Y9Ur@bdvb~engqG_BrWZ}X!eTUh>pZjcFL_&HUX-CQeo%yd4E>M(p#d@)LM4*$^lX5w59D^3m7(f zM>Q{pl2neRg?9W>5xX@j$1^L#%Pgsk3rxr1g2(+5arP02=k;0}8}rF;Zl@Q4?1~QM z${6hHURox$oVL;kEuYgAajH>}+8xTrseWcPt+-mr&84BF=b-P0YZ}O6W3#x2YJp2;PIYz z`}QNfFSL_^H>MQhfgxJGxEAVc?tF}@`Z=J8U<%lDf^@1Dp=@Tk(jFeA`9UcP4>(#T4OP4S5&H*OHkgTQkx-}f zNwtOkO%~{90?gMnnzhJ9+UKg>!EYS})9z!0zC}*JmfG6u8)x8W`MuS&glP|(xxHl` z==cgwu2I;s^jR9ilQ=_Z;ydvl4HPrD>^dA81mD`qU?+v;o` z1}wf*Y%^D&!WB;MQU=QTlvx#DC1qcx#hmSXNO#pl>rwpXMonGk`+40Wj75_*6P1s% zraERoMYkMjx6Q*JeoFB#aoQ@om&Ia=|n2*LY3;$r?m1;n!RBX^vQb@{a3W5%TGz zZ=UW0cw66;s+r5Cqlr{3TwN&KiTp}G<_q;q4*PNA6KcaxaUehI%PamAZj!on+Atbfd)b#|XDc!SMUEft!; zm~QO<>a6gA|N7`iY7KX@Xu=bgOVOd7@;b>N!D?ebooxO{$#Wsuiq-n}fK_;N`%cpH zT(_LN-6b>lP;$XH6x`O4)+t8WjPz}B;4)ejy2qD*d-U{_u9iXKO7SdA@kwsb}FVA9#LG(!$+WQ|dA}i2oA!b0rL=bFdgmVsJ2j8&iLKWhcBQ zZad{?Ce`WbYYhvKRSOFNN}%@hdLms%t*E;B8Wy!EH~UFS!x~vAB`RzyM_FwZ0np6$ ztKvjLT}Q3L0vcJ7d#ESH>CF$Q<>Di{mNNv8?-5T*kL2amEd_&g4YVE)WVnTfzF#!V zax&A%eqYf8eAoo^&WddHb*>rjy!Ui_j_|oI3Y8NqkR*rHWHN{PDdeu*;$AV8MeKM& z%-r&i;rq{%uY;$x?&{aquWa@;$brk4;o42{b9&m0dsh^z!B|Vdyzn!6J~QRLwR+9f zSds|>G{v`5>dqEAR@7hM()1J@k4?QAWkW^ROU?~TCN_-tM4A^}vv_@R=YFb4wtYPa zfw-oN;n)_47E^w?6qo&NX$f zM7@G1^XcZwXyQ3o&#ELH8xMi1JRQ(8Y(Z}-N3JQz^u#8*n^vyB8s4EaX%tgk?)CLD zygx1l|2S*~){JGXnAQ}a>CRp6N|7$3=Jv{kcnJ>-8(fwnpLQV2fV!k85c zZy|`dYhzWHraMUz#!%d?K4*ewbU!VO=j#<^0cUr*wTxuS;yh`XQe_RqHO)C=6Fz9C z(XpxA&GH-L1UL8YW|z$Bwe)n{&Pyv)TUm3CU<>e!#;6_2!OHg zr_1g)xk(Zb|7mloF$7jkW4J$r={zk+#8*6F$gvR*ZUm#TnyaR%R$F6T@3&xiT0hhX zU%kaWjJj5FDM4gN5wi@CdmvuLsI-n{e%t?ZvY?fN8fKxwg8rBj(yChl%RIGQAoU=< zTw?vdi*}b zS&y0$i;qjToF|-kZW)Me<00!Ic$WzXOB$%R#M&qe)p~J>KFZzpk3z@Z*i7SKUKjx} z%A1#Rz6P8Ij~lE)kDU-zWBvjnOQF<<&UL?i=ijt8HFg&ezAd8tLY%uBd{<;Mcg@yuCv?*4Y;vtU^8WUELAYVa?{pti+vM6F#}PJ={MMwr`9sckll2{* zL+EiM+MCsIQ+ml=d4_EHkuc5om9d~x@}Tsb&%qvQ>Ivp1Ywk`U?Qw(ay%B4_8(*%C zMDQo0-t5Bfv8KmQ-6z-XIKO=@Djz#zr_3N;U;_N29)W(WDw`z_Gj}i7`R8QZ+2Bug zK`)*%j|DcqLd;FS@A{nQ@5uN$CLtdYAzmLt7IxjiTVg3EG=5zQo@GyNRd+!8w0z|&;qCWhQ_PAeS z?@Z~iYzVACf-Y+-7^)f9I#M;iYMVBwFnu261m(}UB0U#Wid&!eU<$&We?lbM;8U(? z-l?>$Tp6mKAzf8D@`1-(Q0JRdat%8#^F`lS`HZzY?Vhg^Bj_1~k-buG^5O=e8RF)X zn9vq>2S<5T@rVqZ+V@4?Y>atyye^)+W$}UDEC3=7G-~M)2A}p~IvU0|SIhA)k&1I0 zVCE~!Op$*175AlCb>W-A!nVvUUOXIrTy&UhvbqJ0u44DNEQCEp%al@|SwFl}(P~vrL;l;JIjiVp(gr8&!n+HPIZQF?6gcB|Eo+=k!S6S)WfRfJS z<|9x~vgT7XlhQ8G9ldf#sQUDwypD=V#V&g zAsV#ngmlpMMpMi>3e7;pnQyMz0G(uWW_zHM%(sLR7(Sbw4$e#c438@L_C?B#$gZs_ zOh;cakOJztXuM0loL9BB8>^#RQPFe(`){siUnqg(8a^re0rGSe{!$fw_FUkV`8)x& z;(Cu-AMG`BCFy3;SH)z@1+yA46D&Pm)0(9o8ox3Ql$&}ga<0vlJ=SPQ0GH2nO@utx!=IhV9Cl_6bbG z5{gv~*<79$uj?T!KkOnxC&?ATP85Ok5LNd!mBS3_g`YK^Wxc<u$t zl4u(vo38C@DZ`xBG4VN@u5!3V-z`xA^bQ6YYGo_3*-(KgjC*eAqXfDtXM+knfr30Eh&TE{Km97?Nv^Vmb9B^| zLIOnh?o$Li-_!CxM;!b#C5MKu5XPpkkG^>=-4J0~v;V676&BlK!8ThZi z{ZC29-)xOokOJR}5C9CU3?2-O{=K}z-pQQF($2-n$m9!1KMU{?gq#gP14gSYJE2LU z3)ud!xLlGjfk)~77zb$@Z5uoQZfs(V2NM~MW~wfhP{W@x1S1_Kfo)C(e~~@JUqG8o z+qFj`4M+^46(lx@vzJy&nPtl#$A!C@T6ccjSS>nlY5IN81?2zWfQ$sV#i-C-p&XC)7wJsK#5gm zwVJO?oRtK2#&KZ+`dxYHHN8mM*4n2lbXv^F?R1hw)tjPWM`spCIDAG^wU|#G!5Mg7 zoc1K48Q~!lK7cS>zOh9Rx1!sKPzQ3_s3E&)lm>>i9jPI^YOF#A0&i=zFg*_IAbBGm z29Btz;xj9Y7)*3N5eUX7*d=>5>1y>boM3uX_pPf6SUMzLsPAsWo4#98Y=)v$;gM$AWY-v$D!4z8ir$?YE^M$+$<7RtFAu zN{!?XzkKD$vT3mU*$rlIqH1O+M{I+or}~ZS(3&p>E#VhmeFbfi;S7dd#7-(@qNBPn z4IV|G(}+6lvcNg|k2oU)hQo(iltCP`(PowHp~4*pZ!4FrR$!nrH&eJgyvzK{GLlPI zx2Z?!swClSc2W)O-9+2)oEKhgGr#jb`$Cx4ApKYnbld5{P4HZyMj|%$MdVGp1!-sz&yU6~YM6%08IiT(R~b zW9BoPZc7}8BLc}Z8eD@?=`pWE^kI6E;PikBJZllg0MCGlLKQLUi)2&j8YkIyY}p+3+>_XayQRr=)98?Bj`B;h%;&t&G-EJQYt?v9zb%bI;v84wq1 zEI6qgZT%vnwZBJPF&^lc>*U>2&HtUvq7^b}_=M=y>o$ER{-@9X&(ihT^PGo&0AdQ8scG2V`CW^6(BH$DuX zC{5Z6Yyl?>kQiyfOGIiA&)qP=gk#GOo}QPStf?I5wSA~ww{{5bG6G%LwFBOPzMd>% zRn%W1SYAM$L4wuwdRb$toMAog2*J<|h1iV<$*Q-98_ub&G%;Ybn2`P#ACOp=^UJy* z{_VwFNBxQ#-yNU!50@B=qYXrIbBJBvualjUtiRFU6M}|P^7dO(hMPSG4mKZ#S~j}- z(K3CIk&oYAC=MaCyMlR7)ABB<*G7*( z5mk{@p|GGhR3MvOhEJkiE$I=(VSHisdiPkqqeyfb|B4|17uTsp~tpS+0^>A%6ItLSigp*y0W5)b2rXE zxUxRVue6dD^1x4=(xhC(HsC7jPUTbluyKq-7((*R^434`N#2$0oVdi|+uSRD;-%6* zY43If*V2|gAWHR4`|Ye~RIT)$!gtluf8$bLdnNb@R%u}+zEQmGt(IVOub+6Z&;?xi ze!vqel8SN9BKY&r!0SYJ4^45KU=MmPjB(Z^m?7KT8_OZ2>Q!T+qOO6MxMip}fcc+(HIoBi}18zC(e5F@S+Ca{w5L1oQa7C#Mw&^uaDy zn>ZHE8d%FU>ls}iOM;afLKUvsI0D=NU1`IidNqJe^=CL7k~KMl!pW)ISh>VBL1CiO zSw-O}het`Hdfu+OO~TV`=kHx_p08N`eD@-T6%Z&OUNRnDST9s~b5+YD3m%Wy68g^7_8+^Ts9& za>#ufNj4k6H3TdzU1PqX2(d~@%KC@VwI-KUH(7B&WE9KKxiPEYoiWcY6W-EXLoGwk z5d(I**1+=azzQ9Xbtfdb$YbZVoma<0|H-N*;AM^tO|xjUS+OqAsRgt8`$qQk`4HGN({YXGe2^cr+8O$61CD32d&?MV#MJV( z++Q3dw|XBX7@{XH#o_9jM_GfZ{0t2H?sE`FHDz*_aU^ws+5AtPi$dGiiTAX@-pv_< zRQE1~Y)jD-?6d|(9;?dTc?=4tyx{_NnN+|f_e42DDob-f3zJM`rw z4u@Zu(7A`7$*N{SnI$l~;UJ(_ifuYy*~?AR0NY^M1bc`}UBdF==U6H$A4drSA%X+y zqh!aA*81i^;$^$W%`>lU;%@?FzqMJta=a0=uOT+AUB06sD*t$?EJyIO8a6zUUhWW? zO7ixT+`(1hAFWcrER*ujLBmfp`xbX#l1a+c&n>SXb&1M@wi~(k6T2#|j-~U{#K1l4 zLj!iz)tgt;CV3aeuKTct$ur}FSCoB%{eVYSJId}IaQJ-ao|A`Y7wLz)@iR*rfpjI( z1Dign7ZSIhtYWr%&(qpIo6Q?%lFtx}fK#47ljmEuhVd_H<{m!tNMHf)BZtA(MxVLT zoBu6eJ;sY7e`=4BX$n;#4@*~C>TQ3y!dPGUgM+Dr4q9KdO>Lnep~{$EOiNn?-q?tI z_9dn&L3xki#K*KcsAPz<3n}L}i2q#0|7>`9T#)!U%~%e-lY7jPbu%kRom~?TK`_&pz3b`To4ipI2=$%w8bD2OBkJ6Gq2bqS6!B- zSB{3wb}vsT)wZp^Cv}XxB*uQbtXK%!brAX@7k{!anS2C^Eph!i>-^;GVPg5^;dm7Z z%$k~+UfWG$I<9FEITwf^llwh6RuN9J4YyBf+Q7ikcHPECso(niq#pT@dk0~9+^I5Y(+K+)vRXz) z17*DLr~Q$iYmUK2^?AYY@i!P{2PBG+NB=mC#Bi|!jR>m&x_({efStOI94X9 zeloRh=r{g&3_Vji(|DBbI-JY#?P^$8m^vJG_zpS;YGM{naW9MV%2pi}aBaKFwCbak z;kF|X&Z_4y9nIVcVS(AG*(gV%Ohy#`XhBcF4<2zBN?@_bgos;?y=dV4;@mjh8ZgRj zutIkiu8(Q$rtJH}`7>h{XIg?o(Te)Rl+odhXxGis&e^ZU2jL0+I#`iHpX;AvI!!L` z@nsFFpK(UXn!1cD;6rEH&ohoYABMSd?#%|d>TFf^``Tx*ij}?@Q>*$r(st7iR*NnW z@`g_up^BsWNqxp?9Jjf5vwtuC$P9G`^|5EQ#wc)>1Nd{!V@4prd@c{1s zDX|CH#shf&vP)!>DT**_WxAIe-CIRdDo->aU=oI{=&;9y_@HezB76M zf6z65WXx3WGIkI|^1uDTOMYj5V)~2HoeY3VjA23m*(d)y48K3p6_)=<3IDdS{fFt# z_8%rf;uISKh%e<|6Pc8EDH->>lpGY90zmz1^6d|^S2b~4l?`<9AI-NvOahH}COt?B z1R(yaX$^X3!fXFwCaP=WfW|@p;;#J>Oz8d<;OG&8qKg3teK@h^5pD&U`vx2L{Ce06ze(t$?51CZYh{+wnwY47YgPf)=7G4Z1p6wQBmL`=`2 zBUAF-LDT5(>i>n01oBSr=>Y71&ZqSE=C-2~ zN%Ap3O6dR;qIU=H-jaXMeaBvX|4{x{8<;VF6cd?Z5kPrk05sx1<&b|XSHZ!+;@%(N zSpQ4==|9>;AeamQ;veY0wUbC-U^OgYVC4U$3={t^G(1Q(1Az9vfPgGB-up(E`_88a z6%+zc|27x3)Gz<1O84S@Y+V0^@Rs+k$pd1n`PWDEneXOeMej^ZkU=JZ_zz^jAKq2T z-==6v2|!bs|McsB_hy2DQT-QcN$p?dty=W|a|-{jtH9epN?8B~!uPTLZx$O2jPAcM zZvW`u{|PAoKEv;}&`6hVULijcthHOf_1WOV z;kz8(?Ni|=FyM}_XN$NmR*kw%qk?6vx3lxHjXTKQL2Agu;3aQzme8z7Q!&j|nyKdH zOI5JF8cYPp-8JN*`h&RDsO^m&9;i`~Pj)DMJmmxP zG+viW)B3L*2$h@X>rhrMJS(?v))Cx)1w7EV5DfTUE=5S)GSRqL{`dn;&CY{Gva(xK zck(E@p~=!QJC8aB?wM#@ENAZ3)UADz6Rtc)<7qmkp+m^as3q90Kvm1<9G8cP2UQk>=^6X8F=2#^=Q! zBTm9}KRU{mPE04?5VZ2tAH{BLiQ=Jp12Ov~&C0JV>fuRb7M0&i+SEwM4|obwZ`fqh>%w_YHC3-smNwc9cZC+)XXmzQ=g1Bl_#O=DatUa zgwQ)(S{|!<*);sDgl6wyk3d;xAWoJCwf1$xY$|RzXvraIgefkTxyaqMa9FeL9-&&T zFQV|1N-6xIQHJJmHXrZ(hk4*@rBvz4F%`vQA6GTws*1+MGJ28nch$x++F>8wQ{(yL zsz=O-ecv;CEGdJza+k)l&O(B0c%Yfm&O)NBJe=s_j;W8Cb5=PW+B~FdIh{1CCH$fS zOt`k34v>SIC@zN>W(LtRvjU>n1}7m-PnKQL=^PCtuL3+-k~_yKk^|ONKrp`SAsa<& zh_|dbPZVONC-*&#Z+Od-g`xX%>YnQ(qRy&>2nMr-*j-7_3-K3Xyb=;v&s?i;!0lBK z%zp8Vl^F2LDpx~pKTZR zZD};fpDMsOTYWp)?EatI?EZ{Y(L=caj@bSM&GBtLS+GZTz^Hnv=#BSvM#3}rel@Y$ z-Bz5yMl-EqGA4Z@JK>=VT!MJE zrN%0ZSXU>zVACZELH{{OU7Ws`A(6#5T7@g-U8Z;m&AMJn1B9^`t_h+Jx2TOW%xKWB z_OMpo{uH)OF#z^AP&wY$lhzK|9-|v+IlXsXXC&+`PQa^;G-+k3WM`Fs7}WF8#6EBpxVV{?*?NDSrzpTMMZLy}JQJ?c_<90#h6PU>rs2t} zG#SqZ+F}=+TS8~MI=*ddY!X|Qtg{|lW0=m5R;?7Deo2p5yUuC=yt9ucBYy)uM}5mU zw2&d^r6&zPZluxB4Z<0N>7TD-dJA~4^c0<|t_7B`f4rk3YT%J{8lfoRHJHT~rax)O zz6OyjbFVG-!oQuRv*7asHsi`hoooDn!4*Gjr7t5-zJLR4w&1=`d8c{U+e*vrrYhoa z`DX?<9Oi&@O*tGV;^O0msT`Y_ za$Jy2?X(G&o)TiHolYU8fQvsd`(ixO0dF(=GTe6qmf?#xXq8u#bFqWHRmDwWbdV%B$6G{m%0YTJ9sf4Q6d zy{!UAcTmj&d%z^6qq!R*v9HrI;EEpdz1}H&lW)>?XzCFnu-D+lJ1KbPCVAR#Td^~S z-l5-ZEx1Lv+AOg5put6yFo)wkUkm);79G-ahS9GVmf+qIgFXK7HWjY-TS5MPo6Zv) z;o|qK{4W2DK#%V%$^EaFLhZOOLe=%rj_&_~LZ}niB!PZYmi%OOg|b)~@Agw+7xmNA z2Y`#^nCu8@5fr@9Phra(IDVJC;KDy6@Z=q;V~WB>IQp9DZ2n~c7xU0Jh;Gt_CYXgS zgH(-DGxa_&PuF%okiK20ZSx1fQ)|zf2dJ2)K%H-F0G6`uU>(`=6&=a(p*qsX zNoANI!Gqw0uFJszfBiKjR2FNCr-_HsA35-3kCs{664^`fR^f!jgYZ1tm>`Hcmigb% z+r4Imj-396PO+WIR^o`WhUkHR*(}J8A*$mWDMIuOQHFEUgjhLD9b0) sb.append(STACK_ELE_DELIM); //Just like Arrays.toString(), place a comma between each stack trace ele. + sb.append(ste.toString()); + } + } + + return sb.toString(); + } @Override public void exit(String className, String methodName, int lineNo) { if (entryExitTrace) { - writeTraceOutput(className + ":" + methodName + ": }" + - (lineNo >= 0 ? ":" + lineNo : "")); + + if (exitStackTrace) { + writeTraceOutput(className + ":" + methodName + ": }" + + (lineNo >= 0 ? ":" + lineNo : "") + + STACK_TRACE_DELIM + getStackTrace() ); + } else { + writeTraceOutput(className + ":" + methodName + ": }" + + (lineNo >= 0 ? ":" + lineNo : "") ); + } } } diff --git a/org.intrace/src/org/intrace/output/trace/TraceSettings.java b/org.intrace/src/org/intrace/output/trace/TraceSettings.java index 3972648..3ef29f1 100644 --- a/org.intrace/src/org/intrace/output/trace/TraceSettings.java +++ b/org.intrace/src/org/intrace/output/trace/TraceSettings.java @@ -17,6 +17,16 @@ public class TraceSettings private boolean branchTraceEnabled = false; private boolean argTraceEnabled = true; private boolean truncateArraysEnabled = true; + + /** + * If true, append the 'current' stack trace to the text of the exit trace event. + * This is helpful for discovering who is invoking a particular line of code. + * Here is an example of the trace output: + *
+   * [07:53:15.509]:[1]:example.FirstTraceExample:intArrayMethod: }:70~java.lang.Thread.getStackTrace(Thread.java:1567),example.FirstTraceExample.intArrayMethod(FirstTraceExample.java:70),example.FirstTraceExample.workMethod(FirstTraceExample.java:38),example.FirstTraceExample.otherMain(FirstTraceExample.java:29),example.FirstTraceExample.main(FirstTraceExample.java:16)
+   * 
+ */ + private boolean exitStackTrace = false; public TraceSettings(TraceSettings oldSettings) { @@ -24,6 +34,7 @@ public class TraceSettings branchTraceEnabled = oldSettings.branchTraceEnabled; argTraceEnabled = oldSettings.argTraceEnabled; truncateArraysEnabled = oldSettings.truncateArraysEnabled; + exitStackTrace = oldSettings.exitStackTrace; } public TraceSettings(String args) @@ -74,6 +85,14 @@ public class TraceSettings { truncateArraysEnabled = false; } + else if (arg.equals(TraceConfigConstants.EXIT_STACK_TRACE + "false")) + { + exitStackTrace = false; + } + else if (arg.equals(TraceConfigConstants.EXIT_STACK_TRACE + "true")) + { + exitStackTrace = true; + } } public boolean isEntryExitTraceEnabled() @@ -95,6 +114,9 @@ public class TraceSettings { return truncateArraysEnabled; } + public boolean isExitStackTraceEnabled() { + return exitStackTrace; + } public Map getSettingsMap() { @@ -107,6 +129,9 @@ public class TraceSettings .put(TraceConfigConstants.ARG, Boolean.toString(argTraceEnabled)); settingsMap .put(TraceConfigConstants.ARRAYS, Boolean.toString(truncateArraysEnabled)); + + settingsMap.put(TraceConfigConstants.EXIT_STACK_TRACE, + Boolean.toString(exitStackTrace)); return settingsMap; } } \ No newline at end of file diff --git a/org.intrace/src/org/intrace/shared/AgentConfigConstants.java b/org.intrace/src/org/intrace/shared/AgentConfigConstants.java index a771d2f..b3fe9b2 100644 --- a/org.intrace/src/org/intrace/shared/AgentConfigConstants.java +++ b/org.intrace/src/org/intrace/shared/AgentConfigConstants.java @@ -24,6 +24,7 @@ public class AgentConfigConstants public static final String VERBOSE_MODE = "[verbose-"; public static final String OPT_SERVER_PORT = "[serverport-"; public static final String CALLBACK_PORT = "[callbackport-"; + public static final String EXIT_STACK_TRACE = "[exit-stack-trace-"; public static final String START_WAIT = "[startwait"; public static final String START_ACTIVATE = "[startactivate"; @@ -39,5 +40,6 @@ public class AgentConfigConstants COMMANDS.add(OPT_SERVER_PORT + ""); COMMANDS.add(CALLBACK_PORT + ""); COMMANDS.add(GZIP + ""); + COMMANDS.add(EXIT_STACK_TRACE + ""); } } diff --git a/org.intrace/src/org/intrace/shared/TraceConfigConstants.java b/org.intrace/src/org/intrace/shared/TraceConfigConstants.java index 045c5b8..55c70c4 100644 --- a/org.intrace/src/org/intrace/shared/TraceConfigConstants.java +++ b/org.intrace/src/org/intrace/shared/TraceConfigConstants.java @@ -12,6 +12,7 @@ public class TraceConfigConstants public static final String STD_OUT = "[out-stdout-"; public static final String FILE_OUT = "[out-file-"; public static final String NET_OUT = "[out-network-"; + public static final String EXIT_STACK_TRACE = "[exit-stack-trace-"; public static final Set COMMANDS = new HashSet(); static { @@ -22,5 +23,6 @@ public class TraceConfigConstants COMMANDS.add(STD_OUT + ""); COMMANDS.add(FILE_OUT + ""); COMMANDS.add(NET_OUT + ""); + COMMANDS.add(EXIT_STACK_TRACE + ""); } } diff --git a/org.intrace/testsrc/org/intracetest/agent/StackTraceTest.java b/org.intrace/testsrc/org/intracetest/agent/StackTraceTest.java new file mode 100644 index 0000000..a8faa33 --- /dev/null +++ b/org.intrace/testsrc/org/intracetest/agent/StackTraceTest.java @@ -0,0 +1,63 @@ +package org.intracetest.agent; + +import java.util.Map; + +import junit.framework.TestCase; + +import org.intrace.agent.AgentSettings; +import org.intrace.output.trace.TraceHandler; +import org.intrace.output.trace.TraceSettings; +import org.intrace.shared.AgentConfigConstants; +import org.intrace.shared.TraceConfigConstants; + +public class StackTraceTest extends TestCase +{ + private static final String MY_PACKAGE_AND_CLASS = "org.intracetest.agent.StackTraceTest"; + private String m_stackTrace; + /** Here is the raw stack trace that we want to validate: + *
+org.intracetest.agent.StackTraceTest.c(StackTraceTest.java:57),org.intracetest.agent.StackTraceTest.b(StackTraceTest.java:54),org.intracetest.agent.StackTraceTest.a(StackTraceTest.java:51),org.intracetest.agent.StackTraceTest.testStackTrace(StackTraceTest.java:27),sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57),sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43),java.lang.reflect.Method.invoke(Method.java:601),junit.framework.TestCase.runTest(TestCase.java:168),junit.framework.TestCase.runBare(TestCase.java:134),junit.framework.TestResult$1.protect(TestResult.java:110),junit.framework.TestResult.runProtected(TestResult.java:128),junit.framework.TestResult.run(TestResult.java:113),junit.framework.TestCase.run(TestCase.java:124),junit.framework.TestSuite.runTest(TestSuite.java:243),junit.framework.TestSuite.run(TestSuite.java:238),org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83),org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50),org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38),org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467),org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683),org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390),org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
+   * 
+ * Among other things, this test validates that the following are removed from the stack trace: + *
    + *
  • java.lang.Thread.getStackTrace
  • + *
  • all org.intrace. activity
  • + *
+ * + */ +public void testStackTrace() + { + a(); + String[] parts = m_stackTrace.split(","); + //System.out.println(m_stackTrace); + //JUnit has a thick call stack -- when I checked, there were 23 stack trace elements. + //Application developers only care about the ones on the very top. + assertTrue("Didn't not find the right number of StackTraceElements", parts.length > 4); + validateStackTraceElement("org.intracetest.agent.StackTraceTest.c", parts[0]); + validateStackTraceElement("org.intracetest.agent.StackTraceTest.b", parts[1]); + validateStackTraceElement("org.intracetest.agent.StackTraceTest.a", parts[2]); + validateStackTraceElement("org.intracetest.agent.StackTraceTest.testStackTrace", parts[3]); + //validateStackTraceElement("sun.reflect.NativeMethodAccessorImpl.invoke0", parts[4]); + } + private void validateStackTraceElement(String expectedPackageAndClassAndMethod, String actual) { + String[] partsOfStackTraceElement = actual.split("[\\(:\\)]"); + assertEquals("The package and class and method name were not found in the right place", + expectedPackageAndClassAndMethod, + partsOfStackTraceElement[0]); + + assertEquals("source file not found in the right place", + "StackTraceTest.java", + partsOfStackTraceElement[1]); + + } +private void a() { + b(); + } + private void b() { + c(); + } + private void c() { + m_stackTrace = TraceHandler.INSTANCE.getStackTrace(); + } + +} diff --git a/org.intrace/testsrc/org/intracetest/agent/TraceSettingsTest.java b/org.intrace/testsrc/org/intracetest/agent/TraceSettingsTest.java index 26d769a..fe34af4 100644 --- a/org.intrace/testsrc/org/intracetest/agent/TraceSettingsTest.java +++ b/org.intrace/testsrc/org/intracetest/agent/TraceSettingsTest.java @@ -22,17 +22,21 @@ public class TraceSettingsTest extends TestCase + "true" + TraceConfigConstants.BRANCH + "true" + + TraceConfigConstants.EXIT_STACK_TRACE + + "true" ); assertTrue(ts.isArgTraceEnabled()); assertTrue(ts.isEntryExitTraceEnabled()); assertTrue(ts.isBranchTraceEnabled()); + assertTrue(ts.isExitStackTraceEnabled()); assertTrue(ts.isTruncateArraysEnabled()); ts = new TraceSettings(ts); assertTrue(ts.isArgTraceEnabled()); assertTrue(ts.isEntryExitTraceEnabled()); assertTrue(ts.isBranchTraceEnabled()); + assertTrue(ts.isExitStackTraceEnabled()); assertTrue(ts.isTruncateArraysEnabled()); String toString = ts.toString(); @@ -42,6 +46,7 @@ public class TraceSettingsTest extends TestCase assertEquals(settingsMap.get(TraceConfigConstants.ARG), "true"); assertEquals(settingsMap.get(TraceConfigConstants.ARRAYS), "true"); assertEquals(settingsMap.get(TraceConfigConstants.BRANCH), "true"); + assertEquals(settingsMap.get(TraceConfigConstants.EXIT_STACK_TRACE),"true"); assertEquals(settingsMap.get(TraceConfigConstants.ENTRY_EXIT), "true"); }